semctl07.c revision ec6edca7aa42b6affd989ef91b5897f96795e40f
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20/* 06/30/2001 Port to Linux nsharoff@us.ibm.com */ 21/* 10/30/2002 Port to LTP dbarrera@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@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> /* needed for test */ 42#include <sys/ipc.h> /* needed for test */ 43#include <sys/sem.h> /* needed for test */ 44#include <signal.h> /* needed for test */ 45#include <errno.h> /* needed for test */ 46#include <stdio.h> /* needed by testhead.h */ 47#include <wait.h> /* needed by testhead.h */ 48#include "ipcsem.h" 49#include "test.h" 50#include "usctest.h" 51 52void setup(); 53void cleanup(); 54 55/* 56 *These globals must be defined in the test. 57 */ 58 59char *TCID = "semctl07"; /* Test program identifier. */ 60int TST_TOTAL = 1; /* Total number of test cases. */ 61 62int exp_enos[] = { 0 }; /* List must end with 0 */ 63 64key_t key; 65int semid = -1, nsems; 66 67/*--------------------------------------------------------------*/ 68 69int main(argc, argv) 70int argc; 71char *argv[]; 72{ 73 int status; 74 struct semid_ds buf_ds; 75 76 union semun { 77 int val; 78 struct semid_ds *buf; 79 short *array; 80 }; 81 82 union semun arg; 83 84 setup(); /* temp file is now open */ 85/*--------------------------------------------------------------*/ 86 87 arg.buf = &buf_ds; 88 if ((status = semctl(semid, 0, IPC_STAT, arg)) == -1) { 89 tst_resm(TFAIL, "semctl() failed errno = %d", errno); 90 semctl(semid, 1, IPC_RMID, arg); 91 92 } 93 94 /* 95 * Check contents of semid_ds structure. 96 */ 97 98 if (arg.buf->sem_nsems != nsems) { 99 tst_resm(TFAIL, "error: unexpected number of sems %lu", 100 arg.buf->sem_nsems); 101 102 } 103 if (arg.buf->sem_perm.uid != getuid()) { 104 tst_resm(TFAIL, "error: unexpected uid %d", 105 arg.buf->sem_perm.uid); 106 107 } 108 if (arg.buf->sem_perm.gid != getgid()) { 109 tst_resm(TFAIL, "error: unexpected gid %d", 110 arg.buf->sem_perm.gid); 111 112 } 113 if (arg.buf->sem_perm.cuid != getuid()) { 114 tst_resm(TFAIL, "error: unexpected cuid %d", 115 arg.buf->sem_perm.cuid); 116 117 } 118 if (arg.buf->sem_perm.cgid != getgid()) { 119 tst_resm(TFAIL, "error: unexpected cgid %d", 120 arg.buf->sem_perm.cgid); 121 122 } 123 if ((status = semctl(semid, 0, GETVAL, arg)) == -1) { 124 tst_resm(TFAIL, "semctl(GETVAL) failed errno = %d", errno); 125 126 } 127 arg.val = 1; 128 if ((status = semctl(semid, 0, SETVAL, arg)) == -1) { 129 tst_resm(TFAIL, "SEMCTL(SETVAL) failed errno = %d", errno); 130 131 } 132 if ((status = semctl(semid, 0, GETVAL, arg)) == -1) { 133 tst_resm(TFAIL, "semctl(GETVAL) failed errno = %d", errno); 134 135 } 136 if (status != arg.val) { 137 tst_resm(TFAIL, "error: unexpected value %d", status); 138 139 } 140 if ((status = semctl(semid, 0, GETPID, arg)) == -1) { 141 tst_resm(TFAIL, "semctl(GETPID) failed errno = %d", errno); 142 143 } 144 status = getpid(); 145 if (status == 0) { 146 tst_resm(TFAIL, "error: unexpected pid %d", status); 147 148 } 149 if ((status = semctl(semid, 0, GETNCNT, arg)) == -1) { 150 tst_resm(TFAIL, "semctl(GETNCNT) failed errno = %d", errno); 151 152 } 153 if (status != 0) { 154 tst_resm(TFAIL, "error: unexpected semncnt %d", status); 155 156 } 157 if ((status = semctl(semid, 0, GETZCNT, arg)) == -1) { 158 tst_resm(TFAIL, "semctl(GETZCNT) failed errno = %d", errno); 159 160 } 161 if (status != 0) { 162 tst_resm(TFAIL, "error: unexpected semzcnt %d", status); 163 164 } 165 166 tst_resm(TPASS, "semctl07 ran successfully!"); 167/*--------------------------------------------------------------*/ 168/* Clean up any files created by test before exit. */ 169/*--------------------------------------------------------------*/ 170 171 cleanup(); 172 return (0); 173} 174 175/*--------------------------------------------------------------*/ 176 177/*************************************************************** 178 * setup() - performs all ONE TIME setup for this test. 179 *****************************************************************/ 180void setup() 181{ 182 /* You will want to enable some signal handling so you can capture 183 * unexpected signals like SIGSEGV. 184 * */ 185 tst_sig(NOFORK, DEF_HANDLER, cleanup); 186 187 /* One cavet that hasn't been fixed yet. TEST_PAUSE contains the code to 188 * fork the test with the -c option. You want to make sure you do this 189 * before you create your temporary directory. 190 */ 191 TEST_PAUSE; 192 193 /* 194 * Create a temporary directory and cd into it. 195 * This helps to ensure that a unique msgkey is created. 196 * See ../lib/libipc.c for more information. 197 */ 198 tst_tmpdir(); 199 200 /* get an IPC resource key */ 201 key = getipckey(); 202 nsems = 1; 203 204 if ((semid = semget(key, nsems, SEM_RA | IPC_CREAT)) == -1) { 205 tst_resm(TFAIL, "semget() failed errno = %d", errno); 206 tst_exit(); 207 } 208} 209 210/*************************************************************** 211 * cleanup() - performs all ONE TIME cleanup for this test at 212 * completion or premature exit. 213 ****************************************************************/ 214void cleanup() 215{ 216 /* if it exists, remove the semaphore resouce */ 217 rm_sema(semid); 218 219 tst_rmdir(); 220 221 /* 222 * print timing stats if that option was specified. 223 * print errno log if that option was specified. 224 */ 225 TEST_CLEANUP; 226 227} 228