Home | History | Annotate | Download | only in aio_cancel
      1 /*
      2  * Copyright (c) 2004, Bull SA. All rights reserved.
      3  * Created by:  Laurent.Vivier (at) 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_NOTCANCELED if at least one of the
     13  *	requested operations cannot be canceled because it is in progress.
     14  *
     15  * method:
     16  *
     17  *	queue a lot of aio_write() to a given file descriptor
     18  *	then cancel all operation belonging to this file descriptor
     19  *	check result of each operation:
     20  *	- if aio_error() is EINPROGRESS and aio_cancel() is not AIO_NOTCANCELED
     21  *	  result is failed
     22  *	- if aio_error() is succes (0) and aio_cancel() is AIO_NOTCANCELED
     23  *	  result is susccess
     24  *	- otherwise result is unresolved
     25  *
     26  */
     27 
     28 #define _XOPEN_SOURCE 600
     29 #include <stdio.h>
     30 #include <sys/types.h>
     31 #include <unistd.h>
     32 #include <sys/stat.h>
     33 #include <fcntl.h>
     34 #include <string.h>
     35 #include <errno.h>
     36 #include <stdlib.h>
     37 #include <aio.h>
     38 
     39 #include "posixtest.h"
     40 
     41 #define TNAME "aio_cancel/7-1.c"
     42 
     43 #define BUF_NB		128
     44 #define BUF_SIZE	1024
     45 
     46 int main(void)
     47 {
     48 	char tmpfname[256];
     49 	int fd;
     50 	struct aiocb *aiocb[BUF_NB];
     51 	int i;
     52 	int in_progress;
     53 	int gret;
     54 
     55 	if (sysconf(_SC_ASYNCHRONOUS_IO) < 200112L)
     56 		return PTS_UNSUPPORTED;
     57 
     58 	snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_aio_cancel_7_1_%d",
     59 		 getpid());
     60 	unlink(tmpfname);
     61 	fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
     62 	if (fd == -1) {
     63 		printf(TNAME " Error at open(): %s\n", strerror(errno));
     64 		return PTS_UNRESOLVED;
     65 	}
     66 
     67 	unlink(tmpfname);
     68 
     69 	/* create AIO req */
     70 	for (i = 0; i < BUF_NB; i++) {
     71 		aiocb[i] = malloc(sizeof(struct aiocb));
     72 
     73 		if (aiocb[i] == NULL) {
     74 			printf(TNAME " Error at malloc(): %s\n",
     75 			       strerror(errno));
     76 			close(fd);
     77 			return PTS_UNRESOLVED;
     78 		}
     79 
     80 		aiocb[i]->aio_fildes = fd;
     81 		aiocb[i]->aio_buf = malloc(BUF_SIZE);
     82 
     83 		if (aiocb[i]->aio_buf == NULL) {
     84 			printf(TNAME " Error at malloc(): %s\n",
     85 			       strerror(errno));
     86 			close(fd);
     87 			return PTS_UNRESOLVED;
     88 		}
     89 
     90 		aiocb[i]->aio_nbytes = BUF_SIZE;
     91 		aiocb[i]->aio_offset = 0;
     92 		aiocb[i]->aio_sigevent.sigev_notify = SIGEV_NONE;
     93 
     94 		if (aio_write(aiocb[i]) == -1) {
     95 			printf(TNAME " loop %d: Error at aio_write(): %s\n",
     96 			       i, strerror(errno));
     97 			close(fd);
     98 			return PTS_FAIL;
     99 		}
    100 	}
    101 
    102 	/* try to cancel all
    103 	 * we hope to have enough time to cancel at least one
    104 	 */
    105 	gret = aio_cancel(fd, NULL);
    106 	if (gret == -1) {
    107 		printf(TNAME " Error at aio_cancel(): %s\n", strerror(errno));
    108 		close(fd);
    109 		return PTS_FAIL;
    110 	}
    111 
    112 	do {
    113 		in_progress = 0;
    114 		for (i = 0; i < BUF_NB; i++) {
    115 			int ret = aio_error(aiocb[i]);
    116 
    117 			switch (ret) {
    118 			case -1:
    119 				printf(TNAME " Error at aio_error(): %s\n",
    120 				       strerror(errno));
    121 				close(fd);
    122 				return PTS_FAIL;
    123 				break;
    124 			case EINPROGRESS:
    125 				/* at this point, all operations should be:
    126 				 *    canceled
    127 				 * or in progress
    128 				 *    with aio_cancel() == AIO_NOTCANCELED
    129 				 */
    130 				if (gret != AIO_NOTCANCELED) {
    131 					printf(TNAME
    132 					       " Error at aio_error(): %s\n",
    133 					       strerror(errno));
    134 					close(fd);
    135 					return PTS_FAIL;
    136 				}
    137 
    138 				in_progress = 1;
    139 				break;
    140 			case 0:
    141 				/* we seek one not canceled and check why.
    142 				 * (perhaps) it has not been canceled
    143 				 * because it was in progress
    144 				 * during the cancel operation
    145 				 */
    146 				if (gret == AIO_NOTCANCELED) {
    147 					printf("Test PASSED\n");
    148 					close(fd);
    149 					return PTS_PASS;
    150 				}
    151 				break;
    152 			}
    153 		}
    154 	} while (in_progress);
    155 
    156 	close(fd);
    157 
    158 	return PTS_UNRESOLVED;
    159 }
    160