sysdeps-unix: introduce _dbus_dup()
authorLennart Poettering <lennart@poettering.net>
Wed, 22 Apr 2009 01:08:48 +0000 (03:08 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 19 May 2009 23:36:19 +0000 (01:36 +0200)
This is a simple wrapper around dup()-like functionality.

Also handles CLOEXEC and makes sure we don't interfere with the standard
I/O file descriptors 0, 1 and 2.

dbus/dbus-sysdeps-unix.c
dbus/dbus-sysdeps-unix.h

index 2e12982..5f94c6a 100644 (file)
@@ -2712,6 +2712,48 @@ _dbus_close (int        fd,
 }
 
 /**
+ * Duplicates a file descriptor. Makes sure the fd returned is >= 3
+ * (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC.
+ *
+ * @param fd the file descriptor to duplicate
+ * @returns duplicated file descriptor
+ * */
+int
+_dbus_dup(int        fd,
+          DBusError *error)
+{
+  int new_fd;
+
+#ifdef F_DUPFD_CLOEXEC
+  dbus_bool_t cloexec_done;
+
+  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+  cloexec_done = new_fd >= 0;
+
+  if (new_fd < 0 && errno == EINVAL)
+#endif
+    {
+      new_fd = fcntl(fd, F_DUPFD, 3);
+    }
+
+  if (new_fd < 0) {
+
+    dbus_set_error (error, _dbus_error_from_errno (errno),
+                    "Could not duplicate fd %d", fd);
+    return -1;
+  }
+
+#ifndef F_DUPFD_CLOEXEC
+  if (!cloexec_done)
+#endif
+    {
+      _dbus_fd_set_close_on_exec(new_fd);
+    }
+
+  return new_fd;
+}
+
+/**
  * Sets a file descriptor to be nonblocking.
  *
  * @param fd the file descriptor.
index 0005cd8..5b7723a 100644 (file)
@@ -44,7 +44,9 @@ DBUS_BEGIN_DECLS
 dbus_bool_t 
 _dbus_close     (int               fd,
                  DBusError        *error);
-int 
+int _dbus_dup   (int               fd,
+                 DBusError        *error);
+int
 _dbus_read      (int               fd,
                  DBusString       *buffer,
                  int               count);