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