Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Update.
2002-06-18  Amos Waterland  <apw@us.ibm.com>

	* sysdeps/pthread/aio_cancel.c (aio_cancel): Add check for invalid
	file descriptor.
	* sysdeps/pthread/aio_fsync.c (aio_fsync): Add check for invalid fd;
	add check for fd not open for writing.

	* sysdeps/pthread/aio_suspend.c (aio_suspend): Add check for
	completed element(s) and do not suspend thread if so.  Patch
	heavily modified by drepper.

	* rt/tst-aio7.c: New file.  Regression test for problems which the
	above three changes fix.
	* rt/Makefile (tests): Add tst-aio7.

	* rt/tst-aio6.c: Fix comment.
  • Loading branch information
Ulrich Drepper committed Jun 29, 2002
1 parent eabea97 commit 8b8cc76
Show file tree
Hide file tree
Showing 7 changed files with 272 additions and 44 deletions.
17 changes: 17 additions & 0 deletions ChangeLog
@@ -1,5 +1,22 @@
2002-06-18 Amos Waterland <apw@us.ibm.com>

* sysdeps/pthread/aio_cancel.c (aio_cancel): Add check for invalid
file descriptor.
* sysdeps/pthread/aio_fsync.c (aio_fsync): Add check for invalid fd;
add check for fd not open for writing.

* sysdeps/pthread/aio_suspend.c (aio_suspend): Add check for
completed element(s) and do not suspend thread if so. Patch
heavily modified by drepper.

* rt/tst-aio7.c: New file. Regression test for problems which the
above three changes fix.
* rt/Makefile (tests): Add tst-aio7.

2002-06-29 Ulrich Drepper <drepper@redhat.com>

* rt/tst-aio6.c: Fix comment.

* catgets/gencat.c (read_input_file): Handle more than one slash
at end of line correctly [PR libc/3926].
Based on a patch by Steven Kim <steven.kim@peregrine.com>.
Expand Down
5 changes: 3 additions & 2 deletions rt/Makefile
@@ -1,4 +1,4 @@
# Copyright (C) 1997,98,99,2000,01 Free Software Foundation, Inc.
# Copyright (C) 1997-2001, 2002 Free Software Foundation, Inc.
# This file is part of the GNU C Library.

# The GNU C Library is free software; you can redistribute it and/or
Expand Down Expand Up @@ -39,7 +39,8 @@ librt-routines = $(aio-routines) \
$(shm-routines)

tests := tst-shm tst-clock tst-timer \
tst-aio tst-aio64 tst-aio2 tst-aio3 tst-aio4 tst-aio5 tst-aio6
tst-aio tst-aio64 tst-aio2 tst-aio3 tst-aio4 tst-aio5 tst-aio6 \
tst-aio7

extra-libs := librt
extra-libs-others := $(extra-libs)
Expand Down
4 changes: 2 additions & 2 deletions rt/tst-aio6.c
@@ -1,5 +1,5 @@
/* Test for timeout handling.
Copyright (C) 2000 Free Software Foundation, Inc.
Copyright (C) 2000, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
Expand Down Expand Up @@ -67,7 +67,7 @@ do_test (void)
/* Get the current time. */
gettimeofday (&before, NULL);

/* Wait for input which is unsuccess and therefore the function will
/* Wait for input which is unsuccessful and therefore the function will
time out. */
timeout.tv_sec = 3;
timeout.tv_nsec = 0;
Expand Down
175 changes: 175 additions & 0 deletions rt/tst-aio7.c
@@ -0,0 +1,175 @@
/* Test for AIO POSIX compliance.
Copyright (C) 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */

#include <aio.h>
#include <error.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


/* We might wait for 3 seconds, so increase timeout to 10 seconds. */
#define TIMEOUT 10


#define TEST_FUNCTION do_test ()
static int
do_test (void)
{
int result = 0;

/* Test for aio_cancel() detecting invalid file descriptor. */
{
struct aiocb cb;
int fd = -1;

cb.aio_fildes = fd;
cb.aio_offset = 0;
cb.aio_buf = NULL;
cb.aio_nbytes = 0;
cb.aio_reqprio = 0;
cb.aio_sigevent.sigev_notify = SIGEV_NONE;

errno = 0;

/* Case one: invalid fds that match. */
if (aio_cancel (fd, &cb) != -1 || errno != EBADF)
{
puts ("aio_cancel( -1, {-1..} ) did not return -1 or errno != EBADF");
++result;
}

cb.aio_fildes = -2;
errno = 0;

/* Case two: invalid fds that do not match; just print warning. */
if (aio_cancel (fd, &cb) != -1 || errno != EBADF)
puts ("aio_cancel( -1, {-2..} ) did not return -1 or errno != EBADF");
}

/* Test for aio_fsync() detecting bad fd, and fd not open for writing. */
{
struct aiocb cb;
int fd = -1;

cb.aio_fildes = fd;
cb.aio_offset = 0;
cb.aio_buf = NULL;
cb.aio_nbytes = 0;
cb.aio_reqprio = 0;
cb.aio_sigevent.sigev_notify = SIGEV_NONE;

errno = 0;

/* Case one: invalid fd. */
if (aio_fsync (O_SYNC, &cb) != -1 || errno != EBADF)
{
puts ("aio_fsync( op, {-1..} ) did not return -1 or errno != EBADF");
++result;
}

if ((fd = open ("/dev/null", O_RDONLY)) < 0)
error (1, errno, "opening /dev/null");

cb.aio_fildes = fd;
errno = 0;

/* Case two: valid fd but open for read only. */
if (aio_fsync (O_SYNC, &cb) != -1 || errno != EBADF)
{
puts ("aio_fsync( op, {RO..} ) did not return -1 or errno != EBADF");
++result;
}

close (fd);
}

/* Test for aio_suspend() suspending even if completed elements in list. */
{
const int BYTES = 8, ELEMS = 2;
int i, r, fd;
char buff[BYTES];
char name[] = "/tmp/aio7.XXXXXX";
struct timespec timeout;
struct aiocb cb0, cb1;
struct aiocb *list[ELEMS];

fd = mkstemp (name);
if (fd < 0)
error (1, errno, "creating temp file");

if (unlink (name))
error (1, errno, "unlinking temp file");

if (write (fd, "01234567", BYTES) != BYTES)
error (1, errno, "writing to temp file");

cb0.aio_fildes = fd;
cb0.aio_offset = 0;
cb0.aio_buf = buff;
cb0.aio_nbytes = BYTES;
cb0.aio_reqprio = 0;
cb0.aio_sigevent.sigev_notify = SIGEV_NONE;

r = aio_read (&cb0);
if (r != 0)
error (1, errno, "reading from file");

while (aio_error (&(cb0)) == EINPROGRESS)
usleep (10);

for (i = 0; i < BYTES; i++)
printf ("%c ", buff[i]);
printf ("\n");

/* At this point, the first read is completed, so start another one on
* stdin, which will not complete unless the user inputs something.
*/
cb1.aio_fildes = 0;
cb1.aio_offset = 0;
cb1.aio_buf = buff;
cb1.aio_nbytes = BYTES;
cb1.aio_reqprio = 0;
cb1.aio_sigevent.sigev_notify = SIGEV_NONE;

r = aio_read (&cb1);
if (r != 0)
error (1, errno, "reading from file");

/* Now call aio_suspend() with the two reads. It should return
* immediately according to the POSIX spec.
*/
list[0] = &cb0;
list[1] = &cb1;
timeout.tv_sec = 3;
timeout.tv_nsec = 0;
r = aio_suspend ((const struct aiocb * const *) list, ELEMS, &timeout);

if (r == -1 && errno == EAGAIN)
{
puts ("aio_suspend([done,blocked],2,3) suspended thread");
++result;
}
}

return result;
}

#include "../test-skeleton.c"
9 changes: 8 additions & 1 deletion sysdeps/pthread/aio_cancel.c
@@ -1,5 +1,5 @@
/* Cancel requests associated with given file descriptor.
Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc.
Copyright (C) 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
Expand Down Expand Up @@ -43,6 +43,13 @@ aio_cancel (fildes, aiocbp)
struct requestlist *req = NULL;
int result = AIO_ALLDONE;

/* If fildes is invalid, error. */
if (fcntl (fildes, F_GETFL) < 0)
{
__set_errno (EBADF);
return -1;
}

/* Request the mutex. */
pthread_mutex_lock (&__aio_requests_mutex);

Expand Down
14 changes: 12 additions & 2 deletions sysdeps/pthread/aio_fsync.c
@@ -1,5 +1,5 @@
/* Synchronize I/O in given file descriptor.
Copyright (C) 1997, 1999 Free Software Foundation, Inc.
Copyright (C) 1997, 1999, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
Expand Down Expand Up @@ -36,12 +36,22 @@
int
aio_fsync (int op, struct aiocb *aiocbp)
{
if (op != O_DSYNC && op != O_SYNC)
int flags;

if (op != O_DSYNC && __builtin_expect (op != O_SYNC, 0))
{
__set_errno (EINVAL);
return -1;
}

flags = fcntl (aiocbp->aio_fildes, F_GETFL);
if (__builtin_expect (flags == -1, 0)
|| __builtin_expect ((flags & (O_RDWR | O_WRONLY)) == 0, 0))
{
__set_errno (EBADF);
return -1;
}

return (__aio_enqueue_request ((aiocb_union *) aiocbp,
op == O_SYNC ? LIO_SYNC : LIO_DSYNC) == NULL
? -1 : 0);
Expand Down

0 comments on commit 8b8cc76

Please sign in to comment.