1 /* 2 * 3 * Copyright (c) International Business Machines Corp., 2002 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 /* 06/30/2001 Port to Linux nsharoff (at) us.ibm.com */ 21 /* 10/30/2002 Port to LTP dbarrera (at) us.ibm.com */ 22 23 /* 24 * NAME 25 * semctl07 26 * 27 * CALLS 28 * semctl(2) semget(2) 29 * 30 * ALGORITHM 31 * Get and manipulate a set of semaphores. 32 * 33 * RESTRICTIONS 34 * 35 * HISTORY 36 * 10/03/2008 Renaud Lottiaux (Renaud.Lottiaux (at) kerlabs.com) 37 * - Fix concurrency issue. A statically defined key was used. Leading 38 * to conflict with other instances of the same test. 39 */ 40 41 #include <sys/types.h> 42 #include <sys/ipc.h> 43 #include <sys/sem.h> 44 #include <signal.h> 45 #include <errno.h> 46 #include <stdio.h> 47 #include <sys/wait.h> 48 #include "ipcsem.h" 49 #include "test.h" 50 51 void setup(void); 52 void cleanup(void); 53 54 char *TCID = "semctl07"; 55 int TST_TOTAL = 1; 56 57 key_t key; 58 int semid = -1, nsems; 59 60 int main(int argc, char *argv[]) 61 { 62 int status; 63 struct semid_ds buf_ds; 64 union semun arg; 65 66 tst_parse_opts(argc, argv, NULL, NULL); 67 68 setup(); 69 70 arg.buf = &buf_ds; 71 if ((status = semctl(semid, 0, IPC_STAT, arg)) == -1) { 72 tst_resm(TFAIL, "semctl() failed errno = %d", errno); 73 semctl(semid, 1, IPC_RMID, arg); 74 75 } 76 77 /* 78 * Check contents of semid_ds structure. 79 */ 80 81 if (arg.buf->sem_nsems != nsems) { 82 tst_resm(TFAIL, "error: unexpected number of sems %lu", 83 arg.buf->sem_nsems); 84 85 } 86 if (arg.buf->sem_perm.uid != getuid()) { 87 tst_resm(TFAIL, "error: unexpected uid %d", 88 arg.buf->sem_perm.uid); 89 90 } 91 if (arg.buf->sem_perm.gid != getgid()) { 92 tst_resm(TFAIL, "error: unexpected gid %d", 93 arg.buf->sem_perm.gid); 94 95 } 96 if (arg.buf->sem_perm.cuid != getuid()) { 97 tst_resm(TFAIL, "error: unexpected cuid %d", 98 arg.buf->sem_perm.cuid); 99 100 } 101 if (arg.buf->sem_perm.cgid != getgid()) { 102 tst_resm(TFAIL, "error: unexpected cgid %d", 103 arg.buf->sem_perm.cgid); 104 105 } 106 if ((status = semctl(semid, 0, GETVAL, arg)) == -1) { 107 tst_resm(TFAIL, "semctl(GETVAL) failed errno = %d", errno); 108 109 } 110 arg.val = 1; 111 if ((status = semctl(semid, 0, SETVAL, arg)) == -1) { 112 tst_resm(TFAIL, "SEMCTL(SETVAL) failed errno = %d", errno); 113 114 } 115 if ((status = semctl(semid, 0, GETVAL, arg)) == -1) { 116 tst_resm(TFAIL, "semctl(GETVAL) failed errno = %d", errno); 117 118 } 119 if (status != arg.val) { 120 tst_resm(TFAIL, "error: unexpected value %d", status); 121 122 } 123 if ((status = semctl(semid, 0, GETPID, arg)) == -1) { 124 tst_resm(TFAIL, "semctl(GETPID) failed errno = %d", errno); 125 126 } 127 status = getpid(); 128 if (status == 0) { 129 tst_resm(TFAIL, "error: unexpected pid %d", status); 130 131 } 132 if ((status = semctl(semid, 0, GETNCNT, arg)) == -1) { 133 tst_resm(TFAIL, "semctl(GETNCNT) failed errno = %d", errno); 134 135 } 136 if (status != 0) { 137 tst_resm(TFAIL, "error: unexpected semncnt %d", status); 138 139 } 140 if ((status = semctl(semid, 0, GETZCNT, arg)) == -1) { 141 tst_resm(TFAIL, "semctl(GETZCNT) failed errno = %d", errno); 142 143 } 144 if (status != 0) { 145 tst_resm(TFAIL, "error: unexpected semzcnt %d", status); 146 147 } 148 149 tst_resm(TPASS, "semctl07 ran successfully!"); 150 151 cleanup(); 152 tst_exit(); 153 } 154 155 void setup(void) 156 { 157 tst_sig(NOFORK, DEF_HANDLER, cleanup); 158 159 TEST_PAUSE; 160 161 tst_tmpdir(); 162 163 /* get an IPC resource key */ 164 key = getipckey(); 165 nsems = 1; 166 167 if ((semid = semget(key, nsems, SEM_RA | IPC_CREAT)) == -1) { 168 tst_brkm(TFAIL, NULL, "semget() failed errno = %d", errno); 169 } 170 } 171 172 void cleanup(void) 173 { 174 rm_sema(semid); 175 tst_rmdir(); 176 } 177