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