* [PATCH 0/3] Fix fstat on FIFOs, part 2
@ 2021-02-18 17:13 Ken Brown
2021-02-18 17:13 ` [PATCH 1/3] Cygwin: define fhandler_fifo::fstat Ken Brown
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Ken Brown @ 2021-02-18 17:13 UTC (permalink / raw)
To: cygwin-patches
The first patch fixes a bug, in which fstat on FIFOs sometimes used
pipe handles instead of file handles.
The second and third patches should improve the efficiency of fstat
and open on FIFOs.
Ken Brown (3):
Cygwin: define fhandler_fifo::fstat
Cygwin: fstat_helper: always use handle in call to get_file_attribute
Cygwin: FIFO: temporarily keep a conv_handle in syscalls.cc:open
winsup/cygwin/fhandler.h | 1 +
winsup/cygwin/fhandler_disk_file.cc | 3 +--
winsup/cygwin/fhandler_fifo.cc | 23 +++++++++++++++++++++++
winsup/cygwin/syscalls.cc | 22 +++++++++++++++++++---
4 files changed, 44 insertions(+), 5 deletions(-)
--
2.30.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/3] Cygwin: define fhandler_fifo::fstat
2021-02-18 17:13 [PATCH 0/3] Fix fstat on FIFOs, part 2 Ken Brown
@ 2021-02-18 17:13 ` Ken Brown
2021-02-18 17:13 ` [PATCH 2/3] Cygwin: fstat_helper: always use handle in call to get_file_attribute Ken Brown
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Ken Brown @ 2021-02-18 17:13 UTC (permalink / raw)
To: cygwin-patches
Previously fstat on a FIFO would call fhandler_base::fstat.
The latter is not appropriate if fhandler_fifo::open has already been
called (and O_PATH is not set), for the following reason. If a FIFO
has been opened as a writer or duplexer, then it has an io_handle that
is a pipe handle rather than a file handle. fhandler_base::fstat will
use this handle and potentially return incorrect results. If the FIFO
has been opened as a reader, then it has no io_handle, and a call to
fhandler_base::fstat will lead to a call to fhandler_base::open.
Opening the fhandler a second time can change it in undesired ways;
for example, it can modify the flags and status_flags.
The new fhandler_fifo::fstat avoids these problems by creating an
fhandler_disk_file and calling its fstat method in case
fhandler_fifo::open has already been called and O_PATH is not set.
---
winsup/cygwin/fhandler.h | 1 +
winsup/cygwin/fhandler_fifo.cc | 23 +++++++++++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index e457e2785..78d9c7984 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1510,6 +1510,7 @@ public:
ssize_t __reg3 raw_write (const void *ptr, size_t ulen);
void fixup_after_fork (HANDLE);
void fixup_after_exec ();
+ int __reg2 fstat (struct stat *buf);
int __reg2 fstatvfs (struct statvfs *buf);
select_record *select_read (select_stuff *);
select_record *select_write (select_stuff *);
diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc
index 8b67037cb..365f14053 100644
--- a/winsup/cygwin/fhandler_fifo.cc
+++ b/winsup/cygwin/fhandler_fifo.cc
@@ -1494,6 +1494,29 @@ errout:
len = (size_t) -1;
}
+int __reg2
+fhandler_fifo::fstat (struct stat *buf)
+{
+ if (reader || writer || duplexer)
+ {
+ /* fhandler_fifo::open has been called, and O_PATH is not set.
+ We don't want to call fhandler_base::fstat. In the writer
+ and duplexer cases we have a handle, but it's a pipe handle
+ rather than a file handle, so it's not suitable for stat. In
+ the reader case we don't have a handle, but
+ fhandler_base::fstat would call fhandler_base::open, which
+ would modify the flags and status_flags. */
+ fhandler_disk_file fh (pc);
+ fh.get_device () = FH_FS;
+ int res = fh.fstat (buf);
+ buf->st_dev = buf->st_rdev = dev ();
+ buf->st_mode = dev ().mode ();
+ buf->st_size = 0;
+ return res;
+ }
+ return fhandler_base::fstat (buf);
+}
+
int __reg2
fhandler_fifo::fstatvfs (struct statvfs *sfs)
{
--
2.30.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/3] Cygwin: fstat_helper: always use handle in call to get_file_attribute
2021-02-18 17:13 [PATCH 0/3] Fix fstat on FIFOs, part 2 Ken Brown
2021-02-18 17:13 ` [PATCH 1/3] Cygwin: define fhandler_fifo::fstat Ken Brown
@ 2021-02-18 17:13 ` Ken Brown
2021-02-18 17:13 ` [PATCH 3/3] Cygwin: FIFO: temporarily keep a conv_handle in syscalls.cc:open Ken Brown
2021-02-19 17:07 ` [PATCH 0/3] Fix fstat on FIFOs, part 2 Corinna Vinschen
3 siblings, 0 replies; 5+ messages in thread
From: Ken Brown @ 2021-02-18 17:13 UTC (permalink / raw)
To: cygwin-patches
Previously, the call to get_file_attribute for FIFOs set the first
argument to NULL instead of the handle h returned by get_stat_handle,
thereby forcing the file to be opened for fetching the security
descriptor in get_file_sd(). This was done because h might have been
a pipe handle rather than a file handle, and its permissions would not
necessarily reflect those of the file.
That situation can no longer occur with the new fhandler_fifo::fstat
introduced in the previous commit.
---
winsup/cygwin/fhandler_disk_file.cc | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index ef9171bbf..6170427b0 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -475,8 +475,7 @@ fhandler_base::fstat_helper (struct stat *buf)
else if (pc.issocket ())
buf->st_mode = S_IFSOCK;
- if (!get_file_attribute (is_fs_special () && !pc.issocket () ? NULL : h, pc,
- &buf->st_mode, &buf->st_uid, &buf->st_gid))
+ if (!get_file_attribute (h, pc, &buf->st_mode, &buf->st_uid, &buf->st_gid))
{
/* If read-only attribute is set, modify ntsec return value */
if (::has_attribute (attributes, FILE_ATTRIBUTE_READONLY)
--
2.30.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 3/3] Cygwin: FIFO: temporarily keep a conv_handle in syscalls.cc:open
2021-02-18 17:13 [PATCH 0/3] Fix fstat on FIFOs, part 2 Ken Brown
2021-02-18 17:13 ` [PATCH 1/3] Cygwin: define fhandler_fifo::fstat Ken Brown
2021-02-18 17:13 ` [PATCH 2/3] Cygwin: fstat_helper: always use handle in call to get_file_attribute Ken Brown
@ 2021-02-18 17:13 ` Ken Brown
2021-02-19 17:07 ` [PATCH 0/3] Fix fstat on FIFOs, part 2 Corinna Vinschen
3 siblings, 0 replies; 5+ messages in thread
From: Ken Brown @ 2021-02-18 17:13 UTC (permalink / raw)
To: cygwin-patches
When a FIFO is opened, syscalls.cc:open always calls fstat on the
newly-created fhandler_fifo. This results from a call to
device_access_denied.
To speed-up this fstat call, and therefore the open(2) call, use
PC_KEEP_HANDLE when the fhandler is created. The resulting
conv_handle is retained until after the fstat call if the fhandler is
a FIFO; otherwise, it is closed immediately.
---
winsup/cygwin/syscalls.cc | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 32a155a1c..460fe6801 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -1487,8 +1487,15 @@ open (const char *unix_path, int flags, ...)
opt |= PC_CTTY;
}
+ /* If we're opening a FIFO, we will call device_access_denied
+ below. This leads to a call to fstat, which can use the
+ path_conv handle. */
+ opt |= PC_KEEP_HANDLE;
if (!(fh = build_fh_name (unix_path, opt, stat_suffixes)))
__leave; /* errno already set */
+ opt &= ~PC_KEEP_HANDLE;
+ if (!fh->isfifo ())
+ fh->pc.close_conv_handle ();
if ((flags & O_NOFOLLOW) && fh->issymlink () && !(flags & O_PATH))
{
set_errno (ELOOP);
@@ -1555,9 +1562,18 @@ open (const char *unix_path, int flags, ...)
delete fh;
fh = fh_file;
}
- else if ((fh->is_fs_special () && fh->device_access_denied (flags))
- || !fh->open_with_arch (flags, mode & 07777))
- __leave; /* errno already set */
+ else
+ {
+ if (fh->is_fs_special ())
+ {
+ if (fh->device_access_denied (flags))
+ __leave; /* errno already set */
+ else if (fh->isfifo ())
+ fh->pc.close_conv_handle ();
+ }
+ if (!fh->open_with_arch (flags, mode & 07777))
+ __leave; /* errno already set */
+ }
/* Move O_TMPFILEs to the bin to avoid blocking the parent dir. */
if ((flags & O_TMPFILE) && !fh->pc.isremote ())
try_to_bin (fh->pc, fh->get_handle (), DELETE,
--
2.30.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 0/3] Fix fstat on FIFOs, part 2
2021-02-18 17:13 [PATCH 0/3] Fix fstat on FIFOs, part 2 Ken Brown
` (2 preceding siblings ...)
2021-02-18 17:13 ` [PATCH 3/3] Cygwin: FIFO: temporarily keep a conv_handle in syscalls.cc:open Ken Brown
@ 2021-02-19 17:07 ` Corinna Vinschen
3 siblings, 0 replies; 5+ messages in thread
From: Corinna Vinschen @ 2021-02-19 17:07 UTC (permalink / raw)
To: cygwin-patches
On Feb 18 12:13, Ken Brown via Cygwin-patches wrote:
> The first patch fixes a bug, in which fstat on FIFOs sometimes used
> pipe handles instead of file handles.
>
> The second and third patches should improve the efficiency of fstat
> and open on FIFOs.
>
> Ken Brown (3):
> Cygwin: define fhandler_fifo::fstat
> Cygwin: fstat_helper: always use handle in call to get_file_attribute
> Cygwin: FIFO: temporarily keep a conv_handle in syscalls.cc:open
>
> winsup/cygwin/fhandler.h | 1 +
> winsup/cygwin/fhandler_disk_file.cc | 3 +--
> winsup/cygwin/fhandler_fifo.cc | 23 +++++++++++++++++++++++
> winsup/cygwin/syscalls.cc | 22 +++++++++++++++++++---
> 4 files changed, 44 insertions(+), 5 deletions(-)
>
> --
> 2.30.0
LGTM, please push.
Thanks,
Corinna
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-02-19 17:07 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-18 17:13 [PATCH 0/3] Fix fstat on FIFOs, part 2 Ken Brown
2021-02-18 17:13 ` [PATCH 1/3] Cygwin: define fhandler_fifo::fstat Ken Brown
2021-02-18 17:13 ` [PATCH 2/3] Cygwin: fstat_helper: always use handle in call to get_file_attribute Ken Brown
2021-02-18 17:13 ` [PATCH 3/3] Cygwin: FIFO: temporarily keep a conv_handle in syscalls.cc:open Ken Brown
2021-02-19 17:07 ` [PATCH 0/3] Fix fstat on FIFOs, part 2 Corinna Vinschen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).