diff options
Diffstat (limited to 'dbus')
-rw-r--r-- | dbus/dbus-sysdeps-unix.c | 42 | ||||
-rw-r--r-- | dbus/dbus-sysdeps-unix.h | 4 |
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); |