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  *	Error status should be set to [ECANCELED] and return shall be -1 for
13  *	successfully canceled AIO.
14  *
15  * method:
16  *
17  *	we queue a lot of aio_write() operation to a file descriptor
18  *	then we try to cancel all aio operation of this file descriptor
19  *	we check with aio_error() state of each operation
20  *	if aio_error() is ECANCELED and aio_return() is -1
21  *	test is passed
22  *	if aio_error() is ECANCELED and aio_return() is NOT -1
23  *	test fails
24  *	otherwise
25  *	test is unresolved
26  *
27  */
28 
29 #define _XOPEN_SOURCE 600
30 #include <stdio.h>
31 #include <sys/types.h>
32 #include <unistd.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <stdlib.h>
38 #include <malloc.h>
39 #include <aio.h>
40 
41 #include "posixtest.h"
42 
43 #define TNAME "aio_cancel/4-1.c"
44 
45 #define BUF_NB		128
46 #define BUF_SIZE	1024
47 
main()48 int main()
49 {
50 	char tmpfname[256];
51 	int fd;
52 	struct aiocb *aiocb[BUF_NB];
53 	int i;
54 	int in_progress;
55 
56 #if _POSIX_ASYNCHRONOUS_IO != 200112L
57 	return PTS_UNSUPPORTED;
58 #endif
59 
60 	snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_aio_cancel_4_1_%d",
61 		  getpid());
62 	unlink(tmpfname);
63 	fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL,
64 		  S_IRUSR | S_IWUSR);
65 	if (fd == -1)
66 	{
67 		printf(TNAME " Error at open(): %s\n",
68 		       strerror(errno));
69 		return PTS_UNRESOLVED;
70 	}
71 
72 	unlink(tmpfname);
73 
74 	/* create AIO req */
75 
76 	for (i = 0; i < BUF_NB; i++)
77 	{
78 		aiocb[i] = malloc(sizeof(struct aiocb));
79 		if (aiocb[i] == NULL)
80 		{
81 			printf(TNAME " Error at malloc(): %s\n",
82 		       		strerror(errno));
83 			return PTS_UNRESOLVED;
84 		}
85 		aiocb[i]->aio_fildes = fd;
86 		aiocb[i]->aio_buf = malloc(BUF_SIZE);
87 		if (aiocb[i]->aio_buf == NULL)
88 		{
89 			printf(TNAME " Error at malloc(): %s\n",
90 		       		strerror(errno));
91 			return PTS_UNRESOLVED;
92 		}
93 		aiocb[i]->aio_nbytes = BUF_SIZE;
94 		aiocb[i]->aio_offset = 0;
95 		aiocb[i]->aio_sigevent.sigev_notify = SIGEV_NONE;
96 
97 		if (aio_write(aiocb[i]) == -1)
98 		{
99 			printf(TNAME " loop %d: Error at aio_write(): %s\n",
100 			       i, strerror(errno));
101 			return PTS_FAIL;
102 		}
103 	}
104 
105 	/* try to cancel all
106 	 * we hope to have enough time to cancel at least one
107 	 */
108 
109 	if (aio_cancel(fd, NULL) == -1)
110 	{
111 		printf(TNAME " Error at aio_cancel(): %s\n",
112 		       strerror(errno));
113 		return PTS_FAIL;
114 	}
115 
116 	close(fd);
117 
118 	do {
119 		in_progress = 0;
120 		for (i = 0; i < BUF_NB; i++)
121 		{
122 			int ret;
123 
124 			ret = (aio_error(aiocb[i]));
125 
126 			if (ret == -1)
127 			{
128 				printf(TNAME " Error at aio_error(): %s\n",
129 		       			strerror(errno));
130 				return PTS_FAIL;
131 			}
132 			else if (ret == EINPROGRESS)
133 				in_progress = 1;
134 			else if (ret == ECANCELED)
135 			{
136 				if (aio_return(aiocb[i]) == -1)
137 				{
138 					printf ("Test PASSED\n");
139 					return PTS_PASS;
140 				}
141 
142 				printf(TNAME " aio_return is not -1\n");
143 				return PTS_FAIL;
144 			}
145 		}
146 	} while (in_progress);
147 
148 	return PTS_UNRESOLVED;
149 }
150