]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
hurd: Make fcntl(F_SETLKW*) cancellation points
authorSamuel Thibault <samuel.thibault@ens-lyon.org>
Sun, 28 Jun 2020 18:18:43 +0000 (18:18 +0000)
committerSamuel Thibault <samuel.thibault@ens-lyon.org>
Sun, 28 Jun 2020 18:24:37 +0000 (18:24 +0000)
and add _nocancel variant.

* sysdeps/mach/hurd/Makefile [io] (sysdep_routines): Add fcntl_nocancel.
* sysdeps/mach/hurd/fcntl.c [NOCANCEL]: Include <not-cancel.h>.
[!NOCANCEL]: Include <sysdep-cancel.h>.
(__libc_fcntl) [!NOCANCEL]: Surround __file_record_lock call with enabling async cancel, and use HURD_FD_PORT_USE_CANCEL instead of HURD_FD_PORT_USE.
* sysdeps/mach/hurd/fcntl_nocancel.c: New file, defines __fcntl_nocancel by including fcntl.c.
* sysdeps/mach/hurd/not-cancel.h (__fcntl64_nocancel): Replace macro with
    __fcntl_nocancel declaration with hidden proto, and make
    __fcntl64_nocancel call __fcntl_nocancel.

sysdeps/mach/hurd/Makefile
sysdeps/mach/hurd/fcntl.c
sysdeps/mach/hurd/fcntl_nocancel.c [new file with mode: 0644]
sysdeps/mach/hurd/not-cancel.h

index a1ca034175d6b583c3aa02847bb1e300b36b68c9..9c53db37832f43d2bfa61d246643521db9e50c08 100644 (file)
@@ -197,7 +197,7 @@ endif
 
 ifeq (io, $(subdir))
 sysdep_routines += f_setlk close_nocancel close_nocancel_nostatus \
-                  open_nocancel openat_nocancel read_nocancel \
+                  fcntl_nocancel open_nocancel openat_nocancel read_nocancel \
                   pread64_nocancel write_nocancel pwrite64_nocancel \
                   wait4_nocancel
 endif
index 95b0ebff0f6b31739182ee0302c18e40faf951d4..564d9dcd23132175b34c1a200793232597a5b191 100644 (file)
 #include <hurd/fd.h>
 #include <stdarg.h>
 #include <sys/file.h>          /* XXX for LOCK_* */
+#ifdef NOCANCEL
+#include <not-cancel.h>
+#else
+#include <sysdep-cancel.h>
+#endif
 #include "f_setlk.h"
 
 /* Perform file control operations on FD.  */
@@ -155,8 +160,19 @@ __libc_fcntl (int fd, int cmd, ...)
          .l_pid = fl->l_pid
        };
 
-       err = HURD_FD_PORT_USE (d, __file_record_lock (port, cmd, &fl64,
-                               MACH_PORT_NULL, MACH_MSG_TYPE_MAKE_SEND));
+#ifndef NOCANCEL
+       if (cmd == F_SETLKW64)
+         {
+           int cancel_oldtype = LIBC_CANCEL_ASYNC();
+           err = HURD_FD_PORT_USE_CANCEL (d, __file_record_lock (port, cmd,
+                                          &fl64, MACH_PORT_NULL,
+                                          MACH_MSG_TYPE_MAKE_SEND));
+           LIBC_CANCEL_RESET (cancel_oldtype);
+         }
+       else
+#endif
+         err = HURD_FD_PORT_USE (d, __file_record_lock (port, cmd, &fl64,
+                                 MACH_PORT_NULL, MACH_MSG_TYPE_MAKE_SEND));
 
        /* XXX: To remove once file_record_lock RPC is settled.  */
        if (err == EMIG_BAD_ID || err == EOPNOTSUPP)
@@ -207,8 +223,19 @@ __libc_fcntl (int fd, int cmd, ...)
       {
        struct flock64 *fl = va_arg (ap, struct flock64 *);
 
-       err = HURD_FD_PORT_USE (d, __file_record_lock (port, cmd, fl,
-                               MACH_PORT_NULL, MACH_MSG_TYPE_MAKE_SEND));
+#ifndef NOCANCEL
+       if (cmd == F_SETLKW64)
+         {
+           int cancel_oldtype = LIBC_CANCEL_ASYNC();
+           err = HURD_FD_PORT_USE_CANCEL (d, __file_record_lock (port, cmd,
+                                          fl, MACH_PORT_NULL,
+                                          MACH_MSG_TYPE_MAKE_SEND));
+           LIBC_CANCEL_RESET (cancel_oldtype);
+         }
+       else
+#endif
+         err = HURD_FD_PORT_USE (d, __file_record_lock (port, cmd, fl,
+                                 MACH_PORT_NULL, MACH_MSG_TYPE_MAKE_SEND));
 
        /* XXX: To remove once file_record_lock RPC is settled.  */
        if (err == EMIG_BAD_ID || err == EOPNOTSUPP)
@@ -263,6 +290,8 @@ __libc_fcntl (int fd, int cmd, ...)
   return result;
 }
 libc_hidden_def (__libc_fcntl)
+
+#ifndef NOCANCEL
 weak_alias (__libc_fcntl, __fcntl)
 libc_hidden_weak (__fcntl)
 weak_alias (__libc_fcntl, fcntl)
@@ -272,3 +301,4 @@ libc_hidden_def (__libc_fcntl64)
 weak_alias (__libc_fcntl64, __fcntl64)
 libc_hidden_weak (__fcntl64)
 weak_alias (__fcntl64, fcntl64)
+#endif
diff --git a/sysdeps/mach/hurd/fcntl_nocancel.c b/sysdeps/mach/hurd/fcntl_nocancel.c
new file mode 100644 (file)
index 0000000..8913405
--- /dev/null
@@ -0,0 +1,3 @@
+#define NOCANCEL
+#define __libc_fcntl __fcntl_nocancel
+#include <sysdeps/mach/hurd/fcntl.c>
index 69cd781f688eb088f66386a8a0237a35a16291b9..94b731c0800959687754ce486dcb4978e7e1e7e6 100644 (file)
@@ -69,9 +69,11 @@ __typeof (__wait4) __wait4_nocancel;
 # define __waitpid_nocancel(pid, stat_loc, options) \
   __wait4_nocancel (pid, stat_loc, options, NULL)
 
-/* For now we have none.  Map the name to the normal functions.  */
-#define __fcntl64_nocancel(fd, cmd, ...) \
-  __fcntl64 (fd, cmd, __VA_ARGS__)
+/* Non cancellable fcntl syscall.  */
+__typeof (__fcntl) __fcntl_nocancel;
+/* fcntl64 is just the same as fcntl for us.  */
+#define __fcntl64_nocancel(...) \
+  __fcntl_nocancel (__VA_ARGS__)
 
 #if IS_IN (libc)
 hidden_proto (__close_nocancel)
@@ -85,6 +87,7 @@ hidden_proto (__pwrite64_nocancel)
 hidden_proto (__writev_nocancel)
 hidden_proto (__writev_nocancel_nostatus)
 hidden_proto (__wait4_nocancel)
+hidden_proto (__fcntl_nocancel)
 #endif
 
 #endif /* NOT_CANCEL_H  */