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