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 the value zero if 13 * operation is successfuly queued. 14 * 15 * method: 16 * 17 * - open a file for writing 18 * - submit a list of writes to lio_listio in LIO_NOWAIT mode 19 * - check that lio_listio returns 0 and operations complete successfully 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/10-1.c" 34 35#define NUM_AIOCBS 10 36#define BUF_SIZE 1024 37 38int received_selected = 0; 39int received_all = 0; 40 41void 42sigrt1_handler(int signum, siginfo_t *info, void *context) 43{ 44 received_selected = info->si_value.sival_int; 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_10_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 aiocbs[i]->aio_fildes = fd; 100 aiocbs[i]->aio_offset = 0; 101 aiocbs[i]->aio_buf = &bufs[i*BUF_SIZE]; 102 aiocbs[i]->aio_nbytes = BUF_SIZE; 103 aiocbs[i]->aio_lio_opcode = LIO_WRITE; 104 105 /* Use SIRTMIN+1 for individual completions */ 106 aiocbs[i]->aio_sigevent.sigev_notify = SIGEV_SIGNAL; 107 aiocbs[i]->aio_sigevent.sigev_signo = SIGRTMIN+1; 108 aiocbs[i]->aio_sigevent.sigev_value.sival_int = i; 109 } 110 111 /* Use SIGRTMIN+2 for list completion */ 112 event.sigev_notify = SIGEV_SIGNAL; 113 event.sigev_signo = SIGRTMIN+2; 114 event.sigev_value.sival_ptr = NULL; 115 116 /* Setup handler for individual operation completion */ 117 action.sa_sigaction = sigrt1_handler; 118 sigemptyset(&action.sa_mask); 119 action.sa_flags = SA_SIGINFO|SA_RESTART; 120 sigaction(SIGRTMIN+1, &action, NULL); 121 122 /* Setup handler for list completion */ 123 action.sa_sigaction = sigrt2_handler; 124 sigemptyset(&action.sa_mask); 125 action.sa_flags = SA_SIGINFO|SA_RESTART; 126 sigaction(SIGRTMIN+2, &action, NULL); 127 128 /* Submit request list */ 129 ret = lio_listio(LIO_NOWAIT, aiocbs, NUM_AIOCBS, &event); 130 131 if (ret) { 132 printf(TNAME " Error at lio_listio() %d: %s\n", errno, strerror(errno)); 133 for (i=0; i<NUM_AIOCBS; i++) 134 free (aiocbs[i]); 135 free (bufs); 136 close (fd); 137 exit (PTS_FAIL); 138 } 139 140 while (received_all == 0) 141 sleep (1); 142 143 /* Check return code and free things */ 144 for (i = 0; i < NUM_AIOCBS; i++) { 145 err = aio_error(aiocbs[i]); 146 ret = aio_return(aiocbs[i]); 147 148 if ((err != 0) && (ret != BUF_SIZE)) { 149 printf(TNAME " req %d: error = %d - return = %d\n", i, err, ret); 150 errors++; 151 } 152 153 free (aiocbs[i]); 154 } 155 156 free (bufs); 157 158 close(fd); 159 160 if (errors != 0) 161 exit (PTS_FAIL); 162 163 printf (TNAME " PASSED\n"); 164 165 return PTS_PASS; 166} 167