#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; }