A few more tests come here.
2020-11-30 Bruno Haible <br...@clisp.org> execute tests: Add more tests. * tests/test-execute-main.c: Add tests for reading, writing, isatty on inherited file descriptors >= 3. * tests/test-execute-child.c: Likewise. * tests/test-execute.sh: Update. diff --git a/tests/test-execute-child.c b/tests/test-execute-child.c index 2994476..77f99ae 100644 --- a/tests/test-execute-child.c +++ b/tests/test-execute-child.c @@ -29,7 +29,7 @@ /* Get declarations of the native Windows API functions. */ # define WIN32_LEAN_AND_MEAN # include <windows.h> -/* Get _get_osfhandle. */ +/* Get _get_osfhandle, _isatty. */ # include <io.h> #endif @@ -41,11 +41,14 @@ #undef fprintf #undef fputs #undef fstat +#undef isatty #undef raise +#undef read #undef sprintf #undef stat #undef strcmp #undef strlen +#undef write #if HAVE_MSVC_INVALID_PARAMETER_HANDLER static void __cdecl @@ -170,6 +173,34 @@ main (int argc, char *argv[]) return 1; } } + case 17: + /* Check that file descriptors >= 3, open for reading, can be inherited, + including the file position. */ + { + char buf[6]; + int n = read (10, buf, sizeof (buf)); + return !(n == 4 && memcmp (buf, "obar", 4) == 0); + } + case 18: + /* Check that file descriptors >= 3, open for writing, can be inherited, + including the file position. */ + { + int n = write (10, "bar", 3); + return !(n == 3); + } + case 19: + /* Check that file descriptors >= 3, when inherited, preserve their + isatty() property, part 1 (regular file). */ + case 20: + /* Check that file descriptors >= 3, when inherited, preserve their + isatty() property, part 2 (character devices). */ + { + #if defined _WIN32 && ! defined __CYGWIN__ + return 4 + 2 * (_isatty (10) != 0) + (_isatty (11) != 0); + #else + return 4 + 2 * (isatty (10) != 0) + (isatty (11) != 0); + #endif + } default: abort (); } diff --git a/tests/test-execute-main.c b/tests/test-execute-main.c index d0993d8..62357c1 100644 --- a/tests/test-execute-main.c +++ b/tests/test-execute-main.c @@ -27,6 +27,11 @@ #include <string.h> #include <unistd.h> +#if defined _WIN32 && ! defined __CYGWIN__ +/* Get _isatty. */ +# include <io.h> +#endif + #include "read-file.h" #include "macros.h" @@ -310,6 +315,122 @@ main (int argc, char *argv[]) ASSERT (ret == 0); } break; + case 17: + { + /* Check that file descriptors >= 3, open for reading, can be inherited, + including the file position. */ + FILE *fp = fopen (BASE ".tmp", "w"); + fputs ("Foobar", fp); + ASSERT (fclose (fp) == 0); + + int fd = open (BASE ".tmp", O_RDONLY); + ASSERT (fd >= 0 && fd < 10); + + ASSERT (dup2 (fd, 10) >= 0); + close (fd); + fd = 10; + + char buf[2]; + ASSERT (read (fd, buf, sizeof (buf)) == sizeof (buf)); + /* The file position is now 2. */ + + char *prog_argv[3] = { prog_path, (char *) "17", NULL }; + int ret = execute (progname, prog_argv[0], prog_argv, + false, false, false, false, true, false, NULL); + ASSERT (ret == 0); + + close (fd); + ASSERT (remove (BASE ".tmp") == 0); + } + break; + case 18: + { + /* Check that file descriptors >= 3, open for writing, can be inherited, + including the file position. */ + remove (BASE ".tmp"); + int fd = open (BASE ".tmp", O_RDWR | O_CREAT | O_TRUNC, 0600); + ASSERT (fd >= 0 && fd < 10); + + ASSERT (dup2 (fd, 10) >= 0); + close (fd); + fd = 10; + + ASSERT (write (fd, "Foo", 3) == 3); + /* The file position is now 3. */ + + char *prog_argv[3] = { prog_path, (char *) "18", NULL }; + int ret = execute (progname, prog_argv[0], prog_argv, + false, false, false, false, true, false, NULL); + ASSERT (ret == 0); + + close (fd); + + size_t length; + char *contents = read_file (BASE ".tmp", 0, &length); + ASSERT (length == 6 && memcmp (contents, "Foobar", 6) == 0); + + ASSERT (remove (BASE ".tmp") == 0); + } + break; + case 19: + { + /* Check that file descriptors >= 3, when inherited, preserve their + isatty() property, part 1 (regular file). */ + FILE *fp = fopen (BASE ".tmp", "w"); + fputs ("Foo", fp); + ASSERT (fclose (fp) == 0); + + int fd_in = open (BASE ".tmp", O_RDONLY); + ASSERT (fd_in >= 0 && fd_in < 10); + + int fd_out = open (BASE ".tmp", O_WRONLY | O_APPEND); + ASSERT (fd_out >= 0 && fd_out < 10); + + ASSERT (dup2 (fd_in, 10) >= 0); + close (fd_in); + fd_in = 10; + + ASSERT (dup2 (fd_out, 11) >= 0); + close (fd_out); + fd_out = 11; + + char *prog_argv[3] = { prog_path, (char *) "19", NULL }; + int ret = execute (progname, prog_argv[0], prog_argv, + false, false, false, false, true, false, NULL); + #if defined _WIN32 && ! defined __CYGWIN__ + ASSERT (ret == 4 + 2 * (_isatty (10) != 0) + (_isatty (11) != 0)); + #else + ASSERT (ret == 4 + 2 * (isatty (10) != 0) + (isatty (11) != 0)); + #endif + + close (fd_in); + close (fd_out); + ASSERT (remove (BASE ".tmp") == 0); + } + break; + case 20: + { + /* Check that file descriptors >= 3, when inherited, preserve their + isatty() property, part 2 (character devices). */ + ASSERT (dup2 (STDIN_FILENO, 10) >= 0); + int fd_in = 10; + + ASSERT (dup2 (STDOUT_FILENO, 11) >= 0); + int fd_out = 11; + + char *prog_argv[3] = { prog_path, (char *) "20", NULL }; + int ret = execute (progname, prog_argv[0], prog_argv, + false, false, false, false, true, false, NULL); + #if defined _WIN32 && ! defined __CYGWIN__ + ASSERT (ret == 4 + 2 * (_isatty (10) != 0) + (_isatty (11) != 0)); + #else + ASSERT (ret == 4 + 2 * (isatty (10) != 0) + (isatty (11) != 0)); + #endif + + close (fd_in); + close (fd_out); + } + break; default: ASSERT (false); } diff --git a/tests/test-execute.sh b/tests/test-execute.sh index c5f7d23..1320e76 100755 --- a/tests/test-execute.sh +++ b/tests/test-execute.sh @@ -1,7 +1,7 @@ #!/bin/sh st=0 -for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do +for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do ${CHECKER} ./test-execute-main${EXEEXT} ./test-execute-child${EXEEXT} $i \ || { echo test-execute.sh: test case $i failed >&2; st=1; } done