aboutsummaryrefslogtreecommitdiff
path: root/testcases/kernel/syscalls/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'testcases/kernel/syscalls/ipc')
-rw-r--r--testcases/kernel/syscalls/ipc/msgctl/msgctl01.c2
-rw-r--r--testcases/kernel/syscalls/ipc/msgget/msgget02.c6
-rw-r--r--testcases/kernel/syscalls/ipc/msgstress/msgstress03.c7
-rw-r--r--testcases/kernel/syscalls/ipc/semget/.gitignore2
-rw-r--r--testcases/kernel/syscalls/ipc/semget/Makefile4
-rw-r--r--testcases/kernel/syscalls/ipc/semget/semget01.c187
-rw-r--r--testcases/kernel/syscalls/ipc/semget/semget02.c221
-rw-r--r--testcases/kernel/syscalls/ipc/semget/semget03.c133
-rw-r--r--testcases/kernel/syscalls/ipc/semget/semget05.c189
-rw-r--r--testcases/kernel/syscalls/ipc/semget/semget06.c143
-rw-r--r--testcases/kernel/syscalls/ipc/semop/.gitignore2
-rw-r--r--testcases/kernel/syscalls/ipc/semop/Makefile5
-rw-r--r--testcases/kernel/syscalls/ipc/semop/semop04.c93
-rw-r--r--testcases/kernel/syscalls/ipc/semop/semop05.c157
-rw-r--r--testcases/kernel/syscalls/ipc/shmget/shmget02.c28
15 files changed, 461 insertions, 718 deletions
diff --git a/testcases/kernel/syscalls/ipc/msgctl/msgctl01.c b/testcases/kernel/syscalls/ipc/msgctl/msgctl01.c
index 75adcb229..56d1505fd 100644
--- a/testcases/kernel/syscalls/ipc/msgctl/msgctl01.c
+++ b/testcases/kernel/syscalls/ipc/msgctl/msgctl01.c
@@ -6,7 +6,7 @@
*/
/*
- * Test that IPC_STAT command succeeds and the the buffer is filled with
+ * Test that IPC_STAT command succeeds and the buffer is filled with
* correct data.
*/
#include <errno.h>
diff --git a/testcases/kernel/syscalls/ipc/msgget/msgget02.c b/testcases/kernel/syscalls/ipc/msgget/msgget02.c
index ce59a8fb5..1885599d1 100644
--- a/testcases/kernel/syscalls/ipc/msgget/msgget02.c
+++ b/testcases/kernel/syscalls/ipc/msgget/msgget02.c
@@ -8,11 +8,11 @@
*
* Test for EEXIST, ENOENT, EACCES errors.
*
- * 1) msgget(2) fails if a message queue exists for key and msgflg
+ * - msgget(2) fails if a message queue exists for key and msgflg
* specified both IPC_CREAT and IPC_EXCL.
- * 2) msgget(2) fails if no message queue exists for key and msgflg
+ * - msgget(2) fails if no message queue exists for key and msgflg
* did not specify IPC_CREAT.
- * 3) msgget(2) fails if a message queue exists for key, but the
+ * - msgget(2) fails if a message queue exists for key, but the
* calling process does not have permission to access the queue,
* and does not have the CAP_IPC_OWNER capability.
*
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c
index 3cb70ab18..aa37d9058 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c
+++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c
@@ -110,11 +110,12 @@ int main(int argc, char **argv)
}
free_pids = tst_get_free_pids(cleanup);
- if (nprocs >= free_pids) {
+ /* Each forked child forks once, take it into account here. */
+ if (nprocs * 2 >= free_pids) {
tst_resm(TINFO,
"Requested number of processes higher than limit (%d > %d), "
- "setting to %d", nprocs, free_pids, free_pids);
- nprocs = free_pids;
+ "setting to %d", nprocs * 2, free_pids, free_pids);
+ nprocs = free_pids / 2;
}
srand(getpid());
diff --git a/testcases/kernel/syscalls/ipc/semget/.gitignore b/testcases/kernel/syscalls/ipc/semget/.gitignore
index ce26c93b0..4519b30d2 100644
--- a/testcases/kernel/syscalls/ipc/semget/.gitignore
+++ b/testcases/kernel/syscalls/ipc/semget/.gitignore
@@ -1,5 +1,3 @@
/semget01
/semget02
-/semget03
/semget05
-/semget06
diff --git a/testcases/kernel/syscalls/ipc/semget/Makefile b/testcases/kernel/syscalls/ipc/semget/Makefile
index 26b9f264d..b1201281d 100644
--- a/testcases/kernel/syscalls/ipc/semget/Makefile
+++ b/testcases/kernel/syscalls/ipc/semget/Makefile
@@ -3,10 +3,10 @@
top_srcdir ?= ../../../../..
-LTPLIBS = ltpipc
+LTPLIBS = ltpnewipc
include $(top_srcdir)/include/mk/testcases.mk
-LTPLDLIBS = -lltpipc
+LTPLDLIBS = -lltpnewipc
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/semget/semget01.c b/testcases/kernel/syscalls/ipc/semget/semget01.c
index 217163b3a..872acabd3 100644
--- a/testcases/kernel/syscalls/ipc/semget/semget01.c
+++ b/testcases/kernel/syscalls/ipc/semget/semget01.c
@@ -1,172 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
*/
-/*
- * NAME
- * semget01.c
- *
- * DESCRIPTION
- * semget01 - test that semget() correclty creates a semaphore set
+/*\
+ * [Description]
*
- * ALGORITHM
- * loop if that option was specified
- * call semget() to create the semaphore set
- * check the return code
- * if failure, issue a FAIL message.
- * otherwise,
- * if doing functionality testing
- * stat the semaphore set
- * if the number of primitive semaphores is correct and
- * the semaphore uid == the process uid
- * then,
- * issue a PASS message
- * otherwise
- * issue a FAIL message
- * call cleanup
- *
- * USAGE: <for command-line>
- * semget01 [-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
+ * This case checks that semget() correclty creates a semaphore set.
*/
-#include "ipcsem.h"
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include "lapi/sem.h"
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "tst_safe_sysv_ipc.h"
-char *TCID = "semget01";
-int TST_TOTAL = 1;
+static int sem_id = -1, sem_key = -1;
-int sem_id_1 = -1;
-
-int main(int ac, char **av)
+static void check_functionality(void)
{
- int lc;
- void check_functionality(void);
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- 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;
-
- /*
- * Use TEST macro to make the call
- */
-
- TEST(semget(semkey, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA));
-
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL, "%s call failed - errno = %d : %s",
- TCID, TEST_ERRNO, strerror(TEST_ERRNO));
- } else {
- /* get the semaphore ID */
- sem_id_1 = TEST_RETURN;
-
- check_functionality();
- }
-
- /*
- * remove the semaphore that was created and mark the ID
- * as invalid.
- */
- if (sem_id_1 != -1) {
- rm_sema(sem_id_1);
- sem_id_1 = -1;
- }
- }
+ struct semid_ds semary;
+ union semun un_arg;
- cleanup();
+ un_arg.buf = &semary;
+ SAFE_SEMCTL(sem_id, 0, IPC_STAT, un_arg);
+ TST_EXP_EQ_LI(un_arg.buf->sem_nsems, PSEMS);
+ TST_EXP_EQ_LI(un_arg.buf->sem_perm.cuid, geteuid());
- tst_exit();
+ tst_res(TPASS, "basic semaphore values are okay");
}
-/*
- * check_functionality() - check the functionality of the tested system call.
- */
-void check_functionality(void)
+static void verify_semget(void)
{
- struct semid_ds semary;
- union semun un_arg; /* union defined in ipcsem.h */
-
- /* STAT the semaphore */
- un_arg.buf = &semary;
- if (semctl(sem_id_1, 0, IPC_STAT, un_arg) == -1) {
- tst_brkm(TBROK, cleanup, "Could not stat the semaphore");
+ TEST(semget(sem_key, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA));
+ if (TST_RET == -1) {
+ tst_res(TFAIL | TTERRNO, "semget() failed");
return;
}
- if (un_arg.buf->sem_nsems != PSEMS) {
- tst_resm(TFAIL, "# of semaphores in set != # given to create");
- return;
- }
+ sem_id = TST_RET;
+ check_functionality();
- if (un_arg.buf->sem_perm.cuid != geteuid()) {
- tst_resm(TFAIL, "semaphore uid != process uid");
- return;
- }
-
- tst_resm(TPASS, "basic semaphore values are okay");
+ SAFE_SEMCTL(sem_id, PSEMS, IPC_RMID);
}
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
+static void setup(void)
{
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- /*
- * Create a temporary directory and cd into it.
- * This helps to ensure that a unique msgkey is created.
- * See libs/libltpipc/libipc.c for more information.
- */
- tst_tmpdir();
-
- /* get an IPC resource key */
- semkey = getipckey();
+ sem_key = GETIPCKEY();
}
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * or premature exit.
- */
-void cleanup(void)
+static void cleanup(void)
{
- /* if it exists, remove the semaphore resouce */
- rm_sema(sem_id_1);
-
- tst_rmdir();
-
+ if (sem_id != -1)
+ SAFE_SEMCTL(sem_id, PSEMS, IPC_RMID);
}
+
+static struct tst_test test = {
+ .needs_tmpdir = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = verify_semget,
+};
diff --git a/testcases/kernel/syscalls/ipc/semget/semget02.c b/testcases/kernel/syscalls/ipc/semget/semget02.c
index 4124514c2..4273c84c7 100644
--- a/testcases/kernel/syscalls/ipc/semget/semget02.c
+++ b/testcases/kernel/syscalls/ipc/semget/semget02.c
@@ -1,165 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
*/
-/*
- * NAME
- * semget02.c
+/*\
+ * [Description]
*
- * DESCRIPTION
- * semget02 - test for EACCES and EEXIST errors
+ * This basic error handing of the semget syscall.
*
- * ALGORITHM
- * create a semaphore set without read or alter permissions
- * loop if that option was specified
- * call semget() using two different invalid cases
- * check the errno value
- * issue a PASS message if we get EACCES or EEXIST
- * otherwise, the tests fails
- * issue a FAIL message
- * call cleanup
- *
- * USAGE: <for command-line>
- * semget02 [-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
+ * - EACCES - a semaphore set exists for key, but the calling process does not
+ * have permission to access the set
+ * - EEXIST - a semaphore set already exists for key and IPC_CREAT | IPC_EXCL
+ * is given
+ * - ENOENT - No semaphore set exists for key and semflg did not specify
+ * IPC_CREAT
+ * - EINVAL - nsems is less than 0 or greater than the limit on the number of
+ * semaphores per semaphore set(SEMMSL)
+ * - EINVAL - a semaphore set corresponding to key already exists, but nsems is
+ * larger than the number of semaphores in that set
*/
-#include <pwd.h>
-
-#include "ipcsem.h"
-char *TCID = "semget02";
-int TST_TOTAL = 2;
-
-char nobody_uid[] = "nobody";
-struct passwd *ltpuser;
-
-int sem_id_1 = -1;
-
-struct test_case_t {
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewipc.h"
+#include "lapi/sem.h"
+
+static int sem_id = -1;
+static key_t semkey, semkey1;
+static struct passwd *pw;
+static struct tcase {
+ int *key;
+ int nsems;
int flags;
- int error;
-} TC[] = {
- /* EACCES - the semaphore has no read or alter permissions */
- {
- SEM_RA, EACCES},
- /* EEXIST - the semaphore id exists and semget() was called with */
- /* IPC_CREAT and IPC_EXCL */
- {
- IPC_CREAT | IPC_EXCL, EEXIST}
+ int exp_err;
+ /*1: nobody expected, 0: root expected */
+ int exp_user;
+} tcases[] = {
+ {&semkey, PSEMS, SEM_RA, EACCES, 1},
+ {&semkey, PSEMS, IPC_CREAT | IPC_EXCL, EEXIST, 0},
+ {&semkey1, PSEMS, SEM_RA, ENOENT, 0},
+ {&semkey1, -1, IPC_CREAT | IPC_EXCL, EINVAL, 0},
+ {&semkey1, SEMMSL + 1, IPC_CREAT | IPC_EXCL, EINVAL, 0},
+ {&semkey, PSEMS + 1, SEM_RA, EINVAL, 0},
};
-int main(int ac, char **av)
+static void verify_semget(struct tcase *tc)
{
- int lc;
- int i;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- 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;
-
- for (i = 0; i < TST_TOTAL; i++) {
- /* use the TEST macro to make the call */
-
- TEST(semget(semkey, PSEMS, TC[i].flags));
-
- if (TEST_RETURN != -1) {
- sem_id_1 = TEST_RETURN;
- tst_resm(TFAIL, "call succeeded");
- continue;
- }
+ TST_EXP_FAIL2(semget(*tc->key, tc->nsems, tc->flags), tc->exp_err,
+ "semget(%i, %i, %i)", *tc->key, tc->nsems, tc->flags);
+}
- 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",
- TEST_ERRNO, strerror(TEST_ERRNO));
- }
+static void do_test(unsigned int n)
+{
+ pid_t pid;
+ struct tcase *tc = &tcases[n];
+
+ if (tc->exp_user == 0) {
+ verify_semget(tc);
+ } else {
+ pid = SAFE_FORK();
+ if (pid) {
+ tst_reap_children();
+ } else {
+ SAFE_SETUID(pw->pw_uid);
+ verify_semget(tc);
+ exit(0);
}
}
-
- cleanup();
-
- tst_exit();
}
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
+static void setup(void)
{
- tst_require_root();
-
- /* Switch to nobody user for correct error code collection */
- ltpuser = getpwnam(nobody_uid);
- if (seteuid(ltpuser->pw_uid) == -1) {
- tst_resm(TINFO, "setreuid failed to "
- "to set the effective uid to %d", ltpuser->pw_uid);
- perror("setreuid");
- }
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
+ semkey = GETIPCKEY();
+ semkey1 = GETIPCKEY();
- TEST_PAUSE;
+ sem_id = SAFE_SEMGET(semkey, PSEMS, IPC_CREAT | IPC_EXCL);
- /*
- * Create a temporary directory and cd into it.
- * This helps to ensure that a unique msgkey is created.
- * See libs/libltpipc/libipc.c for more information.
- */
- tst_tmpdir();
-
- /* get an IPC resource key */
- semkey = getipckey();
-
- /* create a semaphore set without read or alter permissions */
- if ((sem_id_1 = semget(semkey, PSEMS, IPC_CREAT | IPC_EXCL)) == -1) {
- tst_brkm(TBROK, cleanup, "couldn't create semaphore in setup");
- }
+ pw = SAFE_GETPWNAM("nobody");
}
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * or premature exit.
- */
-void cleanup(void)
+static void cleanup(void)
{
- /* if it exists, remove the semaphore resource */
- rm_sema(sem_id_1);
-
- tst_rmdir();
-
+ if (sem_id != -1)
+ SAFE_SEMCTL(sem_id, PSEMS, IPC_RMID);
}
+
+static struct tst_test test = {
+ .needs_tmpdir = 1,
+ .needs_root = 1,
+ .forks_child = 1,
+ .tcnt = ARRAY_SIZE(tcases),
+ .setup = setup,
+ .cleanup = cleanup,
+ .test = do_test,
+};
diff --git a/testcases/kernel/syscalls/ipc/semget/semget03.c b/testcases/kernel/syscalls/ipc/semget/semget03.c
deleted file mode 100644
index 995b4bd3a..000000000
--- a/testcases/kernel/syscalls/ipc/semget/semget03.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * NAME
- * semget03.c
- *
- * DESCRIPTION
- * semget03 - test for ENOENT error
- *
- * ALGORITHM
- * loop if that option was specified
- * call semget() with a valid key but with no associated semaphore set
- * and IPC_CREAT is not asserted
- * check the errno value
- * issue a PASS message if we get ENOENT
- * otherwise, the tests fails
- * issue a FAIL message
- * call cleanup
- *
- * USAGE: <for command-line>
- * semget03 [-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 "ipcsem.h"
-
-char *TCID = "semget03";
-int TST_TOTAL = 1;
-
-int sem_id_1 = -1;
-
-int main(int ac, char **av)
-{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- 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;
-
- /* use the TEST macro to make the call */
-
- TEST(semget(semkey, PSEMS, SEM_RA));
-
- if (TEST_RETURN != -1) {
- sem_id_1 = TEST_RETURN;
- tst_resm(TFAIL, "call succeeded when error expected");
- continue;
- }
-
- switch (TEST_ERRNO) {
- case ENOENT:
- tst_resm(TPASS, "expected failure - errno "
- "= %d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
- break;
- default:
- tst_resm(TFAIL, "unexpected error - %d : %s",
- TEST_ERRNO, strerror(TEST_ERRNO));
- break;
- }
- }
-
- cleanup();
-
- tst_exit();
-}
-
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
-{
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- /*
- * Create a temporary directory and cd into it.
- * This helps to ensure that a unique msgkey is created.
- * See libs/libltpipc/libipc.c for more information.
- */
- tst_tmpdir();
-
- /* get an IPC resource key */
- semkey = getipckey();
-}
-
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * or premature exit.
- */
-void cleanup(void)
-{
- /* if it exists, remove the semaphore resource */
- rm_sema(sem_id_1);
-
- tst_rmdir();
-
-}
diff --git a/testcases/kernel/syscalls/ipc/semget/semget05.c b/testcases/kernel/syscalls/ipc/semget/semget05.c
index f801cb8ed..dd9a6285d 100644
--- a/testcases/kernel/syscalls/ipc/semget/semget05.c
+++ b/testcases/kernel/syscalls/ipc/semget/semget05.c
@@ -1,152 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
*/
-/*
- * NAME
- * semget05.c
- *
- * DESCRIPTION
- * semget05 - test for ENOSPC error
+/*\
+ * [Description]
*
- * ALGORITHM
- * create semaphore sets in a loop until the system limit is reached
- * loop if that option was specified
- * attempt to create yet another semaphore set
- * check the errno value
- * issue a PASS message if we get ENOSPC
- * otherwise, the tests fails
- * issue a FAIL message
- * call cleanup
+ * Test for ENOSPC error.
*
- * USAGE: <for command-line>
- * HISTORY
- * 03/2001 - Written by Wayne Boyer
- * 07/2006 - Changes By Michael Reed
- * - Changed the value of MAXIDS for the specific machine by reading
- * the system limit for SEMMNI - The maximum number of sempahore sets
- * 03/2008 - Matthieu Fertré (mfertre@irisa.fr)
- * - Fix concurrency issue. Create private semaphores to
- * avoid conflict with concurrent processes.
- *
- * RESTRICTIONS
- * none
- */
-
-#include "ipcsem.h"
-
-char *TCID = "semget05";
-int TST_TOTAL = 1;
-
-/*
- * The MAXIDS value is somewhat arbitrary and may need to be increased
- * depending on the system being tested.
+ * ENOSPC - a semaphore set exceed the maximum number of semaphore sets(SEMMNI)
*/
-int MAXIDS = 2048;
-
-int *sem_id_arr = NULL;
-int num_sems = 0; /* count the semaphores created */
-
-int main(int ac, char **av)
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include "lapi/sem.h"
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "tst_safe_sysv_ipc.h"
+
+static int *sem_id_arr;
+static int maxsems, array_cnt, used_cnt;
+static key_t semkey;
+
+static void verify_semget(void)
{
- int lc;
- FILE *fp;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- /* Set the MAXIDS for the specific machine by reading the system limit
- * for SEMMNI - The maximum number of sempahore sets
- */
- fp = fopen("/proc/sys/kernel/sem", "r");
- if (fp != NULL) {
- int getmaxid;
- if (fscanf(fp, "%*d %*d %*d %d", &getmaxid) == 1)
- MAXIDS = getmaxid + 1;
- fclose(fp);
- }
-
- sem_id_arr = malloc(sizeof(int) * MAXIDS);
- if (sem_id_arr == NULL)
- tst_brkm(TBROK, cleanup, "malloc failed");
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
-
- TEST(semget(IPC_PRIVATE, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA));
- if (TEST_RETURN != -1) {
- tst_resm(TFAIL, "call succeeded when error expected");
- continue;
- }
-
- switch (TEST_ERRNO) {
- case ENOSPC:
- tst_resm(TPASS, "expected failure - errno "
- "= %d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
- break;
- default:
- tst_resm(TFAIL, "unexpected error - %d : %s",
- TEST_ERRNO, strerror(TEST_ERRNO));
- break;
- }
- }
-
- cleanup();
-
- tst_exit();
+ TST_EXP_FAIL2(semget(semkey + maxsems, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA),
+ ENOSPC, "semget(%i, %i, %i)", semkey + maxsems, PSEMS,
+ IPC_CREAT | IPC_EXCL | SEM_RA);
}
-void setup(void)
+static void setup(void)
{
- int sem_q;
+ int res, num;
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
+ semkey = GETIPCKEY();
+ used_cnt = GET_USED_ARRAYS();
+ tst_res(TINFO, "Current environment %d semaphore arrays are already in use",
+ used_cnt);
+ SAFE_FILE_SCANF("/proc/sys/kernel/sem", "%*d %*d %*d %d", &maxsems);
- TEST_PAUSE;
+ /* Prevent timeout due to high semaphore array limit */
+ tst_set_max_runtime(maxsems / 200);
- tst_tmpdir();
-
- while ((sem_q = semget(IPC_PRIVATE, PSEMS, IPC_CREAT | IPC_EXCL)) != -1) {
- sem_id_arr[num_sems++] = sem_q;
- if (num_sems == MAXIDS) {
- tst_brkm(TBROK, cleanup, "The maximum number of "
- "semaphore ID's has been\n\t reached. Please "
- "increase the MAXIDS value in the test.");
- }
- }
+ sem_id_arr = SAFE_MALLOC((maxsems - used_cnt) * sizeof(int));
+ for (num = 0; num < maxsems - used_cnt; num++) {
+ res = semget(semkey + num, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA);
+ if (res == -1)
+ tst_brk(TBROK | TERRNO, "semget failed unexpectedly");
- if (errno != ENOSPC) {
- tst_brkm(TBROK, cleanup, "Didn't get ENOSPC in test setup"
- " - errno = %d : %s", errno, strerror(errno));
+ sem_id_arr[array_cnt++] = res;
}
+ tst_res(TINFO, "The maximum number of semaphore arrays (%d) has been reached",
+ maxsems);
}
-void cleanup(void)
+static void cleanup(void)
{
- int i;
+ int num;
- for (i = 0; i < num_sems; i++) {
- rm_sema(sem_id_arr[i]);
- }
+ if (!sem_id_arr)
+ return;
+
+ for (num = 0; num < array_cnt; num++)
+ SAFE_SEMCTL(sem_id_arr[num], PSEMS, IPC_RMID);
free(sem_id_arr);
- tst_rmdir();
}
+
+static struct tst_test test = {
+ .needs_tmpdir = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = verify_semget,
+ .save_restore = (const struct tst_path_val[]){
+ {"/proc/sys/kernel/sem", NULL,
+ TST_SR_TCONF_MISSING | TST_SR_SKIP_RO},
+ {}
+ }
+};
diff --git a/testcases/kernel/syscalls/ipc/semget/semget06.c b/testcases/kernel/syscalls/ipc/semget/semget06.c
deleted file mode 100644
index 52297c010..000000000
--- a/testcases/kernel/syscalls/ipc/semget/semget06.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * NAME
- * semget06.c
- *
- * DESCRIPTION
- * semget06 - test for EINVAL error
- *
- * ALGORITHM
- * loop if that option was specified
- * call semget() using two different invalid cases - too many and too
- * few primitive semaphores
- * check the errno value
- * issue a PASS message if we get EINVAL
- * otherwise, the tests fails
- * issue a FAIL message
- * call cleanup
- *
- * USAGE: <for command-line>
- * semget06 [-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 "ipcsem.h"
-
-char *TCID = "semget06";
-int TST_TOTAL = 2;
-
-#define LARGENUM 1024 * 32
-#define SMALLNUM -1
-
-int sem_id_1 = -1;
-
-int num_sems[] = { LARGENUM, SMALLNUM };
-
-int main(int ac, char **av)
-{
- int lc;
- int i;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- 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;
-
- /* loop through the test cases */
-
- for (i = 0; i < TST_TOTAL; i++) {
- TEST(semget(semkey, num_sems[i],
- IPC_CREAT | IPC_EXCL | SEM_RA));
-
- if (TEST_RETURN != -1) {
- sem_id_1 = TEST_RETURN;
- tst_resm(TFAIL, "call succeeded");
- continue;
- }
-
- switch (TEST_ERRNO) {
- case EINVAL:
- tst_resm(TPASS, "expected failure - errno "
- "= %d : %s", TEST_ERRNO,
- strerror(TEST_ERRNO));
- break;
- default:
- tst_resm(TFAIL, "unexpected error - %d : %s",
- TEST_ERRNO, strerror(TEST_ERRNO));
- break;
- }
- }
- }
-
- cleanup();
-
- tst_exit();
-}
-
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
-{
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- /*
- * Create a temporary directory and cd into it.
- * This helps to ensure that a unique msgkey is created.
- * See libs/libltpipc/libipc.c for more information.
- */
- tst_tmpdir();
-
- /* get an IPC resource key */
- semkey = getipckey();
-}
-
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * or premature exit.
- */
-void cleanup(void)
-{
- /* if it exists, remove the semaphore resource */
- rm_sema(sem_id_1);
-
- tst_rmdir();
-
-}
diff --git a/testcases/kernel/syscalls/ipc/semop/.gitignore b/testcases/kernel/syscalls/ipc/semop/.gitignore
index bb57f08af..cc67b1862 100644
--- a/testcases/kernel/syscalls/ipc/semop/.gitignore
+++ b/testcases/kernel/syscalls/ipc/semop/.gitignore
@@ -1,3 +1,5 @@
/semop01
/semop02
/semop03
+/semop04
+/semop05
diff --git a/testcases/kernel/syscalls/ipc/semop/Makefile b/testcases/kernel/syscalls/ipc/semop/Makefile
index 6b2b26d05..43afffb3f 100644
--- a/testcases/kernel/syscalls/ipc/semop/Makefile
+++ b/testcases/kernel/syscalls/ipc/semop/Makefile
@@ -7,6 +7,9 @@ LTPLIBS = ltpnewipc
include $(top_srcdir)/include/mk/testcases.mk
-LTPLDLIBS = -lltpnewipc
+semop01: LTPLDLIBS = -lltpnewipc
+semop02: LTPLDLIBS = -lltpnewipc
+semop03: LTPLDLIBS = -lltpnewipc
+semop05: LDLIBS += -lpthread
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/semop/semop04.c b/testcases/kernel/syscalls/ipc/semop/semop04.c
new file mode 100644
index 000000000..1f49e7740
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/semop/semop04.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (C) 2003-2023 Linux Test Project, Inc.
+ * Author: 2001 Paul Larson <plars@us.ibm.com>
+ * Modified: 2001 Manoj Iyer <manjo@ausin.ibm.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Creates a semaphore and two processes. The processes
+ * each go through a loop where they semdown, delay for a
+ * random amount of time, and semup, so they will almost
+ * always be fighting for control of the semaphore.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include "lapi/sem.h"
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+
+#define LOOPS 1000
+#define SEED 123
+
+static void semup(int semid)
+{
+ struct sembuf semops;
+
+ semops.sem_num = 0;
+ semops.sem_op = 1;
+ semops.sem_flg = SEM_UNDO;
+
+ SAFE_SEMOP(semid, &semops, 1);
+}
+
+static void semdown(int semid)
+{
+ struct sembuf semops;
+
+ semops.sem_num = 0;
+ semops.sem_op = -1;
+ semops.sem_flg = SEM_UNDO;
+
+ SAFE_SEMOP(semid, &semops, 1);
+}
+
+static void mainloop(int semid)
+{
+ int i;
+
+ for (i = 0; i < LOOPS; i++) {
+ semdown(semid);
+ usleep(1 + ((100.0 * rand()) / RAND_MAX));
+ semup(semid);
+ }
+}
+
+static void run(void)
+{
+ int semid;
+ union semun semunion;
+ pid_t pid;
+
+ /* set up the semaphore */
+ semid = SAFE_SEMGET((key_t) 9142, 1, 0666 | IPC_CREAT);
+
+ semunion.val = 1;
+
+ SAFE_SEMCTL(semid, 0, SETVAL, semunion);
+
+ tst_res(TINFO, "srand seed is %d", SEED);
+ srand(SEED);
+
+ pid = SAFE_FORK();
+
+ if (pid) {
+ mainloop(semid);
+ tst_reap_children();
+ TST_EXP_POSITIVE(semctl(semid, 0, IPC_RMID, semunion));
+ } else {
+ mainloop(semid);
+ }
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .forks_child = 1,
+};
diff --git a/testcases/kernel/syscalls/ipc/semop/semop05.c b/testcases/kernel/syscalls/ipc/semop/semop05.c
new file mode 100644
index 000000000..34b714bf0
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/semop/semop05.c
@@ -0,0 +1,157 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2002
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * FILE : sem02.c
+ *
+ * DESCRIPTION : The application creates several threads using pthread_create().
+ * One thread performs a semop() with the SEM_UNDO flag set. The change in
+ * sempaphore value performed by that semop should be "undone" only when the
+ * last pthread exits.
+ *
+ * EXPECTED OUTPUT:
+ * Waiter, pid = <pid#>
+ * Poster, pid = <pid#>, posting
+ * Poster posted
+ * Poster exiting
+ * Waiter waiting, pid = <pid#>
+ * Waiter done waiting
+ *
+ * HISTORY:
+ * written by Dave Olien (oliend@us.ibm.com)
+ * 03/06/2002 Robbie Williamson (robbiew@us.ibm.com)
+ * -ported
+ * 07/04/2003 Paul Larson (plars@linuxtestproject.org)
+ * -ported to LTP
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include "lapi/sem.h"
+#include "test.h"
+
+#define KEY IPC_PRIVATE
+
+#define NUMTHREADS 2
+
+void *retval[NUMTHREADS];
+void *waiter(void *);
+void *poster(void *);
+void cleanup(void);
+
+char *TCID = "sem02";
+int TST_TOTAL = 1;
+
+struct sembuf Psembuf = { 0, -1, SEM_UNDO };
+struct sembuf Vsembuf = { 0, 1, SEM_UNDO };
+
+int sem_id;
+int err_ret; /* This is used to determine PASS/FAIL status */
+int main(int argc, char **argv)
+{
+ int i, rc;
+ union semun semunion;
+
+ pthread_t pt[NUMTHREADS];
+ pthread_attr_t attr;
+
+ tst_parse_opts(argc, argv, NULL, NULL);
+ /* Create the semaphore set */
+ sem_id = semget(KEY, 1, 0666 | IPC_CREAT);
+ if (sem_id < 0) {
+ printf("semget failed, errno = %d\n", errno);
+ exit(1);
+ }
+ /* initialize data structure associated to the semaphore */
+ semunion.val = 1;
+ semctl(sem_id, 0, SETVAL, semunion);
+
+ /* setup the attributes of the thread */
+ /* set the scope to be system to make sure the threads compete on a */
+ /* global scale for cpu */
+ pthread_attr_init(&attr);
+ pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
+
+ err_ret = 1; /* Set initial error value to 1 */
+ /* Create the threads */
+ for (i = 0; i < NUMTHREADS; i++) {
+ if (i == 0)
+ rc = pthread_create(&pt[i], &attr, waiter, retval[i]);
+ else
+ rc = pthread_create(&pt[i], &attr, poster, retval[i]);
+ }
+
+ /* Sleep long enough to see that the other threads do what they are supposed to do */
+ sleep(20);
+ semunion.val = 1;
+ semctl(sem_id, 0, IPC_RMID, semunion);
+ if (err_ret == 1)
+ tst_resm(TFAIL, "failed");
+ else
+ tst_resm(TPASS, "passed");
+ cleanup();
+
+ tst_exit();
+}
+
+/* This thread sleeps 10 seconds then waits on the semaphore. As long
+ as someone has posted on the semaphore, and no undo has taken
+ place, the semop should complete and we'll print "Waiter done
+ waiting." */
+void *waiter(void *foo)
+{
+ int pid;
+ pid = getpid();
+
+ tst_resm(TINFO, "Waiter, pid = %d", pid);
+ sleep(10);
+
+ tst_resm(TINFO, "Waiter waiting, pid = %d", pid);
+ semop(sem_id, &Psembuf, 1);
+ tst_resm(TINFO, "Waiter done waiting");
+ err_ret = 0; /* If the message above is displayed, the test is a PASS */
+ pthread_exit(0);
+}
+
+/* This thread immediately posts on the semaphore and then immediately
+ exits. If the *thread* exits, the undo should not happen, and the
+ waiter thread which will start waiting on it in 10 seconds, should
+ still get it. */
+void *poster(void *foo)
+{
+ int pid;
+
+ pid = getpid();
+ tst_resm(TINFO, "Poster, pid = %d, posting", pid);
+ semop(sem_id, &Vsembuf, 1);
+ tst_resm(TINFO, "Poster posted");
+ tst_resm(TINFO, "Poster exiting");
+
+ pthread_exit(0);
+}
+
+void cleanup(void)
+{
+}
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget02.c b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
index 3788e711f..8168803a5 100644
--- a/testcases/kernel/syscalls/ipc/shmget/shmget02.c
+++ b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
@@ -11,17 +11,17 @@
*
* Test for ENOENT, EEXIST, EINVAL, EACCES, EPERM errors.
*
- * ENOENT - No segment exists for the given key and IPC_CREAT was not specified.
- * EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given.
- * EINVAL - A new segment was to be created and size is less than SHMMIN or
- * greater than SHMMAX. Or a segment for the given key exists, but size is
- * gran eater than the size of that segment.
- * EACCES - The user does not have permission to access the shared memory segment.
- * EPERM - The SHM_HUGETLB flag was specified, but the caller was not privileged
- * (did not have the CAP_IPC_LOCK capability) and is not a member of the
- * sysctl_hugetlb_shm_group group.
- * ENOMEM - The SHM_HUGETLB flag was specified, the caller was privileged but not
- * have enough hugepage memory space.
+ * - ENOENT - No segment exists for the given key and IPC_CREAT was not specified.
+ * - EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given.
+ * - EINVAL - A new segment was to be created and size is less than SHMMIN or
+ * greater than SHMMAX. Or a segment for the given key exists, but size is
+ * gran eater than the size of that segment.
+ * - EACCES - The user does not have permission to access the shared memory segment.
+ * - EPERM - The SHM_HUGETLB flag was specified, but the caller was not
+ * privileged (did not have the CAP_IPC_LOCK capability) and is not a member
+ * of the sysctl_hugetlb_shm_group group.
+ * - ENOMEM - The SHM_HUGETLB flag was specified, the caller was privileged but
+ * not have enough hugepage memory space.
*/
#include <errno.h>
@@ -56,7 +56,7 @@ static struct tcase {
{&shmkey1, SHM_SIZE, IPC_EXCL, 0, 0, ENOENT},
{&shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL, 0, 0, EEXIST},
{&shmkey1, SHMMIN - 1, IPC_CREAT | IPC_EXCL, 0, 0, EINVAL},
- {&shmkey1, SHMMAX + 1, IPC_CREAT | IPC_EXCL, 0, 0, EINVAL},
+ {&shmkey1, 8192 + 1, IPC_CREAT | IPC_EXCL, 0, 0, EINVAL},
{&shmkey, SHM_SIZE * 2, IPC_EXCL, 0, 0, EINVAL},
{&shmkey, SHM_SIZE, SHM_RD, 1, 0, EACCES},
{&shmkey1, SHM_SIZE, IPC_CREAT | SHM_HUGETLB, 0, 1, EPERM},
@@ -149,4 +149,8 @@ static struct tst_test test = {
.test = do_test,
.tcnt = ARRAY_SIZE(tcases),
.hugepages = {TST_NO_HUGEPAGES},
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/kernel/shmmax", "8192", TST_SR_TCONF_MISSING | TST_SR_TBROK_RO},
+ {}
+ },
};