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 (at) us.ibm.com */ 22 /* 06/30/2001 Port to Linux nsharoff (at) 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 54 char *TCID = "shmt04"; /* Test program identifier. */ 55 int TST_TOTAL = 2; /* Total number of test cases. */ 56 /**************/ 57 58 key_t key; 59 sigset_t set; 60 61 #define SIZE 16*1024 62 63 int child(); 64 static int rm_shm(int); 65 66 int main(void) 67 { 68 char *cp = NULL; 69 int pid, pid1, shmid; 70 int status; 71 72 key = (key_t) getpid(); 73 74 sigemptyset(&set); 75 sigaddset(&set, SIGUSR1); 76 sigprocmask(SIG_BLOCK, &set, NULL); 77 78 pid = fork(); 79 switch (pid) { 80 case -1: 81 tst_brkm(TBROK, NULL, "fork failed"); 82 case 0: 83 child(); 84 } 85 86 /*----------------------------------------------------------*/ 87 88 if ((shmid = shmget(key, SIZE, IPC_CREAT | 0666)) < 0) { 89 perror("shmget"); 90 tst_resm(TFAIL, "Error: shmget: shmid = %d, errno = %d\n", 91 shmid, errno); 92 /* 93 * kill the child if parent failed to do the attach 94 */ 95 (void)kill(pid, SIGINT); 96 } else { 97 cp = shmat(shmid, NULL, 0); 98 99 if (cp == (char *)-1) { 100 perror("shmat"); 101 tst_resm(TFAIL, 102 "Error: shmat: shmid = %d, errno = %d\n", 103 shmid, errno); 104 105 /* kill the child if parent failed to do the attch */ 106 107 kill(pid, SIGINT); 108 109 /* remove shared memory segment */ 110 111 rm_shm(shmid); 112 113 tst_exit(); 114 } 115 *cp = 'A'; 116 *(cp + 1) = 'B'; 117 *(cp + 2) = 'C'; 118 119 kill(pid, SIGUSR1); 120 while ((pid1 = wait(&status)) < 0 && (errno == EINTR)) ; 121 if (pid1 != pid) { 122 tst_resm(TFAIL, "Waited on the wrong child"); 123 tst_resm(TFAIL, 124 "Error: wait_status = %d, pid1= %d\n", status, 125 pid1); 126 } 127 } 128 129 tst_resm(TPASS, "shmget,shmat"); 130 131 /*----------------------------------------------------------*/ 132 133 if (shmdt(cp) < 0) { 134 tst_resm(TFAIL, "shmdt"); 135 } 136 137 tst_resm(TPASS, "shmdt"); 138 139 /*----------------------------------------------------------*/ 140 141 rm_shm(shmid); 142 tst_exit(); 143 } 144 145 int child(void) 146 { 147 int shmid, chld_pid; 148 char *cp; 149 int sig; 150 151 sigwait(&set, &sig); 152 chld_pid = getpid(); 153 /*--------------------------------------------------------*/ 154 155 if ((shmid = shmget(key, SIZE, 0)) < 0) { 156 perror("shmget:child process"); 157 tst_resm(TFAIL, 158 "Error: shmget: errno=%d, shmid=%d, child_pid=%d\n", 159 errno, shmid, chld_pid); 160 } else { 161 cp = shmat(shmid, NULL, 0); 162 163 if (cp == (char *)-1) { 164 perror("shmat:child process"); 165 tst_resm(TFAIL, 166 "Error: shmat: errno=%d, shmid=%d, child_pid=%d\n", 167 errno, shmid, chld_pid); 168 } else { 169 if (*cp != 'A') { 170 tst_resm(TFAIL, "child: not A\n"); 171 } 172 if (*(cp + 1) != 'B') { 173 tst_resm(TFAIL, "child: not B\n"); 174 } 175 if (*(cp + 2) != 'C') { 176 tst_resm(TFAIL, "child: not C\n"); 177 } 178 if (*(cp + 8192) != 0) { 179 tst_resm(TFAIL, "child: not 0\n"); 180 } 181 } 182 183 } 184 tst_exit(); 185 } 186 187 static int rm_shm(int shmid) 188 { 189 if (shmctl(shmid, IPC_RMID, NULL) == -1) { 190 perror("shmctl"); 191 tst_brkm(TFAIL, 192 NULL, 193 "shmctl Failed to remove: shmid = %d, errno = %d\n", 194 shmid, errno); 195 } 196 return (0); 197 } 198