|
|
@@ -9,7 +9,7 @@
|
|
|
int main(int argc, char *argv[])
|
|
|
{
|
|
|
pid_t child;
|
|
|
- int infd, outfd, status;
|
|
|
+ int infd, outfd, errfd, status;
|
|
|
char buf[5] = "test";
|
|
|
|
|
|
/* We call ourselves, to test pipe. */
|
|
|
@@ -28,43 +28,94 @@ int main(int argc, char *argv[])
|
|
|
buf[0]++;
|
|
|
if (write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf))
|
|
|
exit(1);
|
|
|
+ } else if (strcmp(argv[1], "err") == 0) {
|
|
|
+ if (write(STDERR_FILENO, buf, sizeof(buf)) != sizeof(buf))
|
|
|
+ exit(1);
|
|
|
} else
|
|
|
abort();
|
|
|
exit(0);
|
|
|
}
|
|
|
|
|
|
+ /* We assume no fd leaks, so close them now. */
|
|
|
+ close(3);
|
|
|
+ close(4);
|
|
|
+ close(5);
|
|
|
+ close(6);
|
|
|
+ close(7);
|
|
|
+ close(8);
|
|
|
+ close(9);
|
|
|
+ close(10);
|
|
|
+
|
|
|
/* This is how many tests you plan to run */
|
|
|
- plan_tests(28);
|
|
|
- child = pipecmd(&outfd, &infd, argv[0], "inout", NULL);
|
|
|
+ plan_tests(67);
|
|
|
+ child = pipecmd(&outfd, &infd, &errfd, argv[0], "inout", NULL);
|
|
|
if (!ok1(child > 0))
|
|
|
exit(1);
|
|
|
ok1(write(infd, buf, sizeof(buf)) == sizeof(buf));
|
|
|
ok1(read(outfd, buf, sizeof(buf)) == sizeof(buf));
|
|
|
+ ok1(read(errfd, buf, sizeof(buf)) == 0);
|
|
|
+ ok1(close(infd) == 0);
|
|
|
+ ok1(close(outfd) == 0);
|
|
|
+ ok1(close(errfd) == 0);
|
|
|
buf[0]--;
|
|
|
ok1(memcmp(buf, "test", sizeof(buf)) == 0);
|
|
|
ok1(waitpid(child, &status, 0) == child);
|
|
|
ok1(WIFEXITED(status));
|
|
|
ok1(WEXITSTATUS(status) == 0);
|
|
|
|
|
|
- child = pipecmd(NULL, &infd, argv[0], "in", NULL);
|
|
|
+ child = pipecmd(NULL, &infd, NULL, argv[0], "in", NULL);
|
|
|
if (!ok1(child > 0))
|
|
|
exit(1);
|
|
|
ok1(write(infd, buf, sizeof(buf)) == sizeof(buf));
|
|
|
+ ok1(close(infd) == 0);
|
|
|
+ ok1(waitpid(child, &status, 0) == child);
|
|
|
+ ok1(WIFEXITED(status));
|
|
|
+ ok1(WEXITSTATUS(status) == 0);
|
|
|
+
|
|
|
+ child = pipecmd(&outfd, NULL, NULL, argv[0], "out", NULL);
|
|
|
+ if (!ok1(child > 0))
|
|
|
+ exit(1);
|
|
|
+ ok1(read(outfd, buf, sizeof(buf)) == sizeof(buf));
|
|
|
+ ok1(close(outfd) == 0);
|
|
|
+ ok1(memcmp(buf, "test", sizeof(buf)) == 0);
|
|
|
+ ok1(waitpid(child, &status, 0) == child);
|
|
|
+ ok1(WIFEXITED(status));
|
|
|
+ ok1(WEXITSTATUS(status) == 0);
|
|
|
+
|
|
|
+ /* Errfd only should be fine. */
|
|
|
+ child = pipecmd(NULL, NULL, &errfd, argv[0], "err", NULL);
|
|
|
+ if (!ok1(child > 0))
|
|
|
+ exit(1);
|
|
|
+ ok1(read(errfd, buf, sizeof(buf)) == sizeof(buf));
|
|
|
+ ok1(close(errfd) == 0);
|
|
|
+ ok1(memcmp(buf, "test", sizeof(buf)) == 0);
|
|
|
+ ok1(waitpid(child, &status, 0) == child);
|
|
|
+ ok1(WIFEXITED(status));
|
|
|
+ ok1(WEXITSTATUS(status) == 0);
|
|
|
+
|
|
|
+ /* errfd == outfd should work with both. */
|
|
|
+ child = pipecmd(&errfd, NULL, &errfd, argv[0], "err", NULL);
|
|
|
+ if (!ok1(child > 0))
|
|
|
+ exit(1);
|
|
|
+ ok1(read(errfd, buf, sizeof(buf)) == sizeof(buf));
|
|
|
+ ok1(close(errfd) == 0);
|
|
|
+ ok1(memcmp(buf, "test", sizeof(buf)) == 0);
|
|
|
ok1(waitpid(child, &status, 0) == child);
|
|
|
ok1(WIFEXITED(status));
|
|
|
ok1(WEXITSTATUS(status) == 0);
|
|
|
|
|
|
- child = pipecmd(&outfd, NULL, argv[0], "out", NULL);
|
|
|
+ child = pipecmd(&outfd, NULL, &outfd, argv[0], "out", NULL);
|
|
|
if (!ok1(child > 0))
|
|
|
exit(1);
|
|
|
ok1(read(outfd, buf, sizeof(buf)) == sizeof(buf));
|
|
|
+ ok1(close(outfd) == 0);
|
|
|
ok1(memcmp(buf, "test", sizeof(buf)) == 0);
|
|
|
ok1(waitpid(child, &status, 0) == child);
|
|
|
ok1(WIFEXITED(status));
|
|
|
ok1(WEXITSTATUS(status) == 0);
|
|
|
|
|
|
// Writing to /dev/null should be fine.
|
|
|
- child = pipecmd(NULL, NULL, argv[0], "out", NULL);
|
|
|
+ child = pipecmd(NULL, NULL, NULL, argv[0], "out", NULL);
|
|
|
if (!ok1(child > 0))
|
|
|
exit(1);
|
|
|
ok1(waitpid(child, &status, 0) == child);
|
|
|
@@ -72,18 +123,35 @@ int main(int argc, char *argv[])
|
|
|
ok1(WEXITSTATUS(status) == 0);
|
|
|
|
|
|
// Reading should fail.
|
|
|
- child = pipecmd(NULL, NULL, argv[0], "in", NULL);
|
|
|
+ child = pipecmd(NULL, NULL, NULL, argv[0], "in", NULL);
|
|
|
if (!ok1(child > 0))
|
|
|
exit(1);
|
|
|
ok1(waitpid(child, &status, 0) == child);
|
|
|
ok1(WIFEXITED(status));
|
|
|
ok1(WEXITSTATUS(status) == 1);
|
|
|
|
|
|
+ child = pipecmd(NULL, NULL, NULL, argv[0], "err", NULL);
|
|
|
+ if (!ok1(child > 0))
|
|
|
+ exit(1);
|
|
|
+ ok1(waitpid(child, &status, 0) == child);
|
|
|
+ ok1(WIFEXITED(status));
|
|
|
+ ok1(WEXITSTATUS(status) == 0);
|
|
|
+
|
|
|
// Can't run non-existent file, but errno set correctly.
|
|
|
- child = pipecmd(NULL, NULL, "/doesnotexist", "in", NULL);
|
|
|
+ child = pipecmd(NULL, NULL, NULL, "/doesnotexist", "in", NULL);
|
|
|
ok1(errno == ENOENT);
|
|
|
ok1(child < 0);
|
|
|
|
|
|
+ /* No fd leaks! */
|
|
|
+ ok1(close(3) == -1 && errno == EBADF);
|
|
|
+ ok1(close(4) == -1 && errno == EBADF);
|
|
|
+ ok1(close(5) == -1 && errno == EBADF);
|
|
|
+ ok1(close(6) == -1 && errno == EBADF);
|
|
|
+ ok1(close(7) == -1 && errno == EBADF);
|
|
|
+ ok1(close(8) == -1 && errno == EBADF);
|
|
|
+ ok1(close(9) == -1 && errno == EBADF);
|
|
|
+ ok1(close(10) == -1 && errno == EBADF);
|
|
|
+
|
|
|
/* This exits depending on whether all tests passed */
|
|
|
return exit_status();
|
|
|
}
|