1 /* 2 * Copyright (c) 2003 - 2004, Intel Corporation. All rights reserved. 3 * This file is licensed under the GPL license. For the full content 4 * of this license, see the COPYING file at the top level of this 5 * source tree. 6 * adam.li (at) intel.com 7 */ 8 /* 9 * If Timers option is supported, then abs_timeout is based on 10 * CLOCK_REALTIME. 11 * Otherwise, the timeout is based on the system clock (time() function). 12 */ 13 14 #include <sys/stat.h> 15 #include <sys/types.h> 16 #include <sys/wait.h> 17 #include <fcntl.h> 18 #include <mqueue.h> 19 #include <signal.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <time.h> 24 #include <unistd.h> 25 #include "posixtest.h" 26 27 #define TEST "8-1" 28 #define FUNCTION "mq_timedreceive" 29 #define ERROR_PREFIX "unexpected error: " FUNCTION " " TEST ": " 30 31 #define NAMESIZE 50 32 #define BUFFER 40 33 #define TIMEOUT 3 34 35 int blocking; 36 void exit_handler(int signo) 37 { 38 printf("FAIL: the case is blocking, exit anyway\n"); 39 blocking = 1; 40 return; 41 } 42 43 int main(void) 44 { 45 char mqname[NAMESIZE], msgrv[BUFFER]; 46 mqd_t mqdes; 47 struct timespec ts; 48 time_t oldtime, newtime; 49 struct mq_attr attr; 50 pid_t pid; 51 int unresolved = 0, failure = 0; 52 53 sprintf(mqname, "/" FUNCTION "_" TEST "_%d", getpid()); 54 55 attr.mq_msgsize = BUFFER; 56 attr.mq_maxmsg = BUFFER; 57 mqdes = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); 58 if (mqdes == (mqd_t) - 1) { 59 perror(ERROR_PREFIX "mq_open"); 60 unresolved = 1; 61 } 62 63 pid = fork(); 64 if (pid != 0) { 65 /* Parent process */ 66 struct sigaction act; 67 act.sa_handler = exit_handler; 68 act.sa_flags = 0; 69 sigemptyset(&act.sa_mask); 70 sigaction(SIGABRT, &act, 0); 71 #ifdef _POSIX_TIMERS 72 printf("Using CLOCK_REALTIME\n"); 73 clock_gettime(CLOCK_REALTIME, &ts); 74 oldtime = ts.tv_sec; 75 ts.tv_sec = ts.tv_sec + TIMEOUT; 76 #else 77 ts.tv_sec = time(NULL) + TIMEOUT; 78 oldtime = time(NULL); 79 #endif 80 ts.tv_nsec = 0; 81 mq_timedreceive(mqdes, msgrv, BUFFER, NULL, &ts); 82 #ifdef _POSIX_TIMERS 83 clock_gettime(CLOCK_REALTIME, &ts); 84 newtime = ts.tv_sec; 85 #else 86 newtime = time(NULL); 87 #endif 88 if ((newtime - oldtime) < TIMEOUT) { 89 printf("FAIL: mq_timedreceive didn't block until " 90 "timout expires\n"); 91 failure = 1; 92 } 93 /* Parent is not blocking, let child abort */ 94 kill(pid, SIGABRT); 95 wait(NULL); 96 if (mq_close(mqdes) != 0) { 97 perror(ERROR_PREFIX "mq_close"); 98 unresolved = 1; 99 } 100 if (mq_unlink(mqname) != 0) { 101 perror(ERROR_PREFIX "mq_unlink"); 102 unresolved = 1; 103 } 104 if (failure == 1 || blocking == 1) { 105 printf("Test FAILED\n"); 106 return PTS_FAIL; 107 } 108 if (unresolved == 1) { 109 printf("Test UNRESOLVED\n"); 110 return PTS_UNRESOLVED; 111 } 112 printf("Test PASSED\n"); 113 return PTS_PASS; 114 } else { 115 sleep(TIMEOUT + 3); /* Parent is probably blocking 116 send a signal to let it abort */ 117 kill(getppid(), SIGABRT); 118 return 0; 119 } 120 } 121