Home | History | Annotate | Download | only in aio_write
      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  *	If O_APPEND is set for the file descripton, write operations append to
     13  *	the file in the same order as the calls were made.
     14  *
     15  * method:
     16  *
     17  *	- open file in append mode
     18  *	- call aio_write thrice with different buffers and sizes
     19  *	- read all file
     20  *	- check read data
     21  *
     22  */
     23 
     24 #define _XOPEN_SOURCE 600
     25 #include <stdio.h>
     26 #include <sys/types.h>
     27 #include <unistd.h>
     28 #include <sys/stat.h>
     29 #include <fcntl.h>
     30 #include <string.h>
     31 #include <errno.h>
     32 #include <stdlib.h>
     33 #include <aio.h>
     34 
     35 #include "posixtest.h"
     36 
     37 #define TNAME "aio_write/2-1.c"
     38 
     39 int main(void)
     40 {
     41 	char tmpfname[256];
     42 #define BUF_SIZE0 512
     43 	char buf0[BUF_SIZE0];
     44 #define BUF_SIZE1 1024
     45 	char buf1[BUF_SIZE1];
     46 #define BUF_SIZE2 1536
     47 	char buf2[BUF_SIZE2];
     48 	char *bufs[3] = { buf0, buf1, buf2 };
     49 	ssize_t sizes[3] = { BUF_SIZE0, BUF_SIZE1, BUF_SIZE2 };
     50 #define CHECK_SIZE (BUF_SIZE0+BUF_SIZE1+BUF_SIZE2)
     51 	char check[CHECK_SIZE];
     52 	int fd;
     53 	struct aiocb aiocb[3];
     54 	int i;
     55 	int err;
     56 	int ret;
     57 
     58 	if (sysconf(_SC_ASYNCHRONOUS_IO) < 200112L)
     59 		return PTS_UNSUPPORTED;
     60 
     61 	snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_aio_write_2_1_%d",
     62 		 getpid());
     63 	unlink(tmpfname);
     64 	fd = open(tmpfname, O_CREAT | O_APPEND | O_RDWR | O_EXCL,
     65 		  S_IRUSR | S_IWUSR);
     66 	if (fd == -1) {
     67 		printf(TNAME " Error at open(): %s\n", strerror(errno));
     68 		exit(PTS_UNRESOLVED);
     69 	}
     70 
     71 	unlink(tmpfname);
     72 
     73 	for (i = 0; i < 3; i++) {
     74 		memset(bufs[i], i, sizes[i]);
     75 		memset(&aiocb[i], 0, sizeof(struct aiocb));
     76 		aiocb[i].aio_fildes = fd;
     77 		aiocb[i].aio_buf = bufs[i];
     78 		aiocb[i].aio_nbytes = sizes[i];
     79 
     80 		if (aio_write(&aiocb[i]) == -1) {
     81 			printf(TNAME " Error at aio_write() %d: %s\n",
     82 			       i, strerror(errno));
     83 			close(fd);
     84 			exit(PTS_FAIL);
     85 		}
     86 	}
     87 
     88 	/* Wait until completion */
     89 	do {
     90 		usleep(10000);
     91 		err = aio_error(&aiocb[2]);
     92 	} while (err == EINPROGRESS);
     93 
     94 	for (i = 0; i < 3; i++) {
     95 		err = aio_error(&aiocb[i]);
     96 		ret = aio_return(&aiocb[i]);
     97 
     98 		if (err != 0) {
     99 			printf(TNAME " Error at aio_error() %d: %s\n", i,
    100 			       strerror(err));
    101 			close(fd);
    102 			exit(PTS_FAIL);
    103 		}
    104 
    105 		if (ret != sizes[i]) {
    106 			printf(TNAME " Error at aio_return() %d\n", i);
    107 			close(fd);
    108 			exit(PTS_FAIL);
    109 		}
    110 	}
    111 
    112 	/* check the values written */
    113 
    114 	if (lseek(fd, 0, SEEK_SET) == -1) {
    115 		printf(TNAME " Error at lseek(): %s\n", strerror(errno));
    116 		exit(PTS_FAIL);
    117 	}
    118 
    119 	if (read(fd, check, CHECK_SIZE) != CHECK_SIZE) {
    120 		printf(TNAME " Error at read(): %s\n", strerror(errno));
    121 		exit(PTS_FAIL);
    122 	}
    123 
    124 	if (memcmp(buf0, check, BUF_SIZE0)) {
    125 		printf(TNAME " Bad value in buffer #0\n");
    126 		exit(PTS_FAIL);
    127 	}
    128 
    129 	if (memcmp(buf1, check + BUF_SIZE0, BUF_SIZE1)) {
    130 		printf(TNAME " Bad value in buffer #1\n");
    131 		exit(PTS_FAIL);
    132 	}
    133 
    134 	if (memcmp(buf2, check + BUF_SIZE0 + BUF_SIZE1, BUF_SIZE2)) {
    135 		printf(TNAME " Bad value in buffer #2\n");
    136 		exit(PTS_FAIL);
    137 	}
    138 
    139 	close(fd);
    140 	printf("Test PASSED\n");
    141 	return PTS_PASS;
    142 }
    143