Home | History | Annotate | Download | only in shmt
      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