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