From: Ken Brown <kbrown@cornell.edu>
To: cygwin-patches@cygwin.com
Subject: [PATCH 7/7] Cygwin: simplify linkat with AT_EMPTY_PATH
Date: Thu, 25 Feb 2021 17:48:12 -0500 [thread overview]
Message-ID: <20210225224812.61523-8-kbrown@cornell.edu> (raw)
In-Reply-To: <20210225224812.61523-1-kbrown@cornell.edu>
linkat(olddirfd, oldpath, oldname, newdirfd, newname, AT_EMPTY_PATH)
is supposed to create a link to the file referenced by olddirfd if
oldname is the empty string. Currently this is done via the /proc
filesystem by converting the call to
linkat(AT_FDCWD, "/proc/self/fd/<olddirfd>", newdirfd, newname,
AT_SYMLINK_FOLLOW),
which ultimately leads to a call to the appropriate fhandler's link
method. Simplify this by using cygheap_fdget to obtain the fhandler
directly.
---
winsup/cygwin/syscalls.cc | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 460fe6801..6ba4f10f7 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -4962,6 +4962,8 @@ linkat (int olddirfd, const char *oldpathname,
int flags)
{
tmp_pathbuf tp;
+ fhandler_base *fh = NULL;
+
__try
{
if (flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH))
@@ -4970,21 +4972,25 @@ linkat (int olddirfd, const char *oldpathname,
__leave;
}
char *oldpath = tp.c_get ();
- /* AT_EMPTY_PATH with an empty oldpathname is equivalent to
-
- linkat(AT_FDCWD, "/proc/self/fd/<olddirfd>", newdirfd,
- newname, AT_SYMLINK_FOLLOW);
-
- Convert the request accordingly. */
if ((flags & AT_EMPTY_PATH) && oldpathname && oldpathname[0] == '\0')
{
+ /* Operate directly on olddirfd, which can be anything
+ except a directory. */
if (olddirfd == AT_FDCWD)
{
set_errno (EPERM);
__leave;
}
- __small_sprintf (oldpath, "/proc/%d/fd/%d", myself->pid, olddirfd);
- flags = AT_SYMLINK_FOLLOW;
+ cygheap_fdget cfd (olddirfd);
+ if (cfd < 0)
+ __leave;
+ if (cfd->pc.isdir ())
+ {
+ set_errno (EPERM);
+ __leave;
+ }
+ fh = cfd;
+ flags = 0; /* In case AT_SYMLINK_FOLLOW was set. */
}
else if (gen_full_path_at (oldpath, olddirfd, oldpathname))
__leave;
@@ -5003,6 +5009,8 @@ linkat (int olddirfd, const char *oldpathname,
}
strcpy (oldpath, old_name.get_posix ());
}
+ if (fh)
+ return fh->link (newpath);
return link (oldpath, newpath);
}
__except (EFAULT) {}
--
2.30.0
next prev parent reply other threads:[~2021-02-25 22:48 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-25 22:48 [PATCH 0/7] Fix some system calls on sockets Ken Brown
2021-02-25 22:48 ` [PATCH 1/7] Cygwin: fix fstat on sockets that are not socket files Ken Brown
2021-02-25 22:48 ` [PATCH 2/7] Cygwin: fix fstatvfs " Ken Brown
2021-02-25 22:48 ` [PATCH 3/7] Cygwin: fix fchmod " Ken Brown
2021-02-25 22:48 ` [PATCH 4/7] Cygwin: fix fchown " Ken Brown
2021-02-25 22:48 ` [PATCH 5/7] Cygwin: fix facl " Ken Brown
2021-02-25 22:48 ` [PATCH 6/7] Cygwin: fix linkat(2) " Ken Brown
2021-02-25 22:48 ` Ken Brown [this message]
2021-03-01 12:31 ` [PATCH 0/7] Fix some system calls on sockets Corinna Vinschen
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=20210225224812.61523-8-kbrown@cornell.edu \
--to=kbrown@cornell.edu \
--cc=cygwin-patches@cygwin.com \
/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: link
Be 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).