This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] aio_fsync


Greetings,

Enclosed you will find patches for the aio_fsync function. 
The goal of the patch is to come into POSIX 1003.1 compliance
as defined by:

http://www.opengroup.org/onlinepubs/007904975/functions/aio_fsync.html

Additionally a new testcase is included which fits into the glibc
test harness.

The authors of this code are Amos Waterland and myself both of the
IBM LTC.

Fixed in this patch are the following bugs:

1) Check that the aio control block pointer is real. 

2) Validate that the file is open for some sort of write operation.

3) Return EINVAL in the case where a bad op is passed.

4) Correct errno back to 0 if on completion of the __aio_enqueue_request
errno is EINTR. This is a side effect of the TEMP_FAILURE_RETRY macro
which does not reset errno when operations are interrupted.
(Can this macro be changed? Should it?)

--- glibc-2.2.5/sysdeps/pthread/aio_fsync.c	Fri Jul  6 04:56:02 2001
+++ glibc/sysdeps/pthread/aio_fsync.c	Thu Jun 13 19:28:01 2002
@@ -36,15 +36,26 @@
 int
 aio_fsync (int op, struct aiocb *aiocbp)
 {
-  if (op != O_DSYNC && op != O_SYNC)
+  int flags;
+
+  if (aiocbp && (flags=fcntl(aiocbp->aio_fildes,F_GETFL)) >=0 && (flags & (O_RDWR | O_WRONLY)) )
     {
-      __set_errno (EINVAL);
-      return -1;
+      if (op != O_DSYNC && op != O_SYNC)
+    	{
+      	  __set_errno (EINVAL);
+      	  return -1;
+    	}
+     
+      if (__aio_enqueue_request ((aiocb_union *) aiocbp,op == O_SYNC ? LIO_SYNC : LIO_DSYNC)==NULL)
+        return -1;
+      if (errno==EINTR)
+        __set_errno(0); 
+
+      return 0;
     }
 
-  return (__aio_enqueue_request ((aiocb_union *) aiocbp,
-				 op == O_SYNC ? LIO_SYNC : LIO_DSYNC) == NULL
-	  ? -1 : 0);
+  __set_errno(EBADF);
+  return -1;
 }
 
 weak_alias (aio_fsync, aio_fsync64)
-------------
diff -uN --exclude=CVS glibc-2.2.5/rt/tst-aio_fsync.c glibc/rt/tst-aio_fsync.c
--- glibc-2.2.5/rt/tst-aio_fsync.c	Thu Jan  1 00:00:00 1970
+++ glibc/rt/tst-aio_fsync.c	Thu Jun 13 19:09:37 2002
@@ -0,0 +1,121 @@
+/* Tests for AIO in librt.
+   Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Tom Gall <tom_gall@vnet.ibm.com> and
+   Amos Waterland <apw@us.ibm.com>, 2002.
+
+   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 <errno.h>
+#include <error.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+/* Prototype for our test function.  */
+extern void do_prepare (int argc, char *argv[]);
+extern int do_test (int argc, char *argv[]);
+
+
+/* We might need a bit longer timeout.  */
+#define TIMEOUT 20 /* sec */
+
+/* This defines the `main' function and some more.  */
+#include <test-skeleton.c>
+
+
+/* These are for the temporary file we generate.  */
+char *name;
+int fd;
+
+#define FMT "%d aio_fildes: %i\treturn: %i\n"
+#define FMT2 "aio_fildes: 0x0\treturn: %i\n"
+
+void
+do_prepare (int argc, char *argv[])
+{
+}
+
+int
+do_test (int argc, char *argv[])
+{
+/* 
+ * test a couple of corner cases
+ */
+  int r;
+  struct aiocb cb;
+  char errorstring[255];
+
+  cb.aio_offset = 0;
+  cb.aio_buf = NULL;
+  cb.aio_nbytes = 0;
+  cb.aio_reqprio = 0;
+  cb.aio_sigevent.sigev_notify = SIGEV_NONE;
+  cb.aio_fildes=open("/tmp/tst-aio_fsync", O_RDWR | O_CREAT,0600);
+  close (cb.aio_fildes);
+
+  /* case: cb.aio_fildes is valid */
+  cb.aio_fildes=open("/tmp/tst-aio_fsync", O_RDONLY ,0600);
+  errno = 0; 
+  r = aio_fsync( O_SYNC, &cb ); 
+  if (errno!=EBADF)
+    {
+      sprintf(errorstring,FMT,1, cb.aio_fildes, r);
+      error(0,errno, errorstring);
+    }
+  close (cb.aio_fildes);
+
+  cb.aio_fildes=open("/tmp/tst-aio_fsync", O_RDWR ,0600);
+  errno = 0; 
+  r = aio_fsync( O_SYNC, &cb ); 
+  if (errno)
+    {
+      sprintf(errorstring,FMT,1, cb.aio_fildes, r);
+      error(0,errno, errorstring);
+    }
+  close (cb.aio_fildes);
+
+  /* case: cb.aio_fildes is not valid */
+  errno = 0; cb.aio_fildes = -1;
+  r = aio_fsync( O_SYNC, &cb );
+  if (errno!=EBADF)
+    {
+      sprintf(errorstring,FMT, 2, cb.aio_fildes, r);
+      error(0,errno, errorstring);
+    }
+
+  /* case: cb is null */
+  errno = 0; 
+  r = aio_fsync( O_SYNC, NULL );
+  if (errno!=EBADF)
+    {
+      sprintf(errorstring,FMT2, r);
+      error(0,errno, errorstring);
+    } 
+
+  /* case: invalid SYNC param */
+  errno = 0; cb.aio_fildes = 1;
+  r = aio_fsync( 100, &cb ); 
+  if (errno!=EINVAL)
+    {
+      sprintf(errorstring,FMT, 3, cb.aio_fildes, r);
+      error(0,errno, errorstring);
+    }
+
+ return 0;
+}
------------------
Regards,

Tom

Tom Gall - PPC64, PPC, Embedded  "Where's the ka-boom? There was
Linux Technology Center           supposed to be an earth
(w) tom_gall@vnet.ibm.com         shattering ka-boom!"
(w) 507-253-4558                 -- Marvin Martian
(h) tgall@rochcivictheatre.org
http://www.ibm.com/linux/ltc


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]