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