14-1.c revision d218f348c12b42a78fa0306d9a033bfa4f67238b
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 * Failure of an individual request does not prevend completion of any 13 * other individual request. 14 * 15 * method: 16 * 17 * - open a file for writing 18 * - submit a list with an invalid aiocb to lio_listio in LIO_NOWAIT mode 19 * - check that the good requests do not fail 20 * 21 */ 22 23#define _XOPEN_SOURCE 600 24#include <sys/stat.h> 25#include <aio.h> 26#include <errno.h> 27#include <fcntl.h> 28#include <signal.h> 29#include <stdio.h> 30#include <stdlib.h> 31#include <string.h> 32#include <unistd.h> 33#include "posixtest.h" 34 35#define TNAME "lio_listio/14-1.c" 36 37#define NUM_AIOCBS 10 38#define BUF_SIZE 1024 39 40int num_received = 0; 41int received_all = 0; 42 43void sigrt1_handler(int signum, siginfo_t * info, void *context) 44{ 45 num_received++; 46} 47 48void sigrt2_handler(int signum, siginfo_t * info, void *context) 49{ 50 received_all = 1; 51} 52 53int main(void) 54{ 55 char tmpfname[256]; 56 int fd; 57 58 struct aiocb *aiocbs[NUM_AIOCBS]; 59 char *bufs; 60 struct sigaction action; 61 struct sigevent event; 62 int errors = 0; 63 int ret; 64 int err; 65 int i; 66 67 if (sysconf(_SC_ASYNCHRONOUS_IO) < 200112L) 68 exit(PTS_UNSUPPORTED); 69 70 snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_lio_listio_14_1_%d", 71 getpid()); 72 unlink(tmpfname); 73 74 fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); 75 76 if (fd == -1) { 77 printf(TNAME " Error at open(): %s\n", strerror(errno)); 78 exit(PTS_UNRESOLVED); 79 } 80 81 unlink(tmpfname); 82 83 bufs = malloc(NUM_AIOCBS * BUF_SIZE); 84 85 if (bufs == NULL) { 86 printf(TNAME " Error at malloc(): %s\n", strerror(errno)); 87 close(fd); 88 exit(PTS_UNRESOLVED); 89 } 90 91 /* Queue up a bunch of aio writes */ 92 for (i = 0; i < NUM_AIOCBS; i++) { 93 94 aiocbs[i] = (struct aiocb *)calloc(sizeof(struct aiocb), 1); 95 if (aiocbs == NULL) { 96 printf(TNAME " Error at malloc(): %s\n", 97 strerror(errno)); 98 free(bufs); 99 close(fd); 100 exit(PTS_UNRESOLVED); 101 } 102 103 if (i == 2) 104 aiocbs[i]->aio_fildes = -1; 105 else 106 aiocbs[i]->aio_fildes = fd; 107 108 aiocbs[i]->aio_offset = 0; 109 aiocbs[i]->aio_buf = &bufs[i * BUF_SIZE]; 110 aiocbs[i]->aio_nbytes = BUF_SIZE; 111 aiocbs[i]->aio_lio_opcode = LIO_WRITE; 112 113 /* Use SIRTMIN+1 for individual completions */ 114 aiocbs[i]->aio_sigevent.sigev_notify = SIGEV_SIGNAL; 115 aiocbs[i]->aio_sigevent.sigev_signo = SIGRTMIN + 1; 116 aiocbs[i]->aio_sigevent.sigev_value.sival_int = i; 117 } 118 119 /* Use SIGRTMIN+2 for list completion */ 120 event.sigev_notify = SIGEV_SIGNAL; 121 event.sigev_signo = SIGRTMIN + 2; 122 event.sigev_value.sival_ptr = NULL; 123 124 /* Setup handler for individual operation completion */ 125 action.sa_sigaction = sigrt1_handler; 126 sigemptyset(&action.sa_mask); 127 action.sa_flags = SA_SIGINFO | SA_RESTART; 128 sigaction(SIGRTMIN + 1, &action, NULL); 129 130 /* Setup handler for list completion */ 131 action.sa_sigaction = sigrt2_handler; 132 sigemptyset(&action.sa_mask); 133 action.sa_flags = SA_SIGINFO | SA_RESTART; 134 sigaction(SIGRTMIN + 2, &action, NULL); 135 136 /* Submit request list */ 137 ret = lio_listio(LIO_NOWAIT, aiocbs, NUM_AIOCBS, &event); 138 139 if (ret != 0) { 140 printf(TNAME " Error lio_listio() %s\n", strerror(errno)); 141 142 for (i = 0; i < NUM_AIOCBS; i++) 143 free(aiocbs[i]); 144 free(bufs); 145 close(fd); 146 exit(PTS_FAIL); 147 } 148 149 while (received_all == 0) 150 sleep(1); 151 152 if (num_received != NUM_AIOCBS) { 153 printf(TNAME 154 " Error incomplete number of completed requests\n"); 155 156 for (i = 0; i < NUM_AIOCBS; i++) 157 free(aiocbs[i]); 158 free(bufs); 159 close(fd); 160 exit(PTS_FAIL); 161 } 162 163 /* Check return code and free things */ 164 for (i = 0; i < NUM_AIOCBS; i++) { 165 if (i == 2) 166 continue; 167 168 err = aio_error(aiocbs[i]); 169 ret = aio_return(aiocbs[i]); 170 171 if ((err != 0) && (ret != BUF_SIZE)) { 172 printf(TNAME " req %d: error = %d - return = %d\n", i, 173 err, ret); 174 errors++; 175 } 176 177 free(aiocbs[i]); 178 } 179 180 free(bufs); 181 182 close(fd); 183 184 if (errors != 0) 185 exit(PTS_FAIL); 186 187 printf(TNAME " PASSED\n"); 188 189 return PTS_PASS; 190} 191