1 /* 2 * Copyright (c) 2003, Intel Corporation. All rights reserved. 3 * Created by: crystal.xiong 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 * mq_timedreceive() test plan: 11 * Test that if the message queue is empty and O_NONBLOCK is not set, 12 * mq_timedreceive() will block until timeout expires. 13 * 14 */ 15 16 #include <sys/stat.h> 17 #include <sys/types.h> 18 #include <sys/wait.h> 19 #include <fcntl.h> 20 #include <mqueue.h> 21 #include <signal.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <time.h> 26 #include <unistd.h> 27 #include "posixtest.h" 28 29 #define TEST "5-2" 30 #define FUNCTION "mq_timedreceive" 31 #define ERROR_PREFIX "unexpected error: " FUNCTION " " TEST ": " 32 33 #define NAMESIZE 50 34 #define BUFFER 40 35 #define TIMEOUT 3 36 #define THRESHOLD (TIMEOUT - 1) 37 38 int blocking; 39 void exit_handler(int signo) 40 { 41 printf("FAIL: the case is blocking, exit anyway\n"); 42 blocking = 1; 43 return; 44 } 45 46 int main(void) 47 { 48 char mqname[NAMESIZE], msgrv[BUFFER]; 49 mqd_t mqdes; 50 struct timespec ts; 51 time_t oldtime, newtime; 52 struct mq_attr attr; 53 pid_t pid; 54 int unresolved = 0, failure = 0; 55 56 sprintf(mqname, "/" FUNCTION "_" TEST "_%d", getpid()); 57 58 attr.mq_msgsize = BUFFER; 59 attr.mq_maxmsg = BUFFER; 60 mqdes = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); 61 if (mqdes == (mqd_t) - 1) { 62 perror(ERROR_PREFIX "mq_open"); 63 unresolved = 1; 64 } 65 66 pid = fork(); 67 if (pid != 0) { 68 /* Parent process */ 69 struct sigaction act; 70 act.sa_handler = exit_handler; 71 act.sa_flags = 0; 72 sigemptyset(&act.sa_mask); 73 sigaction(SIGABRT, &act, 0); 74 75 ts.tv_sec = time(NULL) + TIMEOUT; 76 ts.tv_nsec = 0; 77 oldtime = time(NULL); 78 mq_timedreceive(mqdes, msgrv, BUFFER, NULL, &ts); 79 newtime = time(NULL); 80 if ((newtime - oldtime) < THRESHOLD) { 81 printf("FAIL: mq_timedreceive didn't block until " 82 "timout expires\n"); 83 failure = 1; 84 } 85 /* Parent is not blocking, let child abort */ 86 kill(pid, SIGABRT); 87 if (mq_close(mqdes) != 0) { 88 perror(ERROR_PREFIX "mq_close"); 89 unresolved = 1; 90 } 91 if (mq_unlink(mqname) != 0) { 92 perror(ERROR_PREFIX "mq_unlink"); 93 unresolved = 1; 94 } 95 if (failure == 1 || blocking == 1) { 96 printf("Test FAILED\n"); 97 return PTS_FAIL; 98 } 99 if (unresolved == 1) { 100 printf("Test UNRESOLVED\n"); 101 return PTS_UNRESOLVED; 102 } 103 printf("Test PASSED\n"); 104 return PTS_PASS; 105 } else { 106 sleep(TIMEOUT + 3); /* Parent is probably blocking 107 send a signal to let it abort */ 108 kill(getppid(), SIGABRT); 109 return 0; 110 } 111 printf("Test PASSED\n"); 112 return PTS_PASS; 113 } 114