1 /* 2 * Copyright (c) 2004, Bull SA. All rights reserved. 3 * Created by: Laurent.Vivier (at) 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 * aio_cancel() shall return AIO_NOTCANCELED if at least one of the 13 * requested operations cannot be canceled because it is in progress. 14 * 15 * method: 16 * 17 * queue a lot of aio_write() to a given file descriptor 18 * then cancel all operation belonging to this file descriptor 19 * check result of each operation: 20 * - if aio_error() is EINPROGRESS and aio_cancel() is not AIO_NOTCANCELED 21 * result is failed 22 * - if aio_error() is succes (0) and aio_cancel() is AIO_NOTCANCELED 23 * result is susccess 24 * - otherwise result is unresolved 25 * 26 */ 27 28 #define _XOPEN_SOURCE 600 29 #include <stdio.h> 30 #include <sys/types.h> 31 #include <unistd.h> 32 #include <sys/stat.h> 33 #include <fcntl.h> 34 #include <string.h> 35 #include <errno.h> 36 #include <stdlib.h> 37 #include <aio.h> 38 39 #include "posixtest.h" 40 41 #define TNAME "aio_cancel/7-1.c" 42 43 #define BUF_NB 128 44 #define BUF_SIZE 1024 45 46 int main(void) 47 { 48 char tmpfname[256]; 49 int fd; 50 struct aiocb *aiocb[BUF_NB]; 51 int i; 52 int in_progress; 53 int gret; 54 55 if (sysconf(_SC_ASYNCHRONOUS_IO) < 200112L) 56 return PTS_UNSUPPORTED; 57 58 snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_aio_cancel_7_1_%d", 59 getpid()); 60 unlink(tmpfname); 61 fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); 62 if (fd == -1) { 63 printf(TNAME " Error at open(): %s\n", strerror(errno)); 64 return PTS_UNRESOLVED; 65 } 66 67 unlink(tmpfname); 68 69 /* create AIO req */ 70 for (i = 0; i < BUF_NB; i++) { 71 aiocb[i] = malloc(sizeof(struct aiocb)); 72 73 if (aiocb[i] == NULL) { 74 printf(TNAME " Error at malloc(): %s\n", 75 strerror(errno)); 76 close(fd); 77 return PTS_UNRESOLVED; 78 } 79 80 aiocb[i]->aio_fildes = fd; 81 aiocb[i]->aio_buf = malloc(BUF_SIZE); 82 83 if (aiocb[i]->aio_buf == NULL) { 84 printf(TNAME " Error at malloc(): %s\n", 85 strerror(errno)); 86 close(fd); 87 return PTS_UNRESOLVED; 88 } 89 90 aiocb[i]->aio_nbytes = BUF_SIZE; 91 aiocb[i]->aio_offset = 0; 92 aiocb[i]->aio_sigevent.sigev_notify = SIGEV_NONE; 93 94 if (aio_write(aiocb[i]) == -1) { 95 printf(TNAME " loop %d: Error at aio_write(): %s\n", 96 i, strerror(errno)); 97 close(fd); 98 return PTS_FAIL; 99 } 100 } 101 102 /* try to cancel all 103 * we hope to have enough time to cancel at least one 104 */ 105 gret = aio_cancel(fd, NULL); 106 if (gret == -1) { 107 printf(TNAME " Error at aio_cancel(): %s\n", strerror(errno)); 108 close(fd); 109 return PTS_FAIL; 110 } 111 112 do { 113 in_progress = 0; 114 for (i = 0; i < BUF_NB; i++) { 115 int ret = aio_error(aiocb[i]); 116 117 switch (ret) { 118 case -1: 119 printf(TNAME " Error at aio_error(): %s\n", 120 strerror(errno)); 121 close(fd); 122 return PTS_FAIL; 123 break; 124 case EINPROGRESS: 125 /* at this point, all operations should be: 126 * canceled 127 * or in progress 128 * with aio_cancel() == AIO_NOTCANCELED 129 */ 130 if (gret != AIO_NOTCANCELED) { 131 printf(TNAME 132 " Error at aio_error(): %s\n", 133 strerror(errno)); 134 close(fd); 135 return PTS_FAIL; 136 } 137 138 in_progress = 1; 139 break; 140 case 0: 141 /* we seek one not canceled and check why. 142 * (perhaps) it has not been canceled 143 * because it was in progress 144 * during the cancel operation 145 */ 146 if (gret == AIO_NOTCANCELED) { 147 printf("Test PASSED\n"); 148 close(fd); 149 return PTS_PASS; 150 } 151 break; 152 } 153 } 154 } while (in_progress); 155 156 close(fd); 157 158 return PTS_UNRESOLVED; 159 } 160