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 if (aio_write(aiocb[i]) == -1) { 91 printf(TNAME " loop %d: Error at aio_write(): %s\n", 92 i, strerror(errno)); 93 return PTS_FAIL; 94 } 95 } 96 97 /* try to cancel all 98 * we hope to have enough time to cancel at least one 99 */ 100 101 if (aio_cancel(fd, NULL) == -1) { 102 printf(TNAME " Error at aio_cancel(): %s\n", strerror(errno)); 103 return PTS_FAIL; 104 } 105 106 close(fd); 107 108 do { 109 in_progress = 0; 110 for (i = 0; i < BUF_NB; i++) { 111 int ret; 112 113 ret = (aio_error(aiocb[i])); 114 115 if (ret == -1) { 116 printf(TNAME " Error at aio_error(): %s\n", 117 strerror(errno)); 118 return PTS_FAIL; 119 } else if (ret == EINPROGRESS) 120 in_progress = 1; 121 else if (ret == ECANCELED) { 122 if (aio_return(aiocb[i]) == -1) { 123 printf("Test PASSED\n"); 124 return PTS_PASS; 125 } 126 127 printf(TNAME " aio_return is not -1\n"); 128 return PTS_FAIL; 129 } 130 } 131 } while (in_progress); 132 133 return PTS_UNRESOLVED; 134 } 135