public inbox for cygwin-cvs@sourceware.org help / color / mirror / Atom feed
From: Corinna Vinschen <corinna@sourceware.org> To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin/main] Cygwin: lseek: improve seeking posix_getdents descriptors Date: Fri, 1 Mar 2024 14:44:06 +0000 (GMT) [thread overview] Message-ID: <20240301144406.EDE823858C53@sourceware.org> (raw) https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=6d936915477ca8f64ecba31c9876103d69827fb2 commit 6d936915477ca8f64ecba31c9876103d69827fb2 Author: Corinna Vinschen <corinna@vinschen.de> AuthorDate: Fri Mar 1 15:16:44 2024 +0100 Commit: Corinna Vinschen <corinna@vinschen.de> CommitDate: Fri Mar 1 15:32:39 2024 +0100 Cygwin: lseek: improve seeking posix_getdents descriptors Transfer code lseeking on posix_getdents() directory descriptor into its own static function and rework it so SEEK_END, SEEK_DATA and SEEK_HOLE work here as expected, too. Signed-off-by: Corinna Vinschen <corinna@vinschen.de> Diff: --- winsup/cygwin/syscalls.cc | 83 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 22 deletions(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 600c6c54e343..2c5bf7cbe08b 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1596,6 +1596,66 @@ open (const char *unix_path, int flags, ...) EXPORT_ALIAS (open, _open ) +static int +posix_getdents_lseek (cygheap_fdget &cfd, off_t pos, int dir) +{ + long cur = cfd->telldir (cfd->getdents_dir ()); + long abs_pos; + + switch (dir) + { + case SEEK_CUR: + abs_pos = cur + pos; + break; + case SEEK_SET: + case SEEK_DATA: + abs_pos = pos; + break; + case SEEK_END: + case SEEK_HOLE: + /* First read full dir to learn end-of-dir position. */ + while (::readdir (cfd->getdents_dir ())) + ; + long eod = cfd->telldir (cfd->getdents_dir ()); + /* Seek back so it looks like nothing happend in error case */ + cfd->seekdir (cfd->getdents_dir (), cur); + if (dir == SEEK_HOLE) + { + if (pos > eod) + { + set_errno (ENXIO); + return -1; + } + abs_pos = eod; + } + else + abs_pos = eod + pos; + break; + } + if (abs_pos < 0) + { + set_errno (EINVAL); + return -1; + } + if (abs_pos != cur) + { + cfd->seekdir (cfd->getdents_dir (), abs_pos); + /* In SEEK_DATA case, check that we didn't seek beyond EOF */ + if (dir == SEEK_DATA || dir == SEEK_HOLE) + { + pos = cfd->telldir (cfd->getdents_dir ()); + if (pos < abs_pos) + { + /* Seek back so it looks like nothing happend */ + cfd->seekdir (cfd->getdents_dir (), cur); + set_errno (ENXIO); + return -1; + } + } + } + return abs_pos; +} + extern "C" off_t lseek (int fd, off_t pos, int dir) { @@ -1612,28 +1672,7 @@ lseek (int fd, off_t pos, int dir) if (cfd < 0) res = -1; else if (cfd->getdents_dir ()) - { - if (dir != SEEK_SET && dir != SEEK_CUR) /* No SEEK_END */ - { - set_errno (EINVAL); - res = -1; - } - else - { - long cur; - - cur = cfd->telldir (cfd->getdents_dir ()); - if (dir == SEEK_CUR && cur == 0) - res = cur; - else - { - if (dir == SEEK_CUR) - pos = cur + pos; - cfd->seekdir (cfd->getdents_dir (), pos); - res = pos; - } - } - } + res = posix_getdents_lseek (cfd, pos, dir); else res = cfd->lseek (pos, dir); }
reply other threads:[~2024-03-01 14:44 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240301144406.EDE823858C53@sourceware.org \ --to=corinna@sourceware.org \ --cc=cygwin-cvs@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).