1/* 2 * Copyright (c) 2004, Bull SA. All rights reserved. 3 * Created by: Laurent.Vivier@bull.net 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 * assertion: 11 * 12 * Asynchronous notification shall occur for AIO that are successfully 13 * cancelled. 14 * 15 * method: 16 * 17 * we queue a lot of aio_write() with a valid sigevent to a file descriptor 18 * next we try to cancel all operations on this file descriptor 19 * we guess some have been finished, other are in progress, 20 * other are waiting 21 * we guess we can cancel all operations waiting 22 * then we analyze aio_error() in the event handler 23 * if aio_error() is ECANCELED, the test is passed 24 * otherwise, we don't know (perhaps we haven't cancel any operation ?) 25 * if number of sig event is not equal to number of aio_write() 26 * the test fails (in fact it hangs). 27 * 28 */ 29 30#define _XOPEN_SOURCE 600 31#include <stdio.h> 32#include <sys/types.h> 33#include <unistd.h> 34#include <sys/stat.h> 35#include <fcntl.h> 36#include <string.h> 37#include <errno.h> 38#include <stdlib.h> 39#include <malloc.h> 40#include <aio.h> 41 42#include "posixtest.h" 43 44#define TNAME "aio_cancel/3-1.c" 45 46#define BUF_NB 128 47#define BUF_SIZE 1024 48 49static volatile int countdown = BUF_NB; 50static volatile int canceled = 0; 51 52void sigusr1_handler(int signum, siginfo_t *info, void *context) 53{ 54 struct aiocb *a = info->si_value.sival_ptr; 55 56 if (aio_error(a) == ECANCELED) 57 canceled++; 58 59 aio_return(a); /* free entry */ 60 61 free((void*)a->aio_buf); 62 free(a); 63 64 countdown--; 65} 66 67int main() 68{ 69 char tmpfname[256]; 70 int fd; 71 struct aiocb *aiocb; 72 struct sigaction action; 73 int i; 74 75#if _POSIX_ASYNCHRONOUS_IO != 200112L 76 return PTS_UNSUPPORTED; 77#endif 78 79 snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_aio_cancel_3_1_%d", 80 getpid()); 81 unlink(tmpfname); 82 fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); 83 if (fd == -1) 84 { 85 printf(TNAME " Error at open(): %s\n", 86 strerror(errno)); 87 return PTS_UNRESOLVED; 88 } 89 90 unlink(tmpfname); 91 92 /* install signal handler */ 93 94 action.sa_sigaction = sigusr1_handler; 95 sigemptyset(&action.sa_mask); 96 action.sa_flags = SA_SIGINFO|SA_RESTART; 97 if (sigaction(SIGRTMIN+1, &action, NULL)) 98 { 99 printf(TNAME " Error at sigaction(): %s\n", 100 strerror(errno)); 101 return PTS_FAIL; 102 } 103 104 /* create AIO req */ 105 106 for (i = 0; i < BUF_NB; i++) 107 { 108 aiocb = malloc(sizeof(struct aiocb)); 109 if (aiocb == NULL) 110 { 111 printf(TNAME " Error at malloc(): %s\n", 112 strerror(errno)); 113 return PTS_FAIL; 114 } 115 116 aiocb->aio_fildes = fd; 117 aiocb->aio_buf = malloc(BUF_SIZE); 118 if (aiocb->aio_buf == NULL) 119 { 120 printf(TNAME " Error at malloc(): %s\n", 121 strerror(errno)); 122 return PTS_FAIL; 123 } 124 125 aiocb->aio_nbytes = BUF_SIZE; 126 aiocb->aio_offset = 0; 127 128 aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL; 129 aiocb->aio_sigevent.sigev_signo = SIGRTMIN+1; 130 aiocb->aio_sigevent.sigev_value.sival_ptr = aiocb; 131 132 if (aio_write(aiocb) == -1) 133 { 134 printf(TNAME " loop %d: Error at aio_write(): %s\n", 135 i, strerror(errno)); 136 return PTS_FAIL; 137 } 138 } 139 140 /* try to cancel all 141 * we hope to have enough time to cancel at least one 142 */ 143 144 if (aio_cancel(fd, NULL) == -1) 145 { 146 printf(TNAME " Error at aio_cancel(): %s\n", 147 strerror(errno)); 148 return PTS_FAIL; 149 } 150 151 close(fd); 152 153 while(countdown); 154 155 if (!canceled) 156 return PTS_UNRESOLVED; 157 158 printf ("Test PASSED\n"); 159 return PTS_PASS; 160} 161