aboutsummaryrefslogtreecommitdiffstats
path: root/guts/fcntl.c
diff options
context:
space:
mode:
Diffstat (limited to 'guts/fcntl.c')
-rw-r--r--guts/fcntl.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/guts/fcntl.c b/guts/fcntl.c
new file mode 100644
index 0000000..d03d40c
--- /dev/null
+++ b/guts/fcntl.c
@@ -0,0 +1,68 @@
+/*
+ * static int
+ * wrap_fcntl(int fd, int cmd, ...struct flock *lock) {
+ * int rc = -1;
+ */
+ long arg;
+ int save_errno;
+
+ /* we don't know whether we need lock or arg; grab both, which
+ * should be safe enough on Linuxy systems. */
+ va_start(ap, cmd);
+ arg = va_arg(ap, long);
+ va_end(ap);
+
+ switch (cmd) {
+ case F_DUPFD:
+#ifdef F_DUPFD_CLOEXEC
+ case F_DUPFD_CLOEXEC:
+#endif
+ /* actually do something */
+ rc = real_fcntl(fd, cmd, arg);
+ save_errno = errno;
+ if (rc != -1) {
+ pseudo_debug(2, "fcntl_dup: %d->%d\n", fd, rc);
+ pseudo_client_op(OP_DUP, 0, fd, rc, 0, 0);
+ }
+ errno = save_errno;
+ break;
+ /* no argument: */
+ case F_GETFD:
+ case F_GETFL:
+ case F_GETOWN:
+ case F_GETSIG:
+ case F_GETLEASE:
+ rc = real_fcntl(fd, cmd);
+ break;
+ /* long argument */
+ case F_SETFD:
+ case F_SETFL:
+ case F_SETOWN:
+ case F_SETSIG:
+ case F_SETLEASE:
+ case F_NOTIFY:
+ rc = real_fcntl(fd, cmd, arg);
+ break;
+ /* struct flock * argument */
+ case F_GETLK:
+ case F_SETLK:
+ case F_SETLKW:
+ rc = real_fcntl(fd, cmd, lock);
+ break;
+#if defined(F_GETLK64) && (F_GETLK64 != F_GETLK)
+ /* the cast is safe, all struct pointers must smell the same */
+ case F_GETLK64:
+ case F_SETLK64:
+ case F_SETLKW64:
+ rc = real_fcntl(fd, cmd, (struct flock64 *) lock);
+ break;
+#endif
+ default:
+ pseudo_diag("unknown fcntl argument %d, assuming long argument.\n",
+ cmd);
+ rc = real_fcntl(fd, cmd, arg);
+ break;
+ }
+/* return rc;
+ * }
+ */