1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 #define _GNU_SOURCE /* pull in O_DIRECTORY in bits/fcntl.h */
16 #define T1 "write data before unlink\n"
17 #define T2 "write data after unlink\n"
18 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";
21 "Usage: %s filename command-sequence\n"
22 " command-sequence items:\n"
25 " D open(O_DIRECTORY)\n"
29 " M rw mmap to EOF (must open and stat prior)\n"
32 " O open(O_CREAT|O_RDWR)\n"
33 " r[num] read [optional length]\n"
34 " R reference entire mmap-ed region\n"
38 " T[num] ftruncate [optional position, default 0]\n"
41 " w[num] write optional length\n"
42 " W write entire mmap-ed region\n"
45 " z[num] seek [optional position, default 0]\n"
46 " _ wait for signal\n";
48 static int usr1_received;
49 void usr1_handler(int unused)
55 pop_arg(int argc, char *argv[])
57 static int cur_arg = 3;
62 return argv[cur_arg++];
69 {"O_RDONLY", O_RDONLY},
70 {"O_WRONLY", O_WRONLY},
74 {"O_NOCTTY", O_NOCTTY},
76 {"O_APPEND", O_APPEND},
77 {"O_NONBLOCK", O_NONBLOCK},
78 {"O_NDELAY", O_NDELAY},
81 {"O_DIRECT", O_DIRECT},
83 {"O_LARGEFILE", O_LARGEFILE},
84 {"O_DIRECTORY", O_DIRECTORY},
85 {"O_NOFOLLOW", O_NOFOLLOW},
89 int get_flags(char *data, int *rflags)
97 cloned_flags = strdup(data);
98 if (cloned_flags == NULL) {
99 fprintf(stderr, "Insufficient memory.\n");
103 for (tmp = strtok(cloned_flags, ":"); tmp;
104 tmp = strtok(NULL, ":")) {
107 size = tmp - cloned_flags;
108 for (i = 0; flag_table[i].flag != -1; i++) {
109 if (!strcmp(tmp, flag_table[i].string)){
110 flags |= flag_table[i].flag;
111 size += strlen(flag_table[i].string);
128 #define POP_ARG() (pop_arg(argc, argv))
129 #define min(a,b) ((a)>(b)?(b):(a))
131 int main(int argc, char **argv)
133 char *fname, *commands;
136 size_t mmap_len = 0, i;
137 unsigned char *mmap_ptr = NULL, junk = 0;
138 int rc, len, fd = -1;
143 fprintf(stderr, usage, argv[0]);
147 signal(SIGUSR1, usr1_handler);
151 for (commands = argv[2]; *commands; commands++) {
154 if (usr1_received == 0)
157 signal(SIGUSR1, usr1_handler);
160 if (close(fd) == -1) {
168 if (mkdir(fname, 0755) == -1) {
170 perror("mkdir(0755)");
175 fd = open(fname, O_DIRECTORY);
178 perror("open(O_DIRECTORY)");
186 if (symlink(fname, newfile)) {
196 if (link(fname, newfile)) {
203 if (mknod(fname, S_IFREG | 0644, 0) == -1) {
205 perror("mknod(S_IFREG|0644, 0)");
210 mmap_len = st.st_size;
211 mmap_ptr = mmap(NULL, mmap_len, PROT_WRITE | PROT_READ,
213 if (mmap_ptr == MAP_FAILED) {
223 if (rename (fname, newfile)) {
230 fd = open(fname, O_CREAT|O_RDWR, 0644);
233 perror("open(O_RDWR|O_CREAT)");
238 len = get_flags(commands+1, &flags);
240 fd = open(fname, flags);
248 len = atoi(commands+1);
253 min(len,sizeof(buf))) == -1) {
262 if (fstat(fd, &st) == -1) {
269 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
273 if (stat(fname, &st) == -1) {
280 if (fchmod(fd, 0) == -1) {
287 len = atoi(commands+1);
288 if (ftruncate(fd, len) == -1) {
290 printf("ftruncate (%d,%d)\n", fd, len);
296 if (unlink(fname) == -1) {
303 if (munmap(mmap_ptr, mmap_len)) {
310 len = atoi(commands+1);
314 if ((rc = write(fd, buf,
315 min(len, sizeof(buf))))
325 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
326 mmap_ptr[i] += junk++;
329 if (fsync(fd) == -1) {
336 if (fdatasync(fd) == -1) {
342 len = atoi(commands+1);
343 if (lseek(fd, len, SEEK_SET) == -1) {
361 fprintf(stderr, "unknown command \"%c\"\n", *commands);
362 fprintf(stderr, usage, argv[0]);