diff options
author | Egor Duda <deo@logos-m.ru> | 2001-09-13 17:30:23 +0000 |
---|---|---|
committer | Egor Duda <deo@logos-m.ru> | 2001-09-13 17:30:23 +0000 |
commit | 50ab44e0a7799fa79e4fc1c140f95a0aca2cda33 (patch) | |
tree | 453ab71966e21eced69768abb97a106993a13a30 | |
parent | 4e8b5fc38766dc653bc503bb9d2cc56fc69240c4 (diff) | |
download | newlib-50ab44e0a7799fa79e4fc1c140f95a0aca2cda33.zip newlib-50ab44e0a7799fa79e4fc1c140f95a0aca2cda33.tar.gz newlib-50ab44e0a7799fa79e4fc1c140f95a0aca2cda33.tar.bz2 |
* 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.
90 files changed, 19617 insertions, 3 deletions
diff --git a/winsup/testsuite/ChangeLog b/winsup/testsuite/ChangeLog index f11c6d9..5688f50 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 0000000..e974c87 --- /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 cccc2c7..f5b64b6 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 d1538b7..1856608 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 0000000..20fa811 --- /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 0000000..935b19b --- /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 0000000..7661ba9 --- /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 0000000..d220bb1 --- /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 0000000..12198fe --- /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 0000000..1637c90 --- /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 0000000..44f98b2 --- /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 0000000..7dd016f --- /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 0000000..c5e5242 --- /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 0000000..729f49a --- /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 0000000..b81ecbc --- /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 0000000..83685d3 --- /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 0000000..c09d905 --- /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 0000000..eaf3b64 --- /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 0000000..cda9132 --- /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 0000000..c2e5a47 --- /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 0000000..d8487c1 --- /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 0000000..71a3f1d --- /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 0000000..09de7c0 --- /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 0000000..1fc200d --- /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 0000000..f15e48e --- /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 0000000..1f63cf1 --- /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 0000000..0287fff --- /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 0000000..2d3d797 --- /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 0000000..8044c1d --- /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 0000000..2e80558 --- /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 0000000..290ef10 --- /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 0000000..3059b0b --- /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 0000000..d1a39a0 --- /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 0000000..afb80f2 --- /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 0000000..8561c1a --- /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 0000000..9eeead1 --- /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 0000000..b350725 --- /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 0000000..7c1075c --- /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 0000000..d20d3a3 --- /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 0000000..e618c8c --- /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 0000000..528a080 --- /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 0000000..2e0ff65 --- /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 0000000..0262260 --- /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 0000000..0acc289 --- /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 0000000..061ac31 --- /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 0000000..b36df71 --- /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 0000000..060f3b2 --- /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 0000000..35e944d --- /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 0000000..6c66a4c --- /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 0000000..4f9018f --- /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 0000000..e818689 --- /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 0000000..bc3f20e --- /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 0000000..3d1f434 --- /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 0000000..8b2c050 --- /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 0000000..5de98b6 --- /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 0000000..deadcc2 --- /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 0000000..84640ce --- /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 0000000..699515d --- /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 0000000..9cc935d --- /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 0000000..2c7d9f4 --- /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 0000000..410622c --- /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 0000000..df7b241 --- /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 0000000..67e1f13 --- /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 0000000..99dcdf6 --- /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 0000000..bb5f6e3 --- /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 0000000..3279b90 --- /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 0000000..551efe7 --- /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 28890f1..1ad0fb0 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 0000000..e839239 --- /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 0000000..c1aae92 --- /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 0000000..5b16a51 --- /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 0000000..46b8262 --- /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 0000000..06bf73a --- /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 0000000..a1a9427 --- /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 0000000..9cdb74b --- /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 0000000..8272d36 --- /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 0000000..36aff55 --- /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 0000000..443df02 --- /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 0000000..827ed32 --- /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 0000000..8250464 --- /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 0000000..a388c77 --- /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 0000000..d8dc1b6 --- /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 0000000..b6e535c --- /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 0000000..f7d7c3b --- /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 0000000..8d032ca --- /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 0000000..0d307e2 --- /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 0000000..43a5c22 --- /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 0000000..1ee10fd --- /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 0000000..5343c64 --- /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 0000000..0c29982 --- /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 |