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