summaryrefslogtreecommitdiff
path: root/posix/tst-fork.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-05-28 22:14:55 +0000
committerUlrich Drepper <drepper@redhat.com>2000-05-28 22:14:55 +0000
commitc0f3519d2e841dbaad086091f610cebc8178e7f6 (patch)
tree8ca703fea57ed1eefb8f5f102e2c166f5a1f912d /posix/tst-fork.c
parent2588068bdf891c057443ecfee136fb1bcfc3bf38 (diff)
Update.
* posix/Makefile (tests): Add tst-fork.
Diffstat (limited to 'posix/tst-fork.c')
-rw-r--r--posix/tst-fork.c136
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;
+}