Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/testsuite/ChangeLog94
-rw-r--r--winsup/testsuite/libltp/lib/libtestsuite.c74
-rw-r--r--winsup/testsuite/libltp/lib/tst_sig.c1
-rw-r--r--winsup/testsuite/winsup.api/known_bugs.tcl2
-rw-r--r--winsup/testsuite/winsup.api/ltp/access04.c243
-rw-r--r--winsup/testsuite/winsup.api/ltp/access05.c425
-rw-r--r--winsup/testsuite/winsup.api/ltp/alarm07.c203
-rw-r--r--winsup/testsuite/winsup.api/ltp/chdir04.c189
-rw-r--r--winsup/testsuite/winsup.api/ltp/chmod01.c231
-rw-r--r--winsup/testsuite/winsup.api/ltp/close01.c199
-rw-r--r--winsup/testsuite/winsup.api/ltp/close02.c142
-rw-r--r--winsup/testsuite/winsup.api/ltp/creat01.c206
-rw-r--r--winsup/testsuite/winsup.api/ltp/creat03.c153
-rw-r--r--winsup/testsuite/winsup.api/ltp/exit01.c163
-rw-r--r--winsup/testsuite/winsup.api/ltp/exit02.c227
-rw-r--r--winsup/testsuite/winsup.api/ltp/fchdir01.c248
-rw-r--r--winsup/testsuite/winsup.api/ltp/fchdir02.c159
-rw-r--r--winsup/testsuite/winsup.api/ltp/fork02.c142
-rw-r--r--winsup/testsuite/winsup.api/ltp/fork03.c164
-rw-r--r--winsup/testsuite/winsup.api/ltp/fork06.c152
-rw-r--r--winsup/testsuite/winsup.api/ltp/fork07.c198
-rw-r--r--winsup/testsuite/winsup.api/ltp/fork09.c228
-rw-r--r--winsup/testsuite/winsup.api/ltp/fork10.c215
-rw-r--r--winsup/testsuite/winsup.api/ltp/fork11.c140
-rw-r--r--winsup/testsuite/winsup.api/ltp/fstat02.c245
-rw-r--r--winsup/testsuite/winsup.api/ltp/fstat03.c192
-rw-r--r--winsup/testsuite/winsup.api/ltp/fstat04.c245
-rw-r--r--winsup/testsuite/winsup.api/ltp/ftruncate01.c244
-rw-r--r--winsup/testsuite/winsup.api/ltp/ftruncate02.c314
-rw-r--r--winsup/testsuite/winsup.api/ltp/ftruncate03.c325
-rw-r--r--winsup/testsuite/winsup.api/ltp/getgid02.c158
-rw-r--r--winsup/testsuite/winsup.api/ltp/getgid03.c157
-rw-r--r--winsup/testsuite/winsup.api/ltp/getpgid01.c240
-rw-r--r--winsup/testsuite/winsup.api/ltp/getpgid02.c172
-rw-r--r--winsup/testsuite/winsup.api/ltp/getpid02.c188
-rw-r--r--winsup/testsuite/winsup.api/ltp/getppid02.c146
-rw-r--r--winsup/testsuite/winsup.api/ltp/getuid02.c136
-rw-r--r--winsup/testsuite/winsup.api/ltp/getuid03.c137
-rw-r--r--winsup/testsuite/winsup.api/ltp/kill01.c161
-rw-r--r--winsup/testsuite/winsup.api/ltp/kill02.c858
-rw-r--r--winsup/testsuite/winsup.api/ltp/kill03.c169
-rw-r--r--winsup/testsuite/winsup.api/ltp/kill04.c180
-rw-r--r--winsup/testsuite/winsup.api/ltp/lseek06.c237
-rw-r--r--winsup/testsuite/winsup.api/ltp/lseek07.c288
-rw-r--r--winsup/testsuite/winsup.api/ltp/lseek08.c242
-rw-r--r--winsup/testsuite/winsup.api/ltp/lseek09.c269
-rw-r--r--winsup/testsuite/winsup.api/ltp/lseek10.c347
-rw-r--r--winsup/testsuite/winsup.api/ltp/mmap02.c294
-rw-r--r--winsup/testsuite/winsup.api/ltp/mmap03.c294
-rw-r--r--winsup/testsuite/winsup.api/ltp/mmap04.c295
-rw-r--r--winsup/testsuite/winsup.api/ltp/mmap05.c303
-rw-r--r--winsup/testsuite/winsup.api/ltp/mmap06.c237
-rw-r--r--winsup/testsuite/winsup.api/ltp/mmap07.c236
-rw-r--r--winsup/testsuite/winsup.api/ltp/mmap08.c236
-rw-r--r--winsup/testsuite/winsup.api/ltp/munmap01.c282
-rw-r--r--winsup/testsuite/winsup.api/ltp/munmap02.c307
-rw-r--r--winsup/testsuite/winsup.api/ltp/open02.c150
-rw-r--r--winsup/testsuite/winsup.api/ltp/pipe01.c157
-rw-r--r--winsup/testsuite/winsup.api/ltp/pipe08.c159
-rw-r--r--winsup/testsuite/winsup.api/ltp/pipe09.c232
-rw-r--r--winsup/testsuite/winsup.api/ltp/pipe10.c168
-rw-r--r--winsup/testsuite/winsup.api/ltp/pipe11.c227
-rw-r--r--winsup/testsuite/winsup.api/ltp/poll01.c251
-rw-r--r--winsup/testsuite/winsup.api/ltp/read04.c175
-rw-r--r--winsup/testsuite/winsup.api/ltp/readlink01.c230
-rw-r--r--winsup/testsuite/winsup.api/ltp/readlink03.c361
-rw-r--r--winsup/testsuite/winsup.api/ltp/rename01.c264
-rw-r--r--winsup/testsuite/winsup.api/ltp/rename02.c2
-rw-r--r--winsup/testsuite/winsup.api/ltp/rename08.c206
-rw-r--r--winsup/testsuite/winsup.api/ltp/rename10.c204
-rw-r--r--winsup/testsuite/winsup.api/ltp/rmdir01.c190
-rw-r--r--winsup/testsuite/winsup.api/ltp/stat01.c268
-rw-r--r--winsup/testsuite/winsup.api/ltp/stat02.c277
-rw-r--r--winsup/testsuite/winsup.api/ltp/stat03.c393
-rw-r--r--winsup/testsuite/winsup.api/ltp/symlink03.c404
-rw-r--r--winsup/testsuite/winsup.api/ltp/symlink04.c239
-rw-r--r--winsup/testsuite/winsup.api/ltp/symlink05.c223
-rw-r--r--winsup/testsuite/winsup.api/ltp/sync02.c240
-rw-r--r--winsup/testsuite/winsup.api/ltp/time02.c183
-rw-r--r--winsup/testsuite/winsup.api/ltp/times02.c135
-rw-r--r--winsup/testsuite/winsup.api/ltp/times03.c246
-rw-r--r--winsup/testsuite/winsup.api/ltp/truncate01.c262
-rw-r--r--winsup/testsuite/winsup.api/ltp/truncate02.c335
-rw-r--r--winsup/testsuite/winsup.api/ltp/umask02.c134
-rw-r--r--winsup/testsuite/winsup.api/ltp/umask03.c169
-rw-r--r--winsup/testsuite/winsup.api/ltp/wait401.c187
-rw-r--r--winsup/testsuite/winsup.api/ltp/wait402.c202
-rw-r--r--winsup/testsuite/winsup.api/ltp/write02.c165
-rw-r--r--winsup/testsuite/winsup.api/ltp/write03.c193
-rwxr-xr-xwinsup/testsuite/winsup.api/signal-into-win32-api.c57
90 files changed, 19617 insertions, 3 deletions
diff --git a/winsup/testsuite/ChangeLog b/winsup/testsuite/ChangeLog
index f11c6d96e..5688f503e 100644
--- a/winsup/testsuite/ChangeLog
+++ b/winsup/testsuite/ChangeLog
@@ -1,3 +1,97 @@
+2001-09-13 Egor Duda <deo@logos-m.ru>
+
+ * libltp/lib/tst_sig.c: Pass SIGSEGV to application to consider
+ whether it's expected or not.
+ * winsup.api/known_bugs.tcl: lseek10 is known to fail because mknod
+ is not implemented.
+ * winsup.api/ltp/rename02.c: Fix formatting.
+ * libltp/lib/libtestsuite.c: New file.
+ * winsup.api/signal-into-win32-api.c: New test.
+ * winsup.api/ltp/access04.c: Ditto.
+ * winsup.api/ltp/access05.c: Ditto.
+ * winsup.api/ltp/alarm07.c: Ditto.
+ * winsup.api/ltp/chdir04.c: Ditto.
+ * winsup.api/ltp/chmod01.c: Ditto.
+ * winsup.api/ltp/close01.c: Ditto.
+ * winsup.api/ltp/close02.c: Ditto.
+ * winsup.api/ltp/creat01.c: Ditto.
+ * winsup.api/ltp/creat03.c: Ditto.
+ * winsup.api/ltp/exit01.c: Ditto.
+ * winsup.api/ltp/exit02.c: Ditto.
+ * winsup.api/ltp/fchdir01.c: Ditto.
+ * winsup.api/ltp/fchdir02.c: Ditto.
+ * winsup.api/ltp/fork02.c: Ditto.
+ * winsup.api/ltp/fork03.c: Ditto.
+ * winsup.api/ltp/fork06.c: Ditto.
+ * winsup.api/ltp/fork07.c: Ditto.
+ * winsup.api/ltp/fork09.c: Ditto.
+ * winsup.api/ltp/fork10.c: Ditto.
+ * winsup.api/ltp/fork11.c: Ditto.
+ * winsup.api/ltp/fstat02.c: Ditto.
+ * winsup.api/ltp/fstat03.c: Ditto.
+ * winsup.api/ltp/fstat04.c: Ditto.
+ * winsup.api/ltp/ftruncate01.c: Ditto.
+ * winsup.api/ltp/ftruncate02.c: Ditto.
+ * winsup.api/ltp/ftruncate03.c: Ditto.
+ * winsup.api/ltp/getgid02.c: Ditto.
+ * winsup.api/ltp/getgid03.c: Ditto.
+ * winsup.api/ltp/getpgid01.c: Ditto.
+ * winsup.api/ltp/getpgid02.c: Ditto.
+ * winsup.api/ltp/getpid02.c: Ditto.
+ * winsup.api/ltp/getppid02.c: Ditto.
+ * winsup.api/ltp/getuid02.c: Ditto.
+ * winsup.api/ltp/getuid03.c: Ditto.
+ * winsup.api/ltp/kill01.c: Ditto.
+ * winsup.api/ltp/kill02.c: Ditto.
+ * winsup.api/ltp/kill03.c: Ditto.
+ * winsup.api/ltp/kill04.c: Ditto.
+ * winsup.api/ltp/lseek06.c: Ditto.
+ * winsup.api/ltp/lseek07.c: Ditto.
+ * winsup.api/ltp/lseek08.c: Ditto.
+ * winsup.api/ltp/lseek09.c: Ditto.
+ * winsup.api/ltp/lseek10.c: Ditto.
+ * winsup.api/ltp/mmap02.c: Ditto.
+ * winsup.api/ltp/mmap03.c: Ditto.
+ * winsup.api/ltp/mmap04.c: Ditto.
+ * winsup.api/ltp/mmap05.c: Ditto.
+ * winsup.api/ltp/mmap06.c: Ditto.
+ * winsup.api/ltp/mmap07.c: Ditto.
+ * winsup.api/ltp/mmap08.c: Ditto.
+ * winsup.api/ltp/munmap01.c: Ditto.
+ * winsup.api/ltp/munmap02.c: Ditto.
+ * winsup.api/ltp/open02.c: Ditto.
+ * winsup.api/ltp/pipe01.c: Ditto.
+ * winsup.api/ltp/pipe08.c: Ditto.
+ * winsup.api/ltp/pipe09.c: Ditto.
+ * winsup.api/ltp/pipe10.c: Ditto.
+ * winsup.api/ltp/pipe11.c: Ditto.
+ * winsup.api/ltp/poll01.c: Ditto.
+ * winsup.api/ltp/read04.c: Ditto.
+ * winsup.api/ltp/readlink01.c: Ditto.
+ * winsup.api/ltp/readlink03.c: Ditto.
+ * winsup.api/ltp/rename01.c: Ditto.
+ * winsup.api/ltp/rename08.c: Ditto.
+ * winsup.api/ltp/rename10.c: Ditto.
+ * winsup.api/ltp/rmdir01.c: Ditto.
+ * winsup.api/ltp/stat01.c: Ditto.
+ * winsup.api/ltp/stat02.c: Ditto.
+ * winsup.api/ltp/stat03.c: Ditto.
+ * winsup.api/ltp/symlink03.c: Ditto.
+ * winsup.api/ltp/symlink04.c: Ditto.
+ * winsup.api/ltp/symlink05.c: Ditto.
+ * winsup.api/ltp/sync02.c: Ditto.
+ * winsup.api/ltp/time02.c: Ditto.
+ * winsup.api/ltp/times02.c: Ditto.
+ * winsup.api/ltp/times03.c: Ditto.
+ * winsup.api/ltp/truncate01.c: Ditto.
+ * winsup.api/ltp/truncate02.c: Ditto.
+ * winsup.api/ltp/umask02.c: Ditto.
+ * winsup.api/ltp/umask03.c: Ditto.
+ * winsup.api/ltp/wait401.c: Ditto.
+ * winsup.api/ltp/wait402.c: Ditto.
+ * winsup.api/ltp/write02.c: Ditto.
+ * winsup.api/ltp/write03.c: Ditto.
+
2001-09-09 Egor Duda <deo@logos-m.ru>
* winsup.api/ltp/dup03.c: New test.
diff --git a/winsup/testsuite/libltp/lib/libtestsuite.c b/winsup/testsuite/libltp/lib/libtestsuite.c
new file mode 100644
index 000000000..e974c871e
--- /dev/null
+++ b/winsup/testsuite/libltp/lib/libtestsuite.c
@@ -0,0 +1,74 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * libtestsuite.c
+ *
+ * DESCRIPTION
+ * file containing generic routines which are used by some of the LTP
+ * testsuite tests. Currently, the following routines are present in
+ * this library:
+ *
+ * my_getpwnam(), do_file_setup()
+ *
+ */
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "test.h"
+#include "usctest.h"
+
+struct passwd *
+my_getpwnam(char *name)
+{
+ struct passwd *saved_pwent;
+ struct passwd *pwent;
+
+ if ((pwent = getpwnam(name)) == NULL) {
+ perror("getpwnam");
+ tst_brkm(TBROK, NULL, "getpwnam() failed");
+ }
+ saved_pwent = (struct passwd *)malloc(sizeof(struct passwd));
+
+ *saved_pwent = *pwent;
+
+ return(saved_pwent);
+}
+
+void
+do_file_setup(char *fname)
+{
+ int fd;
+
+ if ((fd = open(fname,O_RDWR|O_CREAT,0700)) == -1) {
+ tst_resm(TBROK, "open(%s, O_RDWR|O_CREAT,0700) Failed, "
+ "errno=%d : %s", fname, errno, strerror(errno));
+ }
+
+ if (close(fd) == -1) {
+ tst_resm(TWARN, "close(%s) Failed on file create, errno=%d : "
+ "%s", fname, errno, strerror(errno));
+ }
+}
diff --git a/winsup/testsuite/libltp/lib/tst_sig.c b/winsup/testsuite/libltp/lib/tst_sig.c
index cccc2c7ee..f5b64b666 100644
--- a/winsup/testsuite/libltp/lib/tst_sig.c
+++ b/winsup/testsuite/libltp/lib/tst_sig.c
@@ -151,7 +151,6 @@ tst_sig(int fork_flag, void (*handler)(), void (*cleanup)())
case SIGPTRESCHED:
#endif /* SIGPTRESCHED */
#ifdef __CYGWIN__
- case SIGSEGV:
case SIGILL:
case SIGTRAP:
case SIGABRT:
diff --git a/winsup/testsuite/winsup.api/known_bugs.tcl b/winsup/testsuite/winsup.api/known_bugs.tcl
index d1538b783..1856608d9 100644
--- a/winsup/testsuite/winsup.api/known_bugs.tcl
+++ b/winsup/testsuite/winsup.api/known_bugs.tcl
@@ -1,6 +1,6 @@
set xfail_list [list dup03 dup05 \
fcntl05 fcntl07B fcntl09 fcntl10 \
- fsync01 gethostid01 lseek04 mknod01 select03 \
+ fsync01 gethostid01 lseek04 lseek10 mknod01 select03 \
setgroups01 setregid01 setreuid01 setuid02 \
ulimit01 unlink06 unlink08 \
sample-fail sample-miscompile]
diff --git a/winsup/testsuite/winsup.api/ltp/access04.c b/winsup/testsuite/winsup.api/ltp/access04.c
new file mode 100644
index 000000000..20fa81187
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/access04.c
@@ -0,0 +1,243 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: access01
+ *
+ * Test Description:
+ * Verify that access() succeeds to check the existance of a file if
+ * search access is permitted on the pathname of the specified file.
+ *
+ * Expected Result:
+ * access() should return 0 value and the specified file should exist
+ * on the file system.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * access01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TESTDIR "testdir"
+#define TESTFILE "testdir/testfile"
+#define DIR_MODE S_IRWXU | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+
+char *TCID="access01"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ struct stat stat_buf; /* struct buffer for stat(2) */
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *)NULL, NULL);
+ if (msg != (char *)NULL) {
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Call access(2) to check the existence of a
+ * file under specified path.
+ */
+ TEST(access(TESTFILE, F_OK));
+
+ /* check return code of access(2) */
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL,
+ "access(%s, F_OK) Failed, errno=%d : %s",
+ TESTFILE, TEST_ERRNO, strerror(TEST_ERRNO));
+ continue;
+ }
+
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Use stat(2) to cross-check the
+ * existance of testfile under
+ * specified path.
+ */
+ if (stat(TESTFILE, &stat_buf) < 0) {
+ tst_resm(TFAIL, "stat() on %s Failed, errno=%d",
+ TESTFILE, TEST_ERRNO);
+ } else {
+ tst_resm(TPASS, "Functionality of access(%s, "
+ "F_OK) successful", TESTFILE);
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ *
+ * Create a temporary directory and change directory to it.
+ * Create a test directory and a file under test directory.
+ * Modify the mode permissions of testfile.
+ */
+void
+setup()
+{
+ int fd; /* File handle for testfile */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Check that the test process id is not root/super-user */
+ if (geteuid() == 0) {
+ tst_brkm(TBROK, NULL, "Must be non-root/super for this test!");
+ tst_exit();
+ }
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Creat a test directory under temporary directory */
+ if (mkdir(TESTDIR, DIR_MODE) < 0) {
+ tst_brkm(TBROK, cleanup,
+ "mkdir(%s, %#o) Failed, errno=%d : %s",
+ TESTDIR, DIR_MODE, errno, strerror(errno));
+ }
+
+ /* Make sure test directory has search permissions set */
+ if (chmod(TESTDIR, DIR_MODE) < 0) {
+ tst_brkm(TBROK, cleanup,
+ "chmod(%s, %#o) Failed, errno=%d : %s",
+ TESTDIR, DIR_MODE, errno, strerror(errno));
+ }
+
+ /* Creat a test file under above directory created */
+ if ((fd = open(TESTFILE, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s",
+ TESTFILE, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Close the testfile created above */
+ if (close(fd) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "close(%s) Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ }
+
+ /* Change the mode permissions on the testfile */
+ if (chmod(TESTFILE, 0) < 0) {
+ tst_brkm(TBROK, cleanup,
+ "chmod(%s, 0) Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ }
+}
+
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ *
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /*
+ * Delete the test directory/file and temporary directory
+ * created in the setup.
+ */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/access05.c b/winsup/testsuite/winsup.api/ltp/access05.c
new file mode 100644
index 000000000..935b19bd3
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/access05.c
@@ -0,0 +1,425 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: access03
+ *
+ * Test Description:
+ * Verify that,
+ * 1. access() fails with -1 return value and sets errno to EACCES
+ * if the permission bits of the file mode do not permit the
+ * requested (Read/Write/Execute) access.
+ * 2. access() fails with -1 return value and sets errno to EINVAL
+ * if the specified access mode argument is invalid.
+ * 3. access() fails with -1 return value and sets errno to EFAULT
+ * if the pathname points outside allocate address space for the
+ * process.
+ * 4. access() fails with -1 return value and sets errno to ENOENT
+ * if the specified file doesn't exist (or pathname is NULL).
+ * 5. access() fails with -1 return value and sets errno to ENAMETOOLONG
+ * if the pathname size is > PATH_MAX characters.
+ *
+ * Expected Result:
+ * access() should fail with return value -1 and set expected errno.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * if errno set == expected errno
+ * Issue sys call fails with expected return value and errno.
+ * Otherwise,
+ * Issue sys call fails with unexpected errno.
+ * Otherwise,
+ * Issue sys call returns unexpected value.
+ *
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory(s)/file(s) created.
+ *
+ * Usage: <for command-line>
+ * access03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * This test should be run by 'non-super-user' only.
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define INV_OK -1
+#define TEST_FILE1 "test_file1"
+#define TEST_FILE2 "test_file2"
+#define TEST_FILE3 "test_file3"
+#define TEST_FILE4 "test_file4"
+
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+
+int no_setup();
+int setup1(); /* setup() to test access() for EACCES */
+int setup2(); /* setup() to test access() for EACCES */
+int setup3(); /* setup() to test access() for EACCES */
+int setup4(); /* setup() to test access() for EINVAL */
+int longpath_setup(); /* setup function to test access() for ENAMETOOLONG */
+
+char Longpathname[PATH_MAX+2];
+char High_address_node[64];
+
+struct test_case_t { /* test case structure */
+ char *pathname;
+ int a_mode;
+ char *desc;
+ int exp_errno;
+ int (*setupfunc)();
+} Test_cases[] = {
+ { TEST_FILE1, R_OK, "Read Access denied on file", EACCES, setup1 },
+ { TEST_FILE2, W_OK, "Write Access denied on file", EACCES, setup2 },
+ { TEST_FILE3, X_OK, "Execute Access denied on file", EACCES, setup3 },
+ { TEST_FILE4, INV_OK, "Access mode invalid", EINVAL, setup4 },
+ { High_address_node, R_OK, "Address beyond address space", EFAULT, no_setup },
+ { (char *)-1, R_OK, "Negative address", EFAULT, no_setup },
+ { "", W_OK, "Pathname is empty", ENOENT, no_setup },
+ { Longpathname, R_OK, "Pathname too long", ENAMETOOLONG, longpath_setup },
+ { NULL, 0, NULL, 0, no_setup }
+};
+
+char *TCID="access03"; /* Test program identifier. */
+int TST_TOTAL=8; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={EACCES, EFAULT, EINVAL, ENOENT, ENAMETOOLONG, 0};
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ char *file_name; /* name of the testfile */
+ char *test_desc; /* test specific message */
+ int access_mode; /* specified access mode for testfile */
+ int ind; /* counter for testcase looping */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count = 0;
+
+ for (ind = 0; Test_cases[ind].desc != NULL; ind++) {
+ file_name = Test_cases[ind].pathname;
+ access_mode = Test_cases[ind].a_mode;
+ test_desc = Test_cases[ind].desc;
+
+ if (file_name == High_address_node) {
+ file_name = (char *)get_high_address();
+ }
+
+ /*
+ * Call access(2) to test different test conditions.
+ * verify that it fails with -1 return value and
+ * sets appropriate errno.
+ */
+ TEST(access(file_name, access_mode));
+
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "access() returned %d, "
+ "expected -1, errno:%d", TEST_RETURN,
+ Test_cases[ind].exp_errno);
+ continue;
+ }
+
+ TEST_ERROR_LOG(TEST_ERRNO);
+
+ /*
+ * Call a function to verify whether
+ * the specified file has specified
+ * access mode.
+ */
+ if (TEST_ERRNO == Test_cases[ind].exp_errno) {
+ tst_resm(TPASS, "access() fails, %s, errno:%d",
+ test_desc, TEST_ERRNO);
+ } else {
+ tst_resm(TFAIL, "access() fails, %s, errno:%d, "
+ "expected errno:%d", test_desc,
+ TEST_ERRNO, Test_cases[ind].exp_errno);
+ }
+ } /* Test Case Looping */
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ *
+ * Create a temporary directory and change directory to it.
+ * Call individual test specific setup functions.
+ */
+void
+setup()
+{
+ int ind; /* counter for testsetup functions */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Check that the test process id is not root/super-user */
+ if (geteuid() == 0) {
+ tst_brkm(TBROK, NULL, "Must be non-root/super for this test!");
+ tst_exit();
+ }
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* call individual setup functions */
+ for (ind = 0; Test_cases[ind].desc != NULL; ind++) {
+ Test_cases[ind].setupfunc();
+ }
+}
+
+/*
+ * no_setup() - some test conditions do not need any setup.
+ * Hence, this function simply returns 0.
+ */
+int
+no_setup()
+{
+ return 0;
+}
+
+/*
+ * setup1() - Setup function to test access() for return value -1
+ * and errno EACCES when read access denied for specified
+ * testfile.
+ *
+ * Creat/open a testfile and close it.
+ * Deny read access permissions on testfile.
+ * This function returns 0.
+ */
+int
+setup1()
+{
+ int fd1; /* file handle for testfile */
+
+ /* Creat a test file under above directory created */
+ if ((fd1 = open(TEST_FILE1, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s",
+ TEST_FILE1, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Close the testfile created above */
+ if (close(fd1) == -1) {
+ tst_brkm(TBROK, cleanup, "close(%s) Failed, errno=%d : %s",
+ TEST_FILE1, errno, strerror(errno));
+ }
+
+ /* Change mode permissions on testfile */
+ if (chmod(TEST_FILE1, 0333) < 0) {
+ tst_brkm(TBROK, cleanup, "chmod() failed on %s, errno=%d",
+ TEST_FILE1, errno);
+ }
+
+ return 0;
+}
+
+/*
+ * setup2() - Setup function to test access() for return value -1 and
+ * errno EACCES when write access denied on testfile.
+ *
+ * Creat/open a testfile and close it.
+ * Deny write access permissions on testfile.
+ * This function returns 0.
+ */
+int
+setup2()
+{
+ int fd2; /* file handle for testfile */
+
+ /* Creat a test file under above directory created */
+ if ((fd2 = open(TEST_FILE2, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s",
+ TEST_FILE2, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Close the testfile created above */
+ if (close(fd2) == -1) {
+ tst_brkm(TBROK, cleanup, "close(%s) Failed, errno=%d : %s",
+ TEST_FILE2, errno, strerror(errno));
+ }
+
+ /* Change mode permissions on testfile */
+ if (chmod(TEST_FILE2, 0555) < 0) {
+ tst_brkm(TBROK, cleanup, "chmod() failed on %s, errno=%d",
+ TEST_FILE2, errno);
+ }
+
+ return 0;
+}
+
+/*
+ * setup3() - Setup function to test access() for return value -1 and
+ * errno EACCES when execute access denied on testfile.
+ *
+ * Creat/open a testfile and close it.
+ * Deny search access permissions on testfile.
+ * This function returns 0.
+ */
+int
+setup3()
+{
+ int fd3; /* file handle for testfile */
+
+ /* Creat a test file under above directory created */
+ if ((fd3 = open(TEST_FILE3, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s",
+ TEST_FILE3, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Close the testfile created above */
+ if (close(fd3) == -1) {
+ tst_brkm(TBROK, cleanup, "close(%s) Failed, errno=%d : %s",
+ TEST_FILE3, errno, strerror(errno));
+ }
+
+ /* Change mode permissions on testfile */
+ if (chmod(TEST_FILE3, 0666) < 0) {
+ tst_brkm(TBROK, cleanup, "chmod() failed on %s, errno=%d",
+ TEST_FILE3, errno);
+ }
+
+ return 0;
+}
+
+/*
+ * setup4() - Setup function to test access() for return value -1
+ * and errno EINVAL when specified access mode argument is
+ * invalid.
+ *
+ * Creat/open a testfile and close it.
+ * This function returns 0.
+ */
+int
+setup4()
+{
+ int fd4; /* file handle for testfile */
+
+ /* Creat a test file under above directory created */
+ if ((fd4 = open(TEST_FILE4, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s",
+ TEST_FILE4, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Close the testfile created above */
+ if (close(fd4) == -1) {
+ tst_brkm(TBROK, cleanup, "close(%s) Failed, errno=%d : %s",
+ TEST_FILE4, errno, strerror(errno));
+ }
+
+ return 0;
+}
+
+/*
+ * longpath_setup() - setup to create a node with a name length exceeding
+ * the MAX. length of PATH_MAX.
+ */
+int
+longpath_setup()
+{
+ int ind;
+
+ for (ind = 0; ind <= (PATH_MAX + 1); ind++) {
+ Longpathname[ind] = 'a';
+ }
+
+ return 0;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ *
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /*
+ * Delete the test directory/file and temporary directory
+ * created in the setup.
+ */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/alarm07.c b/winsup/testsuite/winsup.api/ltp/alarm07.c
new file mode 100644
index 000000000..7661ba978
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/alarm07.c
@@ -0,0 +1,203 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: alarm03
+ *
+ * Test Description:
+ * Check the functionality of the alarm() when the time input
+ * parameter is non-zero and the process does a fork.
+ *
+ * Expected Result:
+ * The alarm request should be cleared in the child process.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ *
+ * Usage: <for command-line>
+ * alarm03 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+#include "test.h"
+#include "usctest.h"
+
+char *TCID="alarm03"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int almreceived = 0; /* flag to indicate SIGALRM received or not */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+void sigproc(int sig); /* signal catching function */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ int time_sec = 3; /* time for which alarm is set */
+ int sleep_time = 5; /* waiting time for the SIGALRM signal */
+ pid_t cpid; /* child process id */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *)NULL, NULL);
+ if (msg != (char *)NULL) {
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Call First alarm() with non-zero time parameter
+ * 'time_sec' to send SIGALRM to the process.
+ */
+ TEST(alarm(time_sec));
+
+ /* Now, fork a child process */
+ cpid = fork();
+ if (cpid < 0) {
+ tst_resm(TFAIL, "fork() fails to create child, "
+ "errno:%d", errno);
+ }
+
+ /* Wait for signal SIGALRM to be generated */
+ sleep(sleep_time);
+
+ if (STD_FUNCTIONAL_TEST) {
+ if (cpid == 0) { /* Child process */
+ /*
+ * For child process if almreceived is 0
+ * means alarm request is cleared.
+ */
+ if (almreceived == 0) {
+ tst_resm(TPASS, "Functionality of "
+ "alarm(%u) successful",
+ time_sec);
+ } else {
+ tst_resm(TFAIL, "alarm request not "
+ "cleared in child, "
+ "almreceived:%d", almreceived);
+ }
+ } else { /* Parent process */
+ /* Wait for child to complete execution */
+ wait(0);
+ }
+ } else {
+ tst_resm(TPASS, "call returned %d", TEST_RETURN);
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Setup signal handler to catch SIGALRM signal.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Set the signal catching function */
+ if (signal(SIGALRM, sigproc) == SIG_ERR) {
+ tst_brkm(TFAIL, cleanup,
+ "signal() fails to catch SIGALARM, errno=%d",
+ errno);
+ }
+}
+
+
+/*
+ * sigproc(int) - This function defines the action that has to be taken
+ * when the SIGALRM signal is caught.
+ * It also sets the variable which is used to check whether the
+ * alarm system call was successful.
+ */
+void
+sigproc(int sig)
+{
+ almreceived = almreceived + 1;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/chdir04.c b/winsup/testsuite/winsup.api/ltp/chdir04.c
new file mode 100644
index 000000000..d220bb17f
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/chdir04.c
@@ -0,0 +1,189 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * chdir02.c
+ *
+ * DESCRIPTION
+ * Testcase to test whether chdir(2) sets errno correctly.
+ *
+ * ALGORITHM
+ * 1. Test for ENAMETOOLONG:
+ * Create a bad directory name with length more than
+ *
+ * VFS_MAXNAMELEN (Linux kernel variable), and attempt to
+ * chdir(2) to it.
+ *
+ * 2. Test for ENOENT:
+ * Attempt to chdir(2) on a non-existent directory
+ *
+ * 3. Test for EFAULT:
+ * Pass an address which lies outside the address space of the
+ * process, and expect an EFAULT.
+ *
+ * USAGE: <for command-line>
+ * chdir02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * NONE
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <test.h>
+#include <usctest.h>
+
+char *TCID = "chdir02";
+int TST_TOTAL = 3;
+extern int Tst_count;
+
+int exp_enos[] = {ENAMETOOLONG, ENOENT, EFAULT, 0};
+
+char bad_dir[] = "abcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyz";
+
+char noexist_dir[] = "/tmp/noexistdir";
+
+struct test_case_t {
+ char *dname;
+ int error;
+} TC[] = {
+ /*
+ * to test whether chdir() is setting ENAMETOOLONG if the
+ * directory is more than VFS_MAXNAMELEN
+ */
+ {bad_dir, ENAMETOOLONG},
+
+ /*
+ * to test whether chdir() is setting ENOENT if the
+ * directory is not existing.
+ */
+ {noexist_dir, ENOENT},
+
+ /*
+ * to test whether chdir() is setting EFAULT if the
+ * directory is an invalid address.
+ */
+ {(void *)-1, EFAULT}
+};
+
+int flag;
+#define FAILED 1
+
+void setup(void);
+void cleanup(void);
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ int i;
+ const char *msg; /* message returned from parse_opts */
+ struct stat statbuf;
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ setup();
+
+ /* set up the expected errnos */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* check looping state if -i option is given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ /* loop through the test cases */
+ for (i=0; i<TST_TOTAL; i++) {
+
+ TEST(chdir(TC[i].dname));
+
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "call succeeded unexpectedly");
+ continue;
+ }
+
+ TEST_ERROR_LOG(TEST_ERRNO);
+
+ if (TEST_ERRNO == TC[i].error) {
+ tst_resm(TPASS, "expected failure - "
+ "errno = %d : %s", TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ } else {
+ tst_resm(TFAIL, "unexpected error - %d : %s - "
+ "expected %d", TEST_ERRNO,
+ strerror(TEST_ERRNO), TC[i].error);
+ }
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temporary directory and cd to it */
+ tst_tmpdir();
+}
+
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /*
+ * Delete the test directory created in setup().
+ */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/chmod01.c b/winsup/testsuite/winsup.api/ltp/chmod01.c
new file mode 100644
index 000000000..12198fe9e
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/chmod01.c
@@ -0,0 +1,231 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: chmod01
+ *
+ * Test Description:
+ * Verify that, chmod(2) succeeds when used to change the mode permissions
+ * of a file.
+ *
+ * Expected Result:
+ * chmod(2) should return 0 and the mode permissions set on file should match
+ * the specified mode.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * chmod01 [-c n] [-e] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+#define TESTFILE "testfile"
+
+char *TCID="chmod01"; /* Test program identifier. */
+int TST_TOTAL=8; /* Total number of test conditions */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+
+int Modes[] = {0, 07, 070, 0700, 0777, 02777, 04777, 06777};
+
+void setup(); /* setup function for the test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ struct stat stat_buf; /* stat(2) struct contents */
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ int ind; /* counter variable for chmod(2) tests */
+ int mode; /* file mode permission */
+
+ TST_TOTAL = sizeof(Modes) / sizeof(int);
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count = 0;
+
+ for (ind = 0; ind < TST_TOTAL; ind++) {
+ mode = Modes[ind];
+
+ /*
+ * Call chmod(2) with different mode permission
+ * bits to set it for "testfile".
+ */
+ TEST(chmod(TESTFILE, mode));
+
+ /* check return code of chmod(2) */
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL,
+ "chmod(%s, %#o) Failed, errno=%d : %s",
+ TESTFILE, mode, TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ continue;
+ }
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Get the testfile information using
+ * stat(2).
+ */
+ if (stat(TESTFILE, &stat_buf) < 0) {
+ tst_brkm(TFAIL, cleanup, "stat(2) of "
+ "%s failed, errno:%d",
+ TESTFILE, TEST_ERRNO);
+ }
+ stat_buf.st_mode &= ~S_IFREG;
+
+ /*
+ * Check for expected mode permissions
+ * on testfile.
+ */
+ if (stat_buf.st_mode == mode) {
+ tst_resm(TPASS, "Functionality of "
+ "chmod(%s, %#o) successful",
+ TESTFILE, mode);
+ } else {
+ tst_resm(TFAIL, "%s: Incorrect "
+ "modes 0%03o, Expected 0%03o",
+ TESTFILE, stat_buf.st_mode,
+ mode);
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * void
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ * Create a test file under temporary directory and close it
+ */
+void
+setup()
+{
+ int fd;
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Creat a test file under temporary directory and close it */
+ if ((fd = open(TESTFILE, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %o) Failed, errno=%d : %s",
+ TESTFILE, FILE_MODE, errno, strerror(errno));
+ }
+ if (close(fd) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "close(%s) Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ }
+
+} /* End setup() */
+
+/*
+ * void
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/close01.c b/winsup/testsuite/winsup.api/ltp/close01.c
new file mode 100644
index 000000000..1637c90eb
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/close01.c
@@ -0,0 +1,199 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * close01.c
+ *
+ * DESCRIPTION
+ * Test that closing a regular file and a pipe works correctly
+ *
+ * ALGORITHM
+ * Creat a file, and dup() a fildes
+ * Open a pipe
+ * call close() using the TEST macro
+ * if the call fails
+ * issue a FAIL message and continue
+ * else if STD_FUNCTIONAL_TEST
+ * attempt to close the file/pipe again
+ * if there is an error
+ * issue a PASS message
+ * else
+ * issue a FAIL message
+ * else
+ * issue a PASS message
+ *
+ *
+ * USAGE: <for command-line>
+ * close01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+
+void cleanup(void);
+void setup(void);
+
+char *TCID = "close01()";
+int TST_TOTAL = 2;
+extern int Tst_count;
+
+char fname[40] = "";
+
+int fild = -1;
+int newfd = -1;
+int pipefildes[2];
+
+struct test_case_t {
+ int *fd;
+ char *type;
+} TC[] = {
+ /* file descriptor for a regular file */
+ {&newfd, "file"},
+
+ /* file descriptor for a pipe */
+ {&pipefildes[0], "pipe"}
+};
+
+main(int ac, char **av)
+{
+
+ int i;
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup(); /* global setup */
+
+ /* The following loop checks looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ /* set up the file and pipe for the test */
+ if ((fild = creat(fname, 0777)) == -1) {
+ perror (fname);
+ tst_brkm(TBROK, cleanup, "can't open file %s", fname);
+ }
+
+ if ((newfd = dup(fild)) == -1) {
+ tst_brkm(TBROK, cleanup, "can't dup the file des");
+ }
+
+ if (pipe(pipefildes) == -1) {
+ tst_brkm(TBROK, cleanup, "can't open pipe");
+ }
+
+ /* loop through the test cases */
+
+ for (i = 0; i < TST_TOTAL; i++) {
+
+ TEST(close(*TC[i].fd));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "call failed unexpectedly");
+ continue;
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+ /* attempt to close the fd again */
+ if (close(*TC[i].fd) == -1) {
+ tst_resm(TPASS, "%s appears closed",
+ TC[i].type);
+ } else {
+ tst_resm(TFAIL, "%s close succeeded on"
+ "second attempt", TC[i].type);
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ }
+
+ }
+ cleanup();
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+ int mypid;
+
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ umask(0);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ mypid = getpid();
+ sprintf(fname, "fname.%d", mypid);
+}
+
+/*
+ * cleanup() - performs all the ONE TIME cleanup for this test at completion
+ * or premature exit.
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing status if that option was specified.
+ * print errno log if that option was specified
+ */
+ TEST_CLEANUP;
+
+ if (fild >= 0)
+ close (fild);
+ if (newfd >= 0)
+ close (newfd);
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/close02.c b/winsup/testsuite/winsup.api/ltp/close02.c
new file mode 100644
index 000000000..44f98b250
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/close02.c
@@ -0,0 +1,142 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * close02.c
+ *
+ * DESCRIPTION
+ * Check that an invalid file descriptor returns EBADF
+ *
+ * ALGORITHM
+ * loop if that option is specified
+ * call close using the TEST macro and passing in an invalid fd
+ * if the call succeedes
+ * issue a FAIL message
+ * else
+ * log the errno
+ * if the errno == EBADF
+ * issue a PASS message
+ * else
+ * issue a FAIL message
+ * cleanup
+ *
+ * USAGE: <for command-line>
+ * close02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+
+void cleanup(void);
+void setup(void);
+
+int exp_enos[] = {EBADF, 0};
+
+char *TCID = "close02()";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup(); /* global setup */
+
+ /* set up expected errnos */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* The following loop checks looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ TEST(close(-1));
+
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "Closed a non existent fildes");
+ } else {
+ TEST_ERROR_LOG(TEST_ERRNO);
+
+ if (TEST_ERRNO != EBADF) {
+ tst_resm(TFAIL, "close() FAILED to set errno "
+ "to EBADF on an invalid fd, got %d",
+ errno);
+ } else {
+ tst_resm(TPASS, "call returned EBADF");
+ }
+ }
+ }
+ cleanup();
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ umask(0);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all the ONE TIME cleanup for this test at completion
+ * or premature exit.
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing status if that option was specified.
+ * print errno log if that option was specified
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/creat01.c b/winsup/testsuite/winsup.api/ltp/creat01.c
new file mode 100644
index 000000000..7dd016f22
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/creat01.c
@@ -0,0 +1,206 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * creat01.c
+ *
+ * DESCRIPTION
+ * Testcase to check the basic functionality of the creat(2) system call.
+ *
+ * ALGORITHM
+ * 1. creat() a file using 0444 mode, write to the fildes, write
+ * should return a positive count.
+ *
+ * 2. creat() should truncate a file to 0 bytes if it already
+ * exists, and should not fail.
+ *
+ * USAGE: <for command-line>
+ * creat01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+
+void setup(void);
+void cleanup(void);
+void functest1(void);
+void functest2(void);
+
+char *TCID = "creat01";
+int TST_TOTAL = 2;
+extern int Tst_count;
+
+char filename[40];
+
+#define MODE1 0644
+#define MODE2 0444
+
+struct test_case_t {
+ char *fname;
+ int mode;
+ void (*functest)();
+} TC[] = {
+ /* creat() the file and write to it */
+ {filename, MODE1, functest1},
+
+ /* creat() the same file and check that it is now 0 length */
+ {filename, MODE2, functest2}
+};
+
+main(int ac, char **av)
+{
+ int i;
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ setup(); /* set "tstdir", and "testfile" variables */
+
+ /* check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ /* loop through the test cases */
+
+ for (i=0; i<TST_TOTAL; i++) {
+ TEST(creat(filename, TC[i].mode));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "Could not creat file %s",
+ filename);
+ continue;
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+ (*TC[i].functest)();
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ if (TEST_RETURN >= 0) {
+ close(TEST_RETURN);
+ }
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * functest1() - check the functionality of the first test by making sure
+ * that a write to the file succeeds
+ */
+void
+functest1()
+{
+ if (write(TEST_RETURN, "A", 1) != 1) {
+ tst_resm(TFAIL, "write was unsuccessful");
+ } else {
+ tst_resm(TPASS, "file was created and written to successfully");
+ }
+}
+
+/*
+ * functest2() - check the functionality of the second test by making sure
+ * that the file is now 0 length
+ */
+void
+functest2()
+{
+ struct stat buf;
+
+ if (stat(filename, &buf) < 0) {
+ tst_brkm(TBROK, cleanup, "failed to stat test file");
+ /*NOTREACHED*/
+ }
+ if (buf.st_size != 0) {
+ tst_resm(TFAIL, "creat() FAILED to truncate "
+ "file to zero bytes");
+ } else {
+ tst_resm(TPASS, "creat() truncated existing file to 0 bytes");
+ }
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup()
+{
+ if (geteuid() == 0) {
+ tst_brkm(TBROK, tst_exit, "Must not run this as root");
+ /*NOTREACHED*/
+ }
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ umask(0);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ tst_tmpdir();
+
+ sprintf(filename, "creat01.%d", getpid());
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ unlink(filename);
+
+ /* delete the test directory created in setup() */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/creat03.c b/winsup/testsuite/winsup.api/ltp/creat03.c
new file mode 100644
index 000000000..c5e5242bf
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/creat03.c
@@ -0,0 +1,153 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * creat03.c
+ *
+ * DESCRIPTION
+ * Testcase to check whether the sticky bit cleared.
+ *
+ * ALGORITHM
+ * Creat a new file, fstat.st_mode should have the 01000 bit off
+ *
+ * USAGE: <for command-line>
+ * creat03 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "creat03"; /* Test program identifier */
+int TST_TOTAL = 1; /* Total number of test cases */
+extern int Tst_count; /* Test case counter */
+
+char pfilname[40] = "";
+#define FMODE 0444
+
+void setup(void);
+void cleanup(void);
+
+main(int ac, char **av)
+{
+ struct stat statbuf;
+ unsigned short filmode;
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup();
+
+ /* check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ TEST(creat(pfilname, FMODE));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "Cannot creat %s", pfilname);
+ continue;
+ /*NOTREACHED*/
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+ if (fstat(TEST_RETURN, &statbuf) == -1) {
+ tst_brkm(TBROK, cleanup, "fstat() failed");
+ }
+ filmode = statbuf.st_mode;
+ tst_resm(TINFO, "Created file has mode = 0%o", filmode);
+ if ((filmode & S_ISVTX) != 0) {
+ tst_resm(TFAIL, "save text bit not cleared");
+ } else {
+ tst_resm(TPASS, "save text bit cleared");
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+
+ if (TEST_RETURN >= 0) {
+ close(TEST_RETURN);
+ }
+
+ /* clean up things in case we are looping */
+ if (unlink(pfilname) == -1) {
+ tst_brkm(TBROK, cleanup, "couldn't remove file");
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp dir and cd to it */
+ tst_tmpdir();
+
+ sprintf(pfilname, "./creat4.%d", getpid());
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion or
+ * premature exit
+ */
+void
+cleanup(void)
+{
+ TEST_CLEANUP;
+
+ /* remove the tmp dir and all its files */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/exit01.c b/winsup/testsuite/winsup.api/ltp/exit01.c
new file mode 100644
index 000000000..729f49ac6
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/exit01.c
@@ -0,0 +1,163 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * exit01.c
+ *
+ * DESCRIPTION
+ * Check that exit returns the correct values to the waiting parent
+ *
+ * ALGORITHM
+ * Fork a process that immediately calls exit() with a known
+ * value. Check for that value in the parent.
+ *
+ * USAGE
+ * exit01
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+
+void cleanup(void);
+void setup(void);
+
+char *TCID = "exit01";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+main(int ac, char **av)
+{
+ int pid, npid, sig, nsig, exno, nexno, status;
+ int rval = 0;
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSIkNG ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup(); /* global setup for test */
+
+ /* check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping. */
+ Tst_count = 0;
+
+ sig = 0;
+ exno = 1;
+
+ if ((pid = fork()) == -1) {
+ tst_brkm(TBROK, cleanup, "fork failed, errno=%d",
+ errno, strerror(errno));
+ }
+
+ if (pid == 0) { /* parent */
+ exit(exno);
+ } else {
+ sleep(1); /* let child start */
+ npid = wait(&status);
+
+ if (npid != pid) {
+ tst_resm(TFAIL, "wait error: "
+ "unexpected pid returned");
+ rval = 1;
+ }
+
+ nsig = status % 256;
+
+ /*
+ * Check if the core dump bit has been set, bit # 7
+ */
+ if (nsig >= 128) {
+ nsig = nsig - 128;
+ }
+
+ /*
+ * nsig is the signal number returned by wait
+ */
+ if (nsig != sig) {
+ tst_resm(TFAIL, "wait error: "
+ "unexpected signal returned");
+ rval = 1;
+ }
+
+ /*
+ * nexno is the exit number returned by wait
+ */
+ nexno = status / 256;
+ if (nexno != exno) {
+ tst_resm(TFAIL, "wait error: "
+ "unexpected exit number returned");
+ rval = 1;
+ }
+ }
+
+ if (rval != 1) {
+ tst_resm(TPASS, "exit() test PASSED");
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ umask(0);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion or
+ * premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/exit02.c b/winsup/testsuite/winsup.api/ltp/exit02.c
new file mode 100644
index 000000000..b81ecbcb9
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/exit02.c
@@ -0,0 +1,227 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * exit02.c
+ *
+ * DESCRIPTION
+ * Check that exit flushes output file buffers and closes files upon
+ * exitting
+ *
+ * ALGORITHM
+ * Fork a process that creates a file and writes a few bytes, and
+ * calls exit WITHOUT calling close(). The parent then reads the
+ * file. If everything that was written is present in the file, then
+ * the test passes.
+ *
+ * USAGE
+ * exit02
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include "test.h"
+#include "usctest.h"
+
+void cleanup(void);
+void setup(void);
+
+char *TCID = "exit02";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+#define READ 0
+#define WRITE 1
+#define MODE 0666
+
+char filen[40];
+
+main(int ac, char **av)
+{
+ int pid, npid, sig, nsig, exno, nexno, status;
+ int filed;
+ char wbuf[BUFSIZ], rbuf[BUFSIZ];
+ int len, rlen;
+ int rval = 0;
+ char *strcpy();
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /*
+ * parse standard options
+ */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup(); /* global setup for test */
+
+ /*
+ * The following loop checks looping state if -i option given
+ */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /*
+ * reset Tst_count in case we are looping.
+ */
+ Tst_count = 0;
+
+ strcpy(wbuf, "abcd");
+ len = strlen(wbuf);
+
+ exno = sig = 0;
+
+ if ((pid = fork()) == -1) {
+ tst_brkm(TBROK, cleanup, "fork failed, error no = %d",
+ errno, strerror(errno));
+ }
+
+ if (pid == 0) { /* child */
+ sleep(1);
+ if ((filed = creat(filen, MODE)) == -1) {
+ tst_resm(TINFO, "creat error: unable to"
+ "open output file");
+ exit(2);
+ }
+ if (write(filed, wbuf, len) != len) {
+ tst_resm(TINFO, "write error");
+ exit(2);
+ }
+ close(filed);
+ exit(exno);
+ } else { /* parent */
+ npid = wait(&status);
+
+ if (npid != pid) {
+ tst_resm(TFAIL, "wait error: "
+ "unexpected pid returned");
+ rval = 1;
+ }
+
+ nsig = status % 256;
+
+ /*
+ * to check if the core dump bit has been
+ * set, bit # 7
+ */
+ if (nsig >= 128)
+ nsig = nsig - 128;
+
+ /*
+ * nsig is the signal number returned by
+ * wait
+ */
+ if (nsig != sig) {
+ tst_resm(TFAIL, "wait error: unexpected "
+ "signal returned %d", nsig);
+ rval = 1;
+ }
+
+ /*
+ * nexno is the exit number returned by wait
+ */
+ nexno = status / 256;
+ if (nexno != exno) {
+ tst_resm(TFAIL, "wait error: unexpected exit "
+ "number %d", nexno);
+ rval = 1;
+ }
+
+ sleep(2); /* let child's exit close opened file */
+
+ filed = open(filen, O_RDONLY, READ);
+ if (filed == -1) {
+ tst_resm(TFAIL, "open error: "
+ "unable to open input file");
+ rval = 1;
+ } else {
+ rlen = read(filed, rbuf, len);
+ if (len != rlen) {
+ tst_resm(TFAIL, "exit error: file "
+ "buffer was not flushed");
+ rval = 1;
+ } else if (memcmp(rbuf, wbuf, rlen) != 0) {
+ tst_resm(TFAIL, "exit error: file "
+ "buffer was not flushed");
+ rval = 1;
+ }
+ }
+ close(filed);
+ unlink(filen);
+ }
+ if (!rval) {
+ tst_resm(TPASS, "exit() test PASSED");
+ }
+ }
+ cleanup();
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - perform all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ umask(0);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ sprintf(filen, "tfile_%d",getpid());
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion or
+ * premature exit.
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified
+ */
+ TEST_CLEANUP;
+
+ /*
+ * Remove tmp dir and all files in it
+ */
+ tst_rmdir();
+
+ /*
+ * exit with return code appropriate for results
+ */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/fchdir01.c b/winsup/testsuite/winsup.api/ltp/fchdir01.c
new file mode 100644
index 000000000..83685d34d
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/fchdir01.c
@@ -0,0 +1,248 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * fchdir01.c
+ *
+ * DESCRIPTION
+ * fchdir01 - create a directory and cd into it.
+ *
+ * ALGORITHM
+ * create a new directory
+ * open the directory and get a file descriptor
+ * loop if that option was specified
+ * fchdir() into the directory
+ * check the return code
+ * if failure, issue a FAIL message.
+ * otherwise,
+ * if doing functionality testing, call check_functionality()
+ * if correct,
+ * issue a PASS message
+ * otherwise
+ * issue a FAIL message
+ * call cleanup
+ *
+ * USAGE: <for command-line>
+ * fchdir01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 03/2001 - Written by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * none
+ */
+
+#include "test.h"
+#include "usctest.h"
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+
+void cleanup(void);
+void setup(void);
+
+char *TCID = "fchdir01";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+int fd = -1;
+char temp_dir_buf [PATH_MAX];
+char* temp_dir;
+const char *TEST_DIR = "alpha";
+
+#define MODES S_IRWXU
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ void check_functionality(void);
+ int r_val;
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ setup(); /* global setup */
+
+ /* The following loop checks looping state if -i option given */
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ /* get the name of the test dirctory */
+ if ((temp_dir = (getcwd(temp_dir_buf, sizeof (temp_dir_buf)))) == NULL) {
+ tst_brkm(TBROK, cleanup, "%s - getcwd() in main() "
+ "failed", TCID);
+ }
+
+ /*
+ * create a new directory and open it
+ */
+
+ if ((r_val = mkdir(TEST_DIR, MODES)) == -1){
+ tst_brkm(TBROK, cleanup, "%s - mkdir() in main() "
+ "failed", TCID);
+ }
+
+ if ((fd = open(TEST_DIR, O_RDONLY)) == -1) {
+ tst_brkm(TBROK, cleanup, "open of directory failed");
+ }
+
+ /*
+ * Use TEST macro to make the call
+ */
+
+ TEST(fchdir(fd));
+
+ if (TEST_RETURN == -1) {
+ tst_brkm(TFAIL, cleanup, "%s call failed - errno = %d :"
+ " %s", TCID, TEST_ERRNO, strerror(TEST_ERRNO));
+ } else {
+ if (STD_FUNCTIONAL_TEST) {
+ check_functionality();
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ }
+
+ /*
+ * clean up things in case we are looping
+ */
+
+ /*
+ * NOTE: in case of failure here, we need to use "tst_resm()"
+ * and not "tst_brkm()". This is because if we get to this
+ * point, we have already set a PASS or FAIL for the test
+ * and "tst_brkm()" won't report as we might expect.
+ */
+
+ /* chdir back to our temporary work directory */
+ if ((r_val = chdir("..")) == -1){
+ tst_resm(TBROK, "fchdir failed - errno = %d : %s",
+ errno, strerror(errno));
+ }
+
+ if ((r_val = rmdir(TEST_DIR)) == -1){
+ tst_resm(TBROK, "rmdir failed - errno = %d : %s",
+ errno, strerror(errno));
+ }
+
+ /*
+ * clean up things in case we are looping
+ */
+ /* free(temp_dir); */
+ temp_dir = NULL;
+ }
+
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * check_functionality() - check that we are in the correct directory.
+ */
+void
+check_functionality(void)
+{
+ char buf [PATH_MAX];
+ char *cwd;
+ char **bufptr = &cwd;
+ char *dir;
+
+ /*
+ * Get the current directory path.
+ */
+ if ((cwd = (getcwd(buf, sizeof (buf)))) == NULL) {
+ tst_brkm(TBROK, cleanup, "%s - getcwd() in "
+ "check_functionality() failed", TCID);
+ }
+
+ /*
+ * strip off all but the last directory name in the
+ * current working directory.
+ */
+ do {
+ if ((dir = strsep(bufptr, "/")) == NULL) {
+ tst_brkm(TBROK, cleanup, "%s - strsep() in "
+ "check_functionality() failed", TCID);
+ }
+ } while(*bufptr != NULL);
+
+ /*
+ * Make sure we are in the right place.
+ */
+ if (strcmp(TEST_DIR, dir) == 0) {
+ tst_resm(TPASS, "%s call succeeded", TCID);
+ } else {
+ tst_resm(TFAIL, "%s functionality test failed", TCID);
+ }
+}
+
+/*
+ * setup() - performs all the ONE TIME setup for this test.
+ */
+void
+setup(void)
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* create a test directory and cd into it */
+ tst_tmpdir();
+}
+
+/*
+ * cleanup() - performs all the ONE TIME cleanup for this test at completion
+ * or premature exit.
+ */
+void
+cleanup(void)
+{
+ if (fd >= 0)
+ close (fd);
+
+ /* remove the test directory */
+ tst_rmdir();
+
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
+
diff --git a/winsup/testsuite/winsup.api/ltp/fchdir02.c b/winsup/testsuite/winsup.api/ltp/fchdir02.c
new file mode 100644
index 000000000..c09d905b5
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/fchdir02.c
@@ -0,0 +1,159 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * fchdir02.c
+ *
+ * DESCRIPTION
+ * fchdir02 - try to cd into a bad directory (bad fd).
+ *
+ * CALLS
+ * fchdir()
+ *
+ * ALGORITHM
+ * loop if that option was specified
+ * call fchdir() with an invalid file descriptor
+ * check the errno value
+ * issue a PASS message if we get EBADF - errno 9
+ * otherwise, the tests fails
+ * issue a FAIL message
+ * break any remaining tests
+ * call cleanup
+ *
+ * USAGE: <for command-line>
+ * fchdir02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 03/2001 - Written by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * none
+ */
+
+#include "test.h"
+#include "usctest.h"
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+void cleanup(void);
+void setup(void);
+
+char *TCID = "fchdir02";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+int exp_enos[] = {9, 0}; /* 0 terminated list of expected errnos */
+
+main(int ac, char **av)
+{
+ const int bad_fd = -5;
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ setup(); /* global setup */
+
+ /* The following loop checks looping state if -i option given */
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ /*
+ * Look for a failure by using an invalid number for fd
+ */
+
+ TEST(fchdir(bad_fd));
+
+ if (TEST_RETURN != -1) {
+ tst_brkm(TFAIL, cleanup, "call succeeded with bad "
+ "file descriptor");
+ }
+
+ TEST_ERROR_LOG(TEST_ERRNO);
+
+ switch(TEST_ERRNO) {
+ case EBADF:
+ tst_resm(TPASS, "expected failure - errno = %d : %s",
+ TEST_ERRNO, strerror(TEST_ERRNO));
+ break;
+ default:
+ tst_brkm(TFAIL, cleanup, "call failed with an "
+ "unexpected error - %d : %s", TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ }
+ }
+
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all the ONE TIME setup for this test.
+ */
+void
+setup(void)
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* create a test directory and cd into it */
+ tst_tmpdir();
+
+ /* Set up the expected error numbers for -e option */
+ TEST_EXP_ENOS(exp_enos);
+}
+
+/*
+ * cleanup() - performs all the ONE TIME cleanup for this test at completion
+ * or premature exit.
+ */
+void
+cleanup(void)
+{
+ /* remove the test directory */
+ tst_rmdir();
+
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
+
diff --git a/winsup/testsuite/winsup.api/ltp/fork02.c b/winsup/testsuite/winsup.api/ltp/fork02.c
new file mode 100644
index 000000000..eaf3b6404
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/fork02.c
@@ -0,0 +1,142 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * fork02.c
+ *
+ * DESCRIPTION
+ * Test correct operation of fork:
+ * pid == 0 in child;
+ * pid > 0 in parent from wait;
+ *
+ * ALGORITHM
+ * Fork one process, check for pid == 0 in child.
+ * Check for pid > 0 in parent after wait.
+ *
+ * USAGE
+ * fork02
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include "test.h"
+#include "usctest.h"
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "fork02";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+main(int ac, char **av)
+{
+ int pid1, pid2, status;
+
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /*
+ * parse standard options
+ */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ /*
+ * perform global setup for the test
+ */
+ setup();
+
+ /*
+ * check looping state if -i option is given
+ */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /*
+ * reset Tst_count in case we are looping.
+ */
+ Tst_count = 0;
+
+ if ((pid1 = fork()) == -1) {
+ tst_brkm(TBROK, cleanup, "fork() failed");
+ }
+
+ if (pid1 == 0) {
+ tst_resm(TINFO, "Inside child");
+ _exit(0);
+ } else {
+ tst_resm(TINFO, "Inside parent");
+ pid2 = wait(&status);
+ tst_resm(TINFO, "exit status of wait %d", status);
+
+ if (pid1 == pid2) {
+ tst_resm(TPASS, "test 1 PASSED");
+ } else {
+ tst_resm(TFAIL, "test 1 FAILED");
+ }
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup()
+{
+ /*
+ * capture signals
+ */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /*
+ * Pause if that option was specified
+ */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/fork03.c b/winsup/testsuite/winsup.api/ltp/fork03.c
new file mode 100644
index 000000000..cda913273
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/fork03.c
@@ -0,0 +1,164 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * fork03.c
+ *
+ * DESCRIPTION
+ * Check that child can use a large text space and do a large
+ * number of operations.
+ *
+ * ALGORITHM
+ * Fork one process, check for pid == 0 in child.
+ * Check for pid > 0 in parent after wait.
+ *
+ * USAGE
+ * fork03
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <stdio.h>
+#include "test.h"
+#include "usctest.h"
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "fork03";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+main(int ac, char **av)
+{
+ float fl1, fl2;
+ int i;
+ int pid1, pid2, status;
+
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /*
+ * parse standard options
+ */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ /*
+ * perform global setup for the test
+ */
+ setup();
+
+ /*
+ * check looping state if -i option is given
+ */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /*
+ * reset Tst_count in case we are looping.
+ */
+ Tst_count = 0;
+
+ if ((pid1 = fork()) == -1) {
+ tst_brkm(TBROK, cleanup, "fork() failed");
+ }
+
+ if (pid1 == 0) { /* child */
+ /* child uses some cpu cycles */
+ for (i = 1; i < 32767; i++) {
+ fl1 = 0.000001;
+ fl1 = fl2 = 0.000001;
+ fl1 = fl1 * 10.0;
+ fl2 = fl1 / 1.232323;
+ fl1 = fl2 - fl2;
+ fl1 = fl2;
+ }
+
+ /* Pid must always be zero in child */
+
+ if (pid1 != 0) {
+ exit(1);
+ } else {
+ exit(0);
+ }
+ } else { /* parent */
+ tst_resm(TINFO, "process id in parent of child from "
+ "fork : %d", pid1);
+ pid2 = wait(&status); /* wait for child */
+
+ if (pid1 != pid2) {
+ tst_resm(TFAIL, "pids don't match : %d vs %d",
+ pid1, pid2);
+ continue;
+ }
+
+ if ((status >> 8) != 0) {
+ tst_resm(TFAIL, "child exited with failure");
+ continue;
+ }
+
+ tst_resm(TPASS, "test 1 PASSED");
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup()
+{
+ /*
+ * capture signals
+ */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /*
+ * Pause if that option was specified
+ */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/fork06.c b/winsup/testsuite/winsup.api/ltp/fork06.c
new file mode 100644
index 000000000..c2e5a471a
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/fork06.c
@@ -0,0 +1,152 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * fork06.c
+ *
+ * DESCRIPTION
+ * Test that a process can fork children a large number of
+ * times in succession
+ *
+ * ALGORITHM
+ * Attempt to fork a child that exits immediately
+ * Repeat it many times(1000), counting the number of successes and
+ * failures
+ *
+ * USAGE
+ * fork06
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <stdio.h>
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "fork06";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+#define NUMFORKS 1000
+
+main(int ac, char **av)
+{
+ int i, pid, status, childpid, succeed, fail;
+
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /*
+ * parse standard options
+ */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ /*
+ * perform global setup for the test
+ */
+ setup();
+
+ /*
+ * check looping state if -i option is given
+ */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /*
+ * reset Tst_count in case we are looping.
+ */
+ Tst_count = 0;
+
+ succeed = 0;
+ fail = 0;
+
+ for (i = 0; i < NUMFORKS; i++) {
+ if ((pid = fork()) == -1) {
+ fail++;
+ continue;
+ }
+
+ if (pid == 0) { /* child */
+ _exit(0);
+ }
+
+ /* parent */
+ childpid = wait(&status);
+ if (pid != childpid) {
+ tst_resm(TFAIL, "pid from wait %d", childpid);
+ }
+ succeed++;
+ }
+
+ tst_resm(TINFO, "tries %d", i);
+ tst_resm(TINFO, "successes %d", succeed);
+ tst_resm(TINFO, "failures %d", fail);
+
+ if ((wait(&status)) == -1) {
+ tst_resm(TINFO, "There were no children to wait for");
+ } else {
+ tst_resm(TINFO, "There were children left");
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup()
+{
+ /*
+ * capture signals
+ */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /*
+ * Pause if that option was specified
+ */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/fork07.c b/winsup/testsuite/winsup.api/ltp/fork07.c
new file mode 100644
index 000000000..d8487c13a
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/fork07.c
@@ -0,0 +1,198 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * fork07.c
+ *
+ * DESCRIPTION
+ * Check that all children inherit parent's file descriptor
+ *
+ * ALGORITHM
+ * Parent opens a file, writes to it; forks processes until
+ * -1 is returned. Each child attempts to read the file then returns.
+ *
+ * USAGE
+ * fork07
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <stdio.h>
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "fork07";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+char pbuf[10];
+char fnamebuf[40];
+
+main(int ac, char **av)
+{
+ int status, count, forks, pid1;
+ int ch_r_stat;
+ FILE *rea, *writ;
+
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /*
+ * parse standard options
+ */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ /*
+ * perform global setup for the test
+ */
+ setup();
+
+ /*
+ * check looping state if -i option is given
+ */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /*
+ * reset Tst_count in case we are looping.
+ */
+ Tst_count = 0;
+
+ if ((writ = fopen(fnamebuf, "w")) == NULL)
+ tst_resm(TFAIL, "failed to fopen file for write");
+ if ((rea = fopen(fnamebuf, "r")) == NULL)
+ tst_resm(TFAIL, "failed to fopen file for read");
+
+ fprintf(writ,"abcdefghijklmnopqrstuv") ;
+ fflush(writ);
+ sleep(1);
+
+ if ((getc(rea)) != 'a')
+ tst_resm(TFAIL, "getc from read side was confused");
+
+ forks = 0;
+
+forkone:
+ ++forks;
+ pid1 = -1;
+ if ( forks >= 1000 || (pid1 = fork()) != 0) { /* parent */
+ if (pid1 > 0) {
+ goto forkone;
+ } else if (pid1 < 0) {
+ tst_resm(TINFO, "last child forked");
+ }
+ } else { /* child */
+ ch_r_stat = getc(rea);
+#ifdef DEBUG
+ tst_resm(TINFO, "Child got char: %c", ch_r_stat);
+ tst_resm(TINFO, "integer value of getc in child "
+ "expected %d got %d", 'b', ch_r_stat);
+#endif
+ if (ch_r_stat != EOF) { /* for error or EOF */
+ tst_resm(TPASS, "test passed in child no %d",
+ forks);
+ exit(0);
+ } else {
+ tst_resm(TFAIL, "Test failed in child no. %d",
+ forks);
+ exit(-1);
+ }
+ }
+
+ /* parent */
+ --forks;
+ for (count = 0; count <= forks; count++) {
+ wait(&status);
+#ifdef DEBUG
+ tst_resm(TINFO, " exit status of wait "
+ " expected 0 got %d", status);
+#endif
+ if (status == 0) {
+ tst_resm(TPASS, "parent test passed");
+ } else {
+ tst_resm(TFAIL, "parent test failed");
+ }
+ }
+ tst_resm(TINFO, "Number of processes forked is %d", forks);
+ }
+ fclose (writ);
+ fclose (rea);
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup()
+{
+ /*
+ * capture signals
+ */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ umask(0);
+
+ /*
+ * Pause if that option was specified
+ */
+ TEST_PAUSE;
+
+ /*
+ * make a temp directory and cd to it
+ */
+ tst_tmpdir();
+
+ strcpy(fnamebuf, "fork07.");
+ sprintf(pbuf, "%d", getpid());
+ strcat(fnamebuf, pbuf);
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /*
+ * remove tmp dir and all files in it
+ */
+ unlink(fnamebuf);
+ tst_rmdir();
+
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/fork09.c b/winsup/testsuite/winsup.api/ltp/fork09.c
new file mode 100644
index 000000000..71a3f1d0b
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/fork09.c
@@ -0,0 +1,228 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * fork01.c
+ *
+ * DESCRIPTION
+ * Check that child has access to a full set of files.
+ *
+ * ALGORITHM
+ * Parent opens a maximum number of files
+ * Child closes one and attempts to open another, it should be
+ * available
+ *
+ * USAGE
+ * fork01
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <limits.h> /* for OPEN_MAX */
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "fork01";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+char filname[40], childfile[40];
+int first;
+FILE **fildeses; /* file streams */
+int mypid, nfiles;
+
+main(int ac, char **av)
+{
+ int pid, status, dtable, nf;
+
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /*
+ * parse standard options
+ */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ /*
+ * perform global setup for the test
+ */
+ setup();
+
+ fildeses = (FILE**)malloc((OPEN_MAX + 10) * sizeof(FILE *));
+ if (fildeses == NULL) {
+ tst_brkm(TBROK, cleanup, "malloc failed");
+ /*NOTREACHED*/
+ }
+
+ /*
+ * check looping state if -i option is given
+ */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /*
+ * reset Tst_count in case we are looping.
+ */
+ Tst_count = 0;
+
+ mypid = getpid();
+
+ tst_resm(TINFO, "OPEN_MAX is %d", OPEN_MAX);
+
+ /* establish first free file */
+ sprintf(filname, "fork01.%d", mypid);
+ if ((first = creat(filname, 0660)) == -1) {
+ tst_brkm(TBROK, cleanup, "Cannot open first file %s, "
+ "errno = %d", filname, errno);
+ /*NOTREACHED*/
+ }
+ close(first);
+
+ tst_resm(TINFO, "first file descriptor is %d ", first);
+
+ if (unlink(filname) == -1) {
+ tst_brkm(TBROK, cleanup, "Cannot unlink file %s, "
+ "errno = %d", filname, errno);
+ /*NOTREACHED*/
+ }
+
+ /*
+ * now open all the files for the test
+ */
+ for (nfiles = first; nfiles < OPEN_MAX; nfiles++) {
+ sprintf(filname, "file%d.%d", nfiles, mypid);
+ if ((fildeses[nfiles] = fopen(filname, "a")) == NULL) {
+ tst_brkm(TBROK, cleanup, "Parent: cannot open "
+ "file %d %s errno = %d", nfiles,
+ filname, errno);
+ /*NOTREACHED*/
+ }
+#ifdef DEBUG
+ tst_resm(TINFO, "filname: %s", filname);
+#endif
+ }
+
+ tst_resm(TINFO, "Parent reporting %d files open", nfiles - 1);
+
+ if ((pid = fork()) == -1) {
+ tst_brkm(TBROK, cleanup, "Fork failed");
+ /*NOTREACHED*/
+ }
+
+ if (pid == 0) { /* child */
+ nfiles--;
+ if (fclose(fildeses[nfiles]) == -1) {
+ tst_resm(TINFO, "Child could not close file "
+ "#%d, errno = %d", nfiles, errno);
+ exit(1);
+ /*NOTREACHED*/
+ } else {
+ sprintf(childfile, "cfile.%d", getpid());
+ if ((fildeses[nfiles] =
+ fopen(childfile, "a")) == NULL) {
+ tst_resm(TINFO, "Child could not open "
+ "file %s, errno = %d",
+ childfile, errno);
+ exit(1);
+ /*NOTREACHED*/
+ } else {
+ tst_resm(TINFO, "Child opened new "
+ "file #%d", nfiles);
+ unlink(childfile);
+ exit(0);
+ }
+ }
+ } else { /* parent */
+ wait(&status);
+ if (status >> 8 != 0) {
+ tst_resm(TFAIL, "test 1 FAILED");
+ } else {
+ tst_resm(TPASS, "test 1 PASSED");
+ }
+ }
+
+ /* clean up things in case we are looping */
+ for (nf = first; nf < nfiles; nf++) {
+ fclose(fildeses[nf]);
+ sprintf(filname, "file%d.%d", nf, mypid);
+ unlink(filname);
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup()
+{
+ /*
+ * capture signals
+ */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ umask(0);
+
+ /*
+ * Pause if that option was specified
+ */
+ TEST_PAUSE;
+
+ /*
+ * make a temp directory and cd to it
+ */
+ tst_tmpdir();
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or at premature exit
+ */
+void
+cleanup()
+{
+ int nf;
+
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /*
+ * remove tmp dir and all files in it
+ */
+ tst_rmdir();
+
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/fork10.c b/winsup/testsuite/winsup.api/ltp/fork10.c
new file mode 100644
index 000000000..09de7c06f
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/fork10.c
@@ -0,0 +1,215 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * fork04.c
+ *
+ * DESCRIPTION
+ * Check inheritance of file descriptor by children, they
+ * should all be refering to the same file.
+ *
+ * ALGORITHM
+ * Child reads several chars and exits.
+ * Parent forks another child, have the child and parent attempt to use
+ * that location
+ *
+ * USAGE
+ * fork04
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "fork04";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+char pidbuf[10];
+char fnamebuf[40];
+
+main(int ac, char **av)
+{
+ int status, pid, fildes;
+ char parchar[2];
+ char chilchar[2];
+ long lseek();
+
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /*
+ * parse standard options
+ */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ /*
+ * perform global setup for the test
+ */
+ setup();
+
+ /*
+ * check looping state if -i option is given
+ */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /*
+ * reset Tst_count in case we are looping.
+ */
+ Tst_count = 0;
+
+ if ((fildes = creat(fnamebuf, 0600)) < 0) {
+ tst_brkm(TBROK, cleanup, "Parent: cannot open %s for "
+ "write, errno = %d", fnamebuf, errno);
+ /*NOTREACHED*/
+ }
+ write(fildes, "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", 27);
+ close(fildes);
+
+ if ((fildes = open(fnamebuf, 0)) == -1) {
+ tst_brkm(TBROK, cleanup, "Parent: cannot open %s for "
+ "reading", fnamebuf);
+ /*NOTREACHED*/
+ }
+
+ if ((pid = fork()) == -1) {
+ tst_brkm(TBROK, cleanup, "fork() #1 failed");
+ /*NOTREACHED*/
+ }
+
+ if (pid == 0) { /* child */
+ tst_resm(TINFO, "fork child A");
+ if (lseek(fildes, 10L, 0) == -1L) {
+ tst_resm(TFAIL, "bad lseek by child");
+ exit(1);
+ }
+ exit(0);
+ } else { /* parent */
+ wait(&status);
+
+ /* parent starts second child */
+ if ((pid = fork()) == -1) {
+ tst_brkm(TBROK, cleanup, "fork() #2 failed");
+ /*NOTREACHED*/
+ }
+
+ if (pid == 0) { /* child */
+ if (read(fildes, chilchar, 1) <= 0) {
+ tst_resm(TFAIL, "Child can't read "
+ "file");
+ exit(1);
+ } else {
+ if (chilchar[0] != 'K') {
+ chilchar[1] = '\n';
+ exit(1);
+ } else {
+ exit(0);
+ }
+ }
+ } else { /* parent */
+ (void)wait(&status);
+ if (status >> 8 != 0) {
+ tst_resm(TFAIL, "Bad return from "
+ "second child");
+ continue;
+ }
+ /* parent reads */
+ if (read(fildes, parchar, 1) <= 0) {
+ tst_resm(TFAIL, "Parent cannot read "
+ "file");
+ continue;
+ } else {
+ write(fildes, parchar, 1);
+ if (parchar[0] != 'L') {
+ parchar[1] = '\n';
+ tst_resm(TFAIL, "Test failed");
+ continue;
+ }
+ }
+ }
+ }
+ tst_resm(TPASS, "test 1 PASSED");
+ close (fildes);
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup()
+{
+ /*
+ * capture signals
+ */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ umask(0);
+
+ /*
+ * Pause if that option was specified
+ */
+ TEST_PAUSE;
+
+ /*
+ * make a temp directory and cd to it
+ */
+ tst_tmpdir();
+
+ strcpy(fnamebuf, "fork04.");
+ sprintf(pidbuf, "%d", getpid());
+ strcat(fnamebuf, pidbuf);
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /*
+ * remove tmp dir and all files in it
+ */
+ tst_rmdir();
+
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/fork11.c b/winsup/testsuite/winsup.api/ltp/fork11.c
new file mode 100644
index 000000000..1fc200dd1
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/fork11.c
@@ -0,0 +1,140 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * fork05.c
+ *
+ * DESCRIPTION
+ * Test that parent gets a pid from each child when doing wait
+ *
+ * ALGORITHM
+ * Fork NUMFORKS children that do nothing.
+ *
+ * USAGE
+ * fork05
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "fork05";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+#define NUMFORKS 100
+
+main(int ac, char **av)
+{
+ int i, pid, cpid, status;
+
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /*
+ * parse standard options
+ */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ /*
+ * perform global setup for the test
+ */
+ setup();
+
+ /*
+ * check looping state if -i option is given
+ */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /*
+ * reset Tst_count in case we are looping.
+ */
+ Tst_count = 0;
+
+ for (i=0; i<NUMFORKS; i++) {
+ if ((pid = fork()) == 0) { /* child */
+ exit(0);
+ }
+
+ if (pid > 0) { /* parent */
+ cpid = wait(&status);
+ if (cpid == pid) {
+ tst_resm(TPASS, "fork #%d passed", i+1);
+ } else {
+ tst_resm(TFAIL, "fork #%d failed", i+1);
+ }
+ } else {
+ tst_resm(TFAIL, "fork #%d failed", i+1);
+ break;
+ }
+ }
+ tst_resm(TINFO, "Number of processes forked = %d", i);
+ tst_resm(TINFO, "Exit test 1");
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup()
+{
+ /*
+ * capture signals
+ */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /*
+ * Pause if that option was specified
+ */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/fstat02.c b/winsup/testsuite/winsup.api/ltp/fstat02.c
new file mode 100644
index 000000000..f15e48e78
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/fstat02.c
@@ -0,0 +1,245 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: fstat02
+ *
+ * Test Description:
+ * Verify that, fstat(2) succeeds to get the status of a file and fills
+ * the stat structure elements though file pointed to by file descriptor
+ * not opened for reading.
+ *
+ * Expected Result:
+ * fstat() should return value 0 on success and the stat structure elements
+ * should be filled with specified 'file' information.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * fstat02 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * This test should be run by 'non-super-user' only.
+ *
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define FILE_MODE 0644
+#define TESTFILE "testfile"
+#define FILE_SIZE 1024
+#define BUF_SIZE 256
+#define MASK 0777
+
+char *TCID="fstat02"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+uid_t User_id; /* user id/group id of test process */
+gid_t Group_id;
+int fildes; /* File descriptor of testfile */
+
+void setup(); /* Setup function for the test */
+void cleanup(); /* Cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ struct stat stat_buf; /* stat structure buffer */
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count = 0;
+
+ /*
+ * Call fstat(2) to get the status of
+ * specified 'file' pointed to by 'fd'
+ * into stat structure.
+ */
+ TEST(fstat(fildes, &stat_buf));
+
+ /* check return code of fstat(2) */
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL,
+ "fstat on %s Failed, errno=%d : %s",
+ TESTFILE, TEST_ERRNO, strerror(TEST_ERRNO));
+ continue;
+ }
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Verify the data returned by fstat(2)
+ * aganist the expected data.
+ */
+ if ((stat_buf.st_uid != User_id) ||
+ (stat_buf.st_gid != Group_id) ||
+ (stat_buf.st_size != FILE_SIZE) ||
+ ((stat_buf.st_mode & MASK) != FILE_MODE)) {
+ tst_resm(TFAIL, "Functionality of fstat(2) on "
+ "'%s' Failed", TESTFILE);
+ } else {
+ tst_resm(TPASS, "Functionality of fstat(2) on "
+ "'%s' Succcessful", TESTFILE);
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * void
+ * setup() - Performs setup function for the test.
+ * Creat a temporary directory and chdir to it.
+ * Creat a temporary file and write some known data into it.
+ * Get the effective uid/gid of test process.
+ */
+void
+setup()
+{
+ int i;
+ char tst_buff[BUF_SIZE];
+ int wbytes;
+ int write_len = 0;
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Check that the test process id is not super/root */
+ if (geteuid() == 0) {
+ tst_brkm(TBROK, NULL, "Must be non-super/root for this test!");
+ tst_exit();
+ }
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ if ((fildes = open(TESTFILE, O_WRONLY|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d : %s",
+ TESTFILE, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Fill the test buffer with the known data */
+ for (i = 0; i < BUF_SIZE; i++) {
+ tst_buff[i] = 'a';
+ }
+
+ /* Write to the file 1k data from the buffer */
+ while (write_len < FILE_SIZE) {
+ if ((wbytes = write(fildes, tst_buff, sizeof(tst_buff))) <= 0) {
+ tst_brkm(TBROK, cleanup,
+ "write(2) on %s Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ } else {
+ write_len += wbytes;
+ }
+ }
+
+ /* Get the uid/gid of the process */
+ User_id = getuid();
+ Group_id = getgid();
+
+} /* End setup() */
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Close the test file and remove the test file and temporary directory.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Close the test file */
+ if (close(fildes) == -1) {
+ tst_brkm(TFAIL, NULL, "close(%s) Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ }
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/fstat03.c b/winsup/testsuite/winsup.api/ltp/fstat03.c
new file mode 100644
index 000000000..1f63cf106
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/fstat03.c
@@ -0,0 +1,192 @@
+/*
+ * Test Name: fstat03
+ *
+ * Test Description:
+ * Verify that, fstat(2) returns -1 and sets errno to EBADF if the file
+ * pointed to by file descriptor is not valid.
+ *
+ * Expected Result:
+ * fstat() should fail with return value -1 and set expected errno.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * if errno set == expected errno
+ * Issue sys call fails with expected return value and errno.
+ * Otherwise,
+ * Issue sys call fails with unexpected errno.
+ * Otherwise,
+ * Issue sys call returns unexpected value.
+ *
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory(s)/file(s) created.
+ *
+ * Usage: <for command-line>
+ * fstat03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * This test should be executed by 'non-super-user' only.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+#define TEST_FILE "testfile"
+
+char *TCID="fstat03"; /* Test program identifier. */
+int TST_TOTAL = 1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={EBADF, 0};
+int fildes; /* testfile descriptor */
+
+void setup(); /* Main setup function for the tests */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ struct stat stat_buf; /* stat structure buffer */
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /*
+ * Invoke setup function to create a testfile under temporary
+ * directory.
+ */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+ /*
+ * Call fstat(2) to get the status information
+ * of a closed testfile pointed to by 'fd'.
+ * verify that fstat fails with -1 return value and
+ * sets appropriate errno.
+ */
+ TEST(fstat(fildes, &stat_buf));
+
+ /* Check return code from fstat(2) */
+ if (TEST_RETURN == -1) {
+ TEST_ERROR_LOG(TEST_ERRNO);
+ if (TEST_ERRNO == EBADF) {
+ tst_resm(TPASS, "fstat() fails with "
+ "expected error EBADF");
+ } else {
+ tst_resm(TFAIL, "fstat() fails with "
+ "wrong errno:%d", TEST_ERRNO);
+ }
+ } else {
+ tst_resm(TFAIL, "fstat() returned %d, "
+ "expected -1, error EBADF");
+ }
+ } /* End for TEST_LOOPING */
+
+ /*
+ * Invoke cleanup() to delete the test directory/file(s) created
+ * in the setup().
+ */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * void
+ * setup(void) - performs all ONE TIME setup for this test.
+ * Exit the test program on receipt of unexpected signals.
+ * Create a temporary directory and change directory to it.
+ * Create a testfile under temporary directory.
+ * Close the testfile.
+ */
+void
+setup()
+{
+ /* Capture unexpected signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Make a temp dir and cd to it */
+ tst_tmpdir();
+
+ /* Create a testfile under temporary directory */
+ if ((fildes = open(TEST_FILE, O_RDWR|O_CREAT, 0666)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, 0666) failed, errno=%d : %s",
+ TEST_FILE, errno, strerror(errno));
+ }
+
+ if (close(fildes) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "close(%s) Failed, errno=%d : %s",
+ TEST_FILE, errno, strerror(errno));
+ }
+} /* End of setup */
+
+/*
+ * void
+ * cleanup() - Performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Print test timing stats and errno log if test executed with options.
+ * Close the testfile if still opened.
+ * Remove temporary directory and sub-directories/files under it
+ * created during setup().
+ * Exit the test program with normal exit code.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Remove files and temporary directory created */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/fstat04.c b/winsup/testsuite/winsup.api/ltp/fstat04.c
new file mode 100644
index 000000000..0287fff36
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/fstat04.c
@@ -0,0 +1,245 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: fstat01
+ *
+ * Test Description:
+ * Verify that, fstat(2) succeeds to get the status of a file pointed by
+ * file descriptor and fills the stat structure elements.
+ *
+ * Expected Result:
+ * fstat() should return value 0 on success and the stat structure should
+ * be filled with specified 'file' information.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * fstat01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * This test should be run by 'non-super-user' only.
+ *
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define FILE_MODE 0644
+#define TESTFILE "testfile"
+#define FILE_SIZE 1024
+#define BUF_SIZE 256
+#define MASK 0777
+
+char *TCID="fstat01"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+uid_t User_id; /* user id/group id of test process */
+gid_t Group_id;
+int fildes; /* File descriptor of testfile */
+
+void setup(); /* Setup function for the test */
+void cleanup(); /* Cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ struct stat stat_buf; /* stat structure buffer */
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count = 0;
+
+ /*
+ * Call fstat(2) to get the status of
+ * specified 'file' pointed to 'fd'
+ * into stat structure.
+ */
+ TEST(fstat(fildes, &stat_buf));
+
+ /* check return code of fstat(2) */
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL,
+ "fstat on %s Failed, errno=%d : %s",
+ TESTFILE, TEST_ERRNO, strerror(TEST_ERRNO));
+ continue;
+ }
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Verify the data returned by fstat(2)
+ * aganist the expected data.
+ */
+ if ((stat_buf.st_uid != User_id) ||
+ (stat_buf.st_gid != Group_id) ||
+ (stat_buf.st_size != FILE_SIZE) ||
+ ((stat_buf.st_mode & MASK) != FILE_MODE)) {
+ tst_resm(TFAIL, "Functionality of fstat(2) on "
+ "'%s' Failed", TESTFILE);
+ } else {
+ tst_resm(TPASS, "Functionality of fstat(2) on "
+ "'%s' Succcessful", TESTFILE);
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * void
+ * setup() - Performs setup function for the test.
+ * Creat a temporary directory and chdir to it.
+ * Creat a test file and write some data into it.
+ * Get the user/group id info. of test process.
+ */
+void
+setup()
+{
+ int i; /* counter */
+ char tst_buff[BUF_SIZE]; /* data buffer */
+ int wbytes; /* no. of bytes written */
+ int write_len = 0; /* data length */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Check that the test process id is not super/root */
+ if (geteuid() == 0) {
+ tst_brkm(TBROK, NULL, "Must be non-super/root for this test!");
+ tst_exit();
+ }
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ if ((fildes = open(TESTFILE, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d : %s",
+ TESTFILE, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Fill the test buffer with the known data */
+ for (i = 0; i < BUF_SIZE; i++) {
+ tst_buff[i] = 'a';
+ }
+
+ /* Write to the file 1k data from the buffer */
+ while (write_len < FILE_SIZE) {
+ if ((wbytes = write(fildes, tst_buff, sizeof(tst_buff))) <= 0) {
+ tst_brkm(TBROK, cleanup,
+ "write(2) on %s Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ } else {
+ write_len += wbytes;
+ }
+ }
+
+ /* Get the uid/gid of the process */
+ User_id = getuid();
+ Group_id = getgid();
+
+} /* End setup() */
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Close the testfile opened for reading/writing.
+ * Delete the testfile and temporary directory.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Close the test file */
+ if (close(fildes) == -1) {
+ tst_brkm(TFAIL, NULL, "close(%s) Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ }
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/ftruncate01.c b/winsup/testsuite/winsup.api/ltp/ftruncate01.c
new file mode 100644
index 000000000..2d3d797ec
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/ftruncate01.c
@@ -0,0 +1,244 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: ftruncate01
+ *
+ * Test Description:
+ * Verify that, ftruncate(2) succeeds to truncate a file to a specified
+ * length if the file indicated by file descriptor opened for writing.
+ *
+ * Expected Result:
+ * ftruncate(2) should return a value 0 and the length of the file after
+ * truncation should be equal to the length it is truncated to.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * ftruncate01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * This test should be run by 'non-super-user' only.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TESTFILE "testfile" /* file under test */
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+#define BUF_SIZE 256 /* buffer size */
+#define FILE_SIZE 1024 /* test file size */
+#define TRUNC_LEN 256 /* truncation length */
+
+char *TCID="ftruncate01"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test conditions */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int fildes; /* file descriptor for test file */
+
+void setup(); /* setup function for the test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ struct stat stat_buf; /* stat(2) struct contents */
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ off_t file_length; /* test file length */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count = 0;
+
+ /*
+ * Call ftruncate(2) to truncate a test file to a
+ * specified length.
+ */
+ TEST(ftruncate(fildes, TRUNC_LEN));
+
+ /* check return code of ftruncate(2) */
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL,
+ "ftruncate() of %s Failed, errno=%d : %s",
+ TESTFILE, TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ continue;
+ }
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Get the testfile information using
+ * fstat(2).
+ */
+ if (fstat(fildes, &stat_buf) < 0) {
+ tst_brkm(TFAIL, cleanup,
+ "stat(2) of %s failed, error:%d",
+ TESTFILE, errno);
+ }
+ stat_buf.st_mode &= ~S_IFREG;
+ file_length = stat_buf.st_size;
+
+ /*
+ * Check for expected size of testfile after
+ * truncate(2) on it.
+ */
+ if (file_length != TRUNC_LEN) {
+ tst_resm(TFAIL, "%s: Incorrect file size %d, "
+ "Expected %d", TESTFILE, file_length,
+ TRUNC_LEN);
+ } else {
+ tst_resm(TPASS, "Functionality of ftruncate() "
+ "on %s successful", TESTFILE);
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * void
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ * Create a test file under temporary directory and write some
+ * data into it.
+ */
+void
+setup()
+{
+ int i; /* counter for for loop() */
+ int c, c_total = 0; /* bytes to be written to file */
+ char tst_buff[BUF_SIZE]; /* buffer to hold data */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Fill the test buffer with the known data */
+ for (i = 0; i < BUF_SIZE; i++) {
+ tst_buff[i] = 'a';
+ }
+
+ /* open a file for reading/writing */
+ if ((fildes = open(TESTFILE, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %o) Failed, errno=%d : %s",
+ TESTFILE, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Write to the file 1k data from the buffer */
+ while (c_total < FILE_SIZE) {
+ if ((c = write(fildes, tst_buff, sizeof(tst_buff))) <= 0) {
+ tst_brkm(TBROK, cleanup,
+ "write(2) on %s Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ } else {
+ c_total += c;
+ }
+ }
+} /* End setup() */
+
+/*
+ * void
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Close the temporary file.
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Close the testfile after writing data into it */
+ if (close(fildes) == -1) {
+ tst_brkm(TFAIL, NULL,
+ "close(%s) Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ }
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/ftruncate02.c b/winsup/testsuite/winsup.api/ltp/ftruncate02.c
new file mode 100644
index 000000000..8044c1de5
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/ftruncate02.c
@@ -0,0 +1,314 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: ftruncate02
+ *
+ * Test Description:
+ * Verify that, ftruncate(2) succeeds to truncate a file to a certain length,
+ * but the attempt to read past the truncated length will fail.
+ *
+ * Expected Result:
+ * ftruncate(2) should return a value 0 and the attempt to read past the
+ * truncated length will fail. In case where the file before truncation was
+ * shorter, the bytes between the old and new should be all zeroes.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * ftruncate02 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * This test should be run by 'non-super-user' only.
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TESTFILE "testfile" /* file under test */
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+#define BUF_SIZE 256 /* buffer size */
+#define FILE_SIZE 1024 /* test file size */
+#define TRUNC_LEN1 256 /* truncation length */
+#define TRUNC_LEN2 512 /* truncation length */
+
+char *TCID="ftruncate02"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test conditions */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int fd; /* file descriptor of testfile */
+char tst_buff[BUF_SIZE]; /* buffer to hold testfile contents */
+
+void setup(); /* setup function for the test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ struct stat stat_buf; /* stat(2) struct contents */
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ off_t file_length2; /* test file length */
+ off_t file_length1; /* test file length */
+ int rbytes, i; /* bytes read from testfile */
+ int read_len = 0; /* total no. of bytes read from testfile */
+ int err_flag = 0; /* error indicator flag */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count = 0;
+
+ /*
+ * Call ftruncate(2) to truncate a test file to a
+ * specified length (TRUNC_LEN1).
+ */
+ TEST(ftruncate(fd, TRUNC_LEN1));
+
+ /* check return code of ftruncate(2) */
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "ftruncate of %s to size %d Failed, "
+ "errno=%d : %s", TESTFILE, TRUNC_LEN1,
+ TEST_ERRNO, strerror(TEST_ERRNO));
+ continue;
+ }
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Get the testfile information using
+ * fstat(2).
+ */
+ if (fstat(fd, &stat_buf) < 0) {
+ tst_brkm(TFAIL, cleanup, "fstat(2) of %s failed"
+ " after 1st truncate, error:%d",
+ TESTFILE, errno);
+ }
+ stat_buf.st_mode &= ~S_IFREG;
+ file_length1 = stat_buf.st_size;
+
+ /*
+ * Set the file pointer of testfile to the
+ * beginning of the file.
+ */
+ if (lseek(fd, 0, SEEK_SET) < 0) {
+ tst_brkm(TFAIL, cleanup, "lseek(2) on %s failed"
+ " after 1st ftruncate, error:%d",
+ TESTFILE, errno);
+ }
+
+ /* Read the testfile from the beginning. */
+ while ((rbytes = read(fd, tst_buff,
+ sizeof(tst_buff))) > 0) {
+ read_len += rbytes;
+ }
+
+ /*
+ * Execute ftruncate(2) again to truncate
+ * testfile to a size TRUNC_LEN2.
+ */
+ TEST(ftruncate(fd, TRUNC_LEN2));
+
+ /* check return code of ftruncate(2) */
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "ftruncate of %s to size %d "
+ "Failed, errno=%d : %s", TESTFILE,
+ TRUNC_LEN2, TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ continue;
+ }
+
+ /*
+ * Get the testfile information using
+ * fstat(2)
+ */
+ if (fstat(fd, &stat_buf) < 0) {
+ tst_brkm(TFAIL, cleanup, "fstat(2) of %s failed"
+ " after 2nd truncate, error:%d",
+ TESTFILE, errno);
+ }
+ stat_buf.st_mode &= ~S_IFREG;
+ file_length2 = stat_buf.st_size;
+
+ /*
+ * Set the file pointer of testfile to the
+ * offset TRUNC_LEN1 of testfile.
+ */
+ if (lseek(fd, TRUNC_LEN1, SEEK_SET) < 0) {
+ tst_brkm(TFAIL, cleanup, "lseek(2) on %s failed"
+ " after 2nd ftruncate, error:%d",
+ TESTFILE, errno);
+ }
+
+ /* Read the testfile contents till EOF */
+ while((rbytes = read(fd, tst_buff,
+ sizeof(tst_buff))) > 0) {
+ for (i = 0; i < rbytes; i++) {
+ if (tst_buff[i] != 0) {
+ err_flag++;
+ }
+ }
+ }
+
+ /*
+ * Check for expected size of testfile after
+ * issuing ftruncate(2) on it.
+ */
+ if ((file_length1 != TRUNC_LEN1) ||
+ (file_length2 != TRUNC_LEN2) ||
+ (read_len != TRUNC_LEN1) ||
+ (err_flag != 0)) {
+ tst_resm(TFAIL, "Functionality of ftruncate(2) "
+ "on %s Failed", TESTFILE);
+ } else {
+ tst_resm(TPASS, "Functionality of ftruncate(2) "
+ "on %s successful", TESTFILE);
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * void
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ * Create a test file under temporary directory and write some
+ * data into it.
+ */
+void
+setup()
+{
+ int i; /* counter variable */
+ int wbytes; /* bytes written to testfile */
+ int write_len = 0; /* total no. of bytes written to testfile */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Fill the test buffer with the known data */
+ for (i = 0; i < BUF_SIZE; i++) {
+ tst_buff[i] = 'a';
+ }
+ /* open a file for reading/writing */
+ if ((fd = open(TESTFILE, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %o) Failed, errno=%d : %s",
+ TESTFILE, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Write to the file 1k data from the buffer */
+ while (write_len < FILE_SIZE) {
+ if ((wbytes = write(fd, tst_buff, sizeof(tst_buff))) <= 0) {
+ tst_brkm(TBROK, cleanup,
+ "write(2) on %s Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ } else {
+ write_len += wbytes;
+ }
+ }
+} /* End setup() */
+
+/*
+ * void
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Close the testfile.
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Close the testfile after writing data into it */
+ if (close(fd) == -1) {
+ tst_brkm(TFAIL, NULL, "close(%s) Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ }
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/ftruncate03.c b/winsup/testsuite/winsup.api/ltp/ftruncate03.c
new file mode 100644
index 000000000..2e80558e7
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/ftruncate03.c
@@ -0,0 +1,325 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: ftruncate03
+ *
+ * Test Description:
+ * Verify that,
+ * 1) ftruncate(2) returns -1 and sets errno to EINVAL if the specified
+ * truncate length is less than 0.
+ * 2) ftruncate(2) returns -1 and sets errno to EBADF if the file descriptor
+ * of the specified file is not valid.
+ *
+ * Expected Result:
+ * ftruncate() should fail with return value -1 and set expected errno.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * if errno set == expected errno
+ * Issue sys call fails with expected return value and errno.
+ * Otherwise,
+ * Issue sys call fails with unexpected errno.
+ * Otherwise,
+ * Issue sys call returns unexpected value.
+ *
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory(s)/file(s) created.
+ *
+ * Usage: <for command-line>
+ * ftruncate03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * This test should be executed by 'non-super-user' only.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEST_FILE1 "test_file1" /* file under test */
+#define TEST_FILE2 "test_file2" /* file under test */
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+#define BUF_SIZE 256 /* buffer size */
+#define FILE_SIZE 1024 /* test file size */
+
+int no_setup();
+int setup1(); /* setup function to test chmod for EBADF */
+int setup2(); /* setup function to test chmod for EINVAL */
+
+int fd1; /* File descriptor for testfile1 */
+int fd2; /* File descriptor for testfile2 */
+
+struct test_case_t { /* test case struct. to hold ref. test cond's*/
+ int fd;
+ char *desc;
+ int exp_errno;
+ int len;
+ int (*setupfunc)();
+} Test_cases[] = {
+ { 1, "Length argument is -ve", EINVAL, -1, setup1 },
+ { 2, "File descriptor is not valid", EBADF, 256, setup2 },
+ { 0, NULL, 0, 0, no_setup }
+};
+
+char *TCID="ftruncate03"; /* Test program identifier. */
+int TST_TOTAL=2; /* Total number of test conditions */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={EINVAL, EBADF, 0};
+
+void setup(); /* Main setup function for the test */
+void cleanup(); /* Main cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ char *test_desc; /* test specific error message */
+ int fildes; /* File descriptor of testfile */
+ off_t trunc_len; /* truncate length */
+ int ind;
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /*
+ * Perform global setup for test to call individual test specific
+ * setup functions.
+ */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count = 0;
+
+ for (ind = 0; Test_cases[ind].desc != NULL; ind++) {
+ fildes = Test_cases[ind].fd;
+ test_desc = Test_cases[ind].desc;
+ trunc_len = Test_cases[ind].len;
+
+ if (fildes == 1) {
+ fildes = fd1;
+ } else {
+ fildes = fd2;
+ }
+
+ /*
+ * Call ftruncate(2) to test different test conditions.
+ * verify that it fails with return code -1 and sets
+ * appropriate errno.
+ */
+ TEST(ftruncate(fildes, trunc_len));
+
+ /* check return code of ftruncate(2) */
+ if (TEST_RETURN == -1) {
+ TEST_ERROR_LOG(TEST_ERRNO);
+ if (TEST_ERRNO == Test_cases[ind].exp_errno) {
+ tst_resm(TPASS, "ftruncate() fails, %s,"
+ " errno=%d", test_desc,
+ TEST_ERRNO);
+ } else {
+ tst_resm(TFAIL, "ftruncate() fails, %s,"
+ " errno=%d, expected errno:%d",
+ test_desc, TEST_ERRNO,
+ Test_cases[ind].exp_errno);
+ }
+ } else {
+ tst_resm(TFAIL, "ftruncate() returned %d, "
+ "expected -1, errno:%d", TEST_RETURN,
+ Test_cases[ind].exp_errno);
+ }
+ } /* End of TEST CASE LOOPING. */
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * void
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ * Fill the test buffer with some date used to fill test file(s).
+ * Call individual test specific setup functions.
+ */
+void
+setup()
+{
+ int ind;
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Check that the test process id is not root/super-user */
+ if (geteuid() == 0) {
+ tst_brkm(TBROK, NULL, "Must be non-root/super for this test!");
+ tst_exit();
+ }
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* call individual setup functions */
+ for (ind = 0; Test_cases[ind].desc != NULL; ind++) {
+ Test_cases[ind].setupfunc();
+ }
+} /* End of setup */
+
+/*
+ * int
+ * setup1() - setup function for a test condition for which ftruncate(2)
+ * returns -1 and sets errno to EINVAL.
+ * Create a test file and open it for writing only.
+ */
+int
+setup1()
+{
+ /* Open the testfile in write-only mode */
+ if ((fd1 = open(TEST_FILE1, O_WRONLY|O_CREAT, 0644)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_WRONLY) Failed, errno=%d : %s",
+ TEST_FILE1, errno, strerror(errno));
+ }
+ return 0;
+} /* End setup1() */
+
+/*
+ * int
+ * setup2() - setup function for a test condition for which ftruncate(2)
+ * returns -1 and sets errno to EBADF.
+ * Create a test file and open it for reading/writing, and fill the
+ * testfile with the contents of test buffer.
+ * Close the test file.
+ *
+ */
+int
+setup2()
+{
+ int c, i, c_total = 0;
+ char tst_buff[BUF_SIZE]; /* buffer to hold testfile contents */
+
+ /* Fill the test buffer with the known data */
+ for (i = 0; i < BUF_SIZE; i++) {
+ tst_buff[i] = 'a';
+ }
+
+ /* open a testfile for reading/writing */
+ if ((fd2 = open(TEST_FILE2, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %o) Failed, errno=%d : %s",
+ TEST_FILE2, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Write to the file 1k data from the buffer */
+ while (c_total < FILE_SIZE) {
+ if ((c = write(fd2, tst_buff, sizeof(tst_buff))) <= 0) {
+ tst_brkm(TBROK, cleanup,
+ "write(2) on %s Failed, errno=%d : %s",
+ TEST_FILE2, errno, strerror(errno));
+ } else {
+ c_total += c;
+ }
+ }
+
+ /* Close the testfile after writing data into it */
+ if (close(fd2) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "close(%s) Failed, errno=%d : %s",
+ TEST_FILE2, errno, strerror(errno));
+ }
+ return 0;
+} /* End of setup2 */
+
+/*
+ * int
+ * no_setup() - This function just returns 0.
+ */
+int
+no_setup()
+{
+ return 0;
+}
+
+/*
+ * void
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Close the temporary file.
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Close the testfile after opening it read-only in setup1 */
+ if (close(fd1) == -1) {
+ tst_brkm(TFAIL, NULL,
+ "close(%s) Failed, errno=%d : %s",
+ TEST_FILE1, errno, strerror(errno));
+ }
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/getgid02.c b/winsup/testsuite/winsup.api/ltp/getgid02.c
new file mode 100644
index 000000000..290ef10c5
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/getgid02.c
@@ -0,0 +1,158 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * getgid02.c
+ *
+ * DESCRIPTION
+ * Testcase to check the basic functionality of getegid().
+ *
+ * ALGORITHM
+ * call setup
+ * loop if that option was specified
+ * Execute getegid() call using TEST macro
+ * if not expected value
+ * break remaining tests and cleanup
+ * if STD_FUNCTIONAL_TEST
+ * Execute geteuid() call
+ * Execute getpwduid() call
+ * if the passwd entry is NULL
+ * break the remaining tests and cleanup
+ * else if pwent->pw_gid != TEST_RETURN
+ * print failure message
+ * else
+ * print pass message
+ * else
+ * print pass message
+ * call cleanup
+ *
+ * USAGE: <for command-line>
+ * getgid02 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * none
+ */
+
+#include <pwd.h>
+#include <errno.h>
+
+#include "test.h"
+#include "usctest.h"
+
+void cleanup(void);
+void setup(void);
+
+char *TCID= "getgid02";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ int euid;
+ struct passwd *pwent;
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup(); /* global setup */
+
+ /* The following loop checks looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ TEST(getegid());
+
+ if (TEST_RETURN < 0) {
+ tst_brkm(TBROK, cleanup, "This should never happen");
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+ euid = geteuid();
+
+ pwent = getpwuid(euid);
+
+ if (pwent == NULL) {
+ tst_brkm(TBROK, cleanup, "geteuid() returned "
+ "unexpected value %d", euid);
+ } else {
+ if (pwent->pw_gid != TEST_RETURN) {
+ tst_resm(TFAIL, "getegid() return value"
+ " %d unexpected - expected %d",
+ TEST_RETURN, pwent->pw_gid);
+ } else {
+ tst_resm(TPASS, "effective group id %d "
+ "is correct", TEST_RETURN);
+ }
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all the ONE TIME cleanup for this test at completion
+ * or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing status if that option was specified.
+ * print errno log if that option was specified
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/getgid03.c b/winsup/testsuite/winsup.api/ltp/getgid03.c
new file mode 100644
index 000000000..3059b0b36
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/getgid03.c
@@ -0,0 +1,157 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * getgid01.c
+ *
+ * DESCRIPTION
+ * Testcase to check the basic functionality of getgid().
+ *
+ * ALGORITHM
+ * call setup
+ * loop if that option was specified
+ * Execute getgid() call using TEST macro
+ * if not expected value
+ * break remaining tests and cleanup
+ * if STD_FUNCTIONAL_TEST
+ * Execute getuid() call
+ * Execute getpwduid() call
+ * if the passwd entry is NULL
+ * break the remaining tests and cleanup
+ * else if pwent->pw_gid != TEST_RETURN
+ * print failure message
+ * else
+ * print pass message
+ * else
+ * print pass message
+ * call cleanup
+ *
+ * USAGE: <for command-line>
+ * getgid01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * none
+ */
+
+#include <pwd.h>
+#include <errno.h>
+
+#include "test.h"
+#include "usctest.h"
+
+void cleanup(void);
+void setup(void);
+
+char *TCID= "getgid01";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ int uid;
+ struct passwd *pwent;
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup(); /* global setup */
+
+ /* The following loop checks looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ TEST(getgid());
+
+ if (TEST_RETURN < 0) {
+ tst_brkm(TBROK, cleanup, "This should never happen");
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+ uid = getuid();
+ pwent = getpwuid(uid);
+
+ if (pwent == NULL) {
+ tst_brkm(TBROK, cleanup, "getuid() returned "
+ "unexpected value %d", uid);
+ } else {
+ if (pwent->pw_gid != TEST_RETURN) {
+ tst_resm(TFAIL, "getgid() return value "
+ "%d unexpected - expected %d",
+ TEST_RETURN, pwent->pw_gid);
+ } else {
+ tst_resm(TPASS, "group id %d returned "
+ "correctly", TEST_RETURN);
+ }
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all the ONE TIME cleanup for this test at completion
+ * or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing status if that option was specified.
+ * print errno log if that option was specified
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/getpgid01.c b/winsup/testsuite/winsup.api/ltp/getpgid01.c
new file mode 100644
index 000000000..d1a39a087
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/getpgid01.c
@@ -0,0 +1,240 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * getpgid01.c
+ *
+ * DESCRIPTION
+ * Testcase to check the basic functionality of getpgid().
+ *
+ * ALGORITHM
+ * block1: Does getpgid(0), and checks for error.
+ * block2: Does getpgid(getpid()) and checks for error.
+ * block3: Does getpgid(getppid()) and checks for error.
+ * block4: Verifies that getpgid(getpgid(0)) == getpgid(0).
+ * block5: Does getpgid(1) and checks for error.
+ *
+ * USAGE
+ * getpgid01
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * Expects that there are no EPERM limitations on getting the
+ * process group ID from proc 1 (init).
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <varargs.h>
+#include <sys/wait.h>
+#include <test.h>
+#include <usctest.h>
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "getpgid01";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned by parse_opts */
+
+ register int pgid_0, pgid_1;
+ register int my_pid, my_ppid;
+ int ex_stat, fail = 0;
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ setup();
+
+ /* check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ if ((pgid_0 = fork()) < 0) {
+ tst_brkm(TBROK, cleanup, "fork() failed");
+ }
+ if (pgid_0 > 0) { /* parent */
+ /*
+ * parent process waits for child to exit, and then
+ * exits itself.
+ */
+ while ((pgid_0 = wait(&ex_stat)) > 0);
+
+ if (WEXITSTATUS(ex_stat) == 0) {
+ tst_resm(TINFO, "%s PASSED", TCID);
+ } else {
+ tst_resm(TINFO, "%s FAILED", TCID);
+ }
+
+ /* let the child carry on */
+ exit(0);
+ }
+
+ /* child */
+block1:
+ tst_resm(TINFO, "Enter block 1");
+ fail = 0;
+ if ((pgid_0 = getpgid(0)) < 0) {
+ perror("getpgid");
+ tst_resm(TFAIL, "getpgid(0) failed");
+ fail = 1;
+ }
+
+ if (fail) {
+ tst_resm(TINFO, "Test block 1: getpgid(0) FAILED");
+ } else {
+ tst_resm(TPASS, "Test block 1: getpgid(0) PASSED");
+ }
+ tst_resm(TINFO, "Exit block 1");
+
+block2:
+ tst_resm(TINFO, "Enter block 2");
+ fail = 0;
+
+ my_pid = getpid();
+ if ((pgid_1 = getpgid(my_pid)) < 0) {
+ perror("getpgid");
+ tst_resm(TFAIL, "getpgid(my_pid=%d) failed", my_pid);
+ tst_exit();
+ }
+ if (pgid_0 != pgid_1) {
+ tst_resm(TFAIL, "getpgid(my_pid=%d) != getpgid(0) "
+ "[%d != %d]", my_pid, pgid_1, pgid_0);
+ fail = 1;
+ }
+ if (fail) {
+ tst_resm(TINFO, "Test block 2: getpgid(getpid()) "
+ "FAILED");
+ } else {
+ tst_resm(TPASS, "Test blcok 2: getpgid(getpid()) "
+ "PASSED");
+ }
+ tst_resm(TINFO, "Exit block 2");
+
+block3:
+ tst_resm(TINFO, "Enter block 3");
+ fail = 0;
+
+ my_ppid = getppid();
+ if ((pgid_1 = getpgid(my_ppid)) < 0) {
+ perror("getpgid");
+ tst_resm(TFAIL, "getpgid(my_ppid=%d) failed",
+ my_ppid);
+ tst_exit();
+ }
+ if (pgid_0 != pgid_1) {
+ tst_resm(TFAIL, "getpgid(my_ppid=%d) != getpgid(0) "
+ "[%d != %d]", my_ppid, pgid_1, pgid_0);
+ fail = 1;
+ }
+
+ if (fail) {
+ tst_resm(TINFO, "Test block 3: getpgid(getppid()) "
+ "FAILED");
+ } else {
+ tst_resm(TPASS, "Test block 3: getpgid(getppid()) "
+ "PASSED");
+ }
+ tst_resm(TINFO, "Exit block 3");
+
+block4:
+ tst_resm(TINFO, "Enter block 4");
+ fail = 0;
+
+ if ((pgid_1 = getpgid(pgid_0)) < 0) {
+ perror("getpgid");
+ tst_resm(TFAIL, "getpgid(my_pgid=%d) failed", pgid_0);
+ tst_exit();
+ }
+ if (pgid_0 != pgid_1) {
+ tst_resm(TFAIL, "getpgid(my_pgid=%d) != getpgid(0) "
+ "[%d != %d]", pgid_0, pgid_1, pgid_0);
+ fail = 1;
+ }
+
+ if (fail) {
+ tst_resm(TINFO, "Test block 4: getpgid(1) FAILED");
+ } else {
+ tst_resm(TPASS, "Test block 4: getpgid(1) PASSED");
+ }
+ tst_resm(TINFO, "Exit block 4");
+#ifndef __CYGWIN__
+block5:
+ tst_resm(TINFO, "Enter block 5");
+ fail = 0;
+
+ if (getpgid(1) < 0) {
+ perror("getpgid");
+ tst_resm(TFAIL, "getpgid(1) failed");
+ fail = 1;
+ }
+
+ if (fail) {
+ tst_resm(TINFO, "Test block 5: getpgid(1) FAILED");
+ } else {
+ tst_resm(TPASS, "Test block 5: getpgid(1) PASSED");
+ }
+ tst_resm(TINFO, "Exit block 5");
+#endif
+ }
+ cleanup();
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
+
diff --git a/winsup/testsuite/winsup.api/ltp/getpgid02.c b/winsup/testsuite/winsup.api/ltp/getpgid02.c
new file mode 100644
index 000000000..afb80f261
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/getpgid02.c
@@ -0,0 +1,172 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * getpgid02.c
+ *
+ * DESCRIPTION
+ * Testcase to check the basic functionality of getpgid().
+ *
+ * ALGORITHM
+ * test 1: Does getpgid(-99) and expects ESRCH.
+ * test 2: Searches an unused pid and expects ESRCH.
+ *
+ * USAGE: <for command-line>
+ * getpgid02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * none
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <varargs.h>
+#include <sys/wait.h>
+#include <test.h>
+#include <usctest.h>
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "getpgid01";
+int TST_TOTAL = 2;
+extern int Tst_count;
+
+int pgid_0, pgid_1;
+#define BADPID -99
+
+int exp_enos[]={ESRCH, 0};
+
+struct test_case_t {
+ int *id;
+ int error;
+} TC[] = {
+ /* The pid value is negative */
+ {&pgid_0, ESRCH},
+
+ /* The pid value does not match any process */
+ {&pgid_1, ESRCH}
+};
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ int i;
+ const char *msg; /* message returned by parse_opts */
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ setup();
+
+ /* set up the expected errnos */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+
+ /* loop through the test cases */
+ for (i = 0; i < TST_TOTAL; i++) {
+
+ TEST(getpgid(*TC[i].id));
+
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "call succeeded unexpectedly");
+ continue;
+ }
+
+ TEST_ERROR_LOG(TEST_ERRNO);
+
+ if (TEST_ERRNO == TC[i].error) {
+ tst_resm(TPASS, "expected failure - "
+ "errno = %d : %s", TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ } else {
+ tst_resm(TFAIL, "unexpected error - %d : %s - "
+ "expected %d", TEST_ERRNO,
+ strerror(TEST_ERRNO), TC[i].error);
+ }
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ pgid_0 = BADPID;
+
+ /*
+ * Find a pid that isn't currently being used. Start
+ * at 'our pid - 1' and go backwards until we find one.
+ * In this way, we can be reasonably sure that the pid
+ * we find won't be reused for a while as new pids are
+ * allocated counting up to PID_MAX.
+ */
+ for (pgid_1 = getpid() - 1; --pgid_1 > 0; ) {
+ if (kill(pgid_1, 0) < 0 && errno == ESRCH) {
+ break;
+ }
+ }
+}
+
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
+
diff --git a/winsup/testsuite/winsup.api/ltp/getpid02.c b/winsup/testsuite/winsup.api/ltp/getpid02.c
new file mode 100644
index 000000000..8561c1a09
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/getpid02.c
@@ -0,0 +1,188 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: getpid01
+ *
+ * Test Description:
+ * Verify that getpid() system call gets the process ID of the of the
+ * calling process.
+ *
+ * Expected Result:
+ * getpid() should return pid of the process on success.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ *
+ * Usage: <for command-line>
+ * getpid01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+#include "test.h"
+#include "usctest.h"
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+char *TCID="getpid01"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ pid_t proc_id; /* process id of the test process */
+ pid_t pid; /* process id of the child process */
+ pid_t pproc_id; /* parent process id */
+ int status; /* exit status of child process */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Invoke getpid() to get the process id of
+ * the test process.
+ */
+ TEST(getpid());
+
+ /* Save the process id returned by getpid() */
+ proc_id = TEST_RETURN;
+
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /* Fork a child now */
+ if ((pid = fork()) < 0) {
+ tst_resm(TFAIL, "fork() failed to create child,"
+ " error=%d", TEST_ERRNO);
+ } else if (pid == 0) { /* Child process */
+ /* Get the parent process id */
+ pproc_id = getppid();
+
+ /* Verify if the two process IDs match */
+ if (pproc_id != proc_id) {
+ exit(1);
+ }
+ exit(0);
+ } else { /* parent process */
+ wait(&status);
+
+ /* Check exit status of child */
+ if (WEXITSTATUS(status) != 0) {
+ tst_resm(TFAIL, "getpid() returned "
+ "invalid pid %d", proc_id);
+ } else {
+ tst_resm(TPASS, "Functionality of "
+ "getpid() successful");
+ }
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Setup signal catching function.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/getppid02.c b/winsup/testsuite/winsup.api/ltp/getppid02.c
new file mode 100644
index 000000000..9eeead13f
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/getppid02.c
@@ -0,0 +1,146 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * getppid01.c
+ *
+ * DESCRIPTION
+ * Testcase to check the basic functionality of the getppid() syscall.
+ *
+ * USAGE: <for command-line>
+ * getppid01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <errno.h>
+#include <test.h>
+#include <usctest.h>
+
+char *TCID = "getppid01";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+main(int ac, char **av)
+{
+ int pid, ppid;
+
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /*
+ * parse standard options
+ */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ setup();
+
+ /*
+ * check looping state if -i option is given
+ */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /*
+ * reset Tst_count in case we are looping.
+ */
+ Tst_count = 0;
+
+ ppid = getpid();
+ pid = fork();
+ if (pid < 0) {
+ tst_brkm(TBROK, cleanup, "fork() failed");
+ }
+
+ if (pid == 0) { /* child */
+ TEST(getppid());
+
+ if (TEST_RETURN < 0) {
+ tst_resm(TFAIL, "something is really broken");
+ continue;
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+ if (TEST_RETURN != ppid) {
+ tst_resm(TFAIL, "getppid() failed");
+ } else {
+ tst_resm(TPASS, "return value = "
+ "parent's pid value");
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+
+ } else {
+ wait(NULL);
+
+ /* let the child carry on */
+ exit(0);
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
+
diff --git a/winsup/testsuite/winsup.api/ltp/getuid02.c b/winsup/testsuite/winsup.api/ltp/getuid02.c
new file mode 100644
index 000000000..b35072518
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/getuid02.c
@@ -0,0 +1,136 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * getuid02.c
+ *
+ * DESCRIPTION
+ * Testcase to check the basic functionality of the geteuid() system call.
+ *
+ * USAGE: <for command-line>
+ * getuid02 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <pwd.h>
+#include <errno.h>
+#include <test.h>
+#include <usctest.h>
+
+char *TCID = "getuid02";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned by parse_opts */
+
+ struct passwd *pwent;
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ setup();
+
+ /* check looping state if -i option is given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ TEST(geteuid());
+
+ if (TEST_RETURN < 0) {
+ tst_brkm(TBROK, cleanup, "This should never happen");
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+
+ pwent = getpwuid(TEST_RETURN);
+ if (pwent == NULL) {
+ tst_resm(TFAIL, "geteuid() returned unexpected "
+ "value %d", TEST_RETURN);
+ } else {
+ if (pwent->pw_uid != TEST_RETURN) {
+ tst_resm(TFAIL, "getpwuid() value, %d, "
+ "does not match geteuid() "
+ "value, %d", pwent->pw_uid,
+ TEST_RETURN);
+ } else {
+ tst_resm(TPASS, "values from geteuid()"
+ " and getpwuid() match");
+ }
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
+
diff --git a/winsup/testsuite/winsup.api/ltp/getuid03.c b/winsup/testsuite/winsup.api/ltp/getuid03.c
new file mode 100644
index 000000000..7c1075ca4
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/getuid03.c
@@ -0,0 +1,137 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * getuid01.c
+ *
+ * DESCRIPTION
+ * Testcase to check the basic functionality of the getuid() system call.
+ *
+ * USAGE: <for command-line>
+ * getuid01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+
+#include <pwd.h>
+#include <errno.h>
+#include <test.h>
+#include <usctest.h>
+
+char *TCID = "getuid01";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned by parse_opts */
+
+ struct passwd *pwent;
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ setup();
+
+ /* check looping state if -i option is given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ TEST(getuid());
+
+ if (TEST_RETURN < 0) {
+ tst_brkm(TBROK, cleanup, "This should never happen");
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+
+ pwent = getpwuid(TEST_RETURN);
+ if (pwent == NULL) {
+ tst_resm(TFAIL, "getuid() returned unexpected "
+ "value %d", TEST_RETURN);
+ } else {
+ if (pwent->pw_uid != TEST_RETURN) {
+ tst_resm(TFAIL, "getpwuid() value, %d, "
+ "does not match getuid() "
+ "value, %d", pwent->pw_uid,
+ TEST_RETURN);
+ } else {
+ tst_resm(TPASS, "values from getuid()"
+ " and getpwuid() match");
+ }
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
+
diff --git a/winsup/testsuite/winsup.api/ltp/kill01.c b/winsup/testsuite/winsup.api/ltp/kill01.c
new file mode 100644
index 000000000..d20d3a347
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/kill01.c
@@ -0,0 +1,161 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * kill01.c
+ *
+ * DESCRIPTION
+ * Test case to check the basic functionality of kill().
+ *
+ * ALGORITHM
+ * call setup
+ * loop if the -i option was given
+ * fork a child
+ * execute the kill system call
+ * check the return value
+ * if return value is -1
+ * issue a FAIL message, break remaining tests and cleanup
+ * if we are doing functional testing
+ * if the process was terminated with the expected signal.
+ * issue a PASS message
+ * otherwise
+ * issue a FAIL message
+ * call cleanup
+ *
+ * USAGE
+ * kill01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * This test should be ran as a non-root user.
+ */
+
+#include "test.h"
+#include "usctest.h"
+
+#include <signal.h>
+#include <errno.h>
+#include <sys/wait.h>
+
+void cleanup(void);
+void setup(void);
+
+char *TCID= "kill01()";
+int TST_TOTAL = 1;
+
+extern int Tst_count;
+
+#define TEST_SIG SIGKILL
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ pid_t pid;
+ int exno, status, nsig;
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ setup(); /* global setup */
+
+ /* The following loop checks looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+ status = 1;
+ exno = 1;
+ pid = fork();
+ if (pid < 0) {
+ tst_brkm(TBROK, cleanup, "Fork of child failed");
+ } else if (pid == 0) {
+ pause();
+ /*NOTREACHED*/
+ exit(exno);
+ } else {
+ TEST(kill(pid, TEST_SIG));
+ waitpid(pid, &status, 0);
+ }
+
+ if (TEST_RETURN == -1) {
+ tst_brkm(TFAIL, cleanup, "%s failed - errno = %d : %s",
+ TCID, TEST_ERRNO, strerror(TEST_ERRNO));
+ /*NOTREACHED*/
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Check to see if the process was terminated with the
+ * expected signal.
+ */
+ nsig = WTERMSIG(status);
+ if (nsig == TEST_SIG) {
+ tst_resm(TPASS, "received expected signal %d",
+ nsig);
+ } else {
+ tst_resm(TFAIL, "expected signal %d received %d" ,TEST_SIG,nsig);
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all the ONE TIME cleanup for this test at completion
+ * or premature exit.
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing status if that option was specified.
+ * print errno log if that option was specified
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/kill02.c b/winsup/testsuite/winsup.api/ltp/kill02.c
new file mode 100644
index 000000000..e618c8c71
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/kill02.c
@@ -0,0 +1,858 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ *
+ */
+/* $Id$ */
+/***********************************************************************************
+
+ OS Test - Silicon Graphics, Inc.
+
+ TEST IDENTIFIER : kill02 Sending a signal to processes with the same process group ID.
+
+ PARENT DOCUMENT : kiltds01 Kill System Call.
+
+ AUTHOR : Dave Baumgartner
+
+ CO-PILOT : Barrie Kletscher
+
+ DATE STARTED : 12/30/85
+
+ TEST ITEMS
+
+ 1. Sending a signal to pid of zero sends to all processes whose process
+ group ID is equal to the process group ID as the sender.
+
+ 2. Sending a signal to pid of zero does not send to processes in another process group.
+
+
+ OUTPUT SPECIFICATIONS
+
+ PASS :
+ kiltcs02 1 PASS The signal was sent to all processes in the process group.
+ kiltcs02 2 PASS The signal was not sent to selective processes that were not in the process group.
+
+ FAIL :
+ kiltcs02 1 FAIL The signal was not sent to all processes in the process group.
+ kiltcs02 2 FAIL The signal was sent to a process that was not in the process group.
+
+ BROK :
+ kiltcs02 # BROK System call XXX failed. Errno:X, Error message:XXX.
+ kiltcs02 # BROK Setting to catch unexpected signal %d failed. Errno: %d, Error message %s.
+ kiltcs02 # BROK Setting to ignore signal %d failed. Errno: %d, Error message %s.
+
+ WARN :
+ kiltcs02 0 WARN Unexpected signal X was caught.
+
+ SPECIAL PROCEDURAL REQUIREMENTS
+
+ The program must be linked with tst_res.o.
+
+ DETAILED DESCRIPTION
+
+ **Setup**
+ Set up unexpected signal handling.
+ Set up one pipe for each process to be created with no blocking for read.
+
+ **MAIN**
+ If setup fails exit.
+ Fork 2 children(1 & 2).
+ Wait for set up complete messages from the 1st and 2nd child.
+ Send the signal SIGUSR1 with pid equal to zero.
+ Sleep a reasonable amount of time so that each child has been swapped in
+ to process the signal.
+ Now decide the outcome of the test items by reading from each pipe to find
+ out if the child was interrupted by the signal and wrote to it.
+ Remove the second child.
+ Tell the first child it is time to remove it's child B because the decisions have been made.
+ Exit.
+
+ **First Child**
+ Set to catch SIGUSR1 with an int_rout1.
+ Set up to handle the message from the parent to remove child B.
+ Fork two children(A & B).
+ Wait for set up complete messages from child A & child B.
+ Send a set up complete message to the parent.
+ Pause until the signal SIGUSR1 comes in from the parent.
+ Pause until the parent says it is time to remove the child.
+ Exit.
+
+ **Second Child**
+ Set to catch SIGUSR1 with an int_rout2.
+ Set the process group to be something different than the parents.
+ Send a set up complete message to the parent.
+ Pause until killed by parent because this child shouldn't receive signal SIGUSR1.
+
+ **Child A**
+ Set to catch SIGUSR1 with an int_routA.
+ Send a set up complete message to the parent(First Child).
+ Pause until the signal SIGUSR1 comes in from the parent.
+ Exit.
+
+ **Child B**
+ Set to catch SIGUSR1 with an int_routB.
+ Set the process group to be something different than the parents(First Child's).
+ Send a set up complete message to the parent.
+ Pause until killed by parent because this child shouldn't receive signal SIGUSR1.
+
+ **usr1_rout-Used by all children**
+ Write to the appropriate pipe that the signal SIGUSR1 was caught.
+
+ **usr2_rout**
+ Remove child B.
+
+******************************************************************************/
+#include <sys/param.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include "test.h"
+#include "usctest.h"
+
+#define MAXMESG 150 /*The maximum message that can be created. */
+#define CHAR_SET_FAILED "0" /*Set up failing status transferred through the pipe. */
+#define CHAR_SET_PASSED "1" /*Set up passing status transferred through the pipe. */
+#define SIG_CAUGHT "2" /*Indicates that the signal SIGUSR1 was caught. */
+#define SIG_RECEIVED 1 /*Integer value that indicates that the signal SIGUSR1 */
+ /*was caught. */
+#define SIG_NOT_RECD 0 /*Integer value that indicates that the signal SIGUSR1 */
+ /*was caught. */
+#define INT_SET_FAILED 0 /*Set up failing status transferred through the pipe. */
+#define INT_SET_PASSED 1 /*Set up passing status transferred through the pipe. */
+#define SLEEP_TIME 10 /*Amount of time the children get to catch the signal */
+#define TRUE 40 /*Child exits with this if execution was as */
+ /*expected. */
+#define FALSE 50 /*Child exits with this if it timed out waiting for the */
+ /*parents signal. */
+#define TIMEOUT 60 /*Amount of time given in alarm calls. */
+#define CHILD_EXIT(VAR) ((VAR >> 8) & 0377) /*Exit value from the child. */
+#define CHILD_SIG(VAR) (VAR & 0377) /*Signal value from the termination of child. */
+ /*from the parent. */
+#define SYS_FAIL "The system call %s failed. Errno: %d, Error message: %s."
+
+int pid1; /*Return value from 1st fork. Global so that it can be */
+ /*used in interrupt handling routines. */
+int pid2; /*Return value from 2nd fork. Global so that it can be */
+ /*used in interrupt handling routines. */
+int pidA; /*Return value from 1st fork in child 1. Global so that it */
+ /*can be used in interrupt handling routines. */
+int pidB; /*Return value from 2nd fork in child 1. Global so that it */
+ /*can be used in interrupt handling routines. */
+extern int errno; /*Error number returned by a system call. */
+int pipe1_fd[2]; /*Pipe file descriptors used for communication */
+ /*between child 1 and the 1st parent. */
+int pipe2_fd[2]; /*Pipe file descriptors used for communication */
+ /*between child 2 and the 1st parent. */
+int pipeA_fd[2]; /*Pipe file descriptors used for communication */
+ /*between child A and the 1st parent. */
+int pipeB_fd[2]; /*Pipe file descriptors used for communication */
+ /*between child B and the 1st parent. */
+char pipe_buf[10]; /*Pipe buffer. */
+char buf_tmp1[2],buf_tmp2[2]; /*Temp hold for info read into pipe_buf. */
+int read1_stat = 0; /*Number of characters read from pipe 1. */
+int read2_stat = 0; /*Number of characters read from pipe 2. */
+int readA_stat = 0; /*Number of characters read from pipe A. */
+int readB_stat = 0; /*Number of characters read from pipe B. */
+int alarm_flag = FALSE; /*This flag indicates an alarm time out. */
+char who_am_i = '0'; /*This indicates which process is which when using */
+ /*interrupt routine usr1_rout. */
+
+void notify_timeout(); /*Signal handler that the parent enters if it times out */
+ /*waiting for the child to indicate its set up status. */
+void parent_rout(); /*This is the parents routine. */
+void child1_rout(); /*This is child 1's routine. */
+void child2_rout(); /*This is child 2's routine. */
+void childA_rout(); /*This is child A's routine. */
+void childB_rout(); /*This is child B's routine. */
+void usr1_rout(); /*This routine is used by all children to indicate that */
+ /*they have caught signal SIGUSR1. */
+void par_kill(); /*This routine is called by the original parent to */
+ /*remove child 2 and to indicate to child 1 to */
+ /*remove its children. */
+void chld1_kill(); /*This routine is used by child 1 to remove itself and */
+ /*its children A and B. */
+
+void setup();
+void cleanup();
+
+char *TCID="kill02"; /* Test program identifier. */
+int TST_TOTAL=2; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+extern int Tst_nobuf; /* var. used to turn off tst_res buffering */
+
+int exp_enos[]={0}; /* Array of expected errnos */
+
+/***********************************************************************
+ * MAIN
+ ***********************************************************************/
+int
+main(int ac, char **av)
+{
+ char mesg[MAXMESG]; /* Holds messages to pass to tst_res. */
+
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ Tst_nobuf=1;
+
+ /***************************************************************
+ * parse standard options, and exit if there is an error
+ * the -t and -f options not support yet.
+ ***************************************************************/
+ if ( (msg=parse_opts(ac, av, (option_t *) NULL, NULL)) != (char *) NULL ) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /***************************************************************
+ * perform global setup for test
+ ***************************************************************/
+ setup();
+
+ /***************************************************************
+ * check looping state if -c option given
+ ***************************************************************/
+ for (lc=0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ if ((pid1 = fork()) > 0)
+ {
+ /*
+ * This is the parent, fork again to create child 2.
+ */
+ if ((pid2 = fork()) > 0) {
+ /*
+ * This is the parent.
+ */
+ (void) parent_rout();
+ }
+ else if (pid2 == 0) {
+ /*
+ * This is child 2.
+ */
+ (void) child2_rout();
+ }
+ else {
+ /*
+ * The second fork failed kill the first child.
+ */
+ if (kill(pid1,SIGKILL) == -1 && errno != ESRCH) {
+ tst_resm(TWARN,"Child process may not have been killed.");
+ }
+ (void) sprintf(mesg,SYS_FAIL,"fork",errno,strerror(errno));
+ tst_brkm(TBROK,cleanup,mesg);
+ }
+
+ }
+ else if (pid1 == 0) {
+ /*
+ * This is child 1.
+ */
+ (void) child1_rout();
+ }
+ else {
+ /*
+ * Fork failed.
+ */
+ (void) sprintf(mesg,SYS_FAIL,"fork",errno,strerror(errno));
+ tst_brkm(TBROK,cleanup,mesg);
+ }
+ }
+
+ cleanup();
+
+ return 0;
+} /* END OF MAIN.*/
+
+/******************************************************************************
+ * This is the parents routine. The parent waits for the children 1 and 2 to
+ * get set up. Then sends the signal and checks the outcome.
+ *********************************************************************************/
+void parent_rout()
+{
+ char mesg[MAXMESG]; /*Used to buffer messages for tst_resm. */
+
+ /*
+ * Set to catch the alarm signal SIGALRM.
+ */
+ if (signal(SIGALRM,notify_timeout) == SIG_ERR) {
+ (void) par_kill();
+ tst_brkm(TBROK, NULL,
+ "Could not set to catch the parents time out alarm.");
+ tst_exit();
+ }
+
+ /*
+ * Setting to catch the timeout alarm worked now let the children start up.
+ * Set an alarm which causes a time out on the read pipe loop.
+ * The children will notify the parent that set up is complete
+ * and the pass/fail status of set up.
+ */
+ (void) alarm(TIMEOUT);
+
+ while ((read(pipe1_fd[0],pipe_buf,1) != 1) && (alarm_flag == FALSE))
+ /*EMPTY*/;
+ strncpy(buf_tmp1,pipe_buf,1);
+ (void) alarm(TIMEOUT);
+
+ while ((read(pipe2_fd[0],pipe_buf,1) != 1) && (alarm_flag == FALSE))
+ /*EMPTY*/;
+ (void) alarm(0); /*Reset the alarm clock.*/
+ strncpy(buf_tmp2,pipe_buf,1);
+
+ /*
+ * Check the alarm flag.
+ */
+ if (alarm_flag == TRUE) {
+ tst_brkm(TBROK,NULL,"The set up of the children failed by timing out.");
+ (void) par_kill();
+ cleanup();
+ }
+
+ /*
+ * Check to see if either child failed in the set up.
+ */
+ if ( (strncmp(buf_tmp1,CHAR_SET_FAILED,1) == 0) ||
+ (strncmp(buf_tmp2,CHAR_SET_FAILED,1) == 0)) {
+ /*
+ * Problems were encountered in the set up of one of the children.
+ * The error message has been displayed by the child.
+ */
+ (void) par_kill();
+ cleanup();
+ }
+
+ /*
+ * Setup passed, now send SIGUSR1 to process id of zero.
+ */
+ TEST( kill(0,SIGUSR1) );
+
+ if ( TEST_RETURN == -1)
+ {
+ (void) sprintf(mesg,SYS_FAIL,"kill",errno,strerror(errno));
+ tst_brkm(TBROK,NULL,mesg);
+ (void) par_kill();
+ cleanup();
+ }
+
+ /*
+ * Sleep for a while to allow the children to get a chance to
+ * catch the signal.
+ */
+ (void) sleep(SLEEP_TIME);
+
+ /*
+ * The signal was sent above and time has run out for child response,
+ * check the outcomes.
+ */
+ read1_stat = read(pipe1_fd[0],pipe_buf,1);
+ if (read1_stat == -1 && errno == EAGAIN) read1_stat = 0;
+ read2_stat = read(pipe2_fd[0],pipe_buf,1);
+ if (read2_stat == -1 && errno == EAGAIN) read2_stat = 0;
+ readA_stat = read(pipeA_fd[0],pipe_buf,1);
+ if (readA_stat == -1 && errno == EAGAIN) readA_stat = 0;
+ readB_stat = read(pipeB_fd[0],pipe_buf,1);
+ if (readB_stat == -1 && errno == EAGAIN) readB_stat = 0;
+
+ if (read1_stat == -1 || read2_stat == -1 ||
+ readA_stat == -1 || readB_stat == -1) {
+ /*
+ * The read system call failed.
+ */
+ (void) sprintf(mesg,SYS_FAIL,"read",errno,strerror(errno));
+ tst_brkm(TBROK,NULL,mesg);
+ (void) par_kill();
+ cleanup();
+ }
+
+ /*
+ * Check the processes that were supposed to get the signal.
+ */
+ if (read1_stat == SIG_RECEIVED) {
+ if (readA_stat == SIG_RECEIVED) {
+ /*
+ * Both processes, 1 and A, that were supposed to receive
+ * the signal did receive the signal.
+ */
+ if ( STD_FUNCTIONAL_TEST )
+ tst_resm(TPASS,
+ "The signal was sent to all processes in the process group.");
+ else
+ Tst_count++;
+ }
+ else { /*Process A didn't receive the signal.*/
+ tst_resm(TFAIL,"Process A did not receive the signal.");
+ }
+
+ }
+ else { /*Process 1 didn't receive the signal.*/
+ tst_resm(TFAIL,"Process 1 did not receive the signal.");
+ }
+
+ /*
+ * Check the processes that were not supposed to get the signal.
+ */
+ if (read2_stat == SIG_NOT_RECD) {
+ if (readB_stat == SIG_NOT_RECD) {
+ /*
+ * Both processes, 2 and B did not receive the signal.
+ */
+ if ( STD_FUNCTIONAL_TEST )
+ tst_resm(TPASS,
+ "The signal was not sent to selective processes that were not in the process group.");
+ else
+ Tst_count++;
+ }
+ else { /*Process B received the signal.*/
+ tst_resm(TFAIL,"Process B received the signal.");
+ }
+
+ }
+
+ else /*Process 2 received the signal.*/
+ {
+ tst_resm(TFAIL,"Process 2 received the signal.");
+ }
+
+ (void) par_kill();
+ return;
+} /*End of parent_rout*/
+
+/*******************************************************************************
+ * This is child 1's routine. It creates children A & B, checks their set up,
+ * reports to the parent set up pass/fail info., then waits for
+ * the parents signal.
+ ******************************************************************************/
+void child1_rout()
+{
+ char mesg[MAXMESG]; /*Used to buffer messages for tst_resm. */
+ who_am_i = '1';
+
+ /*
+ * Set to catch the SIGUSR1 with int1_rout.
+ */
+ if (signal(SIGUSR1,usr1_rout) == SIG_ERR)
+ {
+ tst_brkm(TBROK,NULL,"Could not set to catch the childrens signal.");
+ (void) write(pipe1_fd[1],CHAR_SET_FAILED,1);
+ exit(0);
+ }
+
+ /*
+ * Create children A & B.
+ */
+ if ((pidA = fork()) > 0) {
+ /*
+ * This is the parent(child1), fork again to create child B.
+ */
+ if ((pidB = fork()) == 0) {
+ /* This is child B. */
+ (void) childB_rout();
+ }
+
+ else if (pidB == -1) {
+ /*
+ * The fork of child B failed kill child A.
+ */
+ if (kill(pidA,SIGKILL) == -1)
+ tst_resm(TWARN,"Child process may not have been killed.");
+ (void) sprintf(mesg,SYS_FAIL,"fork",errno,strerror(errno));
+ tst_brkm(TBROK,NULL,mesg);
+ (void) write(pipe2_fd[1],CHAR_SET_FAILED,1);
+ exit(0);
+ }
+ }
+
+ else if (pidA == 0) {
+ /* This is child A. */
+ (void) childA_rout();
+
+ }
+
+ else if (pidA == -1) {
+ /*
+ * The fork of child A failed.
+ */
+ (void) sprintf(mesg,SYS_FAIL,"fork",errno,strerror(errno));
+ tst_brkm(TBROK,NULL,mesg);
+ (void) write(pipe1_fd[1],CHAR_SET_FAILED,1);
+ exit(0);
+ }
+
+ /*
+ * Set to catch the SIGUSR2 with chld1_kill.
+ */
+ if (signal(SIGUSR2,chld1_kill) == SIG_ERR) {
+ tst_brkm(TBROK,NULL,"Could not set to catch the parents signal.");
+ (void) write(pipe1_fd[1],CHAR_SET_FAILED,1);
+ (void) chld1_kill();
+ exit(0);
+ }
+
+ /*
+ * Set to catch the alarm signal SIGALRM.
+ */
+ if (signal(SIGALRM,notify_timeout) == SIG_ERR) {
+ tst_brkm(TBROK,NULL,"Could not set to catch the childs time out alarm.");
+ (void) write(pipe1_fd[1],CHAR_SET_FAILED,1);
+ (void) chld1_kill();
+ exit(0);
+ }
+
+ /*
+ * Setting to catch the signals worked now let the children start up.
+ * Set an alarm which causes a time out on the pipe read loop.
+ * The children A & B will notify the parent(child1) that set up is complete
+ * and the pass/fail status of set up.
+ */
+ (void) alarm(TIMEOUT-40);
+
+ while ((read(pipeA_fd[0],pipe_buf,1) != 1) && (alarm_flag == FALSE))
+ /*EMPTY*/;
+ (void) alarm(TIMEOUT-40);
+
+ while ((read(pipeB_fd[0],pipe_buf,1) != 1) && (alarm_flag == FALSE))
+ /*EMPTY*/;
+ (void) alarm(0); /*Reset the alarm clock.*/
+
+ /*
+ * Check the alarm flag.
+ */
+ if (alarm_flag == TRUE) {
+ tst_brkm(TBROK,NULL,"The set up of the children failed by timing out.");
+ (void) chld1_kill();
+ (void) write(pipe1_fd[1],CHAR_SET_FAILED,1);
+ exit(0);
+ }
+
+ /*
+ * Send a set up complete message to the parent.
+ */
+ (void) write(pipe1_fd[1],CHAR_SET_PASSED,1);
+
+ /*
+ * Pause until the signal SIGUSR1 or SIGUSR2 is sent from the parent.
+ */
+ (void) pause();
+
+ /*
+ * Pause until signal SIGUSR2 is sent from the parent.
+ * This pause will only be executed if SIGUSR2 has not been received yet.
+ */
+ while (1) {
+ sleep(1);
+ }
+
+} /*End of child1_rout*/
+
+/*******************************************************************************
+ * This is the routine for child 2, which should not receive the parents signal.
+ ******************************************************************************/
+void child2_rout()
+{
+ who_am_i = '2';
+
+ /*
+ * Set the process group of this process to be different
+ * than the other processes.
+ */
+ (void) setpgrp();
+
+ /*
+ * Set to catch the SIGUSR1 with usr1_rout.
+ */
+ if (signal(SIGUSR1,usr1_rout) == SIG_ERR) {
+ tst_brkm(TBROK,cleanup,"Could not set to catch the parents signal.");
+ (void) write(pipe2_fd[1],CHAR_SET_FAILED,1);
+ exit(0);
+ }
+
+ /* Send a set up complete message to parent.*/
+ (void) write(pipe2_fd[1],CHAR_SET_PASSED,1);
+
+ /*
+ * Pause until killed by the parent or SIGUSR1 is received.
+ */
+ (void) pause();
+}
+
+
+/*******************************************************************************
+ * This is the routine for child A, which should receive the parents signal.
+ ******************************************************************************/
+void childA_rout()
+{
+ who_am_i = 'A';
+
+ /* Send a set up complete message to parent.*/
+ write(pipeA_fd[1],CHAR_SET_PASSED,1);
+
+ /*
+ * Pause until killed by the parent or SIGUSR1 is received.
+ */
+ (void) pause();
+
+ exit(0);
+} /*End of childA_rout*/
+
+/*******************************************************************************
+ * This is the routine for child B, which should not receive the parents signal.
+ ******************************************************************************/
+void childB_rout()
+{
+ who_am_i = 'B';
+
+ /*
+ * Set the process group of this process to be different
+ * than the other processes.
+ */
+ (void) setpgrp();
+
+ /* Send a set up complete message to parent(child 1).*/
+ write(pipeB_fd[1],CHAR_SET_PASSED,1);
+
+ /*
+ * Pause until killed by the parent(child 1) or SIGUSR1 is received.
+ */
+ (void) pause();
+
+ exit(0);
+}
+
+/*******************************************************************************
+ * This routine sets up the interprocess communication pipes, signal handling,
+ * and process group information.
+ ******************************************************************************/
+void
+setup()
+{
+ int errno_buf; /*indicates the errno if pipe set up fails. */
+ int err_flag = FALSE; /*Indicates if an error has occurred in pipe set up. */
+ char mesg[MAXMESG]; /*Used to buffer messages for tst_res. */
+
+ /*
+ * Set the process group ID to be equal between the parent and children.
+ */
+ (void) setpgrp();
+
+ /*
+ * Set to catch unexpected signals.
+ * SIGCLD is set to be ignored because we do not wait for termination status.
+ * SIGUSR1 is set to be ignored because this is the signal we are using for
+ * the test and we are not concerned with the parent getting it.
+ */
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ if (signal(SIGUSR1,SIG_IGN) == SIG_ERR) {
+ (void) sprintf(mesg,
+ "Setting to ignore signal SIGCLD failed. Errno: %d, Error message %s.",
+ errno,strerror(errno));
+ tst_brkm(TBROK,NULL,mesg);
+ tst_exit();
+ }
+
+ if (signal(SIGCLD,SIG_IGN) == SIG_ERR) {
+ (void) sprintf(mesg,
+ "Setting to ignore signal SIGCLD failed. Errno: %d, Error message %s.",
+ errno,strerror(errno));
+ tst_brkm(TBROK,NULL,mesg);
+ tst_exit();
+ }
+
+ /* Indicate which errnos are expected */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+
+ /*
+ * Set up pipe1, pipe2, pipeA, and pipeB.
+ */
+ if ((pipe(pipe1_fd) == -1) || (fcntl(pipe1_fd[0],F_SETFL,O_NDELAY) == -1))
+ {
+ errno_buf = errno;
+ err_flag = TRUE;
+ }
+
+ if ((pipe(pipe2_fd) == -1) || (fcntl(pipe2_fd[0],F_SETFL,O_NDELAY) == -1))
+ {
+ errno_buf = errno;
+ err_flag = TRUE;
+ }
+
+ if ((pipe(pipeA_fd) == -1) || (fcntl(pipeA_fd[0],F_SETFL,O_NDELAY) == -1))
+ {
+ errno_buf = errno;
+ err_flag = TRUE;
+ }
+
+ if ((pipe(pipeB_fd) == -1) || (fcntl(pipeB_fd[0],F_SETFL,O_NDELAY) == -1))
+ {
+ errno_buf = errno;
+ err_flag = TRUE;
+ }
+
+ /*
+ * Check for errors.
+ */
+ if (err_flag == TRUE)
+ {
+ (void) sprintf(mesg,SYS_FAIL,"pipe",errno_buf,strerror(errno_buf));
+ tst_brkm(TBROK, NULL, mesg);
+ tst_exit();
+ }
+ return;
+
+}
+
+/***********************************************************
+ * This routine indicates that the process caught SIGUSR1.
+ **********************************************************/
+void usr1_rout()
+{
+ char mesg[MAXMESG]; /*Used to buffer messages for tst_res. */
+
+ switch (who_am_i)
+ {
+ case '1': if (write(pipe1_fd[1],SIG_CAUGHT,1) == -1)
+ tst_resm(TWARN,"Writing signal catching status failed in child 1.");
+ break;
+ case '2': if (write(pipe2_fd[1],SIG_CAUGHT,1) == -1)
+ tst_resm(TWARN,"Writing signal catching status failed in child 2.");
+ break;
+ case 'A': if (write(pipeA_fd[1],SIG_CAUGHT,1) == -1)
+ tst_resm(TWARN,"Writing signal catching status failed in child A.");
+ break;
+ case 'B': if (write(pipeB_fd[1],SIG_CAUGHT,1) == -1)
+ tst_resm(TWARN,"Writing signal catching status failed in child B.");
+ break;
+ default:
+ sprintf(mesg,"Unexpected value %d for who_am_i in usr1_rout().",who_am_i);
+ tst_resm(TWARN,mesg);
+ break;
+ }
+
+} /*End of usr1_rout*/
+
+
+/***********************************************************
+ * This routine handles the timeout alarm in the parent,
+ * which occurs when the child fails to notify the parent
+ * the status of set up.
+ **********************************************************/
+void notify_timeout()
+{
+ alarm_flag = TRUE;
+
+} /*End of notify_timeout*/
+
+/***********************************************************
+ * This routine handles the procedure for removing the
+ * children forked off during this test.
+ **********************************************************/
+void par_kill()
+{
+ char mesg[MAXMESG]; /*Used to buffer messages for tst_res. */
+ /*
+ * Indicate to child1 that it can remove it's children and itself now.
+ */
+ if (kill(pid1,SIGUSR2) == -1 && errno != ESRCH)
+ {
+ (void) sprintf(mesg,SYS_FAIL,"kill",errno,strerror(errno));
+ tst_resm(TWARN,mesg);
+ tst_resm(TWARN,"Child 1 and it's children may still be alive.");
+ }
+
+ /*
+ * Remove child 2.
+ */
+ if (kill(pid2,SIGKILL) == -1 && errno != ESRCH)
+ tst_resm(TWARN,"Child2 may still be alive.");
+
+ return;
+
+} /*End of par_kill*/
+
+
+/*********************************************************************
+ * This routine is executed by child 1 when the parent tells it to
+ * remove it's children and itself.
+ ********************************************************************/
+void chld1_kill()
+{
+ char mesg[MAXMESG]; /*Used to buffer messages for tst_resm. */
+
+ /*
+ * Remove children A & B.
+ */
+ if (kill(pidA,SIGKILL) == -1 && errno != ESRCH)
+ {
+ (void) sprintf(mesg,
+ "The system call kill failed. Child 1's(A) child may still be alive. Errno: %d, Error message %s.",
+ errno,strerror(errno));
+ tst_resm(TWARN,mesg);
+ }
+ if (kill(pidB,SIGKILL) == -1 && errno != ESRCH)
+ {
+ (void) sprintf(mesg,
+ "The system call kill failed. Child 1's(B) child may still be alive. Errno: %d, Error message %s.",
+ errno,strerror(errno));
+ tst_resm(TWARN,mesg);
+ }
+
+ exit(0);
+
+} /*End of chld1_kill*/
+
+/***************************************************************
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ ***************************************************************/
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+
+} /* End cleanup() */
+
+
diff --git a/winsup/testsuite/winsup.api/ltp/kill03.c b/winsup/testsuite/winsup.api/ltp/kill03.c
new file mode 100644
index 000000000..528a080b4
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/kill03.c
@@ -0,0 +1,169 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * kill03.c
+ *
+ * DESCRIPTION
+ * Test case to check that kill fails when given an invalid signal.
+ *
+ * ALGORITHM
+ * call setup
+ * loop if the -i option was given
+ * fork a child
+ * execute the kill system call with an invalid signal
+ * check the return value
+ * if return value is not -1
+ * issue a FAIL message, break remaining tests and cleanup
+ * if we are doing functional testing
+ * if the errno was set to 22 (invalid argument).
+ * issue a PASS message
+ * otherwise
+ * issue a FAIL message
+ * call cleanup
+ *
+ * USAGE
+ * kill03 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * none
+ */
+
+#include "test.h"
+#include "usctest.h"
+
+#include <signal.h>
+#include <errno.h>
+#include <sys/wait.h>
+
+void cleanup(void);
+void setup(void);
+
+char *TCID= "kill03()";
+int TST_TOTAL = 1;
+
+extern int Tst_count;
+
+int exp_enos[] = {EINVAL, 0};
+
+#define TEST_SIG 2000
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ pid_t pid;
+ int exno, status, nsig;
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ setup(); /* global setup */
+
+ TEST_EXP_ENOS(exp_enos);
+
+ /* The following loop checks looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+ status = 1;
+ exno = 1;
+ pid = fork();
+ if (pid < 0) {
+ tst_brkm(TBROK, cleanup, "Fork of child failed");
+ } else if (pid == 0) {
+ pause();
+ /*NOTREACHED*/
+ exit(exno);
+ } else {
+ TEST(kill(pid, TEST_SIG));
+ kill(pid, SIGKILL);
+ waitpid(pid, &status, 0);
+ }
+
+ if (TEST_RETURN != -1) {
+ tst_brkm(TFAIL, cleanup, "%s failed - errno = %d : %s "
+ "Expected a return value of -1 got %d",
+ TCID, TEST_ERRNO, strerror(TEST_ERRNO)),
+ TEST_RETURN;
+ /*NOTREACHED*/
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Check to see if the errno was set to the expected
+ * value of 22 : EINVAL.
+ */
+ TEST_ERROR_LOG(TEST_ERRNO);
+ if (TEST_ERRNO == EINVAL) {
+ tst_resm(TPASS, "errno set to %d : %s, as "
+ "expected", TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ } else {
+ tst_resm(TFAIL, "errno set to %d : %s expected "
+ "%d : %s", TEST_ERRNO,
+ strerror(TEST_ERRNO), 22, strerror(22));
+ }
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all the ONE TIME cleanup for this test at completion
+ * or premature exit.
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing status if that option was specified.
+ * print errno log if that option was specified
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/kill04.c b/winsup/testsuite/winsup.api/ltp/kill04.c
new file mode 100644
index 000000000..2e0ff6593
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/kill04.c
@@ -0,0 +1,180 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * kill04.c
+ *
+ * DESCRIPTION
+ * Test case to check that kill() fails when passed a non-existant pid.
+ *
+ * ALGORITHM
+ * call setup
+ * loop if the -i option was given
+ * fork a child
+ * execute the kill system call with a non-existant PID
+ * check the return value
+ * if return value is not -1
+ * issue a FAIL message, break remaining tests and cleanup
+ * if we are doing functional testing
+ * if the errno was set to 3 (No such proccess)
+ * issue a PASS message
+ * otherwise
+ * issue a FAIL message
+ * call cleanup
+ *
+ * USAGE
+ * kill04 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * This test should be run by a non-root user
+ */
+
+#include "test.h"
+#include "usctest.h"
+
+#include <signal.h>
+#include <errno.h>
+#include <sys/wait.h>
+
+void cleanup(void);
+void setup(void);
+
+char *TCID= "kill04()";
+int TST_TOTAL = 1;
+
+extern int Tst_count;
+
+int exp_enos[] = {ESRCH, 0};
+
+#define TEST_SIG SIGKILL
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ pid_t pid, fake_pid;
+ int exno, status, fake_status, nsig;
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ setup(); /* global setup */
+
+ TEST_EXP_ENOS(exp_enos);
+
+ /* The following loop checks looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+ status = 1;
+ exno = 1;
+ pid = fork();
+ if (pid < 0) {
+ tst_brkm(TBROK, cleanup, "Fork failed");
+ } else if (pid == 0) {
+ pause();
+ /*NOTREACHED*/
+ exit(exno);
+ } else {
+ fake_pid = fork();
+ if (fake_pid < 0) {
+ tst_brkm(TBROK, cleanup, "Second fork failed");
+ } else if (fake_pid == 0) {
+ pause();
+ /*NOTREACHED*/
+ exit(exno);
+ }
+ kill(fake_pid, TEST_SIG);
+ waitpid(fake_pid, &fake_status, 0);
+ TEST(kill(fake_pid, TEST_SIG));
+ kill(pid, TEST_SIG);
+ waitpid(pid, &status, 0);
+ }
+
+ if (TEST_RETURN != -1) {
+ tst_brkm(TFAIL, cleanup, "%s failed - errno = %d : %s "
+ "Expected a return value of -1 got %d",
+ TCID, TEST_ERRNO, strerror(TEST_ERRNO)),
+ TEST_RETURN;
+ /*NOTREACHED*/
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Check to see if the errno was set to the expected
+ * value of 3 : ESRCH
+ */
+ nsig = WTERMSIG(status);
+ TEST_ERROR_LOG(TEST_ERRNO);
+ if (TEST_ERRNO == ESRCH) {
+ tst_resm(TPASS, "errno set to %d : %s, as "
+ "expected", TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ } else {
+ tst_resm(TFAIL, "errno set to %d : %s expected "
+ "%d : %s", TEST_ERRNO,
+ strerror(TEST_ERRNO), 3, strerror(3));
+ }
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all the ONE TIME cleanup for this test at completion
+ * or premature exit.
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing status if that option was specified.
+ * print errno log if that option was specified
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/lseek06.c b/winsup/testsuite/winsup.api/ltp/lseek06.c
new file mode 100644
index 000000000..0262260fc
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/lseek06.c
@@ -0,0 +1,237 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: lseek01
+ *
+ * Test Description:
+ * Verify that, lseek() call succeeds to set the file pointer position
+ * to less than or equal to the file size, when a file is opened for
+ * read or write.
+ *
+ * Expected Result:
+ * lseek() should return the offset from the beginning of the file measured
+ * in bytes. Also check if able to read valid data from this location.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Pause for SIGUSR1 if option specified.
+ * Create temporary directory.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * lseek01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <utime.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define OFFSET 4
+#define TEMP_FILE "tmp_file"
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+
+char *TCID="lseek01"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int fildes; /* file handle for temp file */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ char read_buf[1]; /* data read from temp. file */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Invoke lseek(2) to move the read/write file
+ * pointer/handle by OFFSET bytes.
+ */
+ TEST(lseek(fildes, OFFSET, SEEK_SET));
+
+ /* check return code of lseek(2) */
+ if (TEST_RETURN == (off_t)-1) {
+ tst_resm(TFAIL, "lseek on (%s) Failed, errno=%d : %s",
+ TEMP_FILE, TEST_ERRNO, strerror(TEST_ERRNO));
+ continue;
+ }
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Check if the return value from lseek(2)
+ * is equal to the specified OFFSET value.
+ */
+ if (TEST_RETURN != OFFSET) {
+ tst_resm(TFAIL, "lseek() returned incorrect "
+ "value %d, expected %d",
+ TEST_RETURN, OFFSET);
+ continue;
+ }
+ /*
+ * The return value is good, now check data.
+ * Read the data byte from this location.
+ */
+ if (read(fildes, &read_buf, sizeof(read_buf)) < 0) {
+ tst_brkm(TFAIL, cleanup, "read() failed "
+ "on %s, error=%d", TEMP_FILE, errno);
+ } else {
+ /*
+ * Check if read byte is the expected character.
+ * For pos 4 ---> 'e'
+ */
+ if (read_buf[0] != 'e') {
+ tst_resm(TFAIL, "Incorrect data read "
+ "from file %s", TEMP_FILE);
+ } else {
+ tst_resm(TPASS, "Functionality "
+ "of lseek() on %s "
+ "successful", TEMP_FILE);
+ }
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ * Create a test file under temporary directory and write some
+ * data into it.
+ */
+void
+setup()
+{
+ char write_buf[BUFSIZ]; /* buffer to hold data */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Get the data to be written to temporary file */
+ strcpy(write_buf, "abcdefg");
+
+ /* Creat/open a temporary file under above directory */
+ if ((fildes = open(TEMP_FILE, O_RDWR | O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s",
+ TEMP_FILE, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Write data into temporary file */
+ if(write(fildes, write_buf, strlen(write_buf)) != strlen(write_buf)) {
+ tst_brkm(TBROK, cleanup, "write(2) on %s Failed, errno=%d : %s",
+ TEMP_FILE, errno, strerror(errno));
+ }
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Close the temporary file created */
+ if (close(fildes) < 0) {
+ tst_brkm(TFAIL, NULL, "close(%s) Failed, errno=%d : %s:",
+ TEMP_FILE, errno, strerror(errno));
+ }
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/lseek07.c b/winsup/testsuite/winsup.api/ltp/lseek07.c
new file mode 100644
index 000000000..0acc28949
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/lseek07.c
@@ -0,0 +1,288 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: lseek02
+ *
+ * Test Description:
+ * Verify that, lseek() call succeeds to set the file pointer position
+ * to more than the file size, when a file is opened for reading/writing.
+ *
+ * Expected Result:
+ * lseek() should return n+1, where n is the size of the file.
+ * Also when some data is written into this file it should start
+ * from that offset.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Pause for SIGUSR1 if option specified.
+ * Create temporary directory.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * lseek02 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <utime.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEMP_FILE "tmp_file"
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+
+char *TCID="lseek02"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int fildes; /* file handle for temp file */
+size_t file_size; /* size of temporary file */
+char write_buf1[BUFSIZ]; /* buffer to hold data */
+char write_buf2[BUFSIZ]; /* buffer to hold data */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ char read_buf[BUFSIZ]; /* data read from temp. file */
+ off_t offset; /* byte position in temporary file */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /* Set the offset position */
+ offset = file_size + (lc * strlen(write_buf2));
+
+ /*
+ * Invoke lseek(2) to move the write file
+ * pointer/handle by the specified offset value.
+ */
+ TEST(lseek(fildes, offset, SEEK_SET));
+
+ /* check return code of lseek(2) */
+ if (TEST_RETURN == (off_t)-1) {
+ tst_resm(TFAIL, "lseek on (%s) Failed, errno=%d : %s",
+ TEMP_FILE, TEST_ERRNO, strerror(TEST_ERRNO));
+ continue;
+ }
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Check if the return value from lseek(2)
+ * is equal to the specified offset value.
+ */
+ if (TEST_RETURN != offset) {
+ tst_resm(TFAIL, "lseek() returned "
+ "incorrect value %d, expected "
+ "%d", TEST_RETURN, offset);
+ continue;
+ }
+ /*
+ * The return value is okay, now write some data at
+ * the current offset position.
+ */
+ if (write(fildes, write_buf2, strlen(write_buf2)) !=
+ strlen(write_buf2)) {
+ tst_brkm(TFAIL, cleanup, "write() failed to "
+ "write additional data, error = %d",
+ errno);
+ }
+
+ /*
+ * Now close the file and open it again
+ * and read all of the data.
+ */
+ if (close(fildes) < 0) {
+ tst_brkm(TFAIL, cleanup, "close() on %s Failed,"
+ " errno = %d", TEMP_FILE, errno);
+ }
+
+ /* Open the file again in read/write mode */
+ if ((fildes = open(TEMP_FILE, O_RDWR)) < 0) {
+ tst_brkm(TFAIL, cleanup, "Could not open the "
+ "%s readonly, error = %d",
+ TEMP_FILE, errno);
+ }
+
+ /*
+ * Now read all of the data. The size should be the
+ * offset + strlen(write_buf2).
+ */
+ if (read(fildes, &read_buf, (offset +
+ strlen(write_buf2))) < 0) {
+ tst_brkm(TFAIL, cleanup, "read() failed on %s, "
+ "error=%d", TEMP_FILE, errno);
+ } else {
+ /*
+ * Check data read is the complete data and not
+ * the only portion written.
+ */
+ if ((strncmp(read_buf, write_buf1,
+ strlen(write_buf1))) != 0) {
+ tst_brkm(TFAIL, cleanup,
+ "Incorrect data read #1 from "
+ "file %s", TEMP_FILE);
+ }
+ if ((strncmp(&read_buf[offset], write_buf2,
+ strlen(write_buf2))) != 0) {
+ tst_brkm(TFAIL, cleanup,
+ "Incorrect data read #2 from "
+ "file %s", TEMP_FILE);
+ }
+ tst_resm(TPASS, "Functionality of "
+ "lseek() on %s successful", TEMP_FILE);
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ * Create a test file under temporary directory and write some
+ * data into it.
+ * Get the size of the file using fstat().
+ */
+void
+setup()
+{
+ struct stat stat_buf; /* struct buffer for stat(2) */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Get the data to be written to temporary file */
+ strcpy(write_buf1, "abcdefg");
+ strcpy(write_buf2, "ijk");
+
+ /* Creat/open a temporary file for writing under above directory */
+ if ((fildes = open(TEMP_FILE, O_WRONLY | O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_WRONLY|O_CREAT, %#o) Failed, errno=%d :%s",
+ TEMP_FILE, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Write data into temporary file */
+ if(write(fildes, write_buf1, strlen(write_buf1)) !=
+ strlen(write_buf1)) {
+ tst_brkm(TBROK, cleanup, "write(2) on %s Failed, errno=%d : %s",
+ TEMP_FILE, errno, strerror(errno));
+ }
+
+ /* Get the size of the temporary file after writing data */
+ if (fstat(fildes, &stat_buf) < 0) {
+ tst_brkm(TBROK, cleanup, "fstat() on %s Failed, errno=%d : %s",
+ TEMP_FILE, errno, strerror(errno));
+ }
+
+ file_size = stat_buf.st_size;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Close the temporary file created */
+ if (close(fildes) < 0) {
+ tst_brkm(TFAIL, NULL, "close(%s) Failed, errno=%d : %s:",
+ TEMP_FILE, errno, strerror(errno));
+ }
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/lseek08.c b/winsup/testsuite/winsup.api/ltp/lseek08.c
new file mode 100644
index 000000000..061ac3152
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/lseek08.c
@@ -0,0 +1,242 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: lseek03
+ *
+ * Test Description:
+ * Verify that, lseek() call succeeds to set the file pointer position
+ * to the end of the file when 'whence' value set to SEEK_END and any
+ * attempts to read from that position should fail.
+ *
+ * Expected Result:
+ * lseek() should return the offset which is set to the file size measured
+ * in bytes. read() attempt should fail with -1 return value.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * lseek03 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <utime.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEMP_FILE "tmp_file"
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+
+char *TCID="lseek03"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int fildes; /* file handle for temp file */
+size_t file_size; /* size of the temporary file */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ char read_buf[1]; /* data read from temp. file */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Invoke lseek(2) to move the read/write file
+ * pointer/handle to the END of the file.
+ */
+ TEST(lseek(fildes, 0, SEEK_END));
+
+ /* check return code of lseek(2) */
+ if (TEST_RETURN == (off_t)-1) {
+ tst_resm(TFAIL, "lseek on (%s) Failed, errno=%d : %s",
+ TEMP_FILE, TEST_ERRNO, strerror(TEST_ERRNO));
+ continue;
+ }
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Check if the return value from lseek(2)
+ * is equal to the file_size.
+ */
+ if (TEST_RETURN != file_size) {
+ tst_resm(TFAIL, "lseek() returned incorrect "
+ "value %d, expected %d",
+ TEST_RETURN, file_size);
+ continue;
+ }
+ /*
+ * The return value is okay, now attempt to read data
+ * from the file. This should fail as the file pointer
+ * should be pointing to END OF FILE.
+ */
+ read_buf[0] = '\0';
+ if (read(fildes, &read_buf, sizeof(read_buf)) > 0) {
+ tst_resm(TFAIL, "read() successful on %s",
+ TEMP_FILE);
+ } else {
+ tst_resm(TPASS, "Functionality of lseek() on "
+ "%s successful", TEMP_FILE);
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /* NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ * Create a test file under temporary directory and write some
+ * data into it.
+ * Get the size of the file using fstat().
+ */
+void
+setup()
+{
+ struct stat stat_buf; /* struct. buffer for stat(2) */
+ char write_buf[BUFSIZ]; /* buffer to hold data */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Get the data to be written to temporary file */
+ strcpy(write_buf, "abcdefg\n");
+
+ /* Creat/open a temporary file under above directory */
+ if ((fildes = open(TEMP_FILE, O_RDWR | O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s",
+ TEMP_FILE, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Write data into temporary file */
+ if(write(fildes, write_buf, strlen(write_buf)) <= 0) {
+ tst_brkm(TBROK, cleanup,
+ "write(2) on %s Failed, errno=%d : %s",
+ TEMP_FILE, errno, strerror(errno));
+ }
+
+ /* Get the size of the file using fstat */
+ if (fstat(fildes, &stat_buf) < 0) {
+ tst_brkm(TBROK, cleanup,
+ "fstat(2) on %s Failed, errno=%d : %s",
+ TEMP_FILE, errno, strerror(errno));
+ }
+
+ file_size = stat_buf.st_size;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Close the temporary file created */
+ if (close(fildes) < 0) {
+ tst_brkm(TFAIL, NULL,
+ "close(%s) Failed, errno=%d : %s:",
+ TEMP_FILE, errno, strerror(errno));
+ }
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/lseek09.c b/winsup/testsuite/winsup.api/ltp/lseek09.c
new file mode 100644
index 000000000..b36df715d
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/lseek09.c
@@ -0,0 +1,269 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: lseek04
+ *
+ * Test Description:
+ * Verify that, lseek() call succeeds to set the file pointer position
+ * to the current specified location, when 'whence' value is set to
+ * SEEK_CUR and the data read from the specified location should match
+ * the expected data.
+ *
+ * Expected Result:
+ * lseek() should return the specified offset from the beginning of the file
+ * measured in bytes. The data read from this location should match the
+ * expected data.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * lseek04 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <utime.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEMP_FILE "tmp_file"
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+
+char *TCID="lseek04"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int fildes; /* file handle for temp file */
+size_t file_size; /* total size of file after data write */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ int rval;
+ const char *msg; /* message returned from parse_opts */
+ char read_buf[BUFSIZ]; /* data read from temp. file */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Invoke lseek(2) to set the file
+ * pointer/handle from the current location
+ * of the file descriptor + specified offset.
+ */
+ TEST(lseek(fildes, 1, SEEK_CUR));
+
+ /* check return code of lseek(2) */
+ if (TEST_RETURN == (off_t)-1) {
+ tst_resm(TFAIL, "lseek on (%s) Failed, errno=%d : %s",
+ TEMP_FILE, TEST_ERRNO, strerror(TEST_ERRNO));
+ continue;
+ }
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Check if the return value from lseek(2) is equal
+ * to the 3 positions from the beginning of the file.
+ * ie, 2 positions from lseek() in the setup +
+ * 1 position from above above.
+ */
+ if (TEST_RETURN != 3) {
+ tst_resm(TFAIL, "lseek() returned incorrect "
+ "value %d, expected 4", TEST_RETURN);
+ continue;
+ }
+ /*
+ * Read the data byte from this location.
+ */
+ read_buf[0] = '\0';
+ if (read(fildes, &read_buf, (file_size - 3)) < 0) {
+ tst_brkm(TFAIL, cleanup,
+ "read() failed on %s, error=%d",
+ TEMP_FILE, errno);
+ } else {
+ /*
+ * Check if read data contains
+ * expected characters
+ * From pos 4 ---> 'defg'.
+ */
+ if (memcmp(read_buf, "defg", 4)) {
+ tst_resm(TFAIL, "Incorrect data read "
+ "from file %s", TEMP_FILE);
+ } else {
+ tst_resm(TPASS, "Functionality of "
+ "lseek() on %s successful",
+ TEMP_FILE);
+ }
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+
+ /* reset file pointer in case we are looping */
+ if (lseek(fildes, 2, SEEK_SET) == -1) {
+ tst_brkm(TBROK, cleanup, "lseek failed - could not "
+ "reset file pointer");
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ * Create a test file under temporary directory and write some
+ * data into it.
+ * Get the size of the file using fstat().
+ */
+void
+setup()
+{
+ struct stat stat_buf; /* buffer to hold stat info. */
+ char write_buf[BUFSIZ]; /* buffer to hold data */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Get the data to be written to temporary file */
+ strcpy(write_buf, "abcdefg");
+
+ /* Creat/open a temporary file under above directory */
+ if ((fildes = open(TEMP_FILE, O_RDWR | O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s",
+ TEMP_FILE, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Write data into temporary file */
+ if(write(fildes, write_buf, strlen(write_buf)) <= 0) {
+ tst_brkm(TBROK, cleanup, "write(2) on %s Failed, errno=%d : %s",
+ TEMP_FILE, errno, strerror(errno));
+ }
+
+ /* Get the temporary file information */
+ if (fstat(fildes, &stat_buf) < 0) {
+ tst_brkm(TBROK, cleanup, "fstat(2) on %s Failed, errno=%d : %s",
+ TEMP_FILE, errno, strerror(errno));
+ }
+
+ file_size = stat_buf.st_size;
+
+ /*
+ * Reset the file pointer position to the specified offset
+ * from the beginning of the file.
+ */
+ if (lseek(fildes, 2, SEEK_SET) != 2) {
+ tst_brkm(TBROK, cleanup,
+ "lseek() fails to set file ptr. to specified offset");
+ }
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Close the temporary file created */
+ if (close(fildes) < 0) {
+ tst_brkm(TFAIL, NULL, "close(%s) Failed, errno=%d : %s:",
+ TEMP_FILE, errno, strerror(errno));
+ }
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/lseek10.c b/winsup/testsuite/winsup.api/ltp/lseek10.c
new file mode 100644
index 000000000..060f3b290
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/lseek10.c
@@ -0,0 +1,347 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: lseek05
+ *
+ * Test Description:
+ * Verify that,
+ * 1. lseek() returns -1 and sets errno to ESPIPE, if the file handle of
+ * the specified file is associated with a pipe, socket, or FIFO.
+ * 2. lseek() returns -1 and sets errno to EINVAL, if the 'Whence' argument
+ * is not a proper value.
+ * 3. lseek() returns -1 and sets errno to EBADF, if the file handle of
+ * the specified file is not valid.
+ *
+ * Expected Result:
+ * lseek() should fail with return value -1 and set expected errno.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * if errno set == expected errno
+ * Issue sys call fails with expected return value and errno.
+ * Otherwise,
+ * Issue sys call fails with unexpected errno.
+ * Otherwise,
+ * Issue sys call returns unexpected value.
+ *
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory(s)/file(s) created.
+ *
+ * Usage: <for command-line>
+ * lseek05 [-c n] [-e] [-i n] [-I x] [-p x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <utime.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEMP_FILE1 "tmp_file1"
+#define TEMP_FILE2 "tmp_file2"
+#define TEMP_FILE3 "tmp_file3"
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+#define PIPE_MODE S_IFIFO | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+#define SEEK_TOP 10
+
+char *TCID="lseek05"; /* Test program identifier. */
+int TST_TOTAL=3; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={ESPIPE, EINVAL, EBADF, 0};
+
+int no_setup();
+int setup1(); /* setup function to test lseek() for ESPIPE */
+int setup2(); /* setup function to test lseek() for EINVAL */
+int setup3(); /* setup function to test lseek() for EBADF */
+
+int fd1; /* file handle for testfile1 */
+int fd2; /* file handle for testfile2 */
+int fd3; /* file handle for testfile3 */
+
+struct test_case_t { /* test case struct. to hold ref. test cond's*/
+ int fd;
+ int Whence;
+ char *desc;
+ int exp_errno;
+ int (*setupfunc)();
+} Test_cases[] = {
+ { 1, SEEK_SET, "'fd' associated with a pipe/fifo", ESPIPE, setup1 },
+ { 2, SEEK_TOP, "'whence' argument is not valid", EINVAL, setup2 },
+ { 3, SEEK_SET, "'fd' is not an open file descriptor", EBADF, setup3 },
+ { 0, 0, NULL, 0, no_setup }
+};
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ int fildes; /* file handle for testfile */
+ int whence; /* position of file handle in the file */
+ char *test_desc; /* test specific error message */
+ int ind; /* counter to test different test conditions */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ for (ind = 0; Test_cases[ind].desc != NULL; ind++) {
+ fildes = Test_cases[ind].fd;
+ test_desc = Test_cases[ind].desc;
+ whence = Test_cases[ind].Whence;
+
+ /* Assign the 'fd' values appropriatly */
+ if (fildes == 1) {
+ fildes = fd1;
+ } else if (fildes == 2) {
+ fildes = fd2;
+ } else {
+ fildes = fd3;
+ }
+ /*
+ * Invoke lseek(2) to test different test conditions.
+ * Verify that it fails with -1 return value and
+ * sets appropriate errno.
+ */
+ TEST(lseek(fildes, 0, whence));
+
+ /* check return code of lseek(2) */
+ if (TEST_RETURN != (off_t)-1) {
+ tst_resm(TFAIL, "lseek() returned %d, expected "
+ "-1, errno:%d", TEST_RETURN,
+ Test_cases[ind].exp_errno);
+ continue;
+ }
+ TEST_ERROR_LOG(TEST_ERRNO);
+ if (TEST_ERRNO == Test_cases[ind].exp_errno) {
+ tst_resm(TPASS, "lseek() fails, %s, errno:%d",
+ test_desc, TEST_ERRNO);
+ } else {
+ tst_resm(TFAIL, "lseek() fails, %s, errno:%d, "
+ "expected errno:%d", test_desc,
+ TEST_ERRNO, Test_cases[ind].exp_errno);
+ }
+ }
+ }
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ * Invoke individual test setup functions according to the order
+ * set in test struct. definition.
+ */
+void
+setup()
+{
+ int ind; /* counter for test setup function */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* call individual setup functions */
+ for (ind = 0; Test_cases[ind].desc != NULL; ind++) {
+ Test_cases[ind].setupfunc();
+ }
+}
+
+/*
+ * no_setup() - This is a dummy function which simply returns 0.
+ */
+int
+no_setup()
+{
+ return 0;
+}
+
+/*
+ * setup1() - setup function for a test condition for which lseek(2)
+ * returns -1 and sets errno to ESPIPE.
+ * Creat a named pipe/fifo using mknod() and open it for
+ * reading/writing.
+ * This function returns 0 on success.
+ */
+int
+setup1()
+{
+ /* Creat a named pipe/fifo using mknod() */
+ if (mknod(TEMP_FILE1, PIPE_MODE, 0) < 0) {
+ tst_brkm(TBROK, cleanup,
+ "mknod(%s, %#o, 0) Failed, errno=%d :%s",
+ TEMP_FILE1, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Open the named pipe/fifo for reading/writing */
+ if ((fd1 = open(TEMP_FILE1, O_RDWR)) < 0) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR) Failed, errno=%d, :%s",
+ TEMP_FILE1, errno, strerror(errno));
+ }
+
+ return 0;
+}
+
+/*
+ * setup2() - setup function for a test condition for which lseek(2)
+ * returns -1 and sets errno to EINVAL.
+ * Creat a temporary file for reading/writing and write some data
+ * into it.
+ * This function returns 0 on success.
+ */
+int
+setup2()
+{
+ char write_buff[BUFSIZ]; /* buffer to hold data */
+
+ /* Get the data to be written to temporary file */
+ strcpy(write_buff, "abcdefg");
+
+ /* Creat/open a temporary file under above directory */
+ if ((fd2 = open(TEMP_FILE2, O_RDWR | O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s",
+ TEMP_FILE2, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Write data into temporary file */
+ if(write(fd2, write_buff, sizeof(write_buff)) <= 0) {
+ tst_brkm(TBROK, cleanup,
+ "write(2) on %s Failed, errno=%d : %s",
+ TEMP_FILE2, errno, strerror(errno));
+ }
+
+ return 0;
+}
+
+/*
+ * setup3() - setup function for a test condition for which lseek(2)
+ * returns -1 and sets errno to EBADF.
+ * Creat a temporary file for reading/writing and close it.
+ * This function returns 0 on success.
+ */
+int
+setup3()
+{
+ /* Creat/open a temporary file under above directory */
+ if ((fd3 = open(TEMP_FILE3, O_RDWR | O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s",
+ TEMP_FILE3, FILE_MODE, errno, strerror(errno));
+ }
+
+ /* Close the temporary file created above */
+ if (close(fd3) < 0) {
+ tst_brkm(TBROK, cleanup,
+ "close(%s) Failed, errno=%d : %s:",
+ TEMP_FILE3, errno, strerror(errno));
+ }
+
+ return 0;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the test directory and testfile(s) created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Close the temporary file(s) created in setup1/setup2*/
+ if (close(fd1) < 0) {
+ tst_brkm(TFAIL, NULL,
+ "close(%s) Failed, errno=%d : %s:",
+ TEMP_FILE1, errno, strerror(errno));
+ }
+ if (close(fd2) < 0) {
+ tst_brkm(TFAIL, NULL,
+ "close(%s) Failed, errno=%d : %s:",
+ TEMP_FILE2, errno, strerror(errno));
+ }
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/mmap02.c b/winsup/testsuite/winsup.api/ltp/mmap02.c
new file mode 100644
index 000000000..35e944d74
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/mmap02.c
@@ -0,0 +1,294 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: mmap02
+ *
+ * Test Description:
+ * Call mmap() with prot parameter set to PROT_READ and with the file
+ * descriptor being open for read, to map a file creating mapped memory
+ * with read access. The minimum file permissions should be 0444.
+ *
+ * The call should succeed to create the mapped region with required
+ * attributes.
+ *
+ * Expected Result:
+ * mmap() should succeed returning the address of the mapped region,
+ * the mapped region should contain the contents of the mapped file.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Pause for SIGUSR1 if option specified.
+ * Create temporary directory.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * mmap02 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEMPFILE "mmapfile"
+
+char *TCID="mmap02"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+char *addr; /* addr of memory mapped region */
+char *dummy; /* dummy string */
+size_t page_sz; /* system page size */
+int fildes = -1; /* file descriptor for temporary file */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Call mmap to map the temporary file 'TEMPFILE'
+ * with read access.
+ */
+ TEST(mmap(0, page_sz, PROT_READ,
+ MAP_FILE|MAP_SHARED, fildes, 0));
+
+ /* Check for the return value of mmap() */
+ if (TEST_RETURN == (int)MAP_FAILED) {
+ tst_resm(TFAIL, "mmap() Failed on %s, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ continue;
+ }
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /* Get the mmap return value */
+ addr = (char *)TEST_RETURN;
+
+ /*
+ * Read the file contents into the dummy
+ * string.
+ */
+ if (read(fildes, dummy, page_sz) < 0) {
+ tst_brkm(TFAIL, cleanup, "read() on %s Failed, "
+ "error:%d", TEMPFILE, errno);
+ }
+
+ /*
+ * Check whether mapped memory region has
+ * the file contents.
+ */
+ if (memcmp(dummy, addr, page_sz)) {
+ tst_resm(TFAIL, "mapped memory area contains "
+ "invalid data");
+ } else {
+ tst_resm(TPASS,
+ "Functionality of mmap() successful");
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+
+ /* Clean up things in case we are looping */
+ /* Unmap the mapped memory */
+ if (munmap(addr, page_sz) != 0) {
+ tst_brkm(TFAIL, NULL, "munmap() fails to unmap the "
+ "memory, errno=%d", errno);
+ }
+
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ *
+ * Get system page size, allocate and initialize the string dummy.
+ * Initialize addr such that it is more than one page below the break
+ * address of the process, and initialize one page region from addr
+ * with char 'A'.
+ * Create a temporary directory a file under it.
+ * Write some known data into file and close it.
+ * Change mode permissions on file to 0444.
+ */
+void
+setup()
+{
+ char *tst_buff; /* test buffer to hold known data */
+
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Get the system page size */
+ if ((page_sz = getpagesize()) < 0) {
+ tst_brkm(TFAIL, NULL,
+ "getpagesize() fails to get system page size");
+ tst_exit();
+ }
+
+ /* Allocate space for the test buffer */
+ if ((tst_buff = (char *)calloc(page_sz, sizeof(char))) == NULL) {
+ tst_brkm(TFAIL, NULL,
+ "calloc() failed to allocate space for tst_buff");
+ tst_exit();
+ }
+
+ /* Fill the test buffer with the known data */
+ memset(tst_buff, 'A', page_sz);
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Creat a temporary file used for mapping */
+ if ((fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0) {
+ tst_brkm(TFAIL, NULL, "open() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ free(tst_buff);
+ cleanup();
+ }
+
+ /* Write test buffer contents into temporary file */
+ if (write(fildes, tst_buff, sizeof(tst_buff)) < sizeof(tst_buff)) {
+ tst_brkm(TFAIL, NULL, "write() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ free(tst_buff);
+ cleanup();
+ }
+
+ /* Free the memory allocated for test buffer */
+ free(tst_buff);
+
+ /* Close the temporary file */
+ if (close(fildes) < 0) {
+ tst_brkm(TFAIL, cleanup, "close() Failed on %s, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ }
+
+ /* Change Mode permissions on Temporary file */
+ if (chmod(TEMPFILE, 0444) < 0) {
+ tst_brkm(TFAIL, cleanup, "chmod(%s, 0444) Failed, errno=%d : "
+ "%s", TEMPFILE, errno, strerror(errno));
+ }
+
+ /* Open the temporary file again, - Readonly mode */
+ if ((fildes = open(TEMPFILE, O_RDONLY)) < 0) {
+ tst_brkm(TFAIL, cleanup, "open(%s, O_RDONLY) Failed, errno=%d "
+ ": %s", TEMPFILE, errno, strerror(errno));
+ }
+
+
+ /* Allocate and initialize dummy string of system page size bytes */
+ if ((dummy = (char *)calloc(page_sz, sizeof(char))) == NULL) {
+ tst_brkm(TFAIL, NULL, "calloc() failed to allocate space");
+ tst_exit();
+ }
+
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Free the memory allocated to dummy variable.
+ * Remove the temporary directory created.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Free the memory allocated for dummy string */
+ if (dummy) {
+ free(dummy);
+ }
+
+ if (fildes >= 0)
+ close (fildes);
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/mmap03.c b/winsup/testsuite/winsup.api/ltp/mmap03.c
new file mode 100644
index 000000000..6c66a4c45
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/mmap03.c
@@ -0,0 +1,294 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: mmap03
+ *
+ * Test Description:
+ * Call mmap() to map a file creating a mapped region with execute access
+ * under the following conditions -
+ * - The prot parameter is set to PROT_EXE
+ * - The file descriptor is open for read
+ * - The file being mapped has execute permission bit set.
+ * - The minimum file permissions should be 0555.
+ *
+ * The call should succeed to map the file creating mapped memory with the
+ * required attributes.
+ *
+ * Expected Result:
+ * mmap() should succeed returning the address of the mapped region,
+ * and the mapped region should contain the contents of the mapped file.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Pause for SIGUSR1 if option specified.
+ * Create temporary directory.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * mmap03 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEMPFILE "mmapfile"
+
+char *TCID="mmap03"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+size_t page_sz; /* system page size */
+char *addr; /* addr of memory mapped region */
+char *dummy; /* dummy variable to hold temp file contents */
+int fildes = -1; /* file descriptor for temporary file */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ char file_content; /* tempfile content */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Call mmap to map the temporary file 'TEMPFILE'
+ * with execute access.
+ */
+ TEST(mmap(0, page_sz, PROT_EXEC,
+ MAP_FILE|MAP_SHARED, fildes, 0));
+
+ /* Check for the return value of mmap() */
+ if (TEST_RETURN == (int)MAP_FAILED) {
+ tst_resm(TFAIL, "mmap() Failed on %s, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ continue;
+ }
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /* Get the mmap return value */
+ addr = (char *)TEST_RETURN;
+
+ /*
+ * Read the file contents into the dummy
+ * variable.
+ */
+ if (read(fildes, dummy, page_sz) < 0) {
+ tst_brkm(TFAIL, cleanup, "read() on %s Failed, "
+ "error:%d", TEMPFILE, errno);
+ }
+
+ /*
+ * Check whether the mapped memory region
+ * has the file contents.
+ */
+ if (memcmp(dummy, addr, page_sz)) {
+ tst_resm(TFAIL, "mapped memory region contains "
+ "invalid data");
+ } else {
+ tst_resm(TPASS,
+ "Functionality of mmap() successful");
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+
+ /* Clean up things in case we are looping */
+ /* Unmap the mapped memory */
+ if (munmap(addr, page_sz) != 0) {
+ tst_brkm(TFAIL, NULL, "munmap() fails to unmap the "
+ "memory, errno=%d", errno);
+ }
+
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Get the system page size.
+ * Create a temporary directory and a file under it.
+ * Write some known data into file and close it.
+ * Change the mode permissions on file to 0555.
+ * Re-open the file for reading.
+ */
+void
+setup()
+{
+ char *tst_buff; /* test buffer to hold known data */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Get the system page size */
+ if ((page_sz = getpagesize()) < 0) {
+ tst_brkm(TFAIL, NULL,
+ "getpagesize() fails to get system page size");
+ tst_exit();
+ }
+
+ /* Allocate space for the test buffer */
+ if ((tst_buff = (char *)calloc(page_sz, sizeof(char))) == NULL) {
+ tst_brkm(TFAIL, NULL,
+ "calloc() failed to allocate space for tst_buff");
+ tst_exit();
+ }
+
+ /* Fill the test buffer with the known data */
+ memset(tst_buff, 'A', page_sz);
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Creat a temporary file used for mapping */
+ if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) {
+ tst_brkm(TFAIL, NULL, "open() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ free(tst_buff);
+ cleanup();
+ }
+
+ /* Write test buffer contents into temporary file */
+ if (write(fildes, tst_buff, strlen(tst_buff)) < strlen(tst_buff)) {
+ tst_brkm(TFAIL, NULL, "write() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ free(tst_buff);
+ cleanup();
+ }
+
+ /* Free the memory allocated for test buffer */
+ free(tst_buff);
+
+ /* Make sure proper permissions set on file */
+ if (chmod(TEMPFILE, 0555) < 0) {
+ tst_brkm(TFAIL, cleanup, "chmod() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ }
+
+ /* Close the temporary file opened for write */
+ if (close(fildes) < 0) {
+ tst_brkm(TFAIL, cleanup, "close() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ }
+
+ /* Allocate and initialize dummy string of system page size bytes */
+ if ((dummy = (char *)calloc(page_sz, sizeof(char))) == NULL) {
+ tst_brkm(TFAIL, cleanup,
+ "calloc() failed to allocate memory for dummy");
+ }
+
+ /* Open the temporary file again for reading */
+ if ((fildes = open(TEMPFILE, O_RDONLY)) < 0) {
+ tst_brkm(TFAIL, cleanup, "open(%s) with read-only Failed, "
+ "errno:%d", TEMPFILE, errno);
+ }
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ Free the memory allocated to dummy variable.
+ * Remove the temporary directory created.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Free the memory space allocated for dummy variable */
+ if (dummy) {
+ free(dummy);
+ }
+
+ if (fildes >= 0)
+ close (fildes);
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/mmap04.c b/winsup/testsuite/winsup.api/ltp/mmap04.c
new file mode 100644
index 000000000..4f9018f92
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/mmap04.c
@@ -0,0 +1,295 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: mmap04
+ *
+ * Test Description:
+ * Call mmap() to map a file creating a mapped region with read/exec access
+ * under the following conditions -
+ * - The prot parameter is set to PROT_READ|PROT_EXEC
+ * - The file descriptor is open for read
+ * - The file being mapped has read and execute permission bit set.
+ * - The minimum file permissions should be 0555.
+ *
+ * The call should succeed to map the file creating mapped memory with the
+ * required attributes.
+ *
+ * Expected Result:
+ * mmap() should succeed returning the address of the mapped region,
+ * and the mapped region should contain the contents of the mapped file.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Pause for SIGUSR1 if option specified.
+ * Create temporary directory.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * mmap04 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEMPFILE "mmapfile"
+
+char *TCID="mmap04"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+size_t page_sz; /* system page size */
+char *addr; /* addr of memory mapped region */
+char *dummy; /* dummy variable to hold temp file contents */
+int fildes = -1; /* file descriptor for temporary file */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ char file_content; /* tempfile content */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Call mmap to map the temporary file 'TEMPFILE'
+ * with read and execute access.
+ */
+ TEST(mmap(0, page_sz, PROT_READ|PROT_EXEC,
+ MAP_FILE|MAP_SHARED, fildes, 0));
+
+ /* Check for the return value of mmap() */
+ if (TEST_RETURN == (int)MAP_FAILED) {
+ tst_resm(TFAIL, "mmap() Failed on %s, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ continue;
+ }
+
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /* Get the mmap return value */
+ addr = (char *)TEST_RETURN;
+
+ /*
+ * Read the file contents into the dummy
+ * variable.
+ */
+ if (read(fildes, dummy, page_sz) < 0) {
+ tst_brkm(TFAIL, cleanup, "read() on %s Failed, "
+ "error:%d", TEMPFILE, errno);
+ }
+
+ /*
+ * Check whether the mapped memory region
+ * has the file contents.
+ */
+ if (memcmp(dummy, addr, page_sz)) {
+ tst_resm(TFAIL, "mapped memory region contains "
+ "invalid data");
+ } else {
+ tst_resm(TPASS,
+ "Functionality of mmap() successful");
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ /* Clean up things in case we are looping. */
+ /* Unmap the mapped memory */
+ if (munmap(addr, page_sz) != 0) {
+ tst_brkm(TFAIL, NULL, "munmap() fails to unmap the "
+ "memory, errno=%d", errno);
+ }
+
+
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Get the system page size.
+ * Create a temporary directory and a file under it.
+ * Write some known data into file and close it.
+ * Change the mode permissions on file to 0555.
+ * Re-open the file for reading.
+ */
+void
+setup()
+{
+ char *tst_buff; /* test buffer to hold known data */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Get the system page size */
+ if ((page_sz = getpagesize()) < 0) {
+ tst_brkm(TFAIL, NULL,
+ "getpagesize() fails to get system page size");
+ tst_exit();
+ }
+
+ if ((tst_buff = (char *)calloc(page_sz, sizeof(char))) == NULL) {
+ tst_brkm(TFAIL, NULL,
+ "calloc() failed to allocate space for tst_buff");
+ tst_exit();
+ }
+
+ /* Fill the test buffer with the known data */
+ memset(tst_buff, 'A', page_sz);
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Creat a temporary file used for mapping */
+ if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) {
+ tst_brkm(TFAIL, NULL, "open() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ free(tst_buff);
+ cleanup();
+ }
+
+ /* Write test buffer contents into temporary file */
+ if (write(fildes, tst_buff, strlen(tst_buff)) < strlen(tst_buff)) {
+ tst_brkm(TFAIL, NULL, "write() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ free(tst_buff);
+ cleanup();
+ }
+
+ /* Free the memory allocated for test buffer */
+ free(tst_buff);
+
+ /* Make sure proper permissions set on file */
+ if (chmod(TEMPFILE, 0555) < 0) {
+ tst_brkm(TFAIL, cleanup, "chmod() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ }
+
+ /* Close the temporary file opened for write */
+ if (close(fildes) < 0) {
+ tst_brkm(TFAIL, cleanup, "close() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ }
+
+ /* Allocate and initialize dummy string of system page size bytes */
+ if ((dummy = (char *)calloc(page_sz, sizeof(char))) == NULL) {
+ tst_brkm(TFAIL, cleanup,
+ "calloc() failed to allocate memory for dummy");
+ }
+
+ /* Open the temporary file again for reading */
+ if ((fildes = open(TEMPFILE, O_RDONLY)) < 0) {
+ tst_brkm(TFAIL, cleanup, "open(%s) with read-only Failed, "
+ "errno:%d", TEMPFILE, errno);
+ }
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Free the memeory allocated to dummy variable.
+ * Remove the temporary directory created.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Free the memory space allocated for dummy variable */
+ if (dummy) {
+ free(dummy);
+ }
+
+ if (fildes >= 0)
+ close (fildes);
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/mmap05.c b/winsup/testsuite/winsup.api/ltp/mmap05.c
new file mode 100644
index 000000000..e8186899f
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/mmap05.c
@@ -0,0 +1,303 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: mmap05
+ *
+ * Test Description:
+ * Call mmap() to map a file creating mapped memory with no access under
+ * the following conditions -
+ * - The prot parameter is set to PROT_NONE
+ * - The file descriptor is open for read(any mode other than write)
+ * - The minimum file permissions should be 0444.
+ *
+ * The call should succeed to map the file creating mapped memory with the
+ * required attributes.
+ *
+ * Expected Result:
+ * mmap() should succeed returning the address of the mapped region,
+ * and an attempt to access the contents of the mapped region should give
+ * rise to the signal SIGSEGV.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Pause for SIGUSR1 if option specified.
+ * Create temporary directory.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * mmap05 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <setjmp.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEMPFILE "mmapfile"
+
+char *TCID="mmap05"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+size_t page_sz; /* system page size */
+char *addr; /* addr of memory mapped region */
+int fildes = -1; /* file descriptor for temporary file */
+int pass=0; /* pass flag perhaps set to 1 in sig_handler */
+sigjmp_buf env; /* environment for sigsetjmp/siglongjmp */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+void sig_handler(); /* signal handler to catch SIGSEGV */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ char file_content; /* tempfile content */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Call mmap to map the temporary file 'TEMPFILE'
+ * with no access.
+ */
+
+ TEST(mmap(0, page_sz, PROT_NONE,
+ MAP_FILE|MAP_SHARED, fildes, 0));
+
+ /* Check for the return value of mmap() */
+ if (TEST_RETURN == (int)MAP_FAILED) {
+ tst_resm(TFAIL, "mmap() Failed on %s, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ continue;
+ }
+
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+
+ /*
+ * Try to access the mapped region. This should
+ * generate a SIGSEGV which will be caught below.
+ *
+ * This is wrapped by the sigsetjmp() call that will
+ * take care of restoring the program's context in an
+ * elegant way in conjunction with the call to
+ * siglongjmp() in the signal handler.
+ */
+ if (sigsetjmp(env, 1) == 0) {
+ file_content = addr[0];
+ }
+
+ if (pass) {
+ tst_resm(TPASS, "Got SIGSEGV as expected");
+ } else {
+ tst_resm(TFAIL, "Mapped memory region with NO "
+ "access is accessible");
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+
+ /* Unmap mapped memory and reset pass in case we are looping */
+ if (munmap(addr, page_sz) != 0) {
+ tst_brkm(TFAIL, cleanup, "munmap() fails to unmap the "
+ "memory, errno=%d", errno);
+ }
+ pass = 0;
+
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Get the system page size.
+ * Create a temporary directory and a file under it.
+ * Write some known data into file and close it.
+ * Change the mode permissions on file to 0444
+ * Re-open the file for reading.
+ */
+void
+setup()
+{
+ char *tst_buff; /* test buffer to hold known data */
+
+ /* capture signals */
+ tst_sig(NOFORK, sig_handler, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Get the system page size */
+ if ((page_sz = getpagesize()) < 0) {
+ tst_brkm(TFAIL, NULL,
+ "getpagesize() fails to get system page size");
+ tst_exit();
+ }
+
+ /* Allocate space for the test buffer */
+ if ((tst_buff = (char *)calloc(page_sz, sizeof(char))) == NULL) {
+ tst_brkm(TFAIL, NULL,
+ "calloc() failed to allocate space for tst_buff");
+ tst_exit();
+ }
+
+ /* Fill the test buffer with the known data */
+ memset(tst_buff, 'A', page_sz);
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Creat a temporary file used for mapping */
+ if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) {
+ tst_brkm(TFAIL, NULL, "open() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ free(tst_buff);
+ cleanup();
+ }
+
+ /* Write test buffer contents into temporary file */
+ if (write(fildes, tst_buff, strlen(tst_buff)) != strlen(tst_buff)) {
+ tst_brkm(TFAIL, NULL, "write() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ free(tst_buff);
+ cleanup();
+ }
+
+ /* Free the memory allocated for test buffer */
+ free(tst_buff);
+
+ /* Close the temporary file opened for write */
+ if (close(fildes) < 0) {
+ tst_brkm(TFAIL, cleanup, "close() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ }
+
+ /* Make sure proper permissions set on file */
+ if (chmod(TEMPFILE, 0444) < 0) {
+ tst_brkm(TFAIL, cleanup, "chmod() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ }
+
+ /* Open the temporary file again for reading */
+ if ((fildes = open(TEMPFILE, O_RDONLY)) < 0) {
+ tst_brkm(TFAIL, cleanup, "open(%s) with read-only Failed, "
+ "errno:%d", TEMPFILE, errno);
+ }
+}
+
+/*
+ * sig_handler() - Signal Cathing function.
+ * This function gets executed when the test process receives
+ * the signal SIGSEGV while trying to access the contents of memory which
+ * is not accessible.
+ */
+void
+sig_handler(sig)
+{
+ if (sig == SIGSEGV) {
+ /* set the global variable and jump back */
+ pass = 1;
+ siglongjmp(env, 1);
+ } else {
+ tst_brkm(TBROK, cleanup, "received an unexpected signal");
+ }
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the temporary directory created.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ if (fildes >= 0)
+ close (fildes);
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/mmap06.c b/winsup/testsuite/winsup.api/ltp/mmap06.c
new file mode 100644
index 000000000..bc3f20eb1
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/mmap06.c
@@ -0,0 +1,237 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: mmap06
+ *
+ * Test Description:
+ * Call mmap() to map a file creating a mapped region with read access
+ * under the following conditions -
+ * - The prot parameter is set to PROT_READ
+ * - The file descriptor is open for writing.
+ *
+ * The call should fail to map the file.
+ *
+ * Expected Result:
+ * mmap() should fail returning -1 and errno should get set to EACCES.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Pause for SIGUSR1 if option specified.
+ * Create temporary directory.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * if errno set == expected errno
+ * Issue sys call fails with expected return value and errno.
+ * Otherwise,
+ * Issue sys call fails with unexpected errno.
+ * Otherwise,
+ * Issue sys call returns unexpected value.
+ *
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory(s)/file(s) created.
+ *
+ * Usage: <for command-line>
+ * mmap06 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEMPFILE "mmapfile"
+
+char *TCID="mmap06"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={EACCES, 0};
+
+size_t page_sz; /* system page size */
+char *addr; /* addr of memory mapped region */
+int fildes = -1; /* file descriptor for temporary file */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Call mmap to map the temporary file 'TEMPFILE'
+ * with read access.
+ */
+ TEST(mmap(0, page_sz, PROT_READ,
+ MAP_FILE|MAP_SHARED, fildes, 0));
+
+ /* Check for the return value of mmap() */
+ if (TEST_RETURN != (int)MAP_FAILED) {
+ tst_resm(TFAIL, "mmap() returned invalid value, "
+ "expected: -1");
+ /* Unmap the mapped memory */
+ if (munmap(addr, page_sz) != 0) {
+ tst_brkm(TBROK, cleanup, "munmap() failed");
+ }
+ continue;
+ }
+ TEST_ERROR_LOG(TEST_ERRNO);
+ if (TEST_ERRNO == EACCES) {
+ tst_resm(TPASS, "mmap() fails, 'fd' doesn't allow "
+ "desired access, errno:%d", errno);
+ } else {
+ tst_resm(TFAIL, "mmap() fails, 'fd' doesn't allow "
+ "desired access, invalid errno:%d", errno);
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Get the system page size.
+ * Create a temporary directory and a file under it.
+ * Write some known data into file.
+ */
+void
+setup()
+{
+ char *tst_buff; /* test buffer to hold known data */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Get the system page size */
+ if ((page_sz = getpagesize()) < 0) {
+ tst_brkm(TFAIL, NULL,
+ "getpagesize() fails to get system page size");
+ tst_exit();
+ }
+
+ /* Allocate space for the test buffer */
+ if ((tst_buff = (char *)calloc(page_sz, sizeof(char))) == NULL) {
+ tst_brkm(TFAIL, NULL,
+ "calloc() failed to allocate space for tst_buff");
+ tst_exit();
+ }
+
+ /* Fill the test buffer with the known data */
+ memset(tst_buff, 'A', page_sz);
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Creat a temporary file used for mapping */
+ if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) {
+ tst_brkm(TFAIL, NULL,
+ "open() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ free(tst_buff);
+ cleanup();
+ }
+
+ /* Write test buffer contents into temporary file */
+ if (write(fildes, tst_buff, strlen(tst_buff)) < strlen(tst_buff)) {
+ tst_brkm(TFAIL, NULL,
+ "write() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ free(tst_buff);
+ cleanup();
+ }
+
+ /* Free the memory allocated for test buffer */
+ free(tst_buff);
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the temporary directory created.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ if (fildes >= 0)
+ close (fildes);
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/mmap07.c b/winsup/testsuite/winsup.api/ltp/mmap07.c
new file mode 100644
index 000000000..3d1f4341d
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/mmap07.c
@@ -0,0 +1,236 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: mmap07
+ *
+ * Test Description:
+ * Call mmap() to map a file creating a mapped region with read access
+ * under the following conditions -
+ * - The prot parameter is set to PROT_WRITE
+ * - The file descriptor is open for writing.
+ * - The flags parameter has MAP_PRIVATE set.
+ *
+ * The call should fail to map the file.
+ *
+ * Expected Result:
+ * mmap() should fail returning -1 and errno should get set to EACCES.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Pause for SIGUSR1 if option specified.
+ * Create temporary directory.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * if errno set == expected errno
+ * Issue sys call fails with expected return value and errno.
+ * Otherwise,
+ * Issue sys call fails with unexpected errno.
+ * Otherwise,
+ * Issue sys call returns unexpected value.
+ *
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory(s)/file(s) created.
+ *
+ * Usage: <for command-line>
+ * mmap07 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEMPFILE "mmapfile"
+
+char *TCID="mmap07"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={EACCES, 0};
+
+size_t page_sz; /* system page size */
+char *addr; /* addr of memory mapped region */
+int fildes = -1; /* file descriptor for temporary file */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Call mmap to map the temporary file 'TEMPFILE'
+ * with write access.
+ */
+ TEST(mmap(0, page_sz, PROT_WRITE,
+ MAP_FILE|MAP_PRIVATE, fildes, 0));
+
+ /* Check for the return value of mmap() */
+ if (TEST_RETURN != (int)MAP_FAILED) {
+ tst_resm(TFAIL, "mmap() returned invalid value, "
+ "expected: -1");
+ /* Unmap the mapped memory */
+ if (munmap(addr, page_sz) != 0) {
+ tst_brkm(TBROK, cleanup, "munmap() failed");
+ }
+ continue;
+ }
+ TEST_ERROR_LOG(TEST_ERRNO);
+ if (TEST_ERRNO == EACCES) {
+ tst_resm(TPASS, "mmap() fails, 'fd' doesn't allow "
+ "desired access, errno:%d", errno);
+ } else {
+ tst_resm(TFAIL, "mmap() fails, 'fd' doesn't allow "
+ "desired access, invalid errno:%d", errno);
+ }
+
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Get the system page size.
+ * Create a temporary directory and a file under it.
+ * Write some known data into file.
+ */
+void
+setup()
+{
+ char *tst_buff; /* test buffer to hold known data */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Get the system page size */
+ if ((page_sz = getpagesize()) < 0) {
+ tst_brkm(TFAIL, NULL,
+ "getpagesize() fails to get system page size");
+ tst_exit();
+ }
+
+ /* Allocate space for the test buffer */
+ if ((tst_buff = (char *)calloc(page_sz, sizeof(char))) == NULL) {
+ tst_brkm(TFAIL, NULL,
+ "calloc() failed to allocate space for tst_buff");
+ tst_exit();
+ }
+
+ /* Fill the test buffer with the known data */
+ memset(tst_buff, 'A', page_sz);
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Creat a temporary file used for mapping */
+ if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) {
+ tst_brkm(TFAIL, NULL, "open() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ free(tst_buff);
+ cleanup();
+ }
+
+ /* Write test buffer contents into temporary file */
+ if (write(fildes, tst_buff, strlen(tst_buff)) < strlen(tst_buff)) {
+ tst_brkm(TFAIL, NULL, "write() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ free(tst_buff);
+ cleanup();
+ }
+
+ /* Free the memory allocated for test buffer */
+ free(tst_buff);
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the temporary directory created.
+ */
+void
+cleanup()
+{
+ /*
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ if (fildes >= 0)
+ close (fildes);
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/mmap08.c b/winsup/testsuite/winsup.api/ltp/mmap08.c
new file mode 100644
index 000000000..8b2c05091
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/mmap08.c
@@ -0,0 +1,236 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: mmap08
+ *
+ * Test Description:
+ * Verify that mmap() fails to map a file creating a mapped region
+ * when the file specified by file descriptor is not valid.
+ *
+ * Expected Result:
+ * mmap() should fail returning -1 and errno should get set to EBADF.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Pause for SIGUSR1 if option specified.
+ * Create temporary directory.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * if errno set == expected errno
+ * Issue sys call fails with expected return value and errno.
+ * Otherwise,
+ * Issue sys call fails with unexpected errno.
+ * Otherwise,
+ * Issue sys call returns unexpected value.
+ *
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory(s)/file(s) created.
+ *
+ * Usage: <for command-line>
+ * mmap08 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEMPFILE "mmapfile"
+
+char *TCID="mmap08"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={EBADF, 0};
+
+size_t page_sz; /* system page size */
+char *addr; /* addr of memory mapped region */
+int fildes = -1; /* file descriptor for temporary file */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Call mmap to map the temporary file 'TEMPFILE'
+ * which is already closed. so, fildes is not valid.
+ */
+ TEST(mmap(0, page_sz, PROT_WRITE,
+ MAP_FILE|MAP_SHARED, fildes, 0));
+
+ /* Check for the return value of mmap() */
+ if (TEST_RETURN != (int)MAP_FAILED) {
+ tst_resm(TFAIL, "mmap() returned invalid value, "
+ "expected: -1");
+ /* Unmap the mapped memory */
+ if (munmap(addr, page_sz) != 0) {
+ tst_brkm(TBROK, cleanup, "munmap() failed");
+ }
+ continue;
+ }
+ TEST_ERROR_LOG(TEST_ERRNO);
+ if (TEST_ERRNO == EBADF) {
+ tst_resm(TPASS, "mmap() fails, 'fd' is not valid, "
+ "errno:%d", errno);
+ } else {
+ tst_resm(TFAIL, "mmap() fails, 'fd' is not valid, "
+ "invalid errno:%d", errno);
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Get the system page size.
+ * Create a temporary directory and a file under it.
+ * Write some known data into file and close it.
+ */
+void
+setup()
+{
+ char *tst_buff; /* test buffer to hold known data */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Get the system page size */
+ if ((page_sz = getpagesize()) < 0) {
+ tst_brkm(TFAIL, NULL,
+ "getpagesize() fails to get system page size");
+ tst_exit();
+ }
+
+ if ((tst_buff = (char *)calloc(page_sz, sizeof(char))) == NULL) {
+ tst_brkm(TFAIL, NULL,
+ "calloc() failed to allocate space for tst_buff");
+ tst_exit();
+ }
+
+ /* Fill the test buffer with the known data */
+ memset(tst_buff, 'A', page_sz);
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Creat a temporary file used for mapping */
+ if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) {
+ tst_brkm(TFAIL, NULL, "open() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ free(tst_buff);
+ cleanup();
+ }
+
+ /* Write test buffer contents into temporary file */
+ if (write(fildes, tst_buff, strlen(tst_buff)) != strlen(tst_buff)) {
+ tst_brkm(TFAIL, NULL, "write() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ free(tst_buff);
+ cleanup();
+ }
+
+ /* Free the memory allocated for test buffer */
+ free(tst_buff);
+
+ /* Close the temporary file opened for writing */
+ if (close(fildes) < 0) {
+ tst_brkm(TFAIL, cleanup, "close() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ }
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the temporary directory created.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ if (fildes >= 0)
+ close (fildes);
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/munmap01.c b/winsup/testsuite/winsup.api/ltp/munmap01.c
new file mode 100644
index 000000000..5de98b6ff
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/munmap01.c
@@ -0,0 +1,282 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: munmap01
+ *
+ * Test Description:
+ * Verify that, munmap call will succeed to unmap a mapped file or
+ * anonymous shared memory region from the calling process's address space
+ * and after successful completion of munmap, the unmapped region is no
+ * longer accessible.
+ *
+ * Expected Result:
+ * munmap call should succeed to unmap a mapped file or anonymous shared
+ * memory region from the process's address space and it returns with a
+ * value 0, further reference to the unmapped region should result in a
+ * segmentation fault (SIGSEGV).
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * munmap01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEMPFILE "mmapfile"
+
+char *TCID="munmap01"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+
+char *addr; /* addr of memory mapped region */
+int fildes; /* file descriptor for tempfile */
+unsigned int map_len; /* length of the region to be mapped */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+void sig_handler(); /* signal catching function */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *)NULL, NULL);
+ if (msg != (char *)NULL) {
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /* Perform global setup for test */
+ setup();
+
+ /*
+ * Call munmap to unmap the mapped region of the
+ * temporary file from the calling process's address space.
+ */
+ TEST(munmap(addr, map_len));
+
+ /* Check for the return value of munmap() */
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "munmap() fails, errno=%d : %s",
+ TEST_ERRNO, strerror(TEST_ERRNO));
+ continue;
+ }
+
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Check whether further reference is possible
+ * to the unmapped memory region by writing
+ * to the first byte of region with
+ * some arbitrary number.
+ */
+ *addr = 50;
+
+ /* This message is printed if no SIGSEGV */
+ tst_resm(TFAIL, "process succeeds to refer unmapped "
+ "memory region");
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ } /* End for TEST_LOOPING */
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ *
+ * Set up signal handler to catch SIGSEGV.
+ * Get system page size, create a temporary file for reading/writing,
+ * write one byte data into it, map the open file for the specified
+ * map length.
+ */
+void
+setup()
+{
+ size_t page_sz; /* system page size */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* call signal function to trap the signal generated */
+ if (signal(SIGSEGV, sig_handler) == SIG_ERR) {
+ tst_brkm(TBROK, cleanup, "signal fails to catch signal");
+ tst_exit();
+ }
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Get the system page size */
+ if ((page_sz = getpagesize()) < 0) {
+ tst_brkm(TBROK, cleanup,
+ "getpagesize() fails to get system page size");
+ tst_exit();
+ }
+
+ /*
+ * Get the length of the open file to be mapped into process
+ * address space.
+ */
+ map_len = 3 * page_sz;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Creat a temporary file used for mapping */
+ if ((fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0) {
+ tst_brkm(TBROK, cleanup, "open() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ tst_exit();
+ }
+
+ /*
+ * move the file pointer to maplength position from the beginning
+ * of the file.
+ */
+ if (lseek(fildes, map_len, SEEK_SET) == -1) {
+ tst_brkm(TBROK, cleanup, "lseek() fails on %s, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ tst_exit();
+ }
+
+ /* Write one byte into temporary file */
+ if (write(fildes, "a", 1) != 1) {
+ tst_brkm(TBROK, cleanup, "write() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ tst_exit();
+ }
+
+ /*
+ * map the open file 'TEMPFILE' from its beginning up to the maplength
+ * into the calling process's address space at the system choosen
+ * with read/write permissions to the the mapped region.
+ */
+ addr = mmap(0, map_len, PROT_READ | PROT_WRITE, \
+ MAP_FILE | MAP_SHARED, fildes, 0);
+
+ /* check for the return value of mmap system call */
+ if (addr == (char *)MAP_FAILED) {
+ tst_brkm(TBROK, cleanup, "mmap() Failed on %s, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ tst_exit();
+ }
+}
+
+/*
+ * sig_handler() - signal catching function.
+ * This function is used to trap the signal generated when tried to read or
+ * write to the memory mapped region which is already detached from the
+ * calling process address space.
+ * this function is invoked when SIGSEGV generated and it calls test
+ * cleanup function and exit the program.
+ */
+void
+sig_handler()
+{
+ tst_resm(TPASS, "Functionality of munmap() successful");
+
+ /* Invoke test cleanup function and exit */
+ cleanup();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Close the temporary file.
+ * Remove the temporary directory.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Close the temporary file */
+ if (close(fildes) < 0) {
+ tst_brkm(TFAIL, NULL, "close() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ }
+
+ /* Remove the temporary directory and all files in it */
+ tst_rmdir();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/munmap02.c b/winsup/testsuite/winsup.api/ltp/munmap02.c
new file mode 100644
index 000000000..deadcc2f6
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/munmap02.c
@@ -0,0 +1,307 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: munmap02
+ *
+ * Test Description:
+ * Verify that, munmap call will succeed to unmap a mapped file or
+ * anonymous shared memory region from the calling process's address space
+ * if the region specified by the address and the length is part or all of
+ * the mapped region.
+ *
+ * Expected Result:
+ * munmap call should succeed to unmap a part or all of mapped region of a
+ * file or anonymous shared memory from the process's address space and it
+ * returns with a value 0,
+ * further reference to the unmapped region should result in a segmentation
+ * fault (SIGSEGV).
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * munmap01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEMPFILE "mmapfile"
+
+char *TCID="munmap02"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+
+size_t page_sz; /* system page size */
+char *addr; /* addr of memory mapped region */
+int fildes; /* file descriptor for tempfile */
+unsigned int map_len; /* length of the region to be mapped */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+void sig_handler(); /* signal catching function */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *)NULL, NULL);
+ if (msg != (char *)NULL) {
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /* Perform global setup for test */
+ setup();
+
+ /*
+ * Call munmap to unmap the part of the mapped region of the
+ * temporary file from the address and length that is part of
+ * the mapped region.
+ */
+ TEST(munmap(addr, map_len));
+
+ /* Check for the return value of munmap() */
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "munmap() fails, errno=%d : %s",
+ TEST_ERRNO, strerror(TEST_ERRNO));
+ continue;
+ }
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Check whether further reference is possible
+ * to the unmapped memory region by writing
+ * to the first byte of region with
+ * some arbitrary number.
+ */
+ *addr = 50;
+
+ /* This message is printed if no SIGSEGV */
+ tst_resm(TFAIL, "process succeeds to refer unmapped "
+ "memory region");
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ } /* End for TEST_LOOPING */
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Setup signal handler to catch SIGSEGV.
+ * Get system page size, create a temporary file for reading/writing,
+ * write one byte data into it, map the open file for the specified
+ * map length.
+ */
+void
+setup()
+{
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* call signal function to trap the signal generated */
+ if (signal(SIGSEGV, sig_handler) == SIG_ERR) {
+ tst_brkm(TBROK, cleanup, "signal fails to catch signal");
+ tst_exit();
+ }
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Get the system page size */
+ if ((page_sz = getpagesize()) < 0) {
+ tst_brkm(TBROK, cleanup,
+ "getpagesize() fails to get system page size");
+ tst_exit();
+ }
+
+ /*
+ * Get the length of the open file to be mapped into process
+ * address space.
+ */
+ map_len = 3 * page_sz;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Creat a temporary file used for mapping */
+ if ((fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0) {
+ tst_brkm(TBROK, cleanup, "open() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ tst_exit();
+ }
+
+ /*
+ * move the file pointer to maplength position from the beginning
+ * of the file.
+ */
+ if (lseek(fildes, map_len, SEEK_SET) == -1) {
+ tst_brkm(TBROK, cleanup, "lseek() fails on %s, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ tst_exit();
+ }
+
+ /* Write one byte into temporary file */
+ if (write(fildes, "a", 1) != 1) {
+ tst_brkm(TBROK, cleanup, "write() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ tst_exit();
+ }
+
+ /*
+ * map the open file 'TEMPFILE' from its beginning up to the maplength
+ * into the calling process's address space at the system choosen
+ * with read/write permissions to the the mapped region.
+ */
+ addr = mmap(0, map_len, PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_SHARED, fildes, 0);
+
+ /* check for the return value of mmap system call */
+ if (addr == (char *)MAP_FAILED) {
+ tst_brkm(TBROK, cleanup, "mmap() Failed on %s, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ tst_exit();
+ }
+
+ /*
+ * increment the start address of the region at which the file is
+ * mapped to a maplength of 3 times the system page size by the value
+ * of system page size and decrement the maplength value by the value
+ * of system page size.
+ */
+ addr = (char *)((long)addr + page_sz);
+ map_len = map_len - page_sz;
+}
+
+/*
+ * void
+ * sig_handler() - signal catching function.
+ * This function is used to trap the signal generated when tried to read or
+ * write to the memory mapped region which is already detached from the
+ * calling process address space.
+ * this function is invoked when SIGSEGV generated and it calls test
+ * cleanup function and exit the program.
+ */
+void
+sig_handler()
+{
+ tst_resm(TPASS, "Functionality of munmap() successful");
+
+ /* Invoke test cleanup function and exit */
+ cleanup();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Unmap the portion of the region of the file left unmapped.
+ * Close the temporary file.
+ * Remove the temporary directory.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /*
+ * get the start address and length of the portion of
+ * the mapped region of the file.
+ */
+ addr = (char *)((long)addr - page_sz);
+ map_len = map_len - page_sz;
+
+ /* unmap the portion of the region of the file left unmapped */
+ if (munmap(addr, map_len) < 0) {
+ tst_brkm(TBROK, NULL,
+ "munmap() fails to unmap portion of mapped region");
+ }
+
+ /* Close the temporary file */
+ if (close(fildes) < 0) {
+ tst_brkm(TBROK, NULL, "close() on %s Failed, errno=%d : %s",
+ TEMPFILE, errno, strerror(errno));
+ }
+
+ /* Remove the temporary directory and all files in it */
+ tst_rmdir();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/open02.c b/winsup/testsuite/winsup.api/ltp/open02.c
new file mode 100644
index 000000000..84640ce97
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/open02.c
@@ -0,0 +1,150 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * open02.c
+ *
+ * DESCRIPTION
+ * Test if open without O_CREAT returns -1 if a file does not exist.
+ *
+ * ALGORITHM
+ * 1. open a new file without O_CREAT, test for return value of -1
+ *
+ * USAGE: <for command-line>
+ * open02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <sys/fcntl.h>
+#include <test.h>
+#include <usctest.h>
+
+char *TCID = "open02";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+char pfilname[40] = "";
+
+int exp_enos[] = {ENOENT, 0};
+
+void cleanup(void);
+void setup(void);
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ struct stat statbuf;
+ int fildes;
+ unsigned short filmode;
+
+ /*
+ * parse standard command line options
+ */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup(); /* global setup for test */
+
+ TEST_EXP_ENOS(exp_enos);
+
+ /*
+ * check looping state if -i option given on the command line
+ */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ Tst_count = 0; /* reset Tst_count while looping. */
+
+ TEST(open(pfilname, O_RDWR, 0444));
+
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "opened non-existent file");
+ continue;
+ }
+
+ TEST_ERROR_LOG(TEST_ERRNO);
+
+ if (TEST_ERRNO != ENOENT) {
+ tst_resm(TFAIL, "open(2) set invalid errno: "
+ "expected ENOENT, got %d", TEST_ERRNO);
+ } else {
+ tst_resm(TPASS, "open returned ENOENT");
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+ umask(0);
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that options was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ sprintf(pfilname, "./open3.%d", getpid());
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion or
+ * premature exit.
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/pipe01.c b/winsup/testsuite/winsup.api/ltp/pipe01.c
new file mode 100644
index 000000000..699515da3
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/pipe01.c
@@ -0,0 +1,157 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * pipe01.c
+ *
+ * DESCRIPTION
+ * Testcase to check the basic functionality of the pipe(2) syscall:
+ * Check that both ends of the pipe (both file descriptors) are
+ * available to a process opening the pipe.
+ *
+ * ALGORITHM
+ * Write a string of characters down a pipe; read the string from the
+ * other file descriptor. Test passes if both can be done, as reported
+ * by the number of characters written and read.
+ *
+ * USAGE: <for command-line>
+ * pipe01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * RESTRICITONS
+ * NONE
+ */
+#include <unistd.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "pipe01";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ int pipe_ret; /* exit status of pipe */
+ int fildes[2]; /* fds for pipe read and write */
+ char wrbuf[BUFSIZ], rebuf[BUFSIZ];
+ int red, written; /* no. of chars read/written to pipe */
+ int greater, length;
+ char *strcpy();
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ TEST(pipe(fildes));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "pipe() failed unexpectedly - errno %d",
+ TEST_ERRNO);
+ continue;
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+
+ strcpy(wrbuf, "abcdefghijklmnopqrstuvwxyz");
+ length = strlen(wrbuf);
+
+ if ((written = write(fildes[1], wrbuf, length)) == -1) {
+ tst_brkm(TBROK, cleanup, "write() failed");
+ }
+
+ if ((written < 0) || (written > 26)) {
+ tst_resm(TFAIL, "Condition #1 test failed");
+ continue;
+ }
+
+ if ((red = read(fildes[0], rebuf, written)) == -1) {
+ tst_brkm(TBROK, cleanup, "read() failed");
+ }
+
+ if ((red < 0) || (red > written)) {
+ tst_resm(TFAIL, "Condition #2 test failed");
+ continue;
+ }
+
+ /* are the strings written and read equal */
+ if ((greater = memcmp(rebuf, wrbuf, red)) != 0) {
+ tst_resm(TFAIL, "Condition #3 test failed");
+ continue;
+ }
+ tst_resm(TPASS, "pipe() functionality is correct");
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/pipe08.c b/winsup/testsuite/winsup.api/ltp/pipe08.c
new file mode 100644
index 000000000..9cc935d39
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/pipe08.c
@@ -0,0 +1,159 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * pipe08.c
+ *
+ * DESCRIPTION
+ * Check that a SIGPIPE signal is generated when a write is
+ * attempted on an empty pipe.
+ *
+ * ALGORITHM
+ * 1. Write to a pipe after closing the read side.
+ * 2. Check for the signal SIGPIPE to be received.
+ *
+ * USAGE: <for command-line>
+ * pipe08 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * USAGE
+ * pipe08
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "pipe08";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+void sighandler(int);
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ int pipe_ret; /* exit status of pipe */
+ int pipefd[2]; /* fds for pipe read/write */
+ char wrbuf[BUFSIZ];
+ int written, length;
+ int close_stat; /* exit status of close(read fd) */
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ if (!STD_FUNCTIONAL_TEST) {
+ tst_resm(TWARN, "-f option should not be used");
+ }
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ TEST(pipe(pipefd));
+
+ if (TEST_RETURN != 0) {
+ tst_resm(TFAIL, "call failed unexpectedly");
+ continue;
+ }
+
+ if ((close_stat = close(pipefd[0])) == -1) {
+ tst_brkm(TBROK, cleanup, "close of read side failed");
+ }
+
+ strcpy(wrbuf, "abcdefghijklmnopqrstuvwxyz\0");
+ length = strlen(wrbuf);
+
+ /*
+ * the SIGPIPE signal will be caught here or else
+ * the program will dump core when the signal is
+ * sent
+ */
+ written = write(pipefd[1], wrbuf, length);
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * sighandler - catch signals and look for SIGPIPE
+ */
+void
+sighandler(int sig)
+{
+ if (sig != SIGPIPE) {
+ tst_resm(TFAIL, "expected SIGPIPE, got %d", sig);
+ } else {
+ tst_resm(TPASS, "got expected SIGPIPE signal");
+ }
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, sighandler, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/pipe09.c b/winsup/testsuite/winsup.api/ltp/pipe09.c
new file mode 100644
index 000000000..2c7d9f4c2
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/pipe09.c
@@ -0,0 +1,232 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * pipe09.c
+ *
+ * DESCRIPTION
+ * Check that two processes can use the same pipe at the same time.
+ *
+ * ALGORITHM
+ * 1. Open a pipe
+ * 2. Fork a child which writes to the pipe
+ * 3. Fork another child which writes a different character to the pipe
+ * 4. Have the parent read from the pipe
+ * 5. It should get the characters from both children.
+ *
+ * USAGE: <for command-line>
+ * pipe09 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+#include <unistd.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+
+#define PIPEWRTCNT 100 /* must be an even number */
+
+char *TCID = "pipe09";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ int i, red, wtstatus, ret_val;
+ int pipe_ret; /* exit stat of pipe */
+ int pipefd[2]; /* fds for pipe read/write */
+ char synbuf[BUFSIZ];
+ char rebuf[BUFSIZ];
+ int Acnt = 0, Bcnt = 0; /* count 'A' and 'B' */
+ int fork_1, fork_2; /* ret values in parent */
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ TEST(pipe(pipefd));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "pipe() call failed");
+ continue;
+ }
+
+ if (!STD_FUNCTIONAL_TEST) {
+ tst_resm(TWARN, "-f option should not be used");
+ tst_resm(TPASS, "call succeeded");
+ continue;
+ }
+
+ if ((fork_1 = fork()) == -1) {
+ tst_brkm(TBROK, cleanup, "fork() #1 failed");
+ /*NOTREACHED*/
+ }
+
+ if (fork_1 == 0) { /* 1st child */
+ if (close(pipefd[0]) != 0) {
+ tst_resm(TWARN, "pipefd[0] close failed, "
+ "errno = %d", errno);
+ exit(1);
+ }
+
+ for (i = 0; i < PIPEWRTCNT / 2; ++i) {
+ if (write(pipefd[1], "A", 1) != 1) {
+ tst_resm(TWARN, "write to pipe failed");
+ exit(1);
+ }
+ }
+ exit(0);
+ }
+
+ /* parent */
+
+ waitpid(fork_1, &wtstatus, 0);
+ if (WEXITSTATUS(wtstatus) != 0) {
+ tst_brkm(TBROK, cleanup, "problem detected in child, "
+ "wait status %d, errno = %d", wtstatus, errno);
+ }
+
+ if ((fork_2 = fork()) == -1) {
+ tst_brkm(TBROK, cleanup, "fork() #2 failed");
+ /*NOTREACHED*/
+ }
+
+ if (fork_2 == 0) { /* 2nd child */
+ if (close(pipefd[0]) != 0) {
+ tst_resm(TWARN, "pipefd[0] close "
+ "failed, errno = %d", errno);
+ exit(1);
+ }
+
+ for (i = 0; i < PIPEWRTCNT / 2; ++i) {
+ if (write(pipefd[1], "B", 1) != 1) {
+ tst_resm(TWARN, "write to pipe failed");
+ exit(1);
+ }
+ }
+ exit(0);
+ }
+
+ /* parent */
+
+ waitpid(fork_2, &wtstatus, 0);
+ if (WEXITSTATUS(wtstatus) != 0) {
+ tst_brkm(TBROK, cleanup, "problem detected in child, "
+ "wait status %d, errno = %d", wtstatus, errno);
+ }
+
+ if (close(pipefd[1]) != 0) {
+ tst_brkm(TBROK, cleanup, "pipefd[1] close failed, "
+ "errno = %d", errno);
+ /*NOTREACHED*/
+ }
+
+ while ((red = read(pipefd[0], rebuf, 100)) > 0) {
+ for (i = 0; i < red; i++) {
+ if (rebuf[i] == 'A') {
+ Acnt++;
+ continue;
+ }
+ if (rebuf[i] == 'B') {
+ Bcnt++;
+ continue;
+ }
+ tst_resm(TFAIL, "got bogus '%c' character",
+ rebuf[i]);
+ break;
+ }
+ }
+
+ if (red == -1) {
+ tst_brkm(TBROK, cleanup, "Failure reading pipefd pipe, "
+ "errno = %d", errno);
+ }
+
+ if (Bcnt == Acnt && Bcnt == (PIPEWRTCNT / 2)) {
+ tst_resm(TPASS, "functionality appears to be correct");
+ } else {
+ tst_resm(TFAIL, "functionality is not correct - Acnt "
+ "= %d, Bcnt = %d", Acnt, Bcnt);
+ }
+
+ /* clean up things in case we are looping */
+ Acnt = Bcnt = 0;
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/pipe10.c b/winsup/testsuite/winsup.api/ltp/pipe10.c
new file mode 100644
index 000000000..410622c37
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/pipe10.c
@@ -0,0 +1,168 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * pipe10.c
+ *
+ * DESCRIPTION
+ * Check that parent can open a pipe and have a child read from it
+ *
+ * ALGORITHM
+ * Parent opens pipe, child reads. Passes if child can read all the
+ * characters written by the parent.
+ *
+ * USAGE: <for command-line>
+ * pipe10 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+#include <errno.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <test.h>
+#include <usctest.h>
+
+char *TCID = "pipe10";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ int pipe_ret; /* exit status of pipe */
+ int fd[2]; /* fds for pipe read/write */
+ char wrbuf[BUFSIZ], rebuf[BUFSIZ];
+ int red, written; /* no of chars read and */
+ /* written to pipe */
+ int length, greater, forkstat;
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ TEST(pipe(fd));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "pipe creation failed");
+ continue;
+ }
+
+ if (!STD_FUNCTIONAL_TEST) {
+ tst_resm(TPASS, "call succeeded");
+ continue;
+ }
+
+ strcpy(wrbuf, "abcdefghijklmnopqrstuvwxyz\0");
+ length = strlen(wrbuf);
+
+ written = write(fd[1], wrbuf, length);
+
+ /* did write write at least some chars */
+ if ((written < 0) || (written > length)) {
+ tst_brkm(TBROK, cleanup, "write to pipe failed");
+ }
+
+ forkstat = fork();
+
+ if (forkstat == -1) {
+ tst_brkm(TBROK, cleanup, "fork() failed");
+ /*NOTREACHED*/
+ }
+
+ if (forkstat == 0) { /* child */
+ red = read(fd[0], rebuf, written);
+
+ /* did read , get at least some chars */
+ if ((red < 0) || (red > written)) {
+ tst_brkm(TBROK, cleanup, "read pipe failed");
+ }
+
+ greater = memcmp(rebuf, wrbuf, red);
+
+ /* are the strings written and read equal */
+ if (greater == 0) {
+ tst_resm(TPASS, "functionality is correct");
+ } else {
+ tst_resm(TFAIL, "read & write strings do "
+ "not match");
+ }
+ } else { /* parent */
+ /* let the child carry on */
+ exit(0);
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/pipe11.c b/winsup/testsuite/winsup.api/ltp/pipe11.c
new file mode 100644
index 000000000..df7b24166
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/pipe11.c
@@ -0,0 +1,227 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * pipe11.c
+ *
+ * DESCRIPTION
+ * Check if many children can read what is written to a pipe by the
+ * parent.
+ *
+ * ALGORITHM
+ * 1. Open a pipe and write to it
+ * 2. Fork a large number of children
+ * 3. Have the children read the pipe and check how many characters
+ * each got
+ *
+ * USAGE: <for command-line>
+ * pipe11 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <limits.h>
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "pipe11";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+#define NUMCHILD 50
+#define NCPERCHILD 50
+char rawchars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
+int kidid;
+int numchild; /* no of children to fork */
+int ncperchild; /* no of chars child should read */
+int szcharbuf; /* size of char buf */
+int pipewrcnt; /* chars written to pipe */
+char *wrbuf, *rdbuf;
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ int pipe_ret; /* exit status of pipe */
+ int fd[2]; /* fds for pipe read/write */
+ int i;
+ int fork_ret, status, cond_numb = 0;
+ int nread, written; /* no of chars read and written */
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ TEST(pipe(fd));
+
+ if (TEST_RETURN != 0) {
+ tst_resm(TFAIL, "pipe creation failed");
+ continue;
+ }
+
+ if (!STD_FUNCTIONAL_TEST) {
+ tst_resm(TPASS, "call succeeded");
+ continue;
+ }
+
+ written = write(fd[1], wrbuf, szcharbuf);
+ if (written != szcharbuf) {
+ tst_brkm(TBROK, cleanup, "write to pipe failed");
+ }
+
+refork:
+ ++kidid;
+ fork_ret = fork();
+
+ if (fork_ret < 0) {
+ tst_brkm(TBROK, cleanup, "fork() failed");
+ /*NOTREACHED*/
+ }
+
+ if ((fork_ret != 0) && (fork_ret != -1) && (kidid < numchild)) {
+ goto refork;
+ }
+
+ if (fork_ret == 0) { /* child */
+ if (close(fd[1])) {
+ tst_resm(TINFO, "child %d " "could not close "
+ "pipe", kidid);
+ exit(0);
+ }
+ nread = read(fd[0], rdbuf, ncperchild);
+ if (nread == ncperchild) {
+ tst_resm(TINFO, "child %d " "got %d chars",
+ kidid, nread);
+ exit(0);
+ } else {
+ tst_resm(TFAIL, "child %d did not receive "
+ "expected no of characters, got %d "
+ "characters", kidid, nread);
+ exit(1);
+ }
+ }
+
+ /* parent */
+ sleep(5);
+ tst_resm(TINFO, "There are %d children to wait for", kidid);
+ for (i = 1; i <= kidid; ++i) {
+ wait(&status);
+ if (status == 0) {
+ tst_resm(TPASS, "child %d exitted successfully",
+ i);
+ } else {
+ tst_resm(TFAIL, "child %d exitted with bad "
+ "status", i);
+ }
+ }
+ }
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ int i, j;
+
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ numchild = NUMCHILD;
+ ncperchild = NCPERCHILD;
+
+ kidid = 0;
+
+ /* allocate read and write buffers */
+ szcharbuf = numchild * ncperchild;
+
+ /* make sure pipe write doesn't block */
+ if (szcharbuf == PIPE_BUF) {
+ /* adjust number of characters per child */
+ ncperchild = szcharbuf / numchild;
+ }
+
+ if ((wrbuf = (char *)malloc(szcharbuf)) == (char *)0) {
+ tst_brkm(TBROK, cleanup, "malloc failed");
+ /*NOTREACHED*/
+ }
+
+ if ((rdbuf = (char *)malloc(szcharbuf)) == (char *)0) {
+ tst_brkm(TBROK, cleanup, "malloc of rdbuf failed");
+ /*NOTREACHED*/
+ }
+
+ /* initialize wrbuf */
+ j = 0;
+ for (i = 0; i < szcharbuf; ) {
+ wrbuf[i++] = rawchars[j++];
+ if (j >= sizeof(rawchars)) {
+ j = 0;
+ }
+ }
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/poll01.c b/winsup/testsuite/winsup.api/ltp/poll01.c
new file mode 100644
index 000000000..67e1f139a
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/poll01.c
@@ -0,0 +1,251 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: poll01
+ *
+ * Test Description:
+ * Verify that valid open file descriptor must be provided to poll() to
+ * succeed.
+ *
+ * Expected Result:
+ * poll should return the correct values when an valid file descriptor is
+ * provided.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ *
+ * Usage: <for command-line>
+ * poll01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * None.
+ */
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include <sys/poll.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define BUF_SIZE 512
+
+char *TCID="poll01"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+
+int fildes[2]; /* file descriptors of the pipe. */
+struct pollfd fds[1]; /* struct. for poll() */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ pid_t cpid; /* child process id */
+ char write_buf[] = "Testing\0"; /* buffer string for write */
+ char read_buf[BUF_SIZE]; /* buffer for read-end of pipe */
+ int status; /* exit status of child process */
+ int rval;
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *)NULL, NULL);
+ if (msg != (char *)NULL) {
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* Reset Tst_count in case we are looping. */
+ Tst_count = 0;
+
+ /*
+ * Call poll() with the TEST macro.
+ */
+ TEST(poll(fds, 1, -1));
+
+ /* check return code of poll() */
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "poll() failed on write, errno=%d"
+ " : %s", TEST_ERRNO, strerror(TEST_ERRNO));
+ continue;
+ }
+
+ /* write the message to the pipe */
+ if (write(fildes[1], write_buf, strlen(write_buf))
+ < strlen(write_buf)) {
+ tst_brkm(TBROK, cleanup, "write() failed on write "
+ "to pipe, error:%d", errno);
+ }
+
+ /* Fork child process */
+ if ((cpid = fork()) == -1) {
+ tst_brkm(TBROK, cleanup, "fork() failed");
+ }
+
+ if (cpid == 0) { /* Child process */
+ /*
+ * close writing end of pipe and read from
+ * the pipe
+ */
+ if (close(fildes[1]) == -1) {
+ tst_brkm(TFAIL, NULL, "close() failed on write "
+ "endof pipe, errno:%d", errno);
+ exit(1);
+ }
+
+ /*
+ * Set poll() data structures to check
+ * if data is present on read
+ */
+ fds[0].fd = fildes[0];
+ fds[0].events = POLLIN;
+
+ /*
+ * If data are present, then read the data. If poll()
+ * and read() return expected values, then the
+ * functionality of poll() is correct.
+ */
+ rval = (poll(fds, 1, -1));
+
+ if (rval == -1) {
+ tst_resm(TFAIL, "poll() failed on read - "
+ "errno=%d : %s",
+ TEST_ERRNO, strerror(errno));
+ exit(1);
+ }
+
+ /* Read data from read end of pipe */
+ if (read(fildes[0], read_buf, sizeof(read_buf)) !=
+ strlen(write_buf)) {
+ tst_brkm(TFAIL, NULL, "read() failed - "
+ "error:%d", errno);
+ exit(1);
+ }
+
+ /* Now, do the actual comparision */
+ if (memcmp(read_buf, write_buf, strlen(write_buf))) {
+ tst_resm(TFAIL, "Data from reading pipe "
+ "are different");
+ exit(1);
+ }
+
+ /* Everything is fine, exit normally */
+ exit(0);
+ } else { /* Parent process */
+ /* Wait for child to complete execution */
+ wait(&status);
+
+ if (WEXITSTATUS(status) == 1) {
+ tst_resm(TFAIL, "child exited abnormally");
+ } else {
+ tst_resm(TPASS,
+ "Functionality of poll() successful");
+ }
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ * Creat read/write pipe using pipe().
+ * Set poll data structures to check writing to the pipe.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Creat read/write pipe */
+ if (pipe(fildes) < 0) {
+ tst_brkm(TBROK, tst_exit,
+ "pipe() failed to create interprocess channel");
+ }
+
+ /* Set poll data structures */
+ fds[0].fd = fildes[1];
+ fds[0].events = POLLOUT;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * close read end of pipe if still open.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* close read end of pipe if still open */
+ if (close(fildes[0]) < 0) {
+ tst_brkm(TFAIL, NULL, "close() failed on read-end of pipe, "
+ "errno:%d", errno);
+ }
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/read04.c b/winsup/testsuite/winsup.api/ltp/read04.c
new file mode 100644
index 000000000..99dcdf68d
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/read04.c
@@ -0,0 +1,175 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * read01.c
+ *
+ * DESCRIPTION
+ * Testcase to check if read returns the number of bytes read correctly.
+ *
+ * ALGORITHM
+ * Create a file and write some bytes out to it.
+ * Attempt to read more than written.
+ * Check the return count, and the read buffer. The read buffer should be
+ * same as the write buffer.
+ *
+ * USAGE: <for command-line>
+ * read01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None
+ */
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "test.h"
+#include "usctest.h"
+
+void cleanup(void);
+void setup(void);
+
+char *TCID = "read01";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+#define TST_SIZE 26 /* could also do strlen(palfa) */
+char fname[255];
+char palfa[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
+int fild;
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ int n;
+ int rfild;
+ char prbuf[BUFSIZ];
+
+ /*
+ * parse standard options
+ */
+ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup(); /* global setup for test */
+
+ /* check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ Tst_count = 0; /* reset Tst_count while looping */
+
+ if ((rfild = open(fname, O_RDONLY)) == -1) {
+ tst_brkm(TBROK, cleanup, "can't open for reading");
+ /*NOTREACHED*/
+ }
+ TEST(read(rfild, prbuf, BUFSIZ));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "call failed unexpectedly");
+ continue;
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+ if (TEST_RETURN != TST_SIZE) {
+ tst_resm(TFAIL, "Bad read count - got %d - "
+ "expected %d", TEST_RETURN, TST_SIZE);
+ continue;
+ }
+ if (memcmp(palfa, prbuf, TST_SIZE) != 0) {
+ tst_resm(TFAIL, "read buffer not equal "
+ "to write buffer");
+ continue;
+ }
+ tst_resm(TPASS, "functionality of read() is correct");
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ if (close(rfild) == -1) {
+ tst_brkm(TBROK, cleanup, "close() failed");
+ /*NOTREACHED*/
+ }
+ }
+ cleanup();
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ umask(0);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ sprintf(fname,"tfile_%d",getpid());
+
+ if ((fild = creat(fname, 0777)) == -1) {
+ tst_brkm(TBROK, cleanup, "creat(%s, 0777) Failed, errno = %d"
+ " : %s", fname, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+ if (write(fild, palfa, TST_SIZE) != TST_SIZE) {
+ tst_brkm(TBROK, cleanup, "can't write to Xread");
+ /*NOTREACHED*/
+ }
+ close (fild);
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion or
+ * premature exit.
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Remove tmp dir and all files in it */
+ unlink(fname);
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/readlink01.c b/winsup/testsuite/winsup.api/ltp/readlink01.c
new file mode 100644
index 000000000..bb5f6e388
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/readlink01.c
@@ -0,0 +1,230 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name : readlink01
+ *
+ * Test Description :
+ * Verify that, readlink will succeed to read the contents of the symbolic
+ * link created the process.
+ *
+ * Expected Result:
+ * readlink() should return the contents of symbolic link path in the buffer
+ * on success.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * readlink01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * This test should be run by 'non-super-user' only.
+ *
+ */
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TESTFILE "testfile"
+#define SYMFILE "slink_file"
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+#define MAX_SIZE 256
+
+char *TCID="readlink01"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+
+int exp_val; /* strlen of testfile */
+
+void setup(); /* Setup function for the test */
+void cleanup(); /* Cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ char buffer[MAX_SIZE]; /* temporary buffer to hold symlink contents*/
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *)NULL, NULL);
+ if (msg != (char *)NULL) {
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Call readlink(2) to read the contents of
+ * symlink into a buffer.
+ */
+ TEST(readlink(SYMFILE, buffer, sizeof(buffer)));
+
+ /* Check return code of readlink(2) */
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "readlink() on %s failed, errno=%d : %s"
+ , SYMFILE, TEST_ERRNO, strerror(TEST_ERRNO));
+ continue;
+ }
+
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Compare the return value of readlink()
+ * with the expected value which is the
+ * strlen() of testfile.
+ */
+ if (TEST_RETURN == exp_val) {
+ /* Check for the contents of buffer */
+ if (memcmp(buffer, TESTFILE, exp_val) != 0) {
+ tst_resm(TFAIL, "Pathname %s and buffer"
+ " contents %s differ",
+ TESTFILE, buffer);
+ } else {
+ tst_resm(TPASS, "readlink() "
+ "functionality on '%s' is "
+ "correct", SYMFILE);
+ }
+ } else {
+ tst_resm(TFAIL, "readlink() return value %d "
+ "does't match, Expected %d",
+ TEST_RETURN, exp_val);
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ *
+ * Create a temporary directory and change directory to it.
+ * Create a test file under temporary directory and close it
+ * Create a symbolic link of testfile.
+ */
+void
+setup()
+{
+ int fd; /* file handle for testfile */
+
+ /* make sure test is not being run as root */
+ if (0 == geteuid()) {
+ tst_brkm(TBROK, tst_exit, "Must not run test as root");
+ }
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ if ((fd = open(TESTFILE, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) failed, errno=%d : %s",
+ TESTFILE, FILE_MODE, errno, strerror(errno));
+ }
+
+ if (close(fd) == -1) {
+ tst_resm(TWARN, "close(%s) Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ }
+
+ /* Create a symlink of testfile under temporary directory */
+ if (symlink(TESTFILE, SYMFILE) < 0) {
+ tst_brkm(TBROK, cleanup,
+ "symlink(%s, %s) failed, errno=%d : %s",
+ TESTFILE, SYMFILE, errno, strerror(errno));
+ }
+
+ /* Get the strlen of testfile */
+ exp_val = strlen(TESTFILE);
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ *
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/readlink03.c b/winsup/testsuite/winsup.api/ltp/readlink03.c
new file mode 100644
index 000000000..3279b903b
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/readlink03.c
@@ -0,0 +1,361 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name : readlink03
+ *
+ * Test Description :
+ * Verify that,
+ * 1) readlink(2) returns -1 and sets errno to EACCES if search/write
+ * permission is denied in the directory where the symbolic link
+ * resides.
+ * 2) readlink(2) returns -1 and sets errno to EINVAL if the buffer size
+ * is not positive.
+ * 3) readlink(2) returns -1 and sets errno to EINVAL if the specified
+ * file is not a symbolic link file.
+ * 4) readlink(2) returns -1 and sets errno to ENAMETOOLONG if the
+ * pathname component of symbolic link is too long (ie, > PATH_MAX).
+ * 5) readlink(2) returns -1 and sets errno to ENOENT if the component of
+ * symbolic link points to an empty string.
+ *
+ * Expected Result:
+ * readlink() should fail with return value -1 and set expected errno.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * if errno set == expected errno
+ * Issue sys call fails with expected return value and errno.
+ * Otherwise,
+ * Issue sys call fails with unexpected errno.
+ * Otherwise,
+ * Issue sys call returns unexpected value.
+ *
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory(s)/file(s) created.
+ *
+ * Usage: <for command-line>
+ * readlink03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS:
+ * This test should be executed by 'non-super-user' only.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define MODE_RWX S_IRWXU | S_IRWXG | S_IRWXO
+#define FILE_MODE S_IRUSR | S_IRGRP | S_IROTH
+#define DIR_TEMP "testdir_1"
+#define TESTFILE "testfile"
+#define TEST_FILE1 "testdir_1/tfile_1"
+#define SYM_FILE1 "testdir_1/sfile_1"
+#define TEST_FILE2 "tfile_2"
+#define SYM_FILE2 "sfile_2"
+#define MAX_SIZE 256
+
+char *TCID="readlink03"; /* Test program identifier. */
+int TST_TOTAL=5; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={EACCES, EINVAL, ENAMETOOLONG, ENOENT, 0};
+
+int no_setup();
+int setup1(); /* setup function to test symlink for EACCES */
+int setup2(); /* setup function to test symlink for EEXIST */
+int lpath_setup(); /* setup function to test chmod for ENAMETOOLONG */
+
+char Longpathname[PATH_MAX+2];
+
+struct test_case_t { /* test case struct. to hold ref. test cond's*/
+ char *link;
+ char *desc;
+ int exp_errno;
+ size_t buf_siz;
+ int (*setupfunc)();
+} Test_cases[] = {
+#ifndef __CYGWIN__
+ { SYM_FILE1, "No Search permissions to process", EACCES, 1, setup1 },
+ { SYM_FILE2, "Buffer size is not positive", EINVAL, -1, setup2 },
+ { TEST_FILE2, "File is not symbolic link", EINVAL, 1, no_setup },
+#else
+ { TEST_FILE2, "File is not symbolic link", EINVAL, 1, setup2 },
+#endif
+ { Longpathname, "Symlink path too long", ENAMETOOLONG, 1, lpath_setup },
+ { "", "Symlink Pathname is empty", ENOENT, 1, no_setup },
+ { NULL, NULL, 0, 0, no_setup }
+};
+
+extern void setup(); /* Setup function for the test */
+extern void cleanup(); /* Cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ char buffer[MAX_SIZE]; /* temporary buffer to hold symlink contents*/
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ char *sym_file; /* symbolic link file name */
+ char *test_desc; /* test specific error message */
+ int i; /* counter to test different test conditions */
+ size_t buf_size; /* size of buffer for readlink */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *)NULL, NULL);
+ if (msg != (char *)NULL) {
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ /*
+ * Invoke setup function to call individual test setup functions
+ * to simulate test conditions.
+ */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ for (i = 0; Test_cases[i].desc != NULL; i++) {
+ sym_file = Test_cases[i].link;
+ test_desc = Test_cases[i].desc;
+ buf_size = Test_cases[i].buf_siz;
+
+ if (buf_size == 1) {
+ buf_size = sizeof(buffer);
+ }
+
+ /*
+ * Call readlink(2) to test different test conditions.
+ * verify that it fails with -1 return value and sets
+ * appropriate errno.
+ */
+ TEST(readlink(sym_file, buffer, buf_size));
+
+ /* Check return code of readlink(2) */
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "readlink() returned %d, "
+ "expected -1, errno:%d", TEST_RETURN,
+ Test_cases[i].exp_errno);
+ continue;
+ }
+
+ TEST_ERROR_LOG(TEST_ERRNO);
+
+ if (TEST_ERRNO == Test_cases[i].exp_errno) {
+ tst_resm(TPASS, "readlink(), %s, returned "
+ "errno %d", test_desc, TEST_ERRNO);
+ tst_resm(TPASS, "readlink(), %s, returned "
+ "errno %d", test_desc, TEST_ERRNO);
+ } else {
+ tst_resm(TFAIL, "readlink() failed, %s, "
+ "errno=%d, expected errno=%d",
+ test_desc, TEST_ERRNO,
+ Test_cases[i].exp_errno);
+ }
+ } /* End of TEST CASE LOOPING. */
+ } /* End for TEST_LOOPING */
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+
+ /*NOTREACHED*/
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ *
+ * Create a temporary directory and change directory to it.
+ * Call test specific setup functions.
+ */
+void
+setup()
+{
+ int i;
+
+ /* make sure test is not being run as root */
+ if (0 == geteuid()) {
+ tst_brkm(TBROK, tst_exit, "Must not run test as root");
+ }
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* call individual setup functions */
+ for (i = 0; Test_cases[i].desc != NULL; i++) {
+ Test_cases[i].setupfunc();
+ }
+}
+
+/*
+ * no_setup() - Some test conditions for readlink(2) do not any setup.
+ */
+int
+no_setup()
+{
+ return 0;
+}
+
+/*
+ * setup1() - setup function for a test condition for which readlink(2)
+ * returns -1 and sets errno to EACCES.
+ *
+ * Create a test directory under temporary directory and create a test file
+ * under this directory with mode "0666" permissions.
+ * Create a symlink of testfile under test directory.
+ * Modify the mode permissions on test directory such that process will not
+ * have search permissions on test directory.
+ */
+int
+setup1()
+{
+ int fd; /* file handle for testfile */
+
+ if (mkdir(DIR_TEMP, MODE_RWX) < 0) {
+ tst_brkm(TBROK, cleanup, "mkdir(2) of %s failed", DIR_TEMP);
+ }
+
+ if ((fd = open(TEST_FILE1, O_RDWR|O_CREAT, 0666)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, 0666) failed, errno=%d : %s",
+ TEST_FILE1, errno, strerror(errno));
+ }
+ if (close(fd) == -1) {
+ tst_brkm(TBROK, cleanup, "close(%s) failed, errno=%d : %s",
+ TEST_FILE1, errno, strerror(errno));
+ }
+
+ /* Creat a symbolic link of testfile under test directory */
+ if (symlink(TEST_FILE1, SYM_FILE1) < 0) {
+ tst_brkm(TBROK, cleanup, "symlink of %s failed", TEST_FILE1);
+ }
+
+ /* Modify mode permissions on test directory */
+ if (chmod(DIR_TEMP, FILE_MODE) < 0) {
+ tst_brkm(TBROK, cleanup, "chmod(2) of %s failed", DIR_TEMP);
+ }
+ return 0;
+}
+
+/*
+ * setup2() - setup function for a test condition for which readlink(2)
+ * returns -1 and sets errno to EINVAL.
+ *
+ * Create a testfile under temporary directory and create a symlink
+ * file of it.
+ */
+int
+setup2()
+{
+ int fd; /* file handle for testfile */
+
+ /* Creat a testfile and close it */
+ if ((fd = open(TEST_FILE2, O_RDWR|O_CREAT, 0666)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, 0666) failed, errno=%d : %s",
+ TEST_FILE2, errno, strerror(errno));
+ }
+ if (close(fd) == -1) {
+ tst_brkm(TBROK, cleanup, "close(%s) failed, errno=%d : %s",
+ TEST_FILE2, errno, strerror(errno));
+ }
+
+ /* Creat a symlink of testfile created above */
+ if (symlink(TEST_FILE2, SYM_FILE2) < 0) {
+ tst_brkm(TBROK, cleanup, "symlink() failed to create %s in "
+ "setup2, error=%d", SYM_FILE2, errno);
+ }
+ return 0;
+}
+
+/*
+ * lpath_setup() - setup to create a node with a name length exceeding
+ * the MAX. length of PATH_MAX.
+ */
+int
+lpath_setup()
+{
+ int i; /* counter variable */
+
+ for (i = 0; i <= (PATH_MAX + 1); i++) {
+ Longpathname[i] = 'a';
+ }
+ return 0;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ *
+ * Restore the mode permissions on test directory.
+ * Remove the temporary directory created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Restore mode permissions on test directory created in setup2() */
+ if (chmod(DIR_TEMP, MODE_RWX) < 0) {
+ tst_brkm(TBROK, NULL, "chmod(2) of %s failed", DIR_TEMP);
+ }
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/rename01.c b/winsup/testsuite/winsup.api/ltp/rename01.c
new file mode 100644
index 000000000..551efe722
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/rename01.c
@@ -0,0 +1,264 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * rename01
+ *
+ * DESCRIPTION
+ * This test will verify the rename(2) syscall basic functionality.
+ * Verify rename() works when the "new" file or directory does not exist.
+ *
+ * ALGORITHM
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * 1. "old" is plain file, new does not exists
+ * create the "old" file, make sure the "new" file
+ * dose not exist
+ * rename the "old" to the "new" file
+ * verify the "new" file points to the "old" file
+ * verify the "old" file does not exist
+ *
+ * 2. "old" is a directory,"new" does not exists
+ * create the "old" directory, make sure "new"
+ * dose not exist
+ * rename the "old" to the "new"
+ * verify the "new" points to the "old"
+ * verify the "old" does not exist
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * USAGE
+ * rename01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None.
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "test.h"
+#include "usctest.h"
+
+void setup();
+void cleanup();
+extern void do_file_setup(char *);
+
+char *TCID="rename01"; /* Test program identifier. */
+int TST_TOTAL=2; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+
+char fname[255], mname[255];
+char fdir[255], mdir[255];
+struct stat buf1;
+dev_t f_olddev, d_olddev;
+ino_t f_oldino, d_oldino;
+
+struct test_case_t {
+ char *name1;
+ char *name2;
+ char *desc;
+ dev_t *olddev;
+ ino_t *oldino;
+} TC[] = {
+ /* comment goes here */
+ {fname, mname, "file", &f_olddev, &f_oldino},
+
+ /* comment goes here */
+ {fdir, mdir, "directory", &d_olddev, &d_oldino}
+};
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ int i;
+
+ /*
+ * parse standard options
+ */
+ if ((msg=parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL) {
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ /*
+ * perform global setup for test
+ */
+ setup();
+
+ /*
+ * check looping state if -i option given
+ */
+ for (lc=0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /* loop through the test cases */
+ for (i=0; i<TST_TOTAL; i++) {
+
+ TEST(rename(TC[i].name1, TC[i].name2));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "call failed unexpectedly");
+ continue;
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+ if (stat(TC[i].name2, &buf1) == -1) {
+ tst_brkm(TBROK, cleanup, "stat of %s "
+ "failed", TC[i].desc);
+ /* NOTREACHED */
+ }
+
+ /*
+ * verify the new file or directory is the
+ * same as the old one
+ */
+ if (buf1.st_dev != *TC[i].olddev ||
+ buf1.st_ino != *TC[i].oldino) {
+ tst_resm(TFAIL, "rename() failed: the "
+ "new %s points to a different "
+ "inode/location", TC[i].desc);
+ continue;
+ }
+ /*
+ * verify that the old file or directory
+ * does not exist
+ */
+ if (stat(fname, &buf1) != -1) {
+ tst_resm(TFAIL, "the old %s still "
+ "exists", TC[i].desc);
+ continue;
+ }
+
+ tst_resm(TPASS, "functionality is correct "
+ "for renaming a %s", TC[i].desc);
+ } else {
+ tst_resm(TPASS, "call succeeded on %s rename",
+ TC[i].desc);
+ }
+ }
+ /* reset things in case we are looping */
+ if (rename(mname, fname) == -1) {
+ tst_brkm(TBROK, cleanup, "file rename failed");
+ }
+
+ if (rename(mdir, fdir) == -1) {
+ tst_brkm(TBROK, cleanup, "directory rename failed");
+ }
+ } /* End for TEST_LOOPING */
+
+ /*
+ * cleanup and exit
+ */
+ cleanup();
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Create a temporary directory and make it current. */
+ tst_tmpdir();
+
+ sprintf(fname,"./tfile_%d",getpid());
+ sprintf(mname,"./rnfile_%d",getpid());
+ sprintf(fdir,"./tdir_%d",getpid());
+ sprintf(mdir,"./rndir_%d",getpid());
+
+ /* create the "old" file */
+ do_file_setup(fname);
+
+ if (stat(fname, &buf1)== -1) {
+ tst_brkm(TBROK,cleanup, "failed to stat file %s"
+ "in setup()", fname);
+ /* NOTREACHED */
+ }
+
+ f_olddev = buf1.st_dev;
+ f_oldino = buf1.st_ino;
+
+ /* create "old" directory */
+ if (mkdir(fdir, 00770) == -1) {
+ tst_brkm(TBROK, cleanup, "Could not create directory %s", fdir);
+ /*NOTREACHED*/
+ }
+
+ if (stat(fdir, &buf1) == -1) {
+ tst_brkm(TBROK, cleanup, "failed to stat directory %s"
+ "in setup()", fname);
+ /* NOTREACHED */
+ }
+
+ d_olddev = buf1.st_dev;
+ d_oldino = buf1.st_ino;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /*
+ * Remove the temporary directory.
+ */
+ tst_rmdir();
+
+ /*
+ * Exit with return code appropriate for results.
+ */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/rename02.c b/winsup/testsuite/winsup.api/ltp/rename02.c
index 28890f119..1ad0fb01e 100644
--- a/winsup/testsuite/winsup.api/ltp/rename02.c
+++ b/winsup/testsuite/winsup.api/ltp/rename02.c
@@ -135,7 +135,7 @@ int
main(int ac, char **av)
{
int lc; /* loop counter */
- const char *msg; /* message returned from parse_opts */
+ const char *msg; /* message returned from parse_opts */
/***************************************************************
* parse standard options
diff --git a/winsup/testsuite/winsup.api/ltp/rename08.c b/winsup/testsuite/winsup.api/ltp/rename08.c
new file mode 100644
index 000000000..e83923901
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/rename08.c
@@ -0,0 +1,206 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * rename08
+ *
+ * DESCRIPTION
+ * This test will verify that rename(2) syscall failed in EFAULT
+ *
+ * ALGORITHM
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ * Create a valid file to use in the rename() call.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * 1. "old" is a valid file, newpath points to address
+ * outside allocated address space
+ * rename the "old" to the "new" file
+ * verify rename() failed with error EFAULT
+ *
+ * 2. "old" points to address outside allocated address space
+ * ,"new" is a valid file
+ * rename the "old" to the "new"
+ * verify rename() failed with error EFAULT
+ *
+ * 3. oldpath and newpath are all NULL
+ * try to rename NULL to NULL
+ * verify rename() failed with error EFAULT
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.*
+ * USAGE
+ * rename08 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None.
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "test.h"
+#include "usctest.h"
+
+void setup();
+void cleanup();
+extern void do_file_setup(char *);
+
+char *TCID="rename08"; /* Test program identifier. */
+int TST_TOTAL=3; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+
+int exp_enos[]={EFAULT, 0}; /* List must end with 0 */
+
+int fd;
+char fname[255];
+
+struct test_case_t {
+ char *fd;
+ char *fd2;
+ int error;
+} TC[] = {
+ /* "new" file is invalid - EFAULT */
+ {fname, (char *)-1, EFAULT},
+
+ /* "old" file is invalid - EFAULT */
+ {(char *)-1, fname, EFAULT},
+
+ /* both files are NULL - EFAULT */
+ {NULL, NULL, EFAULT}
+};
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ int i;
+
+ /*
+ * parse standard options
+ */
+ if ((msg=parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL) {
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ /*
+ * perform global setup for test
+ */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /*
+ * check looping state if -i option given
+ */
+ for (lc=0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /* loop through the test cases */
+ for (i = 0; i < TST_TOTAL; i++) {
+
+ TEST(rename(TC[i].fd, TC[i].fd2));
+
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "call succeeded unexpectedly");
+ continue;
+ }
+
+ TEST_ERROR_LOG(TEST_ERRNO);
+
+ if (TEST_ERRNO == TC[i].error) {
+ tst_resm(TPASS, "expected failure - "
+ "errno = %d : %s", TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ } else {
+ tst_resm(TFAIL, "unexpected error - %d : %s - "
+ "expected %d", TEST_ERRNO,
+ strerror(TEST_ERRNO), TC[i].error);
+ }
+ }
+ } /* End for TEST_LOOPING */
+
+ /*
+ * cleanup and exit
+ */
+ cleanup();
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Create a temporary directory and make it current. */
+ tst_tmpdir();
+
+ sprintf(fname,"./tfile_%d",getpid());
+
+ do_file_setup(fname);
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /*
+ * Remove the temporary directory.
+ */
+ tst_rmdir();
+
+ /*
+ * Exit with return code appropriate for results.
+ */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/rename10.c b/winsup/testsuite/winsup.api/ltp/rename10.c
new file mode 100644
index 000000000..c1aae92b5
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/rename10.c
@@ -0,0 +1,204 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * rename10
+ *
+ * DESCRIPTION
+ * This test will verify that rename(2) syscall fails with ENAMETOOLONG
+ * and ENOENT
+ *
+ * ALGORITHM
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ * create the "old" file
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * 1. rename the "old" to the "new" file
+ * verify rename() failed with error ENAMETOOLONG
+ *
+ * 2. "new" path contains a directory that does not exist
+ * rename the "old" to the "new"
+ * verify rename() failed with error ENOENT
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.*
+ *
+ * USAGE
+ * rename10 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None.
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "test.h"
+#include "usctest.h"
+
+void setup();
+void cleanup();
+extern void do_file_setup(char *);
+
+char *TCID="rename10"; /* Test program identifier. */
+int TST_TOTAL=2; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+
+char badmname[] = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyz";
+
+int exp_enos[]={ENAMETOOLONG, ENOENT, 0}; /* List must end with 0 */
+
+int fd;
+char fname[255], mname[255];
+char mdir[255];
+
+struct test_case_t {
+ char *fd1;
+ char *fd2;
+ int error;
+} TC[] = {
+ /* badmname is too long for a file name - ENAMETOOLONG */
+ {fname, badmname, ENAMETOOLONG},
+
+ /* mname contains a directory component which does not exist - ENOENT */
+ {fname, mname, ENOENT}
+};
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ int i;
+
+ /*
+ * parse standard options
+ */
+ if ((msg=parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL) {
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ /*
+ * perform global setup for test
+ */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /*
+ * check looping state if -i option given
+ */
+ for (lc=0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /* loop through the test cases */
+ for (i=0; i < TST_TOTAL; i++) {
+
+ TEST(rename(TC[i].fd1, TC[i].fd2));
+
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "call succeeded unexpectedly");
+ continue;
+ }
+
+ TEST_ERROR_LOG(TEST_ERRNO);
+
+ if (TEST_ERRNO == TC[i].error) {
+ tst_resm(TPASS, "expected failure - "
+ "errno = %d : %s", TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ } else {
+ tst_resm(TFAIL, "unexpected error - %d : %s - "
+ "expected %d", TEST_ERRNO,
+ strerror(TEST_ERRNO), TC[i].error);
+ }
+ }
+ } /* End for TEST_LOOPING */
+
+ /*
+ * cleanup and exit
+ */
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Create a temporary directory and make it current. */
+ tst_tmpdir();
+
+ sprintf(fname,"./tfile_%d",getpid());
+ sprintf(mdir,"./rndir_%d",getpid());
+ sprintf(mname,"%s/rnfile_%d",mdir,getpid());
+
+ do_file_setup(fname);
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /*
+ * Remove the temporary directory.
+ */
+ tst_rmdir();
+
+ /*
+ * Exit with return code appropriate for results.
+ */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/rmdir01.c b/winsup/testsuite/winsup.api/ltp/rmdir01.c
new file mode 100644
index 000000000..5b16a518b
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/rmdir01.c
@@ -0,0 +1,190 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * rmdir01
+ *
+ * DESCRIPTION
+ * This test will verify that rmdir(2) syscall basic functionality.
+ * verify rmdir(2) returns a value of 0 and the directory being
+ * removed
+ *
+ * ALGORITHM
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * make a directory tstdir
+ * call rmdir(tstdir), check the return value
+ * verify the directory tstdir does not exists.
+ *
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.*
+ * USAGE
+ * rmdir01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 07/2001 Ported by Wayne Boyer
+ *
+ * RESTRICTIONS
+ * None.
+ */
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "test.h"
+#include "usctest.h"
+
+void setup();
+void cleanup();
+
+#define PERMS 0777
+
+char *TCID="rmdir01"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+
+char tstdir [100];
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ struct stat buf;
+
+ /*
+ * parse standard options
+ */
+ if ((msg=parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL) {
+ tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ /*
+ * perform global setup for test
+ */
+ setup();
+
+ /*
+ * check looping state if -i option given
+ */
+ for (lc=0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * TEST rmdir() base functionality
+ */
+
+ /* Initialize the test directory name */
+
+ /* create a directory */
+ if ( mkdir(tstdir, PERMS) == -1 ) {
+ tst_brkm(TBROK, cleanup, "mkdir(%s, %#o) Failed",
+ tstdir, PERMS);
+ /*NOTREACHED*/
+ }
+ /* call rmdir using TEST macro */
+
+ TEST(rmdir(tstdir));
+
+ if (TEST_RETURN == -1 ) {
+ tst_resm(TFAIL, "rmdir(%s) Failed", tstdir);
+ continue;
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+ /* check whether tstdir been removed */
+ if (stat(tstdir, &buf) != -1) {
+ tst_resm(TFAIL, "directory %s still exists",
+ tstdir);
+ continue;
+ } else {
+ tst_resm(TPASS, "directory has been removed");
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+
+ } /* End for TEST_LOOPING */
+
+ /*
+ * cleanup and exit
+ */
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+
+ /* Create a temporary directory and make it current. */
+ tst_tmpdir();
+
+ sprintf(tstdir,"./tstdir_%d",getpid());
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /*
+ * Remove the temporary directory.
+ */
+ tst_rmdir();
+
+ /*
+ * Exit with return code appropriate for results.
+ */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/stat01.c b/winsup/testsuite/winsup.api/ltp/stat01.c
new file mode 100644
index 000000000..46b8262d5
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/stat01.c
@@ -0,0 +1,268 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: stat01
+ *
+ * Test Description:
+ * Verify that, stat(2) succeeds to get the status of a file and fills the
+ * stat structure elements.
+ *
+ * Expected Result:
+ * stat() should return value 0 on success and fills the stat structure
+ * elements with the specified 'file' information.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * stat01 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions:
+ *
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <pwd.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define FILE_MODE 0644
+#define TESTFILE "testfile"
+#define FILE_SIZE 1024
+#define BUF_SIZE 256
+#define MASK 0777
+
+char *TCID="stat01"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={0};
+uid_t User_id; /* Owner id of the test file */
+gid_t Group_id; /* Group id of the test file */
+char nobody_uid[] = "nobody";
+struct passwd *ltpuser;
+
+void setup(); /* Setup function for the test */
+void cleanup(); /* Cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ struct stat stat_buf; /* stat structure buffer */
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ /*NOTREACHED*/
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count = 0;
+
+ /*
+ * Call stat(2) to get the status of
+ * specified 'file' into stat structure.
+ */
+ TEST(stat(TESTFILE, &stat_buf));
+
+ /* check return code of stat(2) */
+ if (TEST_RETURN == -1) {
+ TEST_ERROR_LOG(TEST_ERRNO);
+ tst_resm(TFAIL, \
+ "stat(%s, &stat_buf) Failed, errno=%d : %s",
+ TESTFILE, TEST_ERRNO, strerror(TEST_ERRNO));
+ } else {
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ stat_buf.st_mode &= ~S_IFREG;
+ /*
+ * Verify the data returned by stat(2)
+ * aganist the expected data.
+ */
+ if ((stat_buf.st_uid != User_id) || \
+ (stat_buf.st_gid != Group_id) || \
+ (stat_buf.st_size != FILE_SIZE) || \
+ ((stat_buf.st_mode & MASK) != FILE_MODE)) {
+ tst_resm(TFAIL, "Functionality of "
+ "stat(2) on '%s' Failed",
+ TESTFILE);
+ } else {
+ tst_resm(TPASS, "Functionality of "
+ "stat(2) on '%s' Succcessful",
+ TESTFILE);
+ }
+ } else {
+ tst_resm(TINFO, "Call succeeded");
+ }
+ }
+ Tst_count++; /* incr. TEST_LOOP counter */
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+ /*NOTREACHED*/
+
+} /* End main */
+
+/*
+ * void
+ * setup() - Performs setup function for the test.
+ * Creat a temporary directory and change directory to it.
+ * Creat a testfile and write some known data into it.
+ * Get the effective uid/gid of test process.
+ */
+void
+setup()
+{
+ int i, fd;
+ char tst_buff[BUF_SIZE];
+ int wbytes;
+ int write_len = 0;
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+#if 0
+ /* Switch to nobody user for correct error code collection */
+ if (geteuid() != 0) {
+ tst_brkm(TBROK, tst_exit, "Test must be run as root");
+ }
+ ltpuser = getpwnam(nobody_uid);
+ if (setuid(ltpuser->pw_uid) == -1) {
+ tst_resm(TINFO, "setuid failed to "
+ "to set the effective uid to %d",
+ ltpuser->pw_uid);
+ perror("setuid");
+ }
+#endif
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -i option.
+ * You want to make sure you do this before you create your temporary
+ * directory.
+ */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ if ((fd = open(TESTFILE, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d : %s",
+ TESTFILE, FILE_MODE, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ /* Fill the test buffer with the known data */
+ for (i = 0; i < BUF_SIZE; i++) {
+ tst_buff[i] = 'a';
+ }
+
+ /* Write to the file 1k data from the buffer */
+ while (write_len < FILE_SIZE) {
+ if ((wbytes = write(fd, tst_buff, sizeof(tst_buff))) <= 0) {
+ tst_brkm(TBROK, cleanup,
+ "write(2) on %s Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ /*NOTREACHED*/
+ } else {
+ write_len += wbytes;
+ }
+ }
+
+ /* Close the testfile created */
+ if (close(fd) == -1) {
+ tst_resm(TWARN, "close(%s) Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ }
+
+ /* Get the uid/gid of the process */
+ User_id = getuid();
+ Group_id = getgid();
+
+} /* End setup() */
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the test file and temporary directory created.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/stat02.c b/winsup/testsuite/winsup.api/ltp/stat02.c
new file mode 100644
index 000000000..06bf73a35
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/stat02.c
@@ -0,0 +1,277 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: stat02
+ *
+ * Test Description:
+ * Verify that, stat(2) succeeds to get the status of a file and fills the
+ * stat structure elements though process doesn't have read access to the
+ * file.
+ *
+ * Expected Result:
+ * stat() should return value 0 on success and the stat structure elements
+ * should be filled with specified 'file' information.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * stat02 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions:
+ *
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <pwd.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+#define TESTFILE "testfile"
+#define FILE_SIZE 1024
+#define BUF_SIZE 256
+#define NEW_MODE 0222
+#define MASK 0777
+
+char *TCID="stat02"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={0};
+uid_t User_id; /* eff. user id/group id of test process */
+gid_t Group_id;
+char nobody_uid[] = "nobody";
+struct passwd *ltpuser;
+
+void setup(); /* Setup function for the test */
+void cleanup(); /* Cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ struct stat stat_buf; /* stat structure buffer */
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count = 0;
+
+ /*
+ * Call stat(2) to get the status of
+ * specified 'file' into stat structure.
+ */
+ TEST(stat(TESTFILE, &stat_buf));
+
+ /* check return code of stat(2) */
+ if (TEST_RETURN == -1) {
+ TEST_ERROR_LOG(TEST_ERRNO);
+ tst_resm(TFAIL,
+ "stat(%s, &stat_buf) Failed, errno=%d : %s",
+ TESTFILE, TEST_ERRNO, strerror(TEST_ERRNO));
+ } else {
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ stat_buf.st_mode &= ~S_IFREG;
+ /*
+ * Verify the data returned by stat(2)
+ * aganist the expected data.
+ */
+ if ((stat_buf.st_uid != User_id) || \
+ (stat_buf.st_gid != Group_id) || \
+ (stat_buf.st_size != FILE_SIZE) || \
+ ((stat_buf.st_mode & MASK) != NEW_MODE)) {
+ tst_resm(TFAIL, "Functionality of "
+ "stat(2) on '%s' Failed",
+ TESTFILE);
+ } else {
+ tst_resm(TPASS, "Functionality of "
+ "stat(2) on '%s' Succcessful",
+ TESTFILE);
+ }
+ } else {
+ tst_resm(TPASS, "Call succeeded");
+ }
+ }
+ Tst_count++; /* incr TEST_LOOP counter */
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+ /*NOTREACHED*/
+
+} /* End main */
+
+/*
+ * void
+ * setup() - Performs setup function for the test.
+ * Creat a temporary directory and change directory to it.
+ * Creat a testfile and write some data into it.
+ * Modify the mode permissions of testfile such that test process
+ * has read-only access to testfile.
+ */
+void
+setup()
+{
+ int i, fd; /* counter, file handle for file */
+ char tst_buff[BUF_SIZE]; /* data buffer for file */
+ int wbytes; /* no. of bytes written to file */
+ int write_len = 0;
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+#if 0
+ /* Switch to nobody user for correct error code collection */
+ if (geteuid() != 0) {
+ tst_brkm(TBROK, tst_exit, "Test must be run as root");
+ }
+ ltpuser = getpwnam(nobody_uid);
+ if (setuid(ltpuser->pw_uid) == -1) {
+ tst_resm(TINFO, "setuid failed to "
+ "to set the effective uid to %d",
+ ltpuser->pw_uid);
+ perror("setuid");
+ }
+#endif
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -i option.
+ * You want to make sure you do this before you create your temporary
+ * directory.
+ */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ if ((fd = open(TESTFILE, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d : %s",
+ TESTFILE, FILE_MODE, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ /* Fill the test buffer with the known data */
+ for (i = 0; i < BUF_SIZE; i++) {
+ tst_buff[i] = 'a';
+ }
+
+ /* Write to the file 1k data from the buffer */
+ while (write_len < FILE_SIZE) {
+ if ((wbytes = write(fd, tst_buff, sizeof(tst_buff))) <= 0) {
+ tst_brkm(TBROK, cleanup,
+ "write(2) on %s Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ /*NOTREACHED*/
+ } else {
+ write_len += wbytes;
+ }
+ }
+
+ if (close(fd) == -1) {
+ tst_resm(TWARN, "close(%s) Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ }
+
+ /* Modify mode permissions on the testfile */
+ if (chmod(TESTFILE, NEW_MODE) < 0) {
+ tst_brkm(TBROK, cleanup,
+ "chmod(2) on %s Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ /* Get the uid/gid of the process */
+ User_id = getuid();
+ Group_id = getgid();
+
+} /* End setup() */
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the temporary directory and file created.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/stat03.c b/winsup/testsuite/winsup.api/ltp/stat03.c
new file mode 100644
index 000000000..a1a94279f
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/stat03.c
@@ -0,0 +1,393 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: stat03
+ *
+ * Test Description:
+ * Verify that,
+ * 1) stat(2) returns -1 and sets errno to EACCES if search permission is
+ * denied on a component of the path prefix.
+ * 2) stat(2) returns -1 and sets errno to ENOENT if the specified file
+ * does not exists or empty string.
+ * 3) stat(2) returns -1 and sets errno to EFAULT if pathname points
+ * outside user's accessible address space.
+ * 4) stat(2) returns -1 and sets errno to ENAMETOOLONG if the pathname
+ * component is too long.
+ * 5) stat(2) returns -1 and sets errno to ENOTDIR if the directory
+ * component in pathname is not a directory.
+ *
+ * Expected Result:
+ * stat() should fail with return value -1 and set expected errno.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * if errno set == expected errno
+ * Issue sys call fails with expected return value and errno.
+ * Otherwise,
+ * Issue sys call fails with unexpected errno.
+ * Otherwise,
+ * Issue sys call returns unexpected value.
+ *
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory(s)/file(s) created.
+ *
+ * Usage: <for command-line>
+ * stat03 [-c n] [-e] [-i n] [-I x] [-p x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions:
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define MODE_RWX S_IRWXU | S_IRWXG | S_IRWXO
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+#define DIR_TEMP "testdir_1"
+#define TEST_FILE1 "testdir_1/tfile_1"
+#define TEST_FILE2 "t_file/tfile_2"
+
+int no_setup();
+int setup1(); /* setup function to test chmod for EACCES */
+int setup2(); /* setup function to test chmod for ENOTDIR */
+int longpath_setup(); /* setup function to test chmod for ENAMETOOLONG */
+char nobody_uid[] = "nobody";
+struct passwd *ltpuser;
+
+
+char Longpathname[PATH_MAX+2];
+char High_address_node[64];
+
+struct test_case_t { /* test case struct. to hold ref. test cond's*/
+ char *pathname;
+ char *desc;
+ int exp_errno;
+ int (*setupfunc)();
+} Test_cases[] = {
+#ifndef __CYGWIN__
+ { TEST_FILE1, "No Search permissions to process", EACCES, setup1 },
+#endif
+ { High_address_node, "Address beyond address space", EFAULT, no_setup },
+ { (char *)-1, "Negative address", EFAULT, no_setup },
+ { Longpathname, "Pathname too long", ENAMETOOLONG, longpath_setup },
+ { "", "Pathname is empty", ENOENT, no_setup },
+#ifndef __CYGWIN__
+ { TEST_FILE2, "Path contains regular file", ENOTDIR, setup2 },
+#endif
+ { NULL, NULL, 0, no_setup }
+};
+
+char *TCID="stat03"; /* Test program identifier. */
+int TST_TOTAL = 6; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={EACCES, EFAULT, ENAMETOOLONG, ENOENT, ENOTDIR, 0};
+
+void setup(); /* Main setup function for the tests */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ struct stat stat_buf; /* stat structure buffer */
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ char *file_name; /* ptr. for file name whose mode is modified*/
+ char *test_desc; /* test specific error message */
+ int ind; /* counter to test different test conditions */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ /*NOTREACHED*/
+ }
+
+ /*
+ * Invoke setup function to call individual test setup functions
+ * to simulate test conditions.
+ */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ for (ind = 0; Test_cases[ind].desc != NULL; ind++) {
+ file_name = Test_cases[ind].pathname;
+ test_desc = Test_cases[ind].desc;
+
+ if (file_name == High_address_node) {
+ file_name = (char *)get_high_address();
+ }
+
+ /*
+ * Call stat(2) to test different test conditions.
+ * verify that it fails with -1 return value and
+ * sets appropriate errno.
+ */
+ TEST(stat(file_name, &stat_buf));
+
+ /* Check return code from stat(2) */
+ if (TEST_RETURN == -1) {
+ TEST_ERROR_LOG(TEST_ERRNO);
+ if (TEST_ERRNO == Test_cases[ind].exp_errno) {
+ tst_resm(TPASS,
+ "stat() fails, %s, errno:%d",
+ test_desc, TEST_ERRNO);
+ } else {
+ tst_resm(TFAIL, "stat() fails, %s,
+ errno:%d, expected errno:%d",
+ test_desc, TEST_ERRNO,
+ Test_cases[ind].exp_errno);
+ }
+ } else {
+ tst_resm(TFAIL, "stat(2) returned %d,
+ expected -1, errno:%d", TEST_RETURN,
+ Test_cases[ind].exp_errno);
+ }
+ } /* End of TEST CASE LOOPING. */
+ Tst_count++; /* incr TEST_LOOP counter */
+ } /* End for TEST_LOOPING */
+
+ /*
+ * Invoke cleanup() to delete the test directory/file(s) created
+ * in the setup().
+ */
+ cleanup();
+ /*NOTREACHED*/
+
+} /* End main */
+
+/*
+ * void
+ * setup(void) - performs all ONE TIME setup for this test.
+ * Exit the test program on receipt of unexpected signals.
+ * Create a temporary directory and change directory to it.
+ * Invoke individual test setup functions according to the order
+ * set in struct. definition.
+ */
+void
+setup()
+{
+ int ind; /* counter for setup functions */
+
+ /* Capture unexpected signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+#if 0
+ /* Switch to nobody user for correct error code collection */
+ if (geteuid() != 0) {
+ tst_brkm(TBROK, tst_exit, "Test must be run as root");
+ }
+ ltpuser = getpwnam(nobody_uid);
+ if (setuid(ltpuser->pw_uid) == -1) {
+ tst_resm(TINFO, "setuid failed to "
+ "to set the effective uid to %d",
+ ltpuser->pw_uid);
+ perror("setuid");
+ }
+#endif
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -i option.
+ * You want to make sure you do this before you create your temporary
+ * directory.
+ */
+ TEST_PAUSE;
+
+ /* Make a temp dir and cd to it */
+ tst_tmpdir();
+
+ /* call individual setup functions */
+ for (ind = 0; Test_cases[ind].desc != NULL; ind++) {
+ Test_cases[ind].setupfunc();
+ }
+} /* End setup() */
+
+/*
+ * int
+ * no_setup() - Some test conditions for stat(2) do not any setup.
+ * Hence, this function just returns 0.
+ * This function simply returns 0.
+ */
+int
+no_setup()
+{
+ return 0;
+}
+
+
+/*
+ * int
+ * setup1() - setup function for a test condition for which stat(2)
+ * returns -1 and sets errno to EACCES.
+ * Create a test directory under temporary directory and create a test file
+ * under this directory with mode "0666" permissions.
+ * Modify the mode permissions on test directory such that process will not
+ * have search permissions on test directory.
+ *
+ * The function returns 0.
+ */
+int
+setup1()
+{
+ int fd; /* file handle for testfile */
+
+ /* Creat a test directory */
+ if (mkdir(DIR_TEMP, MODE_RWX) < 0) {
+ tst_brkm(TBROK, cleanup, "mkdir(2) of %s failed", DIR_TEMP);
+ /*NOTREACHED*/
+ }
+
+ /* Creat a test file under above test directory */
+ if ((fd = open(TEST_FILE1, O_RDWR|O_CREAT, 0666)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, 0666) failed, errno=%d : %s",
+ TEST_FILE1, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+ /* Close the test file */
+ if (close(fd) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "close(%s) Failed, errno=%d : %s",
+ TEST_FILE1, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ /* Modify mode permissions on test directory */
+ if (chmod(DIR_TEMP, FILE_MODE) < 0) {
+ tst_brkm(TBROK, cleanup, "chmod(2) of %s failed", DIR_TEMP);
+ /*NOTREACHED*/
+ }
+ return 0;
+}
+
+/*
+ * int
+ * setup2() - setup function for a test condition for which stat(2)
+ * returns -1 and sets errno to ENOTDIR.
+ *
+ * Create a test file under temporary directory so that test tries to
+ * change mode of a testfile "tfile_2" under "t_file" which happens to be
+ * another regular file.
+ */
+int
+setup2()
+{
+ int fd; /* File handle for test file */
+
+ /* Creat a test file under temporary directory */
+ if ((fd = open("t_file", O_RDWR|O_CREAT, MODE_RWX)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(2) on t_file failed, errno=%d : %s",
+ errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+ /* Close the test file created above */
+ if (close(fd) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "close(t_file) Failed, errno=%d : %s",
+ errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+ return 0;
+}
+
+/*
+ * int
+ * longpath_setup() - setup to create a node with a name length exceeding
+ * the MAX. length of PATH_MAX.
+ * This function retruns 0.
+ */
+int
+longpath_setup()
+{
+ int ind; /* counter variable */
+
+ for (ind = 0; ind <= (PATH_MAX + 1); ind++) {
+ Longpathname[ind] = 'a';
+ }
+ return 0;
+}
+
+/*
+ * void
+ * cleanup() - Performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Print test timing stats and errno log if test executed with options.
+ * Remove temporary directory and sub-directories/files under it
+ * created during setup().
+ * Exit the test program with normal exit code.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+#ifndef __CYGWIN__
+ /* Restore mode permissions on test directory created in setup2() */
+ if (chmod(DIR_TEMP, MODE_RWX) < 0) {
+ tst_brkm(TFAIL, NULL, "chmod(2) of %s failed", DIR_TEMP);
+ }
+#endif
+
+ /* Remove files and temporary directory created */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/symlink03.c b/winsup/testsuite/winsup.api/ltp/symlink03.c
new file mode 100644
index 000000000..9cdb74b18
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/symlink03.c
@@ -0,0 +1,404 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name : symlink03
+ *
+ * Test Description :
+ * Verify that,
+ * 1) symlink(2) returns -1 and sets errno to EACCES if search/write
+ * permission is denied in the directory where the symbolic link is
+ * being created.
+ * 2) symlink(2) returns -1 and sets errno to EEXIST if the specified
+ * symbolic link already exists.
+ * 3) symlink(2) returns -1 and sets errno to EFAULT if the specified
+ * file or symbolic link points to invalid address.
+ * 4) symlink(2) returns -1 and sets errno to ENAMETOOLONG if the
+ * pathname component of symbolic link is too long (ie, > PATH_MAX).
+ * 5) symlink(2) returns -1 and sets errno to ENOTDIR if the directory
+ * component in pathname of symbolic link is not a directory.
+ * 6) symlink(2) returns -1 and sets errno to ENOENT if the component of
+ * symbolic link points to an empty string.
+ *
+ * Expected Result:
+ * symlink() should fail with return value -1 and set expected errno.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * if errno set == expected errno
+ * Issue sys call fails with expected return value and errno.
+ * Otherwise,
+ * Issue sys call fails with unexpected errno.
+ * Otherwise,
+ * Issue sys call returns unexpected value.
+ *
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory(s)/file(s) created.
+ *
+ * Usage: <for command-line>
+ * symlink03 [-c n] [-e] [-i n] [-I x] [-p x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions:
+ * This test should be executed by 'non-super-user' only.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define MODE_RWX S_IRWXU | S_IRWXG | S_IRWXO
+#define FILE_MODE S_IRUSR | S_IRGRP | S_IROTH
+#define DIR_TEMP "testdir_1"
+#define TESTFILE "testfile"
+#define TEST_FILE1 "testdir_1/tfile_1"
+#define SYM_FILE1 "testdir_1/sfile_1"
+#define TEST_FILE2 "tfile_2"
+#define SYM_FILE2 "sfile_2"
+#define TEST_FILE3 "tfile_3"
+#define SYM_FILE3 "t_file/sfile_3"
+
+char *TCID="symlink03"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={ENOTDIR, ENOENT, ENAMETOOLONG, EFAULT, EEXIST, EACCES, 0};
+
+int no_setup();
+int setup1(); /* setup function to test symlink for EACCES */
+int setup2(); /* setup function to test symlink for EEXIST */
+int setup3(); /* setup function to test symlink for ENOTDIR */
+int longpath_setup(); /* setup function to test chmod for ENAMETOOLONG */
+
+char Longpathname[PATH_MAX+2];
+char High_address_node[64];
+
+struct test_case_t { /* test case struct. to hold ref. test cond's*/
+ char *file;
+ char *link;
+ char *desc;
+ int exp_errno;
+ int (*setupfunc)();
+} Test_cases[] = {
+ { TEST_FILE1, SYM_FILE1, "No Search permissions to process", EACCES, setup1 },
+ { TEST_FILE2, SYM_FILE2, "Specified symlink already exists", EEXIST, setup2 },
+ { TESTFILE, High_address_node, "Address beyond address space", EFAULT, no_setup },
+ { TESTFILE, (char *)-1, "Negative address", EFAULT, no_setup },
+ { TESTFILE, Longpathname, "Symlink path too long", ENAMETOOLONG, longpath_setup },
+ { TESTFILE, "", "Symlink Pathname is empty", ENOENT, no_setup },
+#ifndef __CYGWIN__
+ { TEST_FILE3, SYM_FILE3, "Symlink Path contains regular file", ENOTDIR, setup3 },
+#endif
+ { NULL, NULL, NULL, 0, no_setup }
+};
+
+extern void setup(); /* Setup function for the test */
+extern void cleanup(); /* Cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ char *test_file; /* testfile name */
+ char *sym_file; /* symbolic link file name */
+ char *test_desc; /* test specific error message */
+ int ind; /* counter to test different test conditions */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ /*NOTREACHED*/
+ }
+
+ /*
+ * Invoke setup function to call individual test setup functions
+ * to simulate test conditions.
+ */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ for (ind = 0; Test_cases[ind].desc != NULL; ind++) {
+ test_file = Test_cases[ind].file;
+ sym_file = Test_cases[ind].link;
+ test_desc = Test_cases[ind].desc;
+
+ if (sym_file == High_address_node) {
+ sym_file = (char *)get_high_address();
+ }
+ /*
+ * Call symlink(2) to test different test conditions.
+ * verify that it fails with -1 return value and sets
+ * appropriate errno.
+ */
+ TEST(symlink(test_file, sym_file));
+
+ /* Check return code of symlink(2) */
+ if (TEST_RETURN == -1) {
+ /*
+ * Perform functional verification if
+ * test executed without (-f) option.
+ */
+ TEST_ERROR_LOG(TEST_ERRNO);
+ if (TEST_ERRNO == Test_cases[ind].exp_errno) {
+ tst_resm(TPASS, "symlink() Fails, %s, "
+ "errno=%d", test_desc,
+ TEST_ERRNO);
+ } else {
+ tst_resm(TFAIL, "symlink() Fails, %s, "
+ "errno=%d, expected errno=%d",
+ test_desc, TEST_ERRNO,
+ Test_cases[ind].exp_errno);
+ }
+ } else {
+ tst_resm(TFAIL, "symlink() returned %d, "
+ "expected -1, errno:%d", TEST_RETURN,
+ Test_cases[ind].exp_errno);
+ }
+ } /* End of TEST CASE LOOPING. */
+
+ Tst_count++; /* incr. TEST_LOOP counter */
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+ /*NOTREACHED*/
+
+} /* End main */
+
+/*
+ * void
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ * Call test specific setup functions.
+ */
+void
+setup()
+{
+ int ind;
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -i option.
+ * You want to make sure you do this before you create your temporary
+ * directory.
+ */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* call individual setup functions */
+ for (ind = 0; Test_cases[ind].desc != NULL; ind++) {
+ Test_cases[ind].setupfunc();
+ }
+} /* End setup() */
+
+/*
+ * int
+ * no_setup() - Some test conditions for mknod(2) do not any setup.
+ * Hence, this function just returns 0.
+ * This function simply returns 0.
+ */
+int
+no_setup()
+{
+ return 0;
+}
+
+/*
+ * int
+ * setup1() - setup function for a test condition for which symlink(2)
+ * returns -1 and sets errno to EACCES.
+ * Create a test directory under temporary directory and create a test file
+ * under this directory with mode "0666" permissions.
+ * Modify the mode permissions on test directory such that process will not
+ * have search permissions on test directory.
+ *
+ * The function returns 0.
+ */
+int
+setup1()
+{
+ int fd; /* file handle for testfile */
+
+ if (mkdir(DIR_TEMP, MODE_RWX) < 0) {
+ tst_brkm(TBROK, cleanup, "mkdir(2) of %s failed", DIR_TEMP);
+ /*NOTREACHED*/
+ }
+
+ if ((fd = open(TEST_FILE1, O_RDWR|O_CREAT, 0666)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, 0666) failed, errno=%d : %s",
+ TEST_FILE1, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+ if (close(fd) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "close(%s) Failed, errno=%d : %s",
+ TEST_FILE1, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ /* Modify mode permissions on test directory */
+ if (chmod(DIR_TEMP, FILE_MODE) < 0) {
+ tst_brkm(TBROK, cleanup, "chmod(2) of %s failed", DIR_TEMP);
+ /*NOTREACHED*/
+ }
+ return 0;
+}
+
+/*
+ * int
+ * setup2() - EEXIST
+ */
+int
+setup2()
+{
+ int fd; /* file handle for testfile */
+
+ if ((fd = open(TEST_FILE2, O_RDWR|O_CREAT, 0666)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, 0666) failed, errno=%d : %s",
+ TEST_FILE1, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+ if (close(fd) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "close(%s) Failed, errno=%d : %s",
+ TEST_FILE2, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ if (symlink(TEST_FILE2, SYM_FILE2) < 0) {
+ tst_brkm(TBROK, cleanup,
+ "symlink() Fails to create %s in setup2, error=%d",
+ SYM_FILE2, errno);
+ /*NOTREACHED*/
+ }
+ return 0;
+}
+
+/*
+ * int
+ * longpath_setup() - setup to create a node with a name length exceeding
+ * the MAX. length of PATH_MAX.
+ * This function retruns 0.
+ */
+int
+longpath_setup()
+{
+ int ind; /* counter variable */
+
+ for (ind = 0; ind <= (PATH_MAX + 1); ind++) {
+ Longpathname[ind] = 'a';
+ }
+ return 0;
+}
+
+/*
+ * int
+ * setup3() - setup function for a test condition for which symlink(2)
+ * returns -1 and sets errno to ENOTDIR.
+ *
+ * Create a symlink file under temporary directory so that test tries to
+ * create symlink file "tfile_3" under "t_file" which happens to be
+ * another symlink file.
+ */
+int
+setup3()
+{
+ int fd; /* file handle for testfile */
+
+ /* Creat/open a testfile and close it */
+ if ((fd = open("t_file", O_RDWR|O_CREAT, MODE_RWX)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(2) on t_file failed, errno=%d : %s",
+ errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+ if (close(fd) == -1) {
+ tst_brkm(TBROK, cleanup, "close(t_file) Failed, errno=%d : %s",
+ errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+ return 0;
+}
+
+/*
+ * void
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Restore the mode permissions on test directory.
+ * Remove the temporary directory created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Restore mode permissions on test directory created in setup2() */
+ if (chmod(DIR_TEMP, MODE_RWX) < 0) {
+ tst_brkm(TBROK, NULL, "chmod(2) of %s failed", DIR_TEMP);
+ }
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/symlink04.c b/winsup/testsuite/winsup.api/ltp/symlink04.c
new file mode 100644
index 000000000..8272d368c
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/symlink04.c
@@ -0,0 +1,239 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name : symlink01
+ *
+ * Test Description :
+ * Verify that, symlink will succeed to creat a symbolic link of an existing
+ * object name path.
+ *
+ * Expected Result:
+ * symlink() should return value 0 on success and symbolic link of an
+ * existing object should be created.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * symlink01 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions:
+ * None.
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include "test.h"
+#include "usctest.h"
+
+#define TESTFILE "testfile"
+#define SYMFILE "slink_file"
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+
+char *TCID="symlink01"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={0};
+
+extern void setup(); /* Setup function for the test */
+extern void cleanup(); /* Cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ struct stat stat_buf; /* stat structure buffer */
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ /*NOTREACHED*/
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Call symlink(2) to create a symlink of
+ * testfile.
+ */
+ TEST(symlink(TESTFILE, SYMFILE));
+
+ /* Check return code of symlink(2) */
+ if (TEST_RETURN == -1) {
+ TEST_ERROR_LOG(TEST_ERRNO);
+ tst_resm(TFAIL, "symlink(%s, %s) Failed, errno=%d : %s",
+ TESTFILE, SYMFILE, TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ } else {
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Get the symlink file status information
+ * using lstat(2).
+ */
+ if (lstat(SYMFILE, &stat_buf) < 0) {
+ tst_brkm(TFAIL, cleanup, "lstat(2) of "
+ "%s failed, error:%d", SYMFILE,
+ errno);
+ /*NOTREACHED*/
+ }
+
+ /* Check if the st_mode contains a link */
+ if (!S_ISLNK(stat_buf.st_mode)) {
+ tst_resm(TFAIL,
+ "symlink of %s doesn't exist",
+ TESTFILE);
+ } else {
+ tst_resm(TPASS, "symlink(%s, %s) "
+ "functionality successful",
+ TESTFILE, SYMFILE);
+ }
+ } else {
+ tst_resm(TPASS, "Call succeeded");
+ }
+ }
+
+ /* Unlink the symlink file for next loop */
+ if (unlink(SYMFILE) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "unlink(%s) Failed, errno=%d : %s",
+ SYMFILE, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+ Tst_count++; /* incr TEST_LOOP counter */
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+ /*NOTREACHED*/
+
+} /* End main */
+
+/*
+ * void
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ * Create a test file under temporary directory and close it
+ */
+void
+setup()
+{
+ int fd; /* file handle for testfile */
+
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -i option.
+ * You want to make sure you do this before you create your temporary
+ * directory.
+ */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* creat/open a testfile */
+ if ((fd = open(TESTFILE, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d : %s",
+ TESTFILE, FILE_MODE, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ /* Close the temporary file created above */
+ if (close(fd) == -1) {
+ tst_resm(TBROK, "close(%s) Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ }
+} /* End setup() */
+
+
+/*
+ * void
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/symlink05.c b/winsup/testsuite/winsup.api/ltp/symlink05.c
new file mode 100644
index 000000000..36aff558f
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/symlink05.c
@@ -0,0 +1,223 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name : symlink02
+ *
+ * Test Description :
+ * Verify that, symlink will succeed to creat a symbolic link of an
+ * non-existing object name path.
+ *
+ * Expected Result:
+ * symlink() should return value 0 on success and symlink of an
+ * non-existing object should be created.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * symlink02 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions:
+ * This test should be run by 'non-super-user' only.
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TESTFILE "testfile"
+#define SYMFILE "slink_file"
+
+char *TCID="symlink02"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={0};
+
+extern void setup(); /* Setup function for the test */
+extern void cleanup(); /* Cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ struct stat stat_buf; /* stat structure buffer */
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ /*NOTREACHED*/
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Call symlink(2) to create a symlink of
+ * an non-existing testfile.
+ */
+ TEST(symlink(TESTFILE, SYMFILE));
+
+ /* Check return code of symlink(2) */
+ if (TEST_RETURN == -1) {
+ TEST_ERROR_LOG(TEST_ERRNO);
+ tst_resm(TFAIL, \
+ "symlink(%s, %s) Failed, errno=%d : %s",
+ TESTFILE, SYMFILE, TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ } else {
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Get the symlink file status information
+ * using lstat(2).
+ */
+ if (lstat(SYMFILE, &stat_buf) < 0) {
+ tst_brkm(TFAIL, cleanup, "lstat(2) of "
+ "%s failed, error:%d",
+ SYMFILE, errno);
+ /*NOTREACHED*/
+ }
+
+ /* Check if the st_mode contains a link */
+ if (!S_ISLNK(stat_buf.st_mode)) {
+ tst_resm(TFAIL, \
+ "symlink of %s doesn't exist",
+ TESTFILE);
+ } else {
+ tst_resm(TPASS, "symlink(%s, %s) "
+ "functionality successful",
+ TESTFILE, SYMFILE);
+ }
+ } else {
+ tst_resm(TPASS, "Call succeeded");
+ }
+ }
+
+ /* Unlink the symlink file for next loop */
+ if (unlink(SYMFILE) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "unlink(%s) Failed, errno=%d : %s",
+ SYMFILE, errno, strerror(errno));
+ }
+ Tst_count++; /* incr TEST_LOOP counter */
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+ /*NOTREACHED*/
+
+} /* End main */
+
+/*
+ * void
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -i option.
+ * You want to make sure you do this before you create your temporary
+ * directory.
+ */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+} /* End setup() */
+
+
+/*
+ * void
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the temporary directory created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/sync02.c b/winsup/testsuite/winsup.api/ltp/sync02.c
new file mode 100644
index 000000000..443df02bf
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/sync02.c
@@ -0,0 +1,240 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: sync01
+ *
+ * Test Description:
+ * Open a file for write; modify the file, then do a sync().
+ * Verify that the data has been written to disk by re-opening the file.
+ *
+ * Expected Result:
+ * sync() alawys returns 0 in Linux. The data written to the file should
+ * be updated to the disk.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * sync01 [-c n] [-f] [-i n] [-I x] [-p x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions:
+ * None.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TEMP_FILE "temp_file"
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+
+char *TCID="sync01"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+char write_buffer[BUFSIZ]; /* buffer used to write data to file*/
+int fildes; /* file descriptor for temporary file */
+
+void setup(); /* Main setup function of test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ char read_buffer[BUFSIZ]; /* buffer used to read data from file*/
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Call sync(2) to commit buffer data to disk.
+ */
+ TEST_VOID(sync());
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL, "%s, Failed, errno=%d : %s",
+ TCID, TEST_ERRNO, strerror(TEST_ERRNO));
+ } else {
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /* Set the file ptr to b'nning of file */
+ if (lseek(fildes, 0, SEEK_SET) < 0) {
+ tst_brkm(TFAIL, cleanup, "lseek() "
+ "failed on %s, error=%d",
+ TEMP_FILE, errno);
+ /*NOTREACHED*/
+ }
+
+ /* Read the contents of file */
+ if (read(fildes, read_buffer, \
+ sizeof(read_buffer)) > 0) {
+ if (memcmp(read_buffer, write_buffer, strlen(write_buffer))) {
+ tst_resm(TFAIL, "Data read "
+ "from %s doesn't match "
+ "with witten data",
+ TEMP_FILE);
+ } else {
+ tst_resm(TPASS, "Functionality "
+ "of sync() successful");
+ }
+ } else {
+ tst_brkm(TFAIL, cleanup,
+ "read() Fails on %s, error=%d",
+ TEMP_FILE, errno);
+ /*NOTREACHED*/
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+ }
+ Tst_count++; /* incr. TEST_LOOP counter */
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+ /*NOTREACHED*/
+
+} /* End main */
+
+/*
+ * void
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ * Create a test file under temporary directory and write some
+ * data into it.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -i option.
+ * You want to make sure you do this before you create your temporary
+ * directory.
+ */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Copy some data into data buffer */
+ strcpy(write_buffer, "abcdefghijklmnopqrstuvwxyz");
+
+ /* Creat a temporary file under above directory */
+ if ((fildes = open(TEMP_FILE, O_RDWR | O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR | O_CREAT, %#o) Failed, errno=%d :%s",
+ TEMP_FILE, FILE_MODE, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ /* Write the buffer data into file */
+ if (write(fildes, write_buffer, strlen(write_buffer)) != \
+ strlen(write_buffer)) {
+ tst_brkm(TBROK, cleanup,
+ "write() failed to write buffer data to %s",
+ TEMP_FILE);
+ /*NOTREACHED*/
+ }
+
+} /* End setup() */
+
+/*
+ * void
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Close the temporary file */
+ if (close(fildes) == -1) {
+ tst_brkm(TFAIL, NULL,
+ "close(%s) Failed, errno=%d : %s",
+ TEMP_FILE, errno, strerror(errno));
+ }
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/time02.c b/winsup/testsuite/winsup.api/ltp/time02.c
new file mode 100644
index 000000000..827ed3201
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/time02.c
@@ -0,0 +1,183 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: time01
+ *
+ * Test Description:
+ * Verify that time(2) returns the value of time in seconds since
+ * the Epoch and stores this value in the memory pointed to by the parameter.
+ *
+ * Expected Result:
+ * time() should return the time (seconds) since the Epoch and this value
+ * should be equal to the value stored in the specified parameter.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ *
+ * Usage: <for command-line>
+ * time01 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions:
+ * None.
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/types.h>
+
+#include "test.h"
+#include "usctest.h"
+
+extern void setup(); /* setup function for the test */
+extern void cleanup(); /* cleanup function for the test */
+
+char *TCID="time01"; /* Test program identifier. */
+int TST_TOTAL = 1; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={0};
+
+int
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ time_t tloc; /* time_t variables for time(2) */
+
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc=0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count=0;
+
+ /*
+ * Call time() to get the time in seconds
+ * since Epoch.
+ */
+ TEST(time(&tloc));
+
+ /* Check return code from time(2) */
+ if (TEST_RETURN == -1) {
+ TEST_ERROR_LOG(TEST_ERRNO);
+ tst_resm(TFAIL, "time(0) Failed, errno=%d : %s",
+ TEST_ERRNO, strerror(TEST_ERRNO));
+ } else {
+ /*
+ * Perform functional verification if test executed
+ * without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ if (tloc == TEST_RETURN) {
+ tst_resm(TPASS, "time() returned value "
+ "%d, stored value %d are same",
+ TEST_RETURN, tloc);
+ } else {
+ tst_resm(TFAIL, "time() returned value "
+ "%d, stored value %d are "
+ "different", TEST_RETURN, tloc);
+ }
+ } else {
+ tst_resm(TPASS, "call succeeded");
+ }
+
+ }
+ Tst_count++; /* incr. TEST_LOOP counter */
+ } /* End for TEST_LOOPING */
+
+ /* cleanup and exit */
+ cleanup();
+ /*NOTREACHED*/
+
+} /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+} /* End setup() */
+
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/times02.c b/winsup/testsuite/winsup.api/ltp/times02.c
new file mode 100644
index 000000000..825046430
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/times02.c
@@ -0,0 +1,135 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * times02.c
+ *
+ * DESCRIPTION
+ * Testcase to test that times() sets errno correctly
+ *
+ * ALGORITHM
+ * block1: Pass an invalid address as the "tms" structure, and expect
+ * that times() would return EFAULT.
+ *
+ * USAGE: <for command-line>
+ * times02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions
+ * NONE
+ */
+
+#include <sys/times.h>
+#include <errno.h>
+#include <test.h>
+#include <usctest.h>
+
+char *TCID = "times02";
+int TST_TOTAL = 1;
+extern int Tst_count;
+int exp_enos[]={EFAULT, 0};
+
+void setup(void);
+void cleanup(void);
+
+main(int argc, char **argv)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ /* parse standard options */
+ if ((msg = parse_opts(argc, argv, (option_t *)NULL, NULL)) !=
+ (char *)NULL) {
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup();
+
+ /* check for looping state if -i option is given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ TEST(times((void *)-1));
+ if (TEST_RETURN == -1) {
+ TEST_ERROR_LOG(TEST_ERRNO);
+ if (errno != EFAULT) {
+ tst_resm(TFAIL, "Expected EFAULT, got %d",
+ errno);
+ } else {
+ tst_resm(TPASS, "Received EFAULT as expected");
+ }
+
+ } else {
+ tst_resm(TFAIL, "times(2) failed to FAIL");
+ }
+
+ }
+ cleanup();
+ /*NOTREACHED*/
+}
+
+/*
+ * setup()
+ * performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -c option.
+ */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup()
+ * performs all ONE TIME cleanup for this test at
+ * completion or premature exit
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+ /*NOTREACHED*/
+}
diff --git a/winsup/testsuite/winsup.api/ltp/times03.c b/winsup/testsuite/winsup.api/ltp/times03.c
new file mode 100644
index 000000000..a388c77f7
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/times03.c
@@ -0,0 +1,246 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * times01.c
+ *
+ * DESCRIPTION
+ * Testcase to check the basic functionality of the times() system call.
+ *
+ * ALGORITHM
+ * This testcase checks the values that times(2) system call returns.
+ * Start a process, and spend some CPU time by performing a spin in
+ * a for-loop. Then use the times() system call, to determine the
+ * cpu time/sleep time, and other statistics.
+ *
+ * USAGE: <for command-line>
+ * times01 [-c n] [-f] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions
+ * NONE
+ */
+
+#include <sys/types.h>
+#include <sys/times.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <test.h>
+#include <usctest.h>
+
+char *TCID = "times01";
+int TST_TOTAL = 1;
+extern int Tst_count;
+int exp_enos[]={0};
+
+void setup(void);
+void cleanup(void);
+
+main(int argc, char **argv)
+{
+ const char *msg; /* message returned from parse_opts */
+
+ struct tms buf1, buf2;
+ time_t start_time, end_time;
+ int i, pid1, pid2, status, fail=0;
+
+ /* parse standard options */
+ if ((msg = parse_opts(argc, argv, (option_t *)NULL, NULL)) !=
+ (char *)NULL) {
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup();
+
+
+ for (i = 0; i < 1000000; i++);
+ /*
+ * At least some CPU time must be used. This is
+ * achieved by executing the times(2) call for
+ * atleast 5 secs. This logic makes it independant
+ * of the processor speed.
+ */
+ start_time = time(NULL);
+ for (;;) {
+ if (times(&buf1) == -1) {
+ TEST_ERROR_LOG(errno);
+ tst_resm(TFAIL, "Call to times(2) "
+ "failed, errno = %d", errno);
+ }
+ end_time = time(NULL);
+ if ((end_time - start_time) > 5) {
+ break;
+ }
+ }
+ if (times(&buf1) == -1) {
+ TEST_ERROR_LOG(errno);
+ tst_resm(TFAIL, "Call to times(2) failed, "
+ "errno = %d", errno);
+ } else {
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ if (buf1.tms_utime == 0) {
+ tst_resm(TFAIL, "Error: times() report "
+ "0 user time");
+ fail=1;
+ }
+ if (buf1.tms_stime == 0) {
+ tst_resm(TFAIL, "Error: times() report "
+ "0 system time");
+ fail=1;
+ }
+ if (buf1.tms_cutime != 0) {
+ tst_resm(TFAIL, "Error: times() report "
+ "%d child user time",
+ buf1.tms_cutime);
+ fail=1;
+ }
+ if (buf1.tms_cstime != 0) {
+ tst_resm(TFAIL, "Error: times() report " "%d child system time",
+ buf1.tms_cstime);
+ fail=1;
+ }
+
+ pid2 = fork();
+ if (pid2 < 0) {
+ tst_brkm(TFAIL, cleanup, "Fork failed");
+ /*NOTREACHED*/
+ } else if (pid2 == 0) {
+ for (i = 0; i < 2000000; i++);
+ /*
+ * Atleast some CPU time must be used
+ * even in the child process (thereby
+ * making it independent of the
+ * processor speed). In fact the child
+ * uses twice as much CPU time.
+ */
+ start_time = time(NULL);
+ for (;;) {
+ if (times(&buf2) == -1) {
+ tst_resm(TFAIL,
+ "Call to times "
+ "failed, "
+ "errno = %d",
+ errno);
+ exit(1);
+ }
+ end_time = time(NULL);
+ if ((end_time - start_time)
+ > 10) {
+ break;
+ }
+ }
+ exit(0);
+ }
+ waitpid(pid2, &status, 0);
+ if (WEXITSTATUS(status) != 0) {
+ tst_resm(TFAIL, "Call to times(2) "
+ "failed in child");
+ }
+ if (times(&buf2) == -1) {
+ TEST_ERROR_LOG(TEST_ERRNO);
+ tst_resm(TFAIL, "Call to times failed "
+ "errno = %d", errno);
+ fail=1;
+ }
+ if (buf1.tms_utime > buf2.tms_utime) {
+ tst_resm(TFAIL, "Error: parents's "
+ "user time(%d) before child "
+ "> parent's user time (%d) "
+ "after child",
+ buf1.tms_utime,
+ buf2.tms_utime);
+ fail=1;
+ }
+ if (buf2.tms_cutime == 0) {
+ tst_resm(TFAIL, "Error: times() "
+ "report %d child user "
+ "time should be > than "
+ "zero", buf2.tms_cutime);
+ fail=1;
+ }
+ if (buf2.tms_cstime == 0) {
+ tst_resm(TFAIL, "Error: times() "
+ "report %d child system time "
+ "should be > than zero",
+ buf2.tms_cstime);
+ fail=1;
+ }
+ if (fail == 0) {
+ tst_resm(TPASS, "%s: Functionality "
+ "test passed", TCID);
+ }
+
+ } else {
+ tst_resm(TPASS, "%s call succeeded", TCID);
+ }
+ }
+ cleanup();
+ /*NOTREACHED*/
+}
+
+/*
+ * setup()
+ * performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -c option.
+ */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup()
+ * performs all ONE TIME cleanup for this test at
+ * completion or premature exit
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+ /*NOTREACHED*/
+}
diff --git a/winsup/testsuite/winsup.api/ltp/truncate01.c b/winsup/testsuite/winsup.api/ltp/truncate01.c
new file mode 100644
index 000000000..d8dc1b68e
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/truncate01.c
@@ -0,0 +1,262 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: truncate01
+ *
+ * Test Description:
+ * Verify that, truncate(2) succeeds to truncate a file to a specified
+ * length.
+ *
+ * Expected Result:
+ * truncate(2) should return a value 0 and the length of the file after
+ * truncation should be equal to the length it is truncated to.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * truncate01 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions:
+ * This test should be run by 'non-super-user' only.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TESTFILE "testfile" /* file under test */
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+#define BUF_SIZE 256 /* buffer size */
+#define FILE_SIZE 1024 /* test file size */
+#define TRUNC_LEN 256 /* truncation length */
+
+char *TCID="truncate01"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test conditions */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int exp_enos[]={0};
+
+void setup(); /* setup function for the test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ struct stat stat_buf; /* stat(2) struct contents */
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ off_t file_length; /* test file length */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count = 0;
+
+ /*
+ * Call truncate(2) to truncate a test file to a
+ * specified length.
+ */
+ TEST(truncate(TESTFILE, TRUNC_LEN));
+
+ /* check return code of truncate(2) */
+ if (TEST_RETURN == -1) {
+ TEST_ERROR_LOG(TEST_ERRNO);
+ tst_resm(TFAIL,
+ "truncate(%s, %d) Failed, errno=%d : %s",
+ TESTFILE, TRUNC_LEN, TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ } else {
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Get the testfile information using
+ * stat(2).
+ */
+ if (stat(TESTFILE, &stat_buf) < 0) {
+ tst_brkm(TFAIL, cleanup, "stat(2) of "
+ "%s failed, error:%d",
+ TESTFILE, errno);
+ /*NOTREACHED*/
+ }
+ stat_buf.st_mode &= ~S_IFREG;
+ file_length = stat_buf.st_size;
+
+ /*
+ * Check for expected size of testfile after
+ * truncate(2) on it.
+ */
+ if (file_length != TRUNC_LEN) {
+ tst_resm(TFAIL, "%s: Incorrect file "
+ "size %d, Expected %d",
+ TESTFILE, file_length,
+ TRUNC_LEN);
+ } else {
+ tst_resm(TPASS, "Functionality of "
+ "truncate(%s, %d) successful",
+ TESTFILE, TRUNC_LEN);
+ }
+ } else {
+ tst_resm(TPASS, "%s call succeeded", TCID);
+ }
+ }
+ Tst_count++; /* incr TEST_LOOP counter */
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+ /*NOTREACHED*/
+
+} /* End main */
+
+/*
+ * void
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ * Fill the buffer with some arbitrary data to be written to a file.
+ * Create a test file under temporary directory and close it
+ * write arbitrary data into testfile.
+ */
+void
+setup()
+{
+ int fd, i; /* file handler for testfile */
+ int c, c_total = 0; /* no. bytes to be written to file */
+ char tst_buff[BUF_SIZE]; /* buffer to hold data */
+
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -i option.
+ * You want to make sure you do this before you create your temporary
+ * directory.
+ */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ /* Fill the test buffer with the known data */
+ for (i = 0; i < BUF_SIZE; i++) {
+ tst_buff[i] = 'a';
+ }
+
+ /* Creat a testfile under temporary directory */
+ if ((fd = open(TESTFILE, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %o) Failed, errno=%d : %s",
+ TESTFILE, FILE_MODE, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ /* Write to the file 1k data from the buffer */
+ while (c_total < FILE_SIZE) {
+ if ((c = write(fd, tst_buff, sizeof(tst_buff))) <= 0) {
+ tst_brkm(TBROK, cleanup,
+ "write(2) on %s Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ /*NOTREACHED*/
+ } else {
+ c_total += c;
+ }
+ }
+
+ /* Close the testfile after writing data into it */
+ if (close(fd) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "close(%s) Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+} /* End setup() */
+
+/*
+ * void
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/truncate02.c b/winsup/testsuite/winsup.api/ltp/truncate02.c
new file mode 100644
index 000000000..b6e535cca
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/truncate02.c
@@ -0,0 +1,335 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Test Name: truncate02
+ *
+ * Test Description:
+ * Verify that, truncate(2) succeeds to truncate a file to a certain length,
+ * but the attempt to read past the truncated length will fail.
+ *
+ * Expected Result:
+ * truncate(2) should return a value 0 and the attempt to read past the
+ * truncated length will fail. In case where the file before truncation was
+ * shorter, the bytes between the old and new should be all zeroes.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Create temporary directory.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * Log the errno and Issue a FAIL message.
+ * Otherwise,
+ * Verify the Functionality of system call
+ * if successful,
+ * Issue Functionality-Pass message.
+ * Otherwise,
+ * Issue Functionality-Fail message.
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ * Delete the temporary directory created.
+ *
+ * Usage: <for command-line>
+ * truncate02 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions:
+ * This test should be run by 'non-super-user' only.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+
+#include "test.h"
+#include "usctest.h"
+
+#define TESTFILE "testfile" /* file under test */
+#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+#define BUF_SIZE 256 /* buffer size */
+#define FILE_SIZE 1024 /* test file size */
+#define TRUNC_LEN1 256 /* truncation length */
+#define TRUNC_LEN2 512 /* truncation length */
+
+char *TCID="truncate02"; /* Test program identifier. */
+int TST_TOTAL=1; /* Total number of test conditions */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+int fd; /* file descriptor of testfile */
+char tst_buff[BUF_SIZE]; /* buffer to hold testfile contents */
+int exp_enos[]={0};
+
+void setup(); /* setup function for the test */
+void cleanup(); /* cleanup function for the test */
+
+int
+main(int ac, char **av)
+{
+ struct stat stat_buf; /* stat(2) struct contents */
+ int lc, i; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ off_t file_length2; /* test file length */
+ off_t file_length1; /* test file length */
+ int rbytes; /* bytes read from testfile */
+ int read_len = 0; /* total no. of bytes read from testfile */
+ int err_flag = 0; /* error indicator flag */
+
+ /* Parse standard options given to run the test. */
+ msg = parse_opts(ac, av, (option_t *) NULL, NULL);
+ if (msg != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ /* Perform global setup for test */
+ setup();
+
+ /* set the expected errnos... */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Check looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* Reset Tst_count in case we are looping. */
+ Tst_count = 0;
+
+ /*
+ * Call truncate(2) to truncate a test file to a
+ * specified length (TRUNC_LEN1).
+ */
+ TEST(truncate(TESTFILE, TRUNC_LEN1));
+
+ /* check return code of truncate(2) */
+ if (TEST_RETURN == -1) {
+ TEST_ERROR_LOG(TEST_ERRNO);
+ tst_resm(TFAIL, \
+ "truncate(%s, %d) Failed, errno=%d : %s",
+ TESTFILE, TRUNC_LEN1, TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ } else {
+ /*
+ * Perform functional verification if test
+ * executed without (-f) option.
+ */
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * Get the testfile information using
+ * stat(2).
+ */
+ if (stat(TESTFILE, &stat_buf) < 0) {
+ tst_brkm(TFAIL, cleanup, "stat(2) of "
+ "%s failed after 1st truncate, "
+ "error:%d", TESTFILE, errno);
+ /*NOTREACHED*/
+ }
+ file_length1 = stat_buf.st_size;
+
+ /*
+ * Set the file pointer of testfile to the
+ * beginning of the file.
+ */
+ if (lseek(fd, 0, SEEK_SET) < 0) {
+ tst_brkm(TFAIL, cleanup, "lseek(2) on "
+ "%s failed after 1st truncate, "
+ "error:%d", TESTFILE, errno);
+ /*NOTREACHED*/
+ }
+
+ /* Read the testfile from the beginning. */
+ while ((rbytes = read(fd, tst_buff, \
+ sizeof(tst_buff))) > 0) {
+ read_len += rbytes;
+ }
+
+ /*
+ * Execute truncate(2) again to truncate
+ * testfile to a size TRUNC_LEN2.
+ */
+ TEST(truncate(TESTFILE, TRUNC_LEN2));
+
+ /* check return code of truncate(2) */
+ if (TEST_RETURN == -1) {
+ TEST_ERROR_LOG(TEST_ERRNO);
+ tst_resm(TFAIL, "truncate of %s to "
+ "size %d Failed, errno=%d : %s",
+ TESTFILE, TRUNC_LEN2,
+ TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ }
+
+ /*
+ * Get the testfile information using
+ * stat(2)
+ */
+ if (stat(TESTFILE, &stat_buf) < 0) {
+ tst_brkm(TFAIL, cleanup, "stat(2) of "
+ "%s failed after 2nd truncate, "
+ "error:%d", TESTFILE, errno);
+ /*NOTREACHED*/
+ }
+ file_length2 = stat_buf.st_size;
+
+ /*
+ * Set the file pointer of testfile to the
+ * offset TRUNC_LEN1 of testfile.
+ */
+ if (lseek(fd, TRUNC_LEN1, SEEK_SET) < 0) {
+ tst_brkm(TFAIL, cleanup, "lseek(2) on "
+ "%s failed after 2nd truncate, "
+ "error:%d", TESTFILE, errno);
+ /*NOTREACHED*/
+ }
+
+ /* Read the testfile contents till EOF */
+ while((rbytes = read(fd, tst_buff, \
+ sizeof(tst_buff))) > 0) {
+ for (i = 0; i < rbytes; i++) {
+ if (tst_buff[i] != 0) {
+ err_flag++;
+ }
+ }
+ }
+
+ /*
+ * Check for expected size of testfile after
+ * issuing truncate(2) on it.
+ */
+ if ((file_length1 != TRUNC_LEN1) || \
+ (file_length2 != TRUNC_LEN2) || \
+ (read_len != TRUNC_LEN1) || \
+ (err_flag != 0)) {
+ tst_resm(TFAIL, "Functionality of "
+ "truncate(2) on %s Failed",
+ TESTFILE);
+ } else {
+ tst_resm(TPASS, \
+ "Functionality of truncate(2) "
+ "on %s successful", TESTFILE);
+ }
+ } else {
+ tst_resm(TPASS, "%s call succeeded", TCID);
+ }
+ }
+ Tst_count++; /* incr. TEST_LOOP counter */
+ } /* End for TEST_LOOPING */
+
+ /* Call cleanup() to undo setup done for the test. */
+ cleanup();
+ /*NOTREACHED*/
+
+} /* End main */
+
+/*
+ * void
+ * setup() - performs all ONE TIME setup for this test.
+ * Create a temporary directory and change directory to it.
+ * Create a test file under temporary directory and write some
+ * data into it.
+ */
+void
+setup()
+{
+ int i; /* counter variable */
+ int wbytes; /* bytes written to testfile */
+ int write_len = 0; /* total no. of bytes written to testfile */
+
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -i option.
+ * You want to make sure you do this before you create your temporary
+ * directory.
+ */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+
+ /* Fill the test buffer with the known data */
+ for (i = 0; i < BUF_SIZE; i++) {
+ tst_buff[i] = 'a';
+ }
+
+ /* Creat a testfile and write some data into it */
+ if ((fd = open(TESTFILE, O_RDWR|O_CREAT, FILE_MODE)) == -1) {
+ tst_brkm(TBROK, cleanup,
+ "open(%s, O_RDWR|O_CREAT, %o) Failed, errno=%d : %s",
+ TESTFILE, FILE_MODE, errno, strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ /* Write to the file 1k data from the buffer */
+ while (write_len < FILE_SIZE) {
+ if ((wbytes = write(fd, tst_buff, sizeof(tst_buff))) <= 0) {
+ tst_brkm(TBROK, cleanup,
+ "write(2) on %s Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ } else {
+ write_len += wbytes;
+ }
+ }
+} /* End setup() */
+
+/*
+ * void
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit.
+ * Close the temporary file opened for reading/writing.
+ * Remove the test directory and testfile created in the setup.
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* Close the testfile after writing data into it */
+ if (close(fd) == -1) {
+ tst_brkm(TFAIL, NULL,
+ "close(%s) Failed, errno=%d : %s",
+ TESTFILE, errno, strerror(errno));
+ }
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+} /* End cleanup() */
diff --git a/winsup/testsuite/winsup.api/ltp/umask02.c b/winsup/testsuite/winsup.api/ltp/umask02.c
new file mode 100644
index 000000000..f7d7c3bc8
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/umask02.c
@@ -0,0 +1,134 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * umask02.c
+ *
+ * DESCRIPTION
+ * Check that umask changes the mask, and that the previous
+ * value of the mask is returned correctly for each value.
+ *
+ * ALGORITHM
+ * For each mask value (9 bits) set mask, and check that the return
+ * corresponds to the previous value set.
+ *
+ * USAGE: <for command-line>
+ * umask02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions
+ * None
+ */
+
+#include <stdio.h>
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "umask02";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+main(int argc, char **argv)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ int uret = 0, i, mskval = 0000;
+
+ /* parse standard options */
+ if ((msg = parse_opts(argc, argv, (option_t *)NULL, NULL)) !=
+ (char *) NULL) {
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup();
+
+ /* Check for looping state if -i option is given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ for (umask(++mskval), i = 1; mskval < 01000;
+ uret = umask(++mskval), i++) {
+ if ((uret != mskval - 1) && (mskval != 0000)) {
+ tst_brkm(TBROK, cleanup, "bad mask value "
+ "returned");
+ /*NOTREACHED*/
+ } else {
+ tst_resm(TPASS, "umask(%d) susuccessfully "
+ "returned %d.", mskval, uret);
+ }
+ }
+ mskval = 0000;
+ uret = 0;
+ tst_resm(TINFO, "end of loop %d\n", lc);
+ }
+ cleanup();
+ /*NOTREACHED*/
+}
+
+/*
+ * setup()
+ * performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -c option.
+ */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup()
+ * performs all ONE TIME cleanup for this test at
+ * completion or premature exit
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+ /*NOTREACHED*/
+}
diff --git a/winsup/testsuite/winsup.api/ltp/umask03.c b/winsup/testsuite/winsup.api/ltp/umask03.c
new file mode 100644
index 000000000..8d032ca5c
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/umask03.c
@@ -0,0 +1,169 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * umask01.c
+ *
+ * DESCRIPTION
+ * Check that umask changes the mask, and that the previous
+ * value of the mask is returned correctly for each value.
+ *
+ * ALGORITHM
+ * For each mask value (9 bits) set mask, and check that the return
+ * corresponds to the previous value set.
+ *
+ * USAGE: <for command-line>
+ * umask01 [-c n] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions
+ * None
+ */
+
+#include <stdio.h>
+#include "test.h"
+#include "usctest.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+char *TCID = "umask01";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+char filname[40];
+
+void setup(void);
+void cleanup(void);
+
+main(int argc, char **argv)
+{
+ int lc;
+ const char *msg;
+
+ struct stat statbuf;
+ int mskval = 0000;
+ int fildes, i;
+ unsigned low9mode;
+
+ /* parse standard options */
+ if ((msg = parse_opts(argc, argv, (option_t *) NULL, NULL))
+ != (char *) NULL) {
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup(); /* global setup */
+
+ /* check looping state if -i option is given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ for (umask(mskval = 0077), i = 1; mskval < 01000;
+ i++, umask(++mskval)) {
+ unlink(filname);
+ if ((fildes = creat(filname, 0777)) == -1) {
+ tst_resm(TBROK, "cannot create "
+ "file with mskval 0%o %d",
+ mskval, mskval);
+ } else {
+ if (fstat(fildes, &statbuf) != 0) {
+ tst_resm(TBROK, "cannot fstat file");
+ } else {
+ low9mode = statbuf.st_mode & 0777;
+ if (low9mode != (~mskval & 0777)) {
+ tst_brkm(TBROK, cleanup,
+ "got %0 expected %o"
+ "mask didnot take",
+ low9mode,
+ (~mskval & 0777));
+ /*NOTREACHED*/
+ } else {
+ tst_resm(TPASS, "Test "
+ "condition: %d, umask: "
+ "0%o", i, mskval);
+ }
+ }
+ }
+ close(fildes);
+ }
+ }
+ cleanup();
+ /*NOTREACHED*/
+}
+
+/*
+ * setup
+ * performs all ONE TIME setup for this test
+ */
+void
+setup()
+{
+ /* capture signals */
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -i option.
+ * You want to make sure you do this before you create your temporary
+ * directory.
+ */
+ TEST_PAUSE;
+
+ /* make temp dir and cd to it */
+ tst_tmpdir();
+
+ sprintf(filname, "umask2.%d", getpid());
+}
+
+/*
+ * cleanup
+ * performs all ONE TIME cleanup for this test at completion or
+ * premature exit
+ */
+void
+cleanup()
+{
+ /*
+ * print timing stats if that option was specified
+ * print errno log if that option was specified
+ */
+ TEST_CLEANUP;
+
+ /*
+ * cleanup the temporary files and the temporary directory
+ */
+ unlink(filname);
+ tst_rmdir();
+
+ /*
+ * exit with return code appropriate for results
+ */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/wait401.c b/winsup/testsuite/winsup.api/ltp/wait401.c
new file mode 100644
index 000000000..0d307e247
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/wait401.c
@@ -0,0 +1,187 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * wait401.c
+ *
+ * DESCRIPTION
+ * wait401 - check that a call to wait4() correctly waits for a child
+ * process to exit
+ *
+ * ALGORITHM
+ * loop if that option was specified
+ * fork a child.
+ * issue the system call
+ * check the return value
+ * if return value == -1
+ * issue a FAIL message, break remaining tests and cleanup
+ * if we are doing functional testing
+ * issue a PASS message if the wait4 call returned the child's pid
+ * else
+ * issue a FAIL message
+ * call cleanup
+ *
+ * USAGE: <for command-line>
+ * wait401 [-c n] [-f] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions
+ * none
+ */
+
+#include "test.h"
+#include "usctest.h"
+
+#include <errno.h>
+#define _USE_BSD
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+
+void cleanup(void);
+void setup(void);
+
+char *TCID= "wait401()";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ pid_t pid;
+ int status = 1;
+ struct rusage *rusage = NULL;
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *) NULL, NULL)) != (char *) NULL) {
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ setup(); /* global setup */
+
+ /* The following loop checks looping state if -i option given */
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+ /*
+ * Allocate some space for the rusage structure
+ */
+
+ if ((rusage = (struct rusage *)malloc(sizeof(struct rusage)))
+ == NULL) {
+ tst_brkm(TBROK, cleanup, "malloc() failed");
+ }
+
+ pid = fork();
+
+ if (pid == -1) {
+ tst_brkm(TBROK, cleanup, "fork() failed");
+ }
+
+ if (pid == 0) { /* this is the child */
+ /*
+ * sleep for a moment to let us do the test
+ */
+ sleep(1);
+ exit(0);
+ } else { /* this is the parent */
+
+ /* call wait4 with the TEST() macro */
+ TEST(wait4(pid, &status, 0, rusage));
+ }
+
+ if (TEST_RETURN == -1) {
+ tst_brkm(TFAIL, cleanup, "%s call failed - errno = %d "
+ ": %s", TCID, TEST_ERRNO, strerror(TEST_ERRNO));
+ }
+
+ if (STD_FUNCTIONAL_TEST) {
+ /*
+ * The return from this call should be non-zero.
+ */
+ if (WIFEXITED(status) == 0) {
+ tst_brkm(TFAIL, cleanup, "%s call succeeded but "
+ "WIFEXITED() did not return expected value "
+ "- %d", TCID, WIFEXITED(status));
+ } else if (TEST_RETURN != pid) {
+ tst_resm(TFAIL, "%s did not return the "
+ "expected value. %d", TCID,
+ TEST_RETURN);
+ } else {
+
+ tst_resm(TPASS, "Received child pid as expected.");
+ }
+ }
+ tst_resm(TPASS, "%s call succeeded", TCID);
+
+ /*
+ * Clean up things in case we are looping.
+ */
+ free(rusage);
+ rusage = NULL;
+ }
+
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all the ONE TIME setup for this test.
+ */
+void
+setup(void)
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all the ONE TIME cleanup for this test at completion
+ * or premature exit.
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
+
diff --git a/winsup/testsuite/winsup.api/ltp/wait402.c b/winsup/testsuite/winsup.api/ltp/wait402.c
new file mode 100644
index 000000000..43a5c22d3
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/wait402.c
@@ -0,0 +1,202 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * wait402.c
+ *
+ * DESCRIPTION
+ * wait402 - check for ECHILD errno when using an illegal pid value
+ *
+ * ALGORITHM
+ * loop if that option was specified
+ * issue the system call with an illegal pid value
+ * check the errno value
+ * issue a PASS message if we get ECHILD
+ * otherwise, the tests fails
+ * issue a FAIL message
+ * break any remaining tests
+ * call cleanup
+ *
+ * USAGE: <for command-line>
+ * wait402 [-c n] [-e] [-i n] [-I x] [-p x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions
+ * none
+ */
+
+#include "test.h"
+#include "usctest.h"
+
+#include <errno.h>
+#define _USE_BSD
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+
+/*
+ * See the Makefile for comments about the following preprocessor code.
+ */
+#if defined (__CYGWIN__)
+#define PID_MAX 0xfffffffd
+#else
+#ifndef _LTP_TASKS_H
+#include <linux/threads.h> /* for PID_MAX value - new */
+#else
+#include <linux/tasks.h> /* for PID_MAX value - old */
+#endif
+#endif
+
+void cleanup(void);
+void setup(void);
+
+char *TCID= "wait402()";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+int exp_enos[] = {10, 0};
+
+main(int ac, char **av)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+ pid_t pid;
+ pid_t epid = PID_MAX + 1;
+ int status = 1;
+ struct rusage *rusage=NULL;
+
+ /* parse standard options */
+ if ((msg = parse_opts(ac, av, (option_t *) NULL, NULL)) != (char *) NULL) {
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ }
+
+ setup(); /* global setup */
+
+ /* The following loop checks looping state if -i option given */
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+
+ /*
+ * Allocate some space for the rusage structure.
+ */
+
+ if ((rusage = (struct rusage *)malloc(sizeof(struct rusage)))
+ == NULL) {
+ tst_brkm(TBROK, cleanup, "malloc() failed");
+ }
+
+ pid = fork();
+
+ if (pid == -1) {
+ tst_brkm(TBROK, cleanup, "fork() failed");
+ }
+
+ if (pid == 0) { /* this is the child */
+ /*
+ * sleep for a moment to let us do the test
+ */
+ sleep(1);
+ exit(0);
+ } else { /* this is the parent */
+ /*
+ * call wait4 with the TEST() macro. epid is set
+ * to an illegal positive value. This should give
+ * an ECHILD error.
+ */
+ TEST(wait4(epid, &status, 0, rusage));
+ }
+
+ if (TEST_RETURN == 0) {
+ tst_brkm(TFAIL, cleanup, "call failed to produce expected error - errno = %d - %s", TEST_ERRNO, strerror(TEST_ERRNO));
+ }
+
+ TEST_ERROR_LOG(TEST_ERRNO);
+
+ switch (TEST_ERRNO) {
+ case ECHILD:
+ tst_resm(TPASS, "received expected failure - errno = %d - %s",
+ TEST_ERRNO, strerror(TEST_ERRNO));
+ break;
+ default:
+ tst_brkm(TFAIL, cleanup, "call failed to produce expected "
+ "error - errno = %d - %s", TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ }
+
+ /*
+ * Clean up things in case we are looping.
+ */
+ if (pid > 0) {
+ wait4(pid, &status, 0, rusage);
+ }
+ free(rusage);
+ rusage = NULL;
+ }
+
+ cleanup();
+
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all the ONE TIME setup for this test.
+ */
+void
+setup(void)
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* Set up the expected error numbers for -e option */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Pause if that option was specified */
+ TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all the ONE TIME cleanup for this test at completion
+ * or premature exit.
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
+
diff --git a/winsup/testsuite/winsup.api/ltp/write02.c b/winsup/testsuite/winsup.api/ltp/write02.c
new file mode 100644
index 000000000..1ee10fd9a
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/write02.c
@@ -0,0 +1,165 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * write02.c
+ *
+ * DESCRIPTION
+ * Basic functionality test: does the return from write match the count
+ * of the number of bytes written.
+ *
+ *
+ * ALGORITHM
+ * Create a file and write some bytes out to it.
+ * Check the return count against the number returned.
+ *
+ * USAGE: <for command-line>
+ * write02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions
+ * None
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "write02()";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void cleanup(void);
+void setup(void);
+
+char pfiln[40] = "";
+
+main(int argc, char **argv)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ int cwrite;
+ int fild;
+ int iws;
+ int badcount = 0;
+ char pwbuf[BUFSIZ + 1];
+
+ /* parse standard options */
+ if (msg = parse_opts(argc, argv, (option_t *) NULL, NULL)) {
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ setup(); /* global setup for test */
+
+ /* The following loop checks looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+block1:
+ tst_resm(TINFO, "Block 1: test to see write() returns proper "
+ "write count");
+
+ for (iws = 0; iws < BUFSIZ; iws++) {
+ pwbuf[iws] = 'A' + (iws % 26);
+ }
+ pwbuf[BUFSIZ] = '\n';
+
+ if ((fild = creat(pfiln, 0777)) == -1) {
+ tst_brkm(TBROK, cleanup, "Can't creat Xwrit");
+ /*NOTREACHED*/
+ }
+ for (iws = BUFSIZ; iws > 0; iws--) {
+ if ((cwrite = write(fild, pwbuf, iws)) != iws) {
+ TEST_ERROR_LOG(errno);
+ badcount++;
+ tst_resm(TINFO, "bad write count");
+ }
+ }
+ if (badcount != 0) {
+ tst_resm(TFAIL, "write() FAILED to return proper cnt");
+ } else {
+ tst_resm(TPASS, "write() PASSED");
+ }
+ tst_resm(TINFO, "block 1 passed");
+ close(fild);
+ }
+ cleanup();
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ umask(0);
+
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -i option.
+ * You want to make sure you do this before you create your temporary
+ * directory.
+ */
+ TEST_PAUSE;
+
+ /* make a temp directory and cd to it */
+ tst_tmpdir();
+
+ sprintf(pfiln, "./write1.%d", getpid());
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion or
+ * premature exit.
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ unlink(pfiln);
+
+ /* Remove tmp dir and all files in it */
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+}
diff --git a/winsup/testsuite/winsup.api/ltp/write03.c b/winsup/testsuite/winsup.api/ltp/write03.c
new file mode 100644
index 000000000..5343c6484
--- /dev/null
+++ b/winsup/testsuite/winsup.api/ltp/write03.c
@@ -0,0 +1,193 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * write03.c
+ *
+ * DESCRIPTION
+ * Testcase to check that write(2) doesn't corrupt a file when it fails
+ *
+ * ALGORITHM
+ * Create a file for writing, write 100 bytes to it. Then make write(2)
+ * fail with some erroneous parameter, close the fd. Then reopen the
+ * file in RDONLY mode, and read the contents of the file. Compare the
+ * buffers, to see whether they are same.
+ *
+ * USAGE: <for command-line>
+ * write03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -e : Turn on errno logging.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * History
+ * 07/2001 John George
+ * -Ported
+ *
+ * Restrictions
+ * NONE
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <test.h>
+#include <usctest.h>
+
+/* 0 terminated list of expected errnos */
+int exp_enos[] = {14,0};
+
+char *TCID = "write03";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+void setup(void);
+void cleanup(void);
+
+int fd = -1;
+char filename[100];
+
+main(int argc, char **argv)
+{
+ int lc; /* loop counter */
+ const char *msg; /* message returned from parse_opts */
+
+ char wbuf[BUFSIZ], rbuf[BUFSIZ];
+
+ /* parse standard options */
+ if ((msg = parse_opts(argc, argv, (option_t *)NULL, NULL)) !=
+ (char *)NULL) {
+ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+ /*NOTREACHED*/
+ }
+
+ /* global setup */
+ setup();
+
+ /* The following loop checks looping state if -i option given */
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /* reset Tst_count in case we are looping */
+ Tst_count = 0;
+
+block1:
+ tst_resm(TINFO, "Enter Block 1: test to check if write "
+ "corrupts the file when write fails");
+
+ fd = creat(filename, 0644);
+ if (fd < 0) {
+ tst_resm(TBROK, "creating a new file failed");
+ cleanup();
+ /*NOTREACHED*/
+ }
+
+ (void)memset(wbuf, '0', 100);
+
+ if (write(fd, wbuf, 100) == -1) {
+ tst_resm(TFAIL, "failed to write to %s", filename);
+ cleanup();
+ /*NOTREACHED*/
+ }
+
+ if (write(fd, (void *)-1, 100) != -1) {
+ tst_resm(TFAIL, "write(2) failed to fail");
+ cleanup();
+ /*NOTREACHED*/
+ }
+ TEST_ERROR_LOG(errno);
+ close(fd);
+ fd = -1;
+
+ if ((fd = open(filename, O_RDONLY)) == -1) {
+ tst_resm(TBROK, "open(2) failed, errno: %d", errno);
+ cleanup();
+ /*NOTREACHED*/
+ }
+
+ if (read(fd, rbuf, 100) == -1) {
+ tst_resm(TBROK, "read(2) failed, errno: %d", errno);
+ cleanup();
+ /*NOTREACHED*/
+ }
+
+ if (memcmp(wbuf, rbuf, 100) == 0) {
+ tst_resm(TPASS, "failure of write(2) didnot corrupt "
+ "the file");
+ } else {
+ tst_resm(TFAIL, "failure of write(2) corrupted the "
+ "file");
+ }
+ tst_resm(TINFO, "Exit block 1");
+ }
+ cleanup();
+ /*NOTREACHED*/
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+ /* capture signals */
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* Set up the expected error numbers for -e option */
+ TEST_EXP_ENOS(exp_enos);
+
+ /* Pause if that option was specified
+ * TEST_PAUSE contains the code to fork the test with the -i option.
+ * You want to make sure you do this before you create your temporary
+ * directory.
+ */
+ TEST_PAUSE;
+
+ /* Create a unique temporary directory and chdir() to it. */
+ tst_tmpdir();
+
+ sprintf(filename, "./write03.%d", getpid());
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ * completion or premature exit
+ */
+void
+cleanup(void)
+{
+ /*
+ * print timing stats if that option was specified.
+ * print errno log if that option was specified.
+ */
+ TEST_CLEANUP;
+
+ if (fd >= 0)
+ close (fd);
+
+ unlink(filename);
+ tst_rmdir();
+
+ /* exit with return code appropriate for results */
+ tst_exit();
+ /*NOTREACHED*/
+}
diff --git a/winsup/testsuite/winsup.api/signal-into-win32-api.c b/winsup/testsuite/winsup.api/signal-into-win32-api.c
new file mode 100755
index 000000000..0c299827a
--- /dev/null
+++ b/winsup/testsuite/winsup.api/signal-into-win32-api.c
@@ -0,0 +1,57 @@
+/*
+ * Test if signal is delivered to the application which is
+ * currently inside of native syscall
+ */
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <windows.h>
+
+int saw_sigchld = 0;
+int sleep_stage = -1;
+
+void
+handle_child (int signo)
+{
+ printf ( "saw SIGCHLD, %d", sleep_stage);
+ saw_sigchld = 1;
+}
+
+int
+main (int argc, char** argv)
+{
+ pid_t pid;
+ if (argc > 1)
+ {
+ Sleep (200);
+ return 0;
+ }
+
+ signal (SIGCHLD, handle_child);
+ pid = fork ();
+ if (pid < 0)
+ {
+ perror ( "fork" );
+ return 2;
+ }
+ else if (pid == 0)
+ execl ( argv[0], argv[0], "child", 0 );
+ else
+ {
+ sleep_stage = 0;
+ Sleep (3000);
+ sleep_stage = 1;
+ sleep (10);
+ sleep_stage = 2;
+ if (!saw_sigchld)
+ {
+ printf ( "oops\n" );
+ kill (pid, SIGTERM);
+ return 1;
+ }
+ else
+ return 0;
+ }
+} \ No newline at end of file