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