[LTP] [PATCH] aio_cancel_7-1: Write into a socket
Martin Doucha
mdoucha@suse.cz
Thu Aug 14 15:16:13 CEST 2025
The test schedules multiple async writes into a file and then hopes that
at least one will block long enough that it can be canceled
before completion. Use a socket pair instead of a file to force async
writes to block indefinitely and make sure at least one can be canceled.
Also add another case to the final result check because the aio_cancel()
call may happen between one write finishing and another write starting.
Then the cancel will be successful and all non-zero task results will be
ECANCELED.
Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
.../conformance/interfaces/aio_cancel/7-1.c | 81 ++++++++++++-------
1 file changed, 54 insertions(+), 27 deletions(-)
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/aio_cancel/7-1.c b/testcases/open_posix_testsuite/conformance/interfaces/aio_cancel/7-1.c
index 268408ab1..28c8fe78a 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/aio_cancel/7-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/aio_cancel/7-1.c
@@ -29,71 +29,82 @@
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
-#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <aio.h>
+#include <sys/socket.h>
#include "posixtest.h"
-#include "tempfile.h"
#define TNAME "aio_cancel/7-1.c"
-#define BUF_NB 128
-#define BUF_SIZE 1024
+#define BUF_NB 8
int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
{
- char tmpfname[PATH_MAX];
- int fd;
+ int fds[2];
struct aiocb *aiocb[BUF_NB];
int i;
int in_progress;
int gret;
+ int bufsize;
+ unsigned int argsize = sizeof(bufsize);
if (sysconf(_SC_ASYNCHRONOUS_IO) < 200112L)
return PTS_UNSUPPORTED;
- PTS_GET_TMP_FILENAME(tmpfname, "pts_aio_cancel_7_1");
- unlink(tmpfname);
- fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
- if (fd == -1) {
- printf(TNAME " Error at open(): %s\n", strerror(errno));
+ gret = socketpair(AF_UNIX, SOCK_DGRAM, 0, fds);
+ if (gret == -1) {
+ printf(TNAME " Error creating sockets(): %s\n",
+ strerror(errno));
return PTS_UNRESOLVED;
}
- unlink(tmpfname);
+ gret = getsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, &bufsize, &argsize);
+ if (gret == -1) {
+ printf(TNAME " Error reading socket buffer size: %s\n",
+ strerror(errno));
+ close(fds[0]);
+ close(fds[1]);
+ return PTS_UNRESOLVED;
+ }
+
+ /* Socket buffer size is twice the maximum message size */
+ bufsize /= 2;
/* create AIO req */
for (i = 0; i < BUF_NB; i++) {
aiocb[i] = calloc(1, sizeof(struct aiocb));
if (aiocb[i] == NULL) {
- printf(TNAME " Error at malloc(): %s\n",
+ printf(TNAME " Error at calloc(): %s\n",
strerror(errno));
- close(fd);
+ close(fds[0]);
+ close(fds[1]);
return PTS_UNRESOLVED;
}
- aiocb[i]->aio_fildes = fd;
- aiocb[i]->aio_buf = malloc(BUF_SIZE);
+ aiocb[i]->aio_fildes = fds[0];
+ aiocb[i]->aio_buf = malloc(bufsize);
if (aiocb[i]->aio_buf == NULL) {
printf(TNAME " Error at malloc(): %s\n",
strerror(errno));
- close(fd);
+ close(fds[0]);
+ close(fds[1]);
return PTS_UNRESOLVED;
}
- aiocb[i]->aio_nbytes = BUF_SIZE;
+ aiocb[i]->aio_nbytes = bufsize;
aiocb[i]->aio_offset = 0;
aiocb[i]->aio_sigevent.sigev_notify = SIGEV_NONE;
if (aio_write(aiocb[i]) == -1) {
printf(TNAME " loop %d: Error at aio_write(): %s\n",
i, strerror(errno));
- close(fd);
+ close(fds[0]);
+ close(fds[1]);
return PTS_FAIL;
}
}
@@ -101,10 +112,11 @@ int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
/* try to cancel all
* we hope to have enough time to cancel at least one
*/
- gret = aio_cancel(fd, NULL);
+ gret = aio_cancel(fds[0], NULL);
if (gret == -1) {
printf(TNAME " Error at aio_cancel(): %s\n", strerror(errno));
- close(fd);
+ close(fds[0]);
+ close(fds[1]);
return PTS_FAIL;
}
@@ -117,9 +129,9 @@ int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
case -1:
printf(TNAME " Error at aio_error(): %s\n",
strerror(errno));
- close(fd);
+ close(fds[0]);
+ close(fds[1]);
return PTS_FAIL;
- break;
case EINPROGRESS:
/* at this point, all operations should be:
* canceled
@@ -130,12 +142,26 @@ int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
printf(TNAME
" Error at aio_error(): %s\n",
strerror(errno));
- close(fd);
+ close(fds[0]);
+ close(fds[1]);
return PTS_FAIL;
}
in_progress = 1;
break;
+ case ECANCELED:
+ /* aio_cancel() happened between one
+ * write finishing and another starting.
+ * aio_cancel() returned AIO_CANCELED
+ * and the first non-zero result is ECANCELED.
+ */
+ if (gret == AIO_CANCELED) {
+ printf("Test PASSED\n");
+ close(fds[0]);
+ close(fds[1]);
+ return PTS_PASS;
+ }
+ break;
case 0:
/* we seek one not canceled and check why.
* (perhaps) it has not been canceled
@@ -144,7 +170,8 @@ int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
*/
if (gret == AIO_NOTCANCELED) {
printf("Test PASSED\n");
- close(fd);
+ close(fds[0]);
+ close(fds[1]);
return PTS_PASS;
}
break;
@@ -152,7 +179,7 @@ int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
}
} while (in_progress);
- close(fd);
-
+ close(fds[0]);
+ close(fds[1]);
return PTS_UNRESOLVED;
}
--
2.50.1
More information about the ltp
mailing list