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