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