diff options
author | Ulrich Drepper <drepper@redhat.com> | 2000-05-28 22:14:55 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2000-05-28 22:14:55 +0000 |
commit | c0f3519d2e841dbaad086091f610cebc8178e7f6 (patch) | |
tree | 8ca703fea57ed1eefb8f5f102e2c166f5a1f912d /posix/tst-fork.c | |
parent | 2588068bdf891c057443ecfee136fb1bcfc3bf38 (diff) | |
download | glibc-c0f3519d2e841dbaad086091f610cebc8178e7f6.tar.gz |
Update.
* posix/Makefile (tests): Add tst-fork.
Diffstat (limited to 'posix/tst-fork.c')
-rw-r--r-- | posix/tst-fork.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/posix/tst-fork.c b/posix/tst-fork.c new file mode 100644 index 0000000000..287fa5ffb5 --- /dev/null +++ b/posix/tst-fork.c @@ -0,0 +1,136 @@ +/* Tests for fork. + Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include <error.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <wait.h> + + +static const char testdata[] = "This is a test"; +static const char testdata2[] = "And here we go again"; + + +int +main (void) +{ + const char *tmpdir = getenv ("TMPDIR"); + char buf[100]; + size_t tmpdirlen; + char *name; + int fd; + pid_t pid; + off_t off; + int status; + + if (tmpdir == NULL || *tmpdir == '\0') + tmpdir = "/tmp"; + tmpdirlen = strlen (tmpdir); + + name = (char *) malloc (tmpdirlen + strlen ("/forkXXXXXX") + 1); + if (name == NULL) + error (EXIT_FAILURE, errno, "cannot allocate file name"); + + mempcpy (mempcpy (name, tmpdir, tmpdirlen), + "/forkXXXXXX", sizeof ("/forkXXXXXX")); + + /* Open our test file. */ + fd = mkstemp (name); + if (fd == -1) + error (EXIT_FAILURE, errno, "cannot open test file `%s'", name); + + /* Make sure it gets removed. */ + unlink (name); + + /* Write some data. */ + if (write (fd, testdata, strlen (testdata)) != strlen (testdata)) + error (EXIT_FAILURE, errno, "cannot write test data"); + + /* Get the position in the stream. */ + off = lseek (fd, 0, SEEK_CUR); + if (off == (off_t) -1 || off != strlen (testdata)) + error (EXIT_FAILURE, errno, "wrong file position"); + + /* Now fork of the process. */ + pid = fork (); + if (pid == 0) + { + /* This is the child. First get the position of the descriptor. */ + off = lseek (fd, 0, SEEK_CUR); + if (off == (off_t) -1 || off != strlen (testdata)) + error (EXIT_FAILURE, errno, "wrong file position in child"); + + /* Reset the position. */ + if (lseek (fd, 0, SEEK_SET) != 0) + error (EXIT_FAILURE, errno, "cannot reset position in child"); + + /* Read the data. */ + if (read (fd, buf, sizeof buf) != strlen (testdata)) + error (EXIT_FAILURE, errno, "cannot read data in child"); + + /* Compare the data. */ + if (memcmp (buf, testdata, strlen (testdata)) != 0) + error (EXIT_FAILURE, 0, "data comparison failed in child"); + + /* Reset position again. */ + if (lseek (fd, 0, SEEK_SET) != 0) + error (EXIT_FAILURE, errno, "cannot reset position again in child"); + + /* Write new data. */ + if (write (fd, testdata2, strlen (testdata2)) != strlen (testdata2)) + error (EXIT_FAILURE, errno, "cannot write new data in child"); + + /* Close the file. This must not remove it. */ + close (fd); + + _exit (0); + } + else if (pid < 0) + /* Something went wrong. */ + error (EXIT_FAILURE, errno, "cannot fork"); + + /* Wait for the child. */ + if (waitpid (pid, &status, 0) != pid) + error (EXIT_FAILURE, 0, "Oops, wrong test program terminated"); + + if (WTERMSIG (status) != 0) + error (EXIT_FAILURE, 0, "Child terminated incorrectly"); + status = WEXITSTATUS (status); + + if (status == 0) + { + /* Test whether the child wrote the right data. First test the + position. It must be the same as in the child. */ + if (lseek (fd, 0, SEEK_CUR) != strlen (testdata2)) + error (EXIT_FAILURE, 0, "file position not changed"); + + if (lseek (fd, 0, SEEK_SET) != 0) + error (EXIT_FAILURE, errno, "cannot reset file position"); + + if (read (fd, buf, sizeof buf) != strlen (testdata2)) + error (EXIT_FAILURE, errno, "cannot read new data"); + + if (memcmp (buf, testdata2, strlen (testdata2)) != 0) + error (EXIT_FAILURE, 0, "new data not read correctly"); + } + + return status; +} |