From 18f7259a439740d02f6cd727e32348b51191de14 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Apr 2009 03:08:48 +0200 Subject: 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. --- dbus/dbus-sysdeps-unix.c | 42 ++++++++++++++++++++++++++++++++++++++++++ dbus/dbus-sysdeps-unix.h | 4 +++- 2 files changed, 45 insertions(+), 1 deletion(-) 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 @@ -2711,6 +2711,48 @@ _dbus_close (int fd, return TRUE; } +/** + * 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. * 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); -- cgit