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 the aiocbp is used to submit another asynchronous operation,
13 *	then aio_return may be successfully used to retrieve the return status.
14 *
15 * method:
16 *
17 *	- open a file
18 *	- fill in an aiocb for writing
19 *	- call aio_write using this aiocb
20 *	- call aio_return to get the aiocb status (number of bytes written)
21 *	- reuse the aiocb for writing
22 *	- call aio_write using this aiocb
23 *	- call aio_return to get the aiocb status (number of bytes written)
24 */
25
26#define _XOPEN_SOURCE 600
27#include <stdio.h>
28#include <sys/types.h>
29#include <unistd.h>
30#include <sys/stat.h>
31#include <fcntl.h>
32#include <string.h>
33#include <errno.h>
34#include <stdlib.h>
35#include <aio.h>
36
37#include "posixtest.h"
38
39#define TNAME "aio_return/3-1.c"
40#define BUF_SIZE 4096
41
42int main(void)
43{
44	char tmpfname[256];
45	char buf[BUF_SIZE];
46	struct aiocb aiocb;
47	int fd, retval;
48
49	if (sysconf(_SC_ASYNCHRONOUS_IO) < 200112L)
50		return PTS_UNSUPPORTED;
51
52	snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_aio_return_3_1_%d",
53		 getpid());
54	unlink(tmpfname);
55	fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
56
57	if (fd == -1) {
58		printf(TNAME " Error at open(): %s\n", strerror(errno));
59		return PTS_UNRESOLVED;
60	}
61
62	unlink(tmpfname);
63
64	memset(buf, 0xaa, BUF_SIZE);
65	memset(&aiocb, 0, sizeof(struct aiocb));
66	aiocb.aio_fildes = fd;
67	aiocb.aio_buf = buf;
68	aiocb.aio_nbytes = BUF_SIZE;
69
70	if (aio_write(&aiocb) == -1) {
71		close(fd);
72		printf(TNAME " Error at aio_write(): %s\n",
73		       strerror(aio_error(&aiocb)));
74		return PTS_FAIL;
75	}
76
77	do {
78		usleep(10000);
79		retval = aio_error(&aiocb);
80	} while (retval == EINPROGRESS);
81
82	retval = aio_return(&aiocb);
83
84	if (retval == -1) {
85		close(fd);
86		printf(TNAME " Error at aio_return(): %d, %s\n", retval,
87		       strerror(aio_error(&aiocb)));
88		return PTS_FAIL;
89	}
90
91	memset(&aiocb, 0, sizeof(struct aiocb));
92	aiocb.aio_fildes = fd;
93	aiocb.aio_buf = buf;
94	aiocb.aio_nbytes = BUF_SIZE / 2;
95
96	if (aio_write(&aiocb) == -1) {
97		close(fd);
98		printf(TNAME " Error at aio_write(): %s\n",
99		       strerror(aio_error(&aiocb)));
100		return PTS_FAIL;
101	}
102
103	do {
104		usleep(10000);
105		retval = aio_error(&aiocb);
106	} while (retval == EINPROGRESS);
107
108	retval = aio_return(&aiocb);
109
110	if (retval == -1) {
111		close(fd);
112		printf(TNAME " Error at aio_return(): %s\n",
113		       strerror(aio_error(&aiocb)));
114		return PTS_UNRESOLVED;
115	} else {
116
117		if (retval != (BUF_SIZE / 2)) {
118			close(fd);
119			printf(TNAME " aio_return() didn't fail as expected: "
120			       "%d, %s\n", retval, strerror(aio_error(&aiocb)));
121			return PTS_UNRESOLVED;
122		}
123
124	}
125
126	close(fd);
127	printf("Test PASSED\n");
128	return PTS_PASS;
129}
130