1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
5 #define _GNU_SOURCE /* pull in O_DIRECTORY in bits/fcntl.h */
11 #include <sys/types.h>
18 #define T1 "write data before unlink\n"
19 #define T2 "write data after unlink\n"
20 char buf[] = "yabba dabba doo, I'm coming for you, I live in a shoe, I don't know what to do.\n'Bigger, bigger,and bigger yet!' cried the Creator. 'You are not yet substantial enough for my boundless intents!' And ever greater and greater the object became, until all was lost 'neath its momentus bulk.\n";
23 "Usage: %s filename command-sequence\n"
24 " command-sequence items:\n"
27 " D open(O_DIRECTORY)\n"
31 " M rw mmap to EOF (must open and stat prior)\n"
34 " O open(O_CREAT|O_RDWR)\n"
35 " r[num] read [optional length]\n"
36 " R reference entire mmap-ed region\n"
40 " T[num] ftruncate [optional position, default 0]\n"
43 " w[num] write optional length\n"
44 " W write entire mmap-ed region\n"
47 " z[num] seek [optional position, default 0]\n"
48 " _ wait for signal\n";
50 static int usr1_received;
51 void usr1_handler(int unused)
57 pop_arg(int argc, char *argv[])
59 static int cur_arg = 3;
64 return argv[cur_arg++];
71 {"O_RDONLY", O_RDONLY},
72 {"O_WRONLY", O_WRONLY},
76 {"O_NOCTTY", O_NOCTTY},
78 {"O_APPEND", O_APPEND},
79 {"O_NONBLOCK", O_NONBLOCK},
80 {"O_NDELAY", O_NDELAY},
83 {"O_DIRECT", O_DIRECT},
85 {"O_LARGEFILE", O_LARGEFILE},
86 {"O_DIRECTORY", O_DIRECTORY},
87 {"O_NOFOLLOW", O_NOFOLLOW},
91 int get_flags(char *data, int *rflags)
99 cloned_flags = strdup(data);
100 if (cloned_flags == NULL) {
101 fprintf(stderr, "Insufficient memory.\n");
105 for (tmp = strtok(cloned_flags, ":"); tmp;
106 tmp = strtok(NULL, ":")) {
109 size = tmp - cloned_flags;
110 for (i = 0; flag_table[i].flag != -1; i++) {
111 if (!strcmp(tmp, flag_table[i].string)){
112 flags |= flag_table[i].flag;
113 size += strlen(flag_table[i].string);
130 #define POP_ARG() (pop_arg(argc, argv))
131 #define min(a,b) ((a)>(b)?(b):(a))
133 int main(int argc, char **argv)
135 char *fname, *commands;
138 size_t mmap_len = 0, i;
139 unsigned char *mmap_ptr = NULL, junk = 0;
140 int rc, len, fd = -1;
145 fprintf(stderr, usage, argv[0]);
149 signal(SIGUSR1, usr1_handler);
153 for (commands = argv[2]; *commands; commands++) {
156 if (usr1_received == 0)
159 signal(SIGUSR1, usr1_handler);
162 if (close(fd) == -1) {
170 if (mkdir(fname, 0755) == -1) {
172 perror("mkdir(0755)");
177 fd = open(fname, O_DIRECTORY);
180 perror("open(O_DIRECTORY)");
188 if (symlink(fname, newfile)) {
198 if (link(fname, newfile)) {
205 if (mknod(fname, S_IFREG | 0644, 0) == -1) {
207 perror("mknod(S_IFREG|0644, 0)");
212 mmap_len = st.st_size;
213 mmap_ptr = mmap(NULL, mmap_len, PROT_WRITE | PROT_READ,
215 if (mmap_ptr == MAP_FAILED) {
225 if (rename (fname, newfile)) {
232 fd = open(fname, O_CREAT|O_RDWR, 0644);
235 perror("open(O_RDWR|O_CREAT)");
240 len = get_flags(commands+1, &flags);
242 fd = open(fname, flags);
250 len = atoi(commands+1);
255 min(len,sizeof(buf))) == -1) {
264 if (fstat(fd, &st) == -1) {
271 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
275 if (stat(fname, &st) == -1) {
282 if (fchmod(fd, 0) == -1) {
289 len = atoi(commands+1);
290 if (ftruncate(fd, len) == -1) {
292 printf("ftruncate (%d,%d)\n", fd, len);
298 if (unlink(fname) == -1) {
305 if (munmap(mmap_ptr, mmap_len)) {
312 len = atoi(commands+1);
316 if ((rc = write(fd, buf,
317 min(len, sizeof(buf))))
327 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
328 mmap_ptr[i] += junk++;
331 if (fsync(fd) == -1) {
338 if (fdatasync(fd) == -1) {
344 len = atoi(commands+1);
345 if (lseek(fd, len, SEEK_SET) == -1) {
363 fprintf(stderr, "unknown command \"%c\"\n", *commands);
364 fprintf(stderr, usage, argv[0]);