#include #include #include #include #include #include #include #include int 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, }; 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; } 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; case -1: fprintf (stderr, "fork failed (%s)\n", strerror (errno)); 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; out: return ret; }