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 * If mode is LIO_WAIT, lio_listio() shall wait until all I/O is 13 * complete and the sig argument shall be ignored. 14 * 15 * method: 16 * 17 * - open a file for writing 18 * - submit a list of writes to lio_listio in LIO_WAIT mode 19 * - check that upon return all I/Os are completed 20 * - check that the sig argument is ignored 21 * 22 */ 23 24 #define _XOPEN_SOURCE 600 25 #include <sys/stat.h> 26 #include <aio.h> 27 #include <errno.h> 28 #include <fcntl.h> 29 #include <signal.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <unistd.h> 34 #include "posixtest.h" 35 36 #define TNAME "lio_listio/1-1.c" 37 38 #define NUM_AIOCBS 10 39 #define BUF_SIZE 1024*1024 40 41 int received_all = 0; 42 43 void sigrt1_handler(int signum, siginfo_t * info, void *context) 44 { 45 received_all = 1; 46 } 47 48 int main(void) 49 { 50 char tmpfname[256]; 51 int fd; 52 53 struct aiocb **aiocbs; 54 char *bufs; 55 struct sigaction action; 56 struct sigevent event; 57 int errors = 0; 58 int ret; 59 int err; 60 int i; 61 62 if (sysconf(_SC_ASYNCHRONOUS_IO) < 200112L) 63 exit(PTS_UNSUPPORTED); 64 65 snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_lio_listio_1_1_%d", 66 getpid()); 67 unlink(tmpfname); 68 69 fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); 70 71 if (fd == -1) { 72 printf(TNAME " Error at open(): %s\n", strerror(errno)); 73 exit(PTS_UNRESOLVED); 74 } 75 76 unlink(tmpfname); 77 78 bufs = malloc(NUM_AIOCBS * BUF_SIZE); 79 80 if (bufs == NULL) { 81 printf(TNAME " Error at malloc(): %s\n", strerror(errno)); 82 close(fd); 83 exit(PTS_UNRESOLVED); 84 } 85 86 aiocbs = malloc(sizeof(struct aiocb *) * NUM_AIOCBS); 87 88 /* Queue up a bunch of aio writes */ 89 for (i = 0; i < NUM_AIOCBS; i++) { 90 91 aiocbs[i] = malloc(sizeof(struct aiocb)); 92 memset(aiocbs[i], 0, sizeof(struct aiocb)); 93 94 aiocbs[i]->aio_fildes = fd; 95 aiocbs[i]->aio_offset = 0; 96 aiocbs[i]->aio_buf = &bufs[i * BUF_SIZE]; 97 aiocbs[i]->aio_nbytes = BUF_SIZE; 98 aiocbs[i]->aio_lio_opcode = LIO_WRITE; 99 100 } 101 102 /* Use SIGRTMIN+1 for list completion */ 103 event.sigev_notify = SIGEV_SIGNAL; 104 event.sigev_signo = SIGRTMIN + 1; 105 event.sigev_value.sival_ptr = NULL; 106 107 /* Setup handler for list completion */ 108 action.sa_sigaction = sigrt1_handler; 109 sigemptyset(&action.sa_mask); 110 action.sa_flags = SA_SIGINFO | SA_RESTART; 111 sigaction(SIGRTMIN + 1, &action, NULL); 112 113 /* Submit request list */ 114 ret = lio_listio(LIO_WAIT, aiocbs, NUM_AIOCBS, &event); 115 116 if (ret) { 117 printf(TNAME " Error at lio_listio() %d: %s\n", errno, 118 strerror(errno)); 119 for (i = 0; i < NUM_AIOCBS; i++) 120 free(aiocbs[i]); 121 free(bufs); 122 free(aiocbs); 123 close(fd); 124 exit(PTS_FAIL); 125 } 126 127 if (received_all != 0) { 128 printf(TNAME " lio_listio() did not ignore the sig argument\n"); 129 for (i = 0; i < NUM_AIOCBS; i++) 130 free(aiocbs[i]); 131 free(bufs); 132 free(aiocbs); 133 close(fd); 134 exit(PTS_FAIL); 135 } 136 137 /* Check return code and free things */ 138 for (i = 0; i < NUM_AIOCBS; i++) { 139 err = aio_error(aiocbs[i]); 140 ret = aio_return(aiocbs[i]); 141 142 if ((err != 0) && (ret != BUF_SIZE)) { 143 printf(TNAME " req %d: error = %d - return = %d\n", i, 144 err, ret); 145 errors++; 146 } 147 148 free(aiocbs[i]); 149 } 150 151 free(bufs); 152 free(aiocbs); 153 154 close(fd); 155 156 if (errors != 0) 157 exit(PTS_FAIL); 158 159 printf(TNAME " PASSED\n"); 160 161 return PTS_PASS; 162 } 163