From e283b08481cfec9aa55b3ddbf369d632c7aa7b0f Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 18 Mar 2021 15:53:49 +0200 Subject: Add fdstat() --- libbutl/fdstream.cxx | 67 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 8 deletions(-) (limited to 'libbutl/fdstream.cxx') diff --git a/libbutl/fdstream.cxx b/libbutl/fdstream.cxx index 4948052..308d76c 100644 --- a/libbutl/fdstream.cxx +++ b/libbutl/fdstream.cxx @@ -12,20 +12,27 @@ # include // close(), read(), write(), lseek(), dup(), pipe(), // ftruncate(), isatty(), ssize_t, STD*_FILENO # include // writev(), iovec -# include // stat(), S_I* +# include // stat(), fstat(), S_I* # include // timeval # include // stat, off_t # include #else # include -# include // _close(), _read(), _write(), _setmode(), _sopen(), - // _lseek(), _dup(), _pipe(), _chsize_s, - // _get_osfhandle() -# include // _SH_DENYNO -# include // _fileno(), stdin, stdout, stderr, SEEK_* -# include // _O_* -# include // S_I* +# include // _close(), _read(), _write(), _setmode(), _sopen(), + // _lseek(), _dup(), _pipe(), _chsize_s, + // _get_osfhandle() +# include // _SH_DENYNO +# include // _fileno(), stdin, stdout, stderr, SEEK_* +# include // _O_* +# include // _stat +# include // fstat(), S_I* + +# ifdef _MSC_VER // Unlikely to be fixed in newer versions. +# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +# endif # include // wcsncmp(), wcsstr() @@ -1372,6 +1379,28 @@ namespace butl throw_generic_ios_failure (errno); } + entry_stat + fdstat (int fd) + { + struct stat s; + if (fstat (fd, &s) != 0) + throw_generic_error (errno); + + auto m (s.st_mode); + entry_type t (entry_type::unknown); + + // Note: cannot be a symlink. + // + if (S_ISREG (m)) + t = entry_type::regular; + else if (S_ISDIR (m)) + t = entry_type::directory; + else if (S_ISBLK (m) || S_ISCHR (m) || S_ISFIFO (m) || S_ISSOCK (m)) + t = entry_type::other; + + return entry_stat {t, static_cast (s.st_size)}; + } + bool fdterm (int fd) { @@ -1779,6 +1808,28 @@ namespace butl throw_generic_ios_failure (e); } + entry_stat + fdstat (int fd) + { + // Since symlinks have been taken care of, we can just _fstat(). + // + struct __stat64 s; + if (_fstat64 (fd, &s) != 0) + throw_generic_error (errno); + + auto m (s.st_mode); + entry_type t (entry_type::unknown); + + if (S_ISREG (m)) + t = entry_type::regular; + else if (S_ISDIR (m)) + t = entry_type::directory; + else if (S_ISCHR (m)) + t = entry_type::other; + + return entry_stat {t, static_cast (s.st_size)}; + } + bool fdterm (int fd) { -- cgit v1.1