summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2009-04-22 03:08:48 +0200
committerLennart Poettering <lennart@poettering.net>2009-05-20 01:36:19 +0200
commit18f7259a439740d02f6cd727e32348b51191de14 (patch)
tree035dba0c670d1f7fd9d21b0db1a2a6dfb64aa133
parent03d50fbd77481568bb2127d8b92e22d2cdc61ab8 (diff)
sysdeps-unix: introduce _dbus_dup()
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.
-rw-r--r--dbus/dbus-sysdeps-unix.c42
-rw-r--r--dbus/dbus-sysdeps-unix.h4
2 files changed, 45 insertions, 1 deletions
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index 2e129826..5f94c6a5 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -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.
diff --git a/dbus/dbus-sysdeps-unix.h b/dbus/dbus-sysdeps-unix.h
index 0005cd87..5b7723a2 100644
--- a/dbus/dbus-sysdeps-unix.h
+++ b/dbus/dbus-sysdeps-unix.h
@@ -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);