157718be8SEnji Cooper /* $NetBSD: t_basedirname.c,v 1.2 2011/07/07 09:49:59 jruoho Exp $ */ 257718be8SEnji Cooper 357718be8SEnji Cooper /* 457718be8SEnji Cooper * Regression test for basename(3). 557718be8SEnji Cooper * 657718be8SEnji Cooper * Written by Jason R. Thorpe <thorpej@NetBSD.org>, Oct. 2002. 757718be8SEnji Cooper * Public domain. 857718be8SEnji Cooper */ 957718be8SEnji Cooper 1057718be8SEnji Cooper #include <atf-c.h> 1157718be8SEnji Cooper 1257718be8SEnji Cooper #include <assert.h> 1357718be8SEnji Cooper #include <stdio.h> 1457718be8SEnji Cooper #include <stdlib.h> 1557718be8SEnji Cooper #include <string.h> 1657718be8SEnji Cooper #include <libgen.h> 1757718be8SEnji Cooper 1857718be8SEnji Cooper struct { 1957718be8SEnji Cooper const char *input; 2057718be8SEnji Cooper const char *output; 2157718be8SEnji Cooper } test_basename_table[] = { 2257718be8SEnji Cooper /* 2357718be8SEnji Cooper * The following are taken from the "Sample Input and Output Strings 2457718be8SEnji Cooper * for basename()" table in IEEE Std 1003.1-2001. 2557718be8SEnji Cooper */ 2657718be8SEnji Cooper { "/usr/lib", "lib" }, 2757718be8SEnji Cooper { "/usr/", "usr" }, 2857718be8SEnji Cooper { "/", "/" }, 2957718be8SEnji Cooper { "///", "/" }, 3057718be8SEnji Cooper { "//usr//lib//", "lib" }, 3157718be8SEnji Cooper /* 3257718be8SEnji Cooper * IEEE Std 1003.1-2001: 3357718be8SEnji Cooper * 3457718be8SEnji Cooper * If path is a null pointer or points to an empty string, 3557718be8SEnji Cooper * basename() shall return a pointer to the string "." . 3657718be8SEnji Cooper */ 3757718be8SEnji Cooper { "", "." }, 3857718be8SEnji Cooper { NULL, "." }, 3957718be8SEnji Cooper /* 4057718be8SEnji Cooper * IEEE Std 1003.1-2001: 4157718be8SEnji Cooper * 4257718be8SEnji Cooper * If the string is exactly "//", it is implementation-defined 4357718be8SEnji Cooper * whether "/" or "//" is returned. 4457718be8SEnji Cooper * 4557718be8SEnji Cooper * The NetBSD implementation returns "/". 4657718be8SEnji Cooper */ 4757718be8SEnji Cooper { "//", "/" }, 4857718be8SEnji Cooper 4957718be8SEnji Cooper { NULL, NULL } 5057718be8SEnji Cooper }; 5157718be8SEnji Cooper 5257718be8SEnji Cooper struct { 5357718be8SEnji Cooper const char *input; 5457718be8SEnji Cooper const char *output; 5557718be8SEnji Cooper } test_dirname_table[] = { 5657718be8SEnji Cooper /* 5757718be8SEnji Cooper * The following are taken from the "Sample Input and Output Strings 5857718be8SEnji Cooper * for dirname()" table in IEEE Std 1003.1-2001. 5957718be8SEnji Cooper */ 6057718be8SEnji Cooper { "/usr/lib", "/usr" }, 6157718be8SEnji Cooper { "/usr/", "/" }, 6257718be8SEnji Cooper { "usr", "." }, 6357718be8SEnji Cooper { "/", "/" }, 6457718be8SEnji Cooper { ".", "." }, 6557718be8SEnji Cooper { "..", "." }, 6657718be8SEnji Cooper /* 6757718be8SEnji Cooper * IEEE Std 1003.1-2001: 6857718be8SEnji Cooper * 6957718be8SEnji Cooper * If path is a null pointer or points to an empty string, 7057718be8SEnji Cooper * dirname() shall return a pointer to the string "." . 7157718be8SEnji Cooper */ 7257718be8SEnji Cooper { "", "." }, 7357718be8SEnji Cooper { NULL, "." }, 7457718be8SEnji Cooper /* 7557718be8SEnji Cooper * IEEE Std 1003.1-2001: 7657718be8SEnji Cooper * 7757718be8SEnji Cooper * Since the meaning of the leading "//" is implementation-defined, 7857718be8SEnji Cooper * dirname("//foo") may return either "//" or "/" (but nothing else). 7957718be8SEnji Cooper * 8057718be8SEnji Cooper * The NetBSD implementation returns "/". 8157718be8SEnji Cooper */ 8257718be8SEnji Cooper { "//foo", "/" }, 8357718be8SEnji Cooper /* 8457718be8SEnji Cooper * Make sure the trailing slashes after the directory name component 8557718be8SEnji Cooper * get trimmed. The Std does not talk about this, but this is what 8657718be8SEnji Cooper * Solaris 8's dirname(3) does. 8757718be8SEnji Cooper */ 8857718be8SEnji Cooper { "/usr///lib", "/usr" }, 8957718be8SEnji Cooper 9057718be8SEnji Cooper { NULL, NULL } 9157718be8SEnji Cooper }; 9257718be8SEnji Cooper 9357718be8SEnji Cooper ATF_TC(basename_posix); 9457718be8SEnji Cooper ATF_TC_HEAD(basename_posix, tc) 9557718be8SEnji Cooper { 9657718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test basename(3) with POSIX examples"); 9757718be8SEnji Cooper } 9857718be8SEnji Cooper 9957718be8SEnji Cooper ATF_TC_BODY(basename_posix, tc) 10057718be8SEnji Cooper { 10157718be8SEnji Cooper char testbuf[32], *base; 10257718be8SEnji Cooper int i; 10357718be8SEnji Cooper 10457718be8SEnji Cooper for (i = 0; test_basename_table[i].output != NULL; i++) { 10557718be8SEnji Cooper if (test_basename_table[i].input != NULL) { 10657718be8SEnji Cooper if (strlen(test_basename_table[i].input) >= 10757718be8SEnji Cooper sizeof(testbuf)) 10857718be8SEnji Cooper atf_tc_skip("Testbuf too small!"); 10957718be8SEnji Cooper strcpy(testbuf, test_basename_table[i].input); 11057718be8SEnji Cooper base = basename(testbuf); 11157718be8SEnji Cooper } else 11257718be8SEnji Cooper base = basename(NULL); 11357718be8SEnji Cooper 114*576a9e49SEd Schouten #ifdef __NetBSD__ 11557718be8SEnji Cooper /* 11657718be8SEnji Cooper * basename(3) is allowed to modify the input buffer. 11757718be8SEnji Cooper * However, that is considered hostile by some programs, 11857718be8SEnji Cooper * and so we elect to consider this an error. 11957718be8SEnji Cooper * 12057718be8SEnji Cooper * This is not a problem, as basename(3) is also allowed 12157718be8SEnji Cooper * to return a pointer to a statically-allocated buffer 12257718be8SEnji Cooper * (it is explicitly not required to be reentrant). 12357718be8SEnji Cooper */ 12457718be8SEnji Cooper if (test_basename_table[i].input != NULL && 12557718be8SEnji Cooper strcmp(test_basename_table[i].input, testbuf) != 0) { 12657718be8SEnji Cooper fprintf(stderr, 12757718be8SEnji Cooper "Input buffer for \"%s\" was modified\n", 12857718be8SEnji Cooper test_basename_table[i].input); 12957718be8SEnji Cooper atf_tc_fail("Input buffer was modified."); 13057718be8SEnji Cooper } 131*576a9e49SEd Schouten #endif 13257718be8SEnji Cooper 13357718be8SEnji Cooper /* Make sure the result is correct. */ 13457718be8SEnji Cooper if (strcmp(test_basename_table[i].output, base) != 0) { 13557718be8SEnji Cooper fprintf(stderr, 13657718be8SEnji Cooper "Input \"%s\", output \"%s\", expected \"%s\"\n", 13757718be8SEnji Cooper test_basename_table[i].input == 13857718be8SEnji Cooper NULL ? "(null)" : test_basename_table[i].input, 13957718be8SEnji Cooper base, test_basename_table[i].output); 14057718be8SEnji Cooper atf_tc_fail("Output does not match expected value."); 14157718be8SEnji Cooper } 14257718be8SEnji Cooper } 14357718be8SEnji Cooper } 14457718be8SEnji Cooper 14557718be8SEnji Cooper 14657718be8SEnji Cooper ATF_TC(dirname_posix); 14757718be8SEnji Cooper ATF_TC_HEAD(dirname_posix, tc) 14857718be8SEnji Cooper { 14957718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test dirname(3) with POSIX examples"); 15057718be8SEnji Cooper } 15157718be8SEnji Cooper 15257718be8SEnji Cooper ATF_TC_BODY(dirname_posix, tc) 15357718be8SEnji Cooper { 15457718be8SEnji Cooper char testbuf[32], *base; 15557718be8SEnji Cooper int i; 15657718be8SEnji Cooper 15757718be8SEnji Cooper for (i = 0; test_dirname_table[i].output != NULL; i++) { 15857718be8SEnji Cooper if (test_dirname_table[i].input != NULL) { 15957718be8SEnji Cooper if (strlen(test_dirname_table[i].input) >= 16057718be8SEnji Cooper sizeof(testbuf)) 16157718be8SEnji Cooper atf_tc_skip("Testbuf too small!"); 16257718be8SEnji Cooper strcpy(testbuf, test_dirname_table[i].input); 16357718be8SEnji Cooper base = dirname(testbuf); 16457718be8SEnji Cooper } else 16557718be8SEnji Cooper base = dirname(NULL); 16657718be8SEnji Cooper 167*576a9e49SEd Schouten #ifdef __NetBSD__ 16857718be8SEnji Cooper /* 16957718be8SEnji Cooper * dirname(3) is allowed to modify the input buffer. 17057718be8SEnji Cooper * However, that is considered hostile by some programs, 17157718be8SEnji Cooper * and so we elect to consider this an error. 17257718be8SEnji Cooper * 17357718be8SEnji Cooper * This is not a problem, as dirname(3) is also allowed 17457718be8SEnji Cooper * to return a pointer to a statically-allocated buffer 17557718be8SEnji Cooper * (it is explicitly not required to be reentrant). 17657718be8SEnji Cooper */ 17757718be8SEnji Cooper if (test_dirname_table[i].input != NULL && 17857718be8SEnji Cooper strcmp(test_dirname_table[i].input, testbuf) != 0) { 17957718be8SEnji Cooper fprintf(stderr, 18057718be8SEnji Cooper "Input buffer for \"%s\" was modified\n", 18157718be8SEnji Cooper test_dirname_table[i].input); 18257718be8SEnji Cooper atf_tc_fail("Input buffer was modified."); 18357718be8SEnji Cooper } 184*576a9e49SEd Schouten #endif 18557718be8SEnji Cooper 18657718be8SEnji Cooper /* Make sure the result is correct. */ 18757718be8SEnji Cooper if (strcmp(test_dirname_table[i].output, base) != 0) { 18857718be8SEnji Cooper fprintf(stderr, 18957718be8SEnji Cooper "Input \"%s\", output \"%s\", expected \"%s\"\n", 19057718be8SEnji Cooper test_dirname_table[i].input == 19157718be8SEnji Cooper NULL ? "(null)" : test_dirname_table[i].input, 19257718be8SEnji Cooper base, test_dirname_table[i].output); 19357718be8SEnji Cooper atf_tc_fail("Output does not match expected value."); 19457718be8SEnji Cooper } 19557718be8SEnji Cooper } 19657718be8SEnji Cooper } 19757718be8SEnji Cooper 19857718be8SEnji Cooper ATF_TP_ADD_TCS(tp) 19957718be8SEnji Cooper { 20057718be8SEnji Cooper ATF_TP_ADD_TC(tp, basename_posix); 20157718be8SEnji Cooper ATF_TP_ADD_TC(tp, dirname_posix); 20257718be8SEnji Cooper 20357718be8SEnji Cooper return atf_no_error(); 20457718be8SEnji Cooper } 205