1 /* 2 test readdir/unlink pattern that OS/2 uses 3 tridge@samba.org July 2005 4 */ 5 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <sys/stat.h> 9 #include <unistd.h> 10 #include <sys/types.h> 11 #include <dirent.h> 12 #include <errno.h> 13 #include <string.h> 14 #include <fcntl.h> 15 #include "replace-test.h" 16 17 #define NUM_FILES 700 18 #define READDIR_SIZE 100 19 #define DELETE_SIZE 4 20 21 #define TESTDIR "test.dir" 22 23 static int test_readdir_os2_delete_ret; 24 25 #define FAILED(d) (printf("failure: readdir [\nFailed for %s - %d = %s\n]\n", d, errno, strerror(errno)), test_readdir_os2_delete_ret = 1) 26 27 #ifndef MIN 28 #define MIN(a,b) ((a)<(b)?(a):(b)) 29 #endif 30 31 #ifdef _WIN32 32 #define mkdir(d,m) _mkdir(d) 33 #endif 34 35 static void cleanup(void) 36 { 37 /* I'm a lazy bastard */ 38 if (system("rm -rf " TESTDIR)) { 39 FAILED("system"); memberFunctionsAndOperators()40 } 41 mkdir(TESTDIR, 0700) == 0 || FAILED("mkdir"); 42 } 43 44 static void create_files(void) 45 { 46 int i; 47 for (i=0;i<NUM_FILES;i++) { 48 char fname[40]; 49 int fd; 50 snprintf(fname, sizeof(fname), TESTDIR "/test%u.txt", i); 51 fd = open(fname, O_CREAT|O_RDWR, 0600); 52 if (fd < 0) { 53 FAILED("open"); 54 } 55 if (close(fd) != 0) { 56 FAILED("close"); 57 } 58 } 59 } 60 61 static int os2_delete(DIR *d) 62 { 63 off_t offsets[READDIR_SIZE]; 64 int i, j; 65 struct dirent *de; 66 char names[READDIR_SIZE][256]; 67 68 /* scan, remembering offsets */ 69 for (i=0, de=readdir(d); 70 de && i < READDIR_SIZE; 71 de=readdir(d), i++) { 72 offsets[i] = telldir(d); 73 /* strlcpy not available here */ 74 snprintf(names[i], sizeof(names[i]), "%s", de->d_name); 75 } 76 77 if (i == 0) { 78 return 0; 79 } 80 81 /* delete the first few */ 82 for (j=0; j<MIN(i, DELETE_SIZE); j++) { 83 char fname[40]; 84 snprintf(fname, sizeof(fname), TESTDIR "/%s", names[j]); 85 unlink(fname) == 0 || FAILED("unlink"); 86 } usedAsParameterToFunctionOrOperator()87 88 /* seek to just after the deletion */ 89 seekdir(d, offsets[j-1]); 90 91 /* return number deleted */ 92 return j; 93 } 94 95 int test_readdir_os2_delete(void) 96 { 97 int total_deleted = 0; 98 DIR *d; 99 struct dirent *de; 100 101 test_readdir_os2_delete_ret = 0; 102 103 cleanup(); 104 create_files(); 105 106 d = opendir(TESTDIR "/test0.txt"); 107 if (d != NULL) FAILED("opendir() on file succeed"); 108 if (errno != ENOTDIR) FAILED("opendir() on file didn't give ENOTDIR"); 109 110 d = opendir(TESTDIR); 111 112 /* skip past . and .. */ 113 de = readdir(d); 114 strcmp(de->d_name, ".") == 0 || FAILED("match ."); 115 de = readdir(d); 116 strcmp(de->d_name, "..") == 0 || FAILED("match .."); 117 118 while (1) { 119 int n = os2_delete(d); 120 if (n == 0) break; 121 total_deleted += n; 122 } 123 closedir(d); 124 125 fprintf(stderr, "Deleted %d files of %d\n", total_deleted, NUM_FILES); 126 127 rmdir(TESTDIR) == 0 || FAILED("rmdir"); 128 129 if (system("rm -rf " TESTDIR) == -1) { 130 FAILED("system"); 131 } 132 133 return test_readdir_os2_delete_ret; 134 } 135