NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/45441: aio_write and aio_read connected to one pipe don't make progress
>Number: 45441
>Category: kern
>Synopsis: aio_write and aio_read connected to one pipe don't make
>progress
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Oct 07 22:55:00 +0000 2011
>Originator: Alexander Nasonov
>Release: NetBSD 5.99.56
>Organization:
home sweet home
>Environment:
NetBSD nebeda.localdomain 5.99.56 NetBSD 5.99.56 (GENERIC) #0: Thu Oct 6
13:58:32 UTC 2011
builds%b6.netbsd.org@localhost:/home/builds/ab/HEAD/amd64/201110061150Z-obj/home/builds/ab/HEAD/src/sys/arch/amd64/compile/GENERIC
amd64
>Description:
If you initialize two aiocb structs to connect to one pipe and call aio_read
before aio_write, then aio_error() calls will always be returning EINPROGRESS.
>How-To-Repeat:
#include <err.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <aio.h>
#include <unistd.h>
static void
init_pipe_data(int fd[], struct aiocb cb[], char *buf[], size_t buf_sz)
{
int i;
if (pipe(fd) != 0)
err(EXIT_FAILURE, "pipe");
for (i = 0; i < 2; i++) {
buf[i] = malloc(buf_sz);
if (buf[i] == NULL)
err(EXIT_FAILURE, "malloc");
buf[i][0] = i;
buf[i][buf_sz-1] = CHAR_MAX - i;
memset(&cb[i], 0, sizeof(cb[i]));
cb[i].aio_buf = buf[i];
cb[i].aio_fildes = fd[i];
cb[i].aio_offset = 0;
cb[i].aio_nbytes = buf_sz;
}
}
static void
destroy_pipe_data(int fd[], char *buf[])
{
int i;
for (i = 0; i < 2; i++) {
free(buf[i]);
close(fd[i]);
}
}
int main()
{
const size_t sz = PIPE_BUF + 13;
int res[2] = { EINPROGRESS, EINPROGRESS };
int fd[2];
struct aiocb cb[2];
char *buf[2];
init_pipe_data(fd, cb, buf, sz);
if (aio_read(&cb[0]) != 0)
err(EXIT_FAILURE, "aio_read");
if (aio_write(&cb[1]) != 0)
err(EXIT_FAILURE, "aio_write");
do {
int i;
for (i = 0; i < 2; i++)
if (res[i] == EINPROGRESS)
res[i] = aio_error(&cb[i]);
} while (res[0] == EINPROGRESS || res[1] == EINPROGRESS);
destroy_pipe_data(fd, buf);
return EXIT_SUCCESS;
}
>Fix:
not known
Home |
Main Index |
Thread Index |
Old Index