diff options
Diffstat (limited to 'tests/bugs/write-behind/bug-1279730.c')
-rw-r--r-- | tests/bugs/write-behind/bug-1279730.c | 232 |
1 files changed, 125 insertions, 107 deletions
diff --git a/tests/bugs/write-behind/bug-1279730.c b/tests/bugs/write-behind/bug-1279730.c index 535d289c582..706ae67b102 100644 --- a/tests/bugs/write-behind/bug-1279730.c +++ b/tests/bugs/write-behind/bug-1279730.c @@ -8,124 +8,142 @@ #include <assert.h> int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - int fd = -1, ret = -1, len = 0; - char *path = NULL, buf[128] = {0, }, *cmd = NULL; - struct stat stbuf = {0, }; - int write_to_child[2] = {0, }, write_to_parent[2] = {0, }; + int fd = -1, ret = -1, len = 0; + char *path = NULL, + buf[128] = + { + 0, + }, + *cmd = NULL; + struct stat stbuf = { + 0, + }; + int write_to_child[2] = + { + 0, + }, + write_to_parent[2] = { + 0, + }; + + path = argv[1]; + cmd = argv[2]; + + assert(argc == 3); + + ret = pipe(write_to_child); + if (ret < 0) { + fprintf(stderr, + "creation of write-to-child pipe failed " + "(%s)\n", + strerror(errno)); + goto out; + } + + ret = pipe(write_to_parent); + if (ret < 0) { + fprintf(stderr, + "creation of write-to-parent pipe failed " + "(%s)\n", + strerror(errno)); + goto out; + } + + ret = fork(); + switch (ret) { + case 0: + close(write_to_child[1]); + close(write_to_parent[0]); + + /* child, wait for instructions to execute command */ + ret = read(write_to_child[0], buf, 128); + if (ret < 0) { + fprintf(stderr, "child: read on pipe failed (%s)\n", + strerror(errno)); + goto out; + } - path = argv[1]; - cmd = argv[2]; + system(cmd); + + ret = write(write_to_parent[1], "1", 2); + if (ret < 0) { + fprintf(stderr, "child: write to pipe failed (%s)\n", + strerror(errno)); + goto out; + } + break; - assert (argc == 3); + case -1: + fprintf(stderr, "fork failed (%s)\n", strerror(errno)); + goto out; + + default: + close(write_to_parent[1]); + close(write_to_child[0]); - ret = pipe (write_to_child); - if (ret < 0) { - fprintf (stderr, "creation of write-to-child pipe failed " - "(%s)\n", strerror (errno)); + fd = open(path, O_CREAT | O_RDWR | O_APPEND, S_IRWXU); + if (fd < 0) { + fprintf(stderr, "open failed (%s)\n", strerror(errno)); goto out; - } + } + + len = strlen("test-content") + 1; + ret = write(fd, "test-content", len); + + if (ret < len) { + fprintf(stderr, "write failed %d (%s)\n", ret, strerror(errno)); + } + + ret = pread(fd, buf, 128, 0); + if ((ret == len) && (strcmp(buf, "test-content") == 0)) { + fprintf(stderr, + "read should've failed as previous " + "write would've failed with EDQUOT, but its " + "successful"); + ret = -1; + goto out; + } - ret = pipe (write_to_parent); - if (ret < 0) { - fprintf (stderr, "creation of write-to-parent pipe failed " - "(%s)\n", strerror (errno)); + ret = write(write_to_child[1], "1", 2); + if (ret < 0) { + fprintf(stderr, "parent: write to pipe failed (%s)\n", + strerror(errno)); goto out; - } + } - ret = fork (); - switch (ret) { - case 0: - close (write_to_child[1]); - close (write_to_parent[0]); - - /* child, wait for instructions to execute command */ - ret = read (write_to_child[0], buf, 128); - if (ret < 0) { - fprintf (stderr, "child: read on pipe failed (%s)\n", - strerror (errno)); - goto out; - } - - system (cmd); - - ret = write (write_to_parent[1], "1", 2); - if (ret < 0) { - fprintf (stderr, "child: write to pipe failed (%s)\n", - strerror (errno)); - goto out; - } - break; + ret = read(write_to_parent[0], buf, 128); + if (ret < 0) { + fprintf(stderr, "parent: read from pipe failed (%s)\n", + strerror(errno)); + goto out; + } + + /* this will force a sync on cached-write and now that quota + limit is increased, sync will be successful. ignore return + value as fstat would fail with EDQUOT (picked up from + cached-write because of previous sync failure. + */ + fstat(fd, &stbuf); + + ret = pread(fd, buf, 128, 0); + if (ret != len) { + fprintf(stderr, + "post cmd read failed %d (data:%s) " + "(error:%s)\n", + ret, buf, strerror(errno)); + goto out; + } - case -1: - fprintf (stderr, "fork failed (%s)\n", strerror (errno)); + if (strcmp(buf, "test-content")) { + fprintf(stderr, "wrong data (%s)\n", buf); goto out; + } + } - default: - close (write_to_parent[1]); - close (write_to_child[0]); - - fd = open (path, O_CREAT | O_RDWR | O_APPEND, S_IRWXU); - if (fd < 0) { - fprintf (stderr, "open failed (%s)\n", - strerror (errno)); - goto out; - } - - len = strlen ("test-content") + 1; - ret = write (fd, "test-content", len); - - if (ret < len) { - fprintf (stderr, "write failed %d (%s)\n", ret, - strerror (errno)); - } - - ret = pread (fd, buf, 128, 0); - if ((ret == len) && (strcmp (buf, "test-content") == 0)) { - fprintf (stderr, "read should've failed as previous " - "write would've failed with EDQUOT, but its " - "successful"); - ret = -1; - goto out; - } - - ret = write (write_to_child[1], "1", 2); - if (ret < 0) { - fprintf (stderr, "parent: write to pipe failed (%s)\n", - strerror (errno)); - goto out; - } - - ret = read (write_to_parent[0], buf, 128); - if (ret < 0) { - fprintf (stderr, "parent: read from pipe failed (%s)\n", - strerror (errno)); - goto out; - } - - /* this will force a sync on cached-write and now that quota - limit is increased, sync will be successful. ignore return - value as fstat would fail with EDQUOT (picked up from - cached-write because of previous sync failure. - */ - fstat (fd, &stbuf); - - ret = pread (fd, buf, 128, 0); - if (ret != len) { - fprintf (stderr, "post cmd read failed %d (data:%s) " - "(error:%s)\n", ret, buf, strerror (errno)); - goto out; - } - - if (strcmp (buf, "test-content")) { - fprintf (stderr, "wrong data (%s)\n", buf); - goto out; - } - } - - ret = 0; + ret = 0; out: - return ret; + return ret; } |