aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--butl/fdstream11
-rw-r--r--butl/fdstream.cxx20
2 files changed, 26 insertions, 5 deletions
diff --git a/butl/fdstream b/butl/fdstream
index 289d925..d3dbef7 100644
--- a/butl/fdstream
+++ b/butl/fdstream
@@ -52,8 +52,9 @@ namespace butl
void
reset (int fd = -1) noexcept;
- // Close an open file descriptor. Throw ios::failure on failure. The object
- // become unopened whenever the exception is thrown or not.
+ // Close an open file descriptor. Throw ios::failure on the underlying OS
+ // error. Reset the descriptor to -1 whenever the exception is thrown or
+ // not.
//
void
close ();
@@ -498,6 +499,12 @@ namespace butl
permissions::rg | permissions::wg |
permissions::ro | permissions::wo);
+ // Duplicate an open file descriptor. Throw ios::failure on the underlying
+ // OS error.
+ //
+ LIBBUTL_EXPORT auto_fd
+ fddup (int fd);
+
// Set the translation mode for the file descriptor. Return the previous
// mode on success, throw ios::failure otherwise.
//
diff --git a/butl/fdstream.cxx b/butl/fdstream.cxx
index 102ad66..16801ed 100644
--- a/butl/fdstream.cxx
+++ b/butl/fdstream.cxx
@@ -6,14 +6,14 @@
#ifndef _WIN32
# include <fcntl.h> // open(), O_*, fcntl()
-# include <unistd.h> // close(), read(), write(), lseek(), ssize_t,
+# include <unistd.h> // close(), read(), write(), lseek(), dup(), ssize_t,
// STD*_FILENO
# include <sys/uio.h> // writev(), iovec
# include <sys/stat.h> // S_I*
# include <sys/types.h> // off_t
#else
# include <io.h> // _close(), _read(), _write(), _setmode(), _sopen(),
- // _lseek()
+ // _lseek(), _dup()
# include <share.h> // _SH_DENYNO
# include <stdio.h> // _fileno(), stdin, stdout, stderr
# include <fcntl.h> // _O_*
@@ -87,7 +87,6 @@ namespace butl
}
}
-
// fdbuf
//
fdbuf::
@@ -737,6 +736,21 @@ namespace butl
return auto_fd (fd);
}
+ auto_fd
+ fddup (int fd)
+ {
+#ifndef _WIN32
+ int nfd (dup (fd));
+#else
+ int nfd (_dup (fd));
+#endif
+
+ if (nfd == -1)
+ throw_ios_failure (errno);
+
+ return auto_fd (nfd);
+ }
+
#ifndef _WIN32
bool