• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@us.ibm.com */
21 /* 06/30/2001   Port to Linux   nsharoff@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 
main(void)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",
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",
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", 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 
child(void)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",
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",
165 				 errno, shmid, chld_pid);
166 		} else {
167 			if (*cp != 'A') {
168 				tst_resm(TFAIL, "child: not A");
169 			}
170 			if (*(cp + 1) != 'B') {
171 				tst_resm(TFAIL, "child: not B");
172 			}
173 			if (*(cp + 2) != 'C') {
174 				tst_resm(TFAIL, "child: not C");
175 			}
176 			if (*(cp + 8192) != 0) {
177 				tst_resm(TFAIL, "child: not 0");
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",
191 				 errno, shmid, chld_pid);
192 		} else {
193 			if (*cp != 'A') {
194 				tst_resm(TFAIL, "child: not A");
195 			}
196 			if (*(cp + 1) != 'B') {
197 				tst_resm(TFAIL, "child: not B");
198 			}
199 			if (*(cp + 2) != 'C') {
200 				tst_resm(TFAIL, "child: not C");
201 			}
202 			if (*(cp + 8192) != 0) {
203 				tst_resm(TFAIL, "child: not 0");
204 			}
205 		}
206 	}
207 	tst_exit();
208 }
209 
rm_shm(int shmid)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",
217 			 shmid, errno);
218 	}
219 	return (0);
220 }
221