summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/syscalls.cc
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2009-09-25 23:55:00 +0000
committerEric Blake <eblake@redhat.com>2009-09-25 23:55:00 +0000
commit2bf78f09289d43d727c0bc95132be1bb22f00e7f (patch)
tree862de1f2ab1b6e07b4113b8fe308be944f9603db /winsup/cygwin/syscalls.cc
parent358d4e3cb0a44d725e54494c97b2ddbaa2281b7b (diff)
downloadcygnal-2bf78f09289d43d727c0bc95132be1bb22f00e7f.tar.gz
cygnal-2bf78f09289d43d727c0bc95132be1bb22f00e7f.tar.bz2
cygnal-2bf78f09289d43d727c0bc95132be1bb22f00e7f.zip
Provide euidaccess, canonicalize_file_name; fix fchmodat.
* syscalls.cc (fchmodat): lchmod is not yet implemented. (euidaccess): New function. * path.cc (realpath): Update comment. (canonicalize_file_name): New function. * include/cygwin/stdlib.h (canonicalize_file_name): Declare it. * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump. * cygwin.din: Export canonicalize_file_name, eaccess, euidaccess. * posix.sgml: Mention them.
Diffstat (limited to 'winsup/cygwin/syscalls.cc')
-rw-r--r--winsup/cygwin/syscalls.cc30
1 files changed, 28 insertions, 2 deletions
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 3eb77fd07..da9cda507 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -1580,6 +1580,29 @@ access (const char *fn, int flags)
return res;
}
+/* Linux provides this extension; it is basically a wrapper around the
+ POSIX:2008 faccessat (AT_FDCWD, fn, flags, AT_EACCESS). We also
+ provide eaccess as an alias for this, in cygwin.din. */
+extern "C" int
+euidaccess (const char *fn, int flags)
+{
+ // flags were incorrectly specified
+ int res = -1;
+ if (flags & ~(F_OK|R_OK|W_OK|X_OK))
+ set_errno (EINVAL);
+ else
+ {
+ fhandler_base *fh = build_fh_name (fn, NULL, PC_SYM_FOLLOW, stat_suffixes);
+ if (fh)
+ {
+ res = fh->fhaccess (flags, true);
+ delete fh;
+ }
+ }
+ debug_printf ("returning %d", res);
+ return res;
+}
+
static void
rename_append_suffix (path_conv &pc, const char *path, size_t len,
const char *suffix)
@@ -3878,9 +3901,12 @@ fchmodat (int dirfd, const char *pathname, mode_t mode, int flags)
myfault efault;
if (efault.faulted (EFAULT))
return -1;
- if (flags & ~AT_SYMLINK_NOFOLLOW)
+ if (flags)
{
- set_errno (EINVAL);
+ /* BSD has lchmod, but Linux does not. POSIX says
+ AT_SYMLINK_NOFOLLOW is allowed to fail on symlinks; but Linux
+ blindly fails even for non-symlinks. */
+ set_errno ((flags & ~AT_SYMLINK_NOFOLLOW) ? EINVAL : EOPNOTSUPP);
return -1;
}
char *path = tp.c_get ();