diff options
author | Lennart Poettering <lennart@poettering.net> | 2009-04-22 03:08:48 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2009-05-20 01:36:19 +0200 |
commit | 18f7259a439740d02f6cd727e32348b51191de14 (patch) | |
tree | 035dba0c670d1f7fd9d21b0db1a2a6dfb64aa133 | |
parent | 03d50fbd77481568bb2127d8b92e22d2cdc61ab8 (diff) | |
download | dbus-18f7259a439740d02f6cd727e32348b51191de14.tar.gz |
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.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); |