1 /* $NetBSD: realpath.c,v 1.2 2024/08/18 20:47:27 christos Exp $ */ 2 3 #include "config.h" 4 5 #include "ntp_stdlib.h" 6 #include "unity.h" 7 8 #include <sys/types.h> 9 #include <sys/stat.h> 10 #include <unistd.h> 11 #include <dirent.h> 12 #include <stdarg.h> 13 14 static char * resolved; 15 16 void setUp(void); 17 void setUp(void) { 18 resolved = NULL; 19 } 20 21 void tearDown(void); 22 void tearDown(void) { 23 free(resolved); 24 resolved = NULL; 25 } 26 27 static int/*BOOL*/ isValidAbsPath(const char * path) 28 { 29 int retv = FALSE; 30 /* this needs some elaboration: */ 31 if (path && path[0] == '/') { 32 struct stat sb; 33 if (0 == lstat(path, &sb)) { 34 retv = (sb.st_mode & S_IFMT) != S_IFLNK; 35 } 36 } 37 return retv; 38 } 39 40 static const char * errMsg(const char *fmt, ...) 41 { 42 static char buf[256]; 43 va_list va; 44 va_start(va, fmt); 45 vsnprintf(buf, sizeof(buf), fmt, va); 46 va_end(va); 47 return buf; 48 } 49 50 void test_CurrentWorkingDir(void); 51 void test_CurrentWorkingDir(void) { 52 # ifdef SYS_WINNT 53 TEST_IGNORE_MESSAGE("not applicable to windows so far"); 54 # else 55 resolved = ntp_realpath("."); 56 TEST_ASSERT_NOT_NULL_MESSAGE(resolved, "failed to resolve '.'"); 57 TEST_ASSERT_TRUE_MESSAGE(isValidAbsPath(resolved), "'.' not resolved to absolute path"); 58 # endif 59 } 60 61 void test_DevLinks(void); 62 void test_DevLinks(void) { 63 # ifdef SYS_WINNT 64 TEST_IGNORE_MESSAGE("not applicable to windows so far"); 65 # else 66 char nam[512]; 67 char abs[512]; 68 struct dirent * ent; 69 DIR * dfs = opendir("/dev"); 70 71 TEST_ASSERT_NOT_NULL_MESSAGE(dfs, "failed to open '/dev' !?!"); 72 while (NULL != (ent = readdir(dfs))) { 73 /* the /dev/std{in,out,err} symlinks are prone to some 74 * kind of race condition under Linux, so we better skip 75 * them here; running tests in parallel can fail mysteriously 76 * otherwise. (Dunno *how* this could happen, but it 77 * did at some point in time, quite reliably...) 78 */ 79 if (!strncmp(ent->d_name, "std", 3)) 80 continue; 81 /* otherwise build the full name & try to resolve: */ 82 snprintf(nam, sizeof(nam), "/dev/%s", ent->d_name); 83 resolved = ntp_realpath(nam); 84 TEST_ASSERT_NOT_NULL_MESSAGE(resolved, errMsg("could not resolve '%s'", nam)); 85 strlcpy(abs, resolved, sizeof(abs)); 86 free(resolved); 87 resolved = NULL; 88 /* test/development code: 89 if (strcmp(nam, abs)) 90 printf(" '%s' --> '%s'\n", nam, abs); 91 */ 92 TEST_ASSERT_TRUE_MESSAGE(isValidAbsPath(abs), errMsg("could not validate '%s'", abs)); 93 } 94 closedir(dfs); 95 # endif 96 } 97