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 * Error status should be set to [ECANCELED] and return shall be -1 for 13 * successfully canceled AIO. 14 * 15 * method: 16 * 17 * we queue a lot of aio_write() operation to a file descriptor 18 * then we try to cancel all aio operation of this file descriptor 19 * we check with aio_error() state of each operation 20 * if aio_error() is ECANCELED and aio_return() is -1 21 * test is passed 22 * if aio_error() is ECANCELED and aio_return() is NOT -1 23 * test fails 24 * otherwise 25 * test is unresolved 26 * 27 */ 28 29 #define _XOPEN_SOURCE 600 30 #include <stdio.h> 31 #include <sys/types.h> 32 #include <unistd.h> 33 #include <sys/stat.h> 34 #include <fcntl.h> 35 #include <string.h> 36 #include <errno.h> 37 #include <stdlib.h> 38 #include <aio.h> 39 40 #include "posixtest.h" 41 42 #define TNAME "aio_cancel/4-1.c" 43 44 #define BUF_NB 128 45 #define BUF_SIZE (1024*1024) 46 47 int main(void) 48 { 49 char tmpfname[256]; 50 int fd; 51 struct aiocb *aiocb[BUF_NB]; 52 int i; 53 int in_progress; 54 55 if (sysconf(_SC_ASYNCHRONOUS_IO) < 200112L) 56 return PTS_UNSUPPORTED; 57 58 snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_aio_cancel_4_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 71 for (i = 0; i < BUF_NB; i++) { 72 aiocb[i] = malloc(sizeof(struct aiocb)); 73 if (aiocb[i] == NULL) { 74 printf(TNAME " Error at malloc(): %s\n", 75 strerror(errno)); 76 return PTS_UNRESOLVED; 77 } 78 memset(aiocb[i], 0, sizeof(struct aiocb)); 79 aiocb[i]->aio_fildes = fd; 80 aiocb[i]->aio_buf = malloc(BUF_SIZE); 81 if (aiocb[i]->aio_buf == NULL) { 82 printf(TNAME " Error at malloc(): %s\n", 83 strerror(errno)); 84 return PTS_UNRESOLVED; 85 } 86 aiocb[i]->aio_nbytes = BUF_SIZE; 87 aiocb[i]->aio_offset = 0; 88 aiocb[i]->aio_sigevent.sigev_notify = SIGEV_NONE; 89 } 90 91 for (i = 0; i < BUF_NB; i++) { 92 if (aio_write(aiocb[i]) == -1) { 93 printf(TNAME " loop %d: Error at aio_write(): %s\n", 94 i, strerror(errno)); 95 return PTS_FAIL; 96 } 97 } 98 99 /* try to cancel all 100 * we hope to have enough time to cancel at least one 101 */ 102 103 if (aio_cancel(fd, NULL) == -1) { 104 printf(TNAME " Error at aio_cancel(): %s\n", strerror(errno)); 105 return PTS_FAIL; 106 } 107 108 close(fd); 109 110 do { 111 in_progress = 0; 112 for (i = 0; i < BUF_NB; i++) { 113 int ret; 114 115 ret = (aio_error(aiocb[i])); 116 117 if (ret == -1) { 118 printf(TNAME " Error at aio_error(): %s\n", 119 strerror(errno)); 120 return PTS_FAIL; 121 } else if (ret == EINPROGRESS) 122 in_progress = 1; 123 else if (ret == ECANCELED) { 124 if (aio_return(aiocb[i]) == -1) { 125 printf("Test PASSED\n"); 126 return PTS_PASS; 127 } 128 129 printf(TNAME " aio_return is not -1\n"); 130 return PTS_FAIL; 131 } 132 } 133 } while (in_progress); 134 135 return PTS_UNRESOLVED; 136 } 137