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