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