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