1/* 2 * Copyright (c) 2002, Intel Corporation. All rights reserved. 3 * Created by: julie.n.fleischer REMOVE-THIS AT intel DOT com 4 * This file is licensed under the GPL license. For the full content 5 * of this license, see the COPYING file at the top level of this 6 * source tree. 7 */ 8 9/* 10 * Test mq_send() will set errno == EINTR if it is interrupted by a signal. 11 * 12 * Have a child send signals until it starts to block. At that point, have 13 * the parent send a signal to interrupt the child. Test passes if errno == 14 * EINVAL. 15 * 16 * Test very similar to 5-2.c except we don't have the additional test to 17 * verify the child _was_ blocking. 18 */ 19 20#include <stdio.h> 21#include <mqueue.h> 22#include <fcntl.h> 23#include <sys/stat.h> 24#include <sys/types.h> 25#include <sys/wait.h> 26#include <unistd.h> 27#include <string.h> 28#include <stdlib.h> 29#include <stdint.h> 30#include <signal.h> 31#include <errno.h> 32#include "posixtest.h" 33 34#define NAMESIZE 50 35#define MSGSTR "0123456789" 36#define BUFFER 40 37#define MAXMSG 5 38 39#define CHILDPASS 1 40#define CHILDFAIL 0 41 42char gqname[NAMESIZE]; 43mqd_t gqueue; 44 45/* 46 * This handler is just used to catch the signal and stop sleep (so the 47 * parent knows the child is still busy sending signals). 48 */ 49void justreturn_handler(int signo) 50{ 51 return; 52} 53 54int main() 55{ 56 int pid; 57 const char *msgptr = MSGSTR; 58 struct mq_attr attr; 59 struct sigaction act; 60 61 sprintf(gqname, "/mq_send_12-1_%d", getpid()); 62 63 attr.mq_maxmsg = MAXMSG; 64 attr.mq_msgsize = BUFFER; 65 gqueue = mq_open(gqname, O_CREAT |O_RDWR, S_IRUSR | S_IWUSR, &attr); 66 if (gqueue == (mqd_t)-1) { 67 perror("mq_open() did not return success"); 68 return PTS_UNRESOLVED; 69 } 70 71 /* parent and child use justreturn_handler to just return out of 72 * situations -- parent uses to stop it's sleep and wait again for 73 * the child; child uses to stop its mq_send 74 */ 75 act.sa_handler=justreturn_handler; 76 act.sa_flags=0; 77 sigemptyset(&act.sa_mask); 78 sigaction(SIGABRT, &act, 0); 79 80 if ((pid = fork()) == 0) { 81 /* child here */ 82 int i; 83 84 sleep(1); // give parent time to set up handler 85 for (i=0; i<MAXMSG+1; i++) { 86 if (mq_send(gqueue, msgptr, strlen(msgptr), 1) == -1) { 87 if (errno == EINTR) { 88 printf("mq_send interrupted by signal\n"); 89 return CHILDPASS; 90 } else { 91 printf("mq_send not interrupted by signal\n"); 92 return CHILDFAIL; 93 } 94 } 95 /* send signal to parent each time message is sent */ 96 kill(getppid(), SIGABRT); 97 } 98 99 printf("Child never blocked\n"); 100 return CHILDFAIL; 101 } else { 102 /* parent here */ 103 int j,k; 104 105 for (j=0; j<MAXMSG+1; j++) { 106 if (sleep(3) == 0) { 107 /* If sleep finished, child is probably blocking */ 108 kill(pid, SIGABRT); //signal child 109 break; 110 } 111 } 112 mq_close(gqueue); 113 if (mq_unlink(gqname) != 0) { 114 perror("mq_unlink()"); 115 return PTS_UNRESOLVED; 116 } 117 118 if (wait(&k) == -1) { 119 perror("Error waiting for child to exit\n"); 120 kill(pid, SIGKILL); //kill child if not gone 121 return PTS_UNRESOLVED; 122 } 123 if (!WIFEXITED(k) || !WEXITSTATUS(k)) { 124 printf("Test FAILED\n"); 125 return PTS_FAIL; 126 } 127 128 printf("Test PASSED\n"); 129 return PTS_PASS; 130 } 131 132 return PTS_UNRESOLVED; 133} 134 135