Home | History | Annotate | Download | only in semop
      1 /*
      2  *
      3  *   Copyright (c) International Business Machines  Corp., 2001
      4  *
      5  *   This program is free software;  you can redistribute it and/or modify
      6  *   it under the terms of the GNU General Public License as published by
      7  *   the Free Software Foundation; either version 2 of the License, or
      8  *   (at your option) any later version.
      9  *
     10  *   This program is distributed in the hope that it will be useful,
     11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
     12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
     13  *   the GNU General Public License for more details.
     14  *
     15  *   You should have received a copy of the GNU General Public License
     16  *   along with this program;  if not, write to the Free Software
     17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     18  */
     19 
     20 /*
     21  * DESCRIPTION
     22  *	semop02 - test for E2BIG, EACCES, EFAULT, EINVAL and ERANGE errors
     23  *
     24  * HISTORY
     25  *	03/2001 - Written by Wayne Boyer
     26  *
     27  *      10/03/2008 Renaud Lottiaux (Renaud.Lottiaux (at) kerlabs.com)
     28  *      - Fix concurrency issue. The second key used for this test could
     29  *        conflict with the key from another task.
     30  */
     31 
     32 #define _GNU_SOURCE
     33 #include <pwd.h>
     34 #include "test.h"
     35 #include "safe_macros.h"
     36 #include "ipcsem.h"
     37 
     38 char *TCID = "semop02";
     39 
     40 static void semop_verify(int i);
     41 int sem_id_1 = -1;	/* a semaphore set with read & alter permissions */
     42 int sem_id_2 = -1;	/* a semaphore set without read & alter permissions */
     43 int bad_id = -1;
     44 
     45 struct sembuf s_buf[PSEMS];
     46 
     47 int badbuf = -1;
     48 
     49 #define NSOPS	5		/* a resonable number of operations */
     50 #define	BIGOPS	1024		/* a value that is too large for the number */
     51 				/* of semop operations that are permitted   */
     52 struct test_case_t {
     53 	int *semid;
     54 	struct sembuf *t_sbuf;
     55 	unsigned t_ops;
     56 	int error;
     57 } TC[] = {
     58 	{&sem_id_1, (struct sembuf *)&s_buf, BIGOPS, E2BIG},
     59 	{&sem_id_2, (struct sembuf *)&s_buf, NSOPS, EACCES},
     60 	{&sem_id_1, (struct sembuf *)-1, NSOPS, EFAULT},
     61 	{&sem_id_1, (struct sembuf *)&s_buf, 0, EINVAL},
     62 	{&bad_id, (struct sembuf *)&s_buf, NSOPS, EINVAL},
     63 	{&sem_id_1, (struct sembuf *)&s_buf, 1, ERANGE}
     64 };
     65 
     66 int TST_TOTAL = ARRAY_SIZE(TC);
     67 
     68 int main(int ac, char **av)
     69 {
     70 	int lc;
     71 	int i;
     72 
     73 	tst_parse_opts(ac, av, NULL, NULL);
     74 
     75 	setup();
     76 
     77 	for (lc = 0; TEST_LOOPING(lc); lc++) {
     78 		tst_count = 0;
     79 
     80 		for (i = 0; i < TST_TOTAL; i++)
     81 			semop_verify(i);
     82 	}
     83 
     84 	cleanup();
     85 	tst_exit();
     86 }
     87 
     88 void setup(void)
     89 {
     90 	char nobody_uid[] = "nobody";
     91 	struct passwd *ltpuser;
     92 	key_t semkey2;
     93 	struct seminfo ipc_buf;
     94 	union semun arr;
     95 
     96 	tst_require_root();
     97 
     98 	ltpuser = SAFE_GETPWNAM(NULL, nobody_uid);
     99 	SAFE_SETUID(NULL, ltpuser->pw_uid);
    100 
    101 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
    102 
    103 	TEST_PAUSE;
    104 
    105 	tst_tmpdir();
    106 
    107 	/* get an IPC resource key */
    108 	semkey = getipckey();
    109 
    110 	/* create a semaphore set with read and alter permissions */
    111 	sem_id_1 = semget(semkey, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA);
    112 	if (sem_id_1 == -1) {
    113 		tst_brkm(TBROK | TERRNO, cleanup,
    114 			 "couldn't create semaphore in setup");
    115 	}
    116 
    117 	/* Get an new IPC resource key. */
    118 	semkey2 = getipckey();
    119 
    120 	/* create a semaphore set without read and alter permissions */
    121 	sem_id_2 = semget(semkey2, PSEMS, IPC_CREAT | IPC_EXCL);
    122 	if (sem_id_2 == -1) {
    123 		tst_brkm(TBROK | TERRNO, cleanup,
    124 			 "couldn't create semaphore in setup");
    125 	}
    126 
    127 	arr.__buf = &ipc_buf;
    128 	if (semctl(sem_id_1, 0, IPC_INFO, arr) == -1)
    129 		tst_brkm(TBROK | TERRNO, cleanup, "semctl() IPC_INFO failed");
    130 
    131 	/* for ERANGE errno test */
    132 	arr.val = 1;
    133 	s_buf[0].sem_op = ipc_buf.semvmx;
    134 	if (semctl(sem_id_1, 0, SETVAL, arr) == -1)
    135 		tst_brkm(TBROK | TERRNO, cleanup, "semctl() SETVAL failed");
    136 }
    137 
    138 static void semop_verify(int i)
    139 {
    140 	TEST(semop(*(TC[i].semid), TC[i].t_sbuf, TC[i].t_ops));
    141 
    142 	if (TEST_RETURN != -1) {
    143 		tst_resm(TFAIL, "call succeeded unexpectedly");
    144 		return;
    145 	}
    146 
    147 	if (TEST_ERRNO == TC[i].error) {
    148 		tst_resm(TPASS | TTERRNO, "semop failed as expected");
    149 	} else {
    150 		tst_resm(TFAIL | TTERRNO,
    151 			 "semop failed unexpectedly; expected: "
    152 			 "%d - %s", TC[i].error, strerror(TC[i].error));
    153 	}
    154 }
    155 
    156 void cleanup(void)
    157 {
    158 	/* if they exist, remove the semaphore resources */
    159 	rm_sema(sem_id_1);
    160 	rm_sema(sem_id_2);
    161 
    162 	tst_rmdir();
    163 }
    164