From: Lennart Poettering Date: Wed, 22 Apr 2009 01:08:48 +0000 (+0200) Subject: sysdeps-unix: introduce _dbus_dup() X-Git-Tag: dbus-1.3.0~4^2~23 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=18f7259a439740d02f6cd727e32348b51191de14;p=thirdparty%2Fdbus.git 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. --- diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 2e129826f..5f94c6a58 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 0005cd87b..5b7723a29 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);