/* * Test program to test if POSIX aio functions work across processes */ #include #include #include #include #include #include #include #include #include #include char *shmem; void processA(void) { int fd; struct aiocb *aiocbp = (struct aiocb *) shmem; char *buf = shmem + sizeof(struct aiocb); fd = open("aio-shmem-test-file", O_CREAT | O_WRONLY | O_SYNC, S_IRWXU); if (fd == -1) { fprintf(stderr, "open() failed\n"); exit(1); } printf("processA starting AIO\n"); strcpy(buf, "foobar"); memset(aiocbp, 0, sizeof(struct aiocb)); aiocbp->aio_fildes = fd; aiocbp->aio_offset = 0; aiocbp->aio_buf = buf; aiocbp->aio_nbytes = strlen(buf); aiocbp->aio_reqprio = 0; aiocbp->aio_sigevent.sigev_notify = SIGEV_NONE; if (aio_write(aiocbp) != 0) { fprintf(stderr, "aio_write() failed\n"); exit(1); } } void processB(void) { struct aiocb *aiocbp = (struct aiocb *) shmem; const struct aiocb * const pl[1] = { aiocbp }; int rv; int returnCode; struct timespec my_timeout = { 0 , 10000 }; int max_polls; printf("waiting for the write to finish in process B\n"); rv = aio_error(aiocbp); if (rv != 0) { fprintf(stderr, "aio_error returned %d: %s\n", rv, strerror(rv)); exit(1); } while (rv == EINPROGRESS) { max_polls = 256; my_timeout.tv_sec = 0; my_timeout.tv_nsec = 10000; returnCode = aio_suspend(pl , 1 , &my_timeout); printf("aio_suspend() returned %d\n",returnCode); while ((returnCode < 0) && (EAGAIN == errno) && (max_polls-- > 0)) { my_timeout.tv_sec = 0; my_timeout.tv_nsec = 10000; returnCode = aio_suspend(pl , 1 , &my_timeout); } rv = aio_error(aiocbp); } rv = aio_return(aiocbp); printf("aio_return returned %d\n", rv); } int main(int argc, char **argv) { int pidB; shmem = mmap(NULL, sizeof(struct aiocb) + 1000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (shmem == MAP_FAILED) { fprintf(stderr, "mmap() failed\n"); exit(1); } #ifdef SINGLE_PROCESS /* this works */ processA(); processB(); #else /* * Start the I/O request in parent process, then fork and try to wait * for it to finish from the child process. (doesn't work, it will hang * forever) */ processA(); pidB = fork(); if (pidB == -1) { fprintf(stderr, "fork() failed\n"); exit(1); } if (pidB != 0) { /* parent */ wait (pidB); } else { /* child */ processB(); } #endif }