shmt04.c revision d2db48030ce485af049d78a1690afc6df99bb689
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/* 03/21/2003 enable ia64 Jacky.Malcles */ 21/* 12/20/2002 Port to LTP robbiew@us.ibm.com */ 22/* 06/30/2001 Port to Linux nsharoff@us.ibm.com */ 23 24/* 25 * NAME 26 * shmt04 27 * 28 * CALLS 29 * shmctl(2) shmget(2) shmat(2) 30 * 31 * ALGORITHM 32 * Parent process forks a child. Child pauses until parent has created 33 * a shared memory segment, attached to it and written to it too. At that 34 * time child gets the shared memory segment id, attaches to it and 35 * verifies that its contents are the same as the contents of the 36 * parent attached segment. 37 * 38 */ 39 40#include <stdio.h> 41#include <sys/types.h> 42#include <sys/ipc.h> 43#include <sys/shm.h> 44#include <sys/wait.h> 45#include <sys/utsname.h> 46#include <signal.h> 47#include <errno.h> 48#include <stdlib.h> 49#include <unistd.h> 50 51/** LTP Port **/ 52#include "test.h" 53#include "usctest.h" 54 55char *TCID = "shmt04"; /* Test program identifier. */ 56int TST_TOTAL = 2; /* Total number of test cases. */ 57/**************/ 58 59key_t key; 60sigset_t sigset; 61 62#define SIZE 16*1024 63 64int child(); 65int rm_shm(int); 66 67int main() 68{ 69 char *cp = NULL; 70 int pid, pid1, shmid; 71 int status; 72 73 key = (key_t) getpid(); 74 75 sigemptyset(&sigset); 76 sigaddset(&sigset, SIGUSR1); 77 sigprocmask(SIG_BLOCK, &sigset, NULL); 78 79 pid = fork(); 80 switch (pid) { 81 case -1: 82 tst_resm(TBROK, "fork failed"); 83 tst_exit(); 84 case 0: 85 child(); 86 } 87 88/*----------------------------------------------------------*/ 89 90 if ((shmid = shmget(key, SIZE, IPC_CREAT | 0666)) < 0) { 91 perror("shmget"); 92 tst_resm(TFAIL, "Error: shmget: shmid = %d, errno = %d\n", 93 shmid, errno); 94 /* 95 * kill the child if parent failed to do the attach 96 */ 97 (void)kill(pid, SIGINT); 98 } else { 99 cp = shmat(shmid, NULL, 0); 100 101 if (cp == (char *)-1) { 102 perror("shmat"); 103 tst_resm(TFAIL, 104 "Error: shmat: shmid = %d, errno = %d\n", 105 shmid, errno); 106 107/* kill the child if parent failed to do the attch */ 108 109 kill(pid, SIGINT); 110 111/* remove shared memory segment */ 112 113 rm_shm(shmid); 114 115 tst_exit(); 116 } 117 *cp = 'A'; 118 *(cp + 1) = 'B'; 119 *(cp + 2) = 'C'; 120 121 kill(pid, SIGUSR1); 122 while ((pid1 = wait(&status)) < 0 && (errno == EINTR)) ; 123 if (pid1 != pid) { 124 tst_resm(TFAIL, "Waited on the wrong child"); 125 tst_resm(TFAIL, 126 "Error: wait_status = %d, pid1= %d\n", status, 127 pid1); 128 } 129 } 130 131 tst_resm(TPASS, "shmget,shmat"); 132 133/*----------------------------------------------------------*/ 134 135 if (shmdt(cp) < 0) { 136 tst_resm(TFAIL, "shmdt"); 137 } 138 139 tst_resm(TPASS, "shmdt"); 140 141/*----------------------------------------------------------*/ 142 143 rm_shm(shmid); 144 tst_exit(); 145} 146 147int child() 148{ 149 int shmid, chld_pid; 150 char *cp; 151 int sig; 152 153 sigwait(&sigset, &sig); 154 chld_pid = getpid(); 155/*--------------------------------------------------------*/ 156 157 if ((shmid = shmget(key, SIZE, 0)) < 0) { 158 perror("shmget:child process"); 159 tst_resm(TFAIL, 160 "Error: shmget: errno=%d, shmid=%d, child_pid=%d\n", 161 errno, shmid, chld_pid); 162 } else { 163 cp = shmat(shmid, NULL, 0); 164 165 if (cp == (char *)-1) { 166 perror("shmat:child process"); 167 tst_resm(TFAIL, 168 "Error: shmat: errno=%d, shmid=%d, child_pid=%d\n", 169 errno, shmid, chld_pid); 170 } else { 171 if (*cp != 'A') { 172 tst_resm(TFAIL, "child: not A\n"); 173 } 174 if (*(cp + 1) != 'B') { 175 tst_resm(TFAIL, "child: not B\n"); 176 } 177 if (*(cp + 2) != 'C') { 178 tst_resm(TFAIL, "child: not C\n"); 179 } 180 if (*(cp + 8192) != 0) { 181 tst_resm(TFAIL, "child: not 0\n"); 182 } 183 } 184 185 } 186 tst_exit(); 187} 188 189int rm_shm(shmid) 190int shmid; 191{ 192 if (shmctl(shmid, IPC_RMID, NULL) == -1) { 193 perror("shmctl"); 194 tst_resm(TFAIL, 195 "shmctl Failed to remove: shmid = %d, errno = %d\n", 196 shmid, errno); 197 tst_exit(); 198 } 199 return (0); 200} 201