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