Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2008-04-23 15:13:52 +0400
committerCorinna Vinschen <corinna@vinschen.de>2008-04-23 15:13:52 +0400
commitc57b57e5c43ab112e50d5e214b8cef61f8027946 (patch)
tree79031d6d1a4253b66d59bafa1745cc604f995a17 /winsup
parentca48eb65e9f332484b1fe00ae373a1121091cbfb (diff)
* cygwin.din: Sort.
(faccessat): Export. (fchmodat): Export. (fchownat): Export. (fstatat): Export. (futimesat): Export. (linkat): Export. (mkdirat): Export. (mkfifoat): Export. (mknodat): Export. (openat): Export. (readlinkat): Export. (renameat): Export. (symlinkat): Export. (unlinkat): Export. * path.cc (readlink): Align definition to POSIX. * syscalls.cc (gen_full_path_at): New static function. (faccessat): Implement. (fchmodat): Implement. (fchownat): Implement. (fstatat): Implement. (futimesat): Implement. (linkat): Implement. (mkdirat): Implement. (mkfifoat): Implement. (mknodat): Implement. (openat): Implement. (readlinkat): Implement. (renameat): Implement. (symlinkat): Implement. (unlinkat): Implement. * include/cygwin/version.h: Bump API minor number.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog35
-rw-r--r--winsup/cygwin/cygwin.din16
-rw-r--r--winsup/cygwin/include/cygwin/version.h5
-rw-r--r--winsup/cygwin/path.cc6
-rw-r--r--winsup/cygwin/syscalls.cc276
5 files changed, 333 insertions, 5 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index c0b8a41a0..3dec78451 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,38 @@
+2008-04-23 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygwin.din: Sort.
+ (faccessat): Export.
+ (fchmodat): Export.
+ (fchownat): Export.
+ (fstatat): Export.
+ (futimesat): Export.
+ (linkat): Export.
+ (mkdirat): Export.
+ (mkfifoat): Export.
+ (mknodat): Export.
+ (openat): Export.
+ (readlinkat): Export.
+ (renameat): Export.
+ (symlinkat): Export.
+ (unlinkat): Export.
+ * path.cc (readlink): Align definition to POSIX.
+ * syscalls.cc (gen_full_path_at): New static function.
+ (faccessat): Implement.
+ (fchmodat): Implement.
+ (fchownat): Implement.
+ (fstatat): Implement.
+ (futimesat): Implement.
+ (linkat): Implement.
+ (mkdirat): Implement.
+ (mkfifoat): Implement.
+ (mknodat): Implement.
+ (openat): Implement.
+ (readlinkat): Implement.
+ (renameat): Implement.
+ (symlinkat): Implement.
+ (unlinkat): Implement.
+ * include/cygwin/version.h: Bump API minor number.
+
2008-04-22 Corinna Vinschen <corinna@vinschen.de>
* dcrt0.cc (dll_crt0_0): Move CWD initialization from here...
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din
index b1fbffe80..3b1aaf1d4 100644
--- a/winsup/cygwin/cygwin.din
+++ b/winsup/cygwin/cygwin.din
@@ -409,6 +409,7 @@ fabs NOSIGFE
_fabs = fabs NOSIGFE
fabsf NOSIGFE
_fabsf = fabsf NOSIGFE
+faccessat SIGFE
facl SIGFE
_facl = facl SIGFE
_facl32 = facl32 SIGFE
@@ -416,9 +417,11 @@ fchdir SIGFE
_fchdir = fchdir SIGFE
fchmod SIGFE
_fchmod = fchmod SIGFE
+fchmodat SIGFE
fchown SIGFE
_fchown = fchown SIGFE
_fchown32 = fchown32 SIGFE
+fchownat SIGFE
fclose SIGFE
_fclose = fclose SIGFE
fcloseall SIGFE
@@ -531,6 +534,7 @@ fsetxattr SIGFE
fstat SIGFE
_fstat = fstat SIGFE
_fstat64 = fstat64 SIGFE
+fstatat SIGFE
fstatfs SIGFE
_fstatfs = fstatfs SIGFE
fstatvfs SIGFE
@@ -561,6 +565,7 @@ ftw SIGFE
funlockfile SIGFE
funopen SIGFE
futimes SIGFE
+futimesat SIGFE
fwrite SIGFE
_fwrite = fwrite SIGFE
gai_strerror = cygwin_gai_strerror NOSIGFE
@@ -861,6 +866,7 @@ _lgammaf_r = lgammaf_r NOSIGFE
lgetxattr SIGFE
link SIGFE
_link = link SIGFE
+linkat SIGFE
listen = cygwin_listen SIGFE
listxattr SIGFE
llabs NOSIGFE
@@ -953,11 +959,14 @@ memset NOSIGFE
_memset = memset NOSIGFE
mkdir SIGFE
_mkdir = mkdir SIGFE
+mkdirat SIGFE
mkdtemp SIGFE
mkfifo SIGFE
+mkfifoat SIGFE
mknod SIGFE
_mknod = mknod SIGFE
_mknod32 = mknod32 SIGFE
+mknodat SIGFE
mkstemp SIGFE
_mkstemp = mkstemp SIGFE
mktemp SIGFE
@@ -1018,8 +1027,9 @@ _ntohs = ntohs NOSIGFE
on_exit SIGFE
open SIGFE
_open = open SIGFE
-open_memstream SIGFE
_open64
+open_memstream SIGFE
+openat SIGFE
opendir SIGFE
__opendir_with_d_ino SIGFE
openlog SIGFE
@@ -1172,6 +1182,7 @@ _readdir = readdir SIGFE
readdir_r SIGFE
readlink SIGFE
_readlink = readlink SIGFE
+readlinkat SIGFE
readv SIGFE
_readv = readv SIGFE
realloc SIGFE
@@ -1192,6 +1203,7 @@ remquo NOSIGFE
remquof NOSIGFE
rename SIGFE
_rename = rename SIGFE
+renameat SIGFE
res_close = __res_close SIGFE
__res_close SIGFE
res_init = __res_init SIGFE
@@ -1542,6 +1554,7 @@ __swbuf SIGFE
__swbuf_r SIGFE
symlink SIGFE
_symlink = symlink SIGFE
+symlinkat SIGFE
sync SIGFE
sysconf SIGFE
_sysconf = sysconf SIGFE
@@ -1633,6 +1646,7 @@ ungetc SIGFE
_ungetc = ungetc SIGFE
unlink SIGFE
_unlink = unlink SIGFE
+unlinkat SIGFE
unlockpt NOSIGFE
unsetenv SIGFE
_unsetenv = unsetenv SIGFE
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index 65902fcdf..007032a59 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -328,12 +328,15 @@ details. */
FIXME: Removed 12 year old and entirely wrong wprintf function at
this point. We need a working implementation soon.
183: Export open_memstream, fmemopen.
+ 184: Export openat, faccessat, fchmodat, fchownat, fstatat, futimesat,
+ linkat, mkdirat, mkfifoat, mknodat, readlinkat, renameat, symlinkat,
+ unlinkat.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 183
+#define CYGWIN_VERSION_API_MINOR 184
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 7c3bc04a5..2970c16b8 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -2519,8 +2519,8 @@ symlink_info::case_check (char *path)
/* readlink system call */
-extern "C" int
-readlink (const char *path, char *buf, int buflen)
+extern "C" ssize_t
+readlink (const char *path, char *buf, size_t buflen)
{
if (buflen < 0)
{
@@ -2550,7 +2550,7 @@ readlink (const char *path, char *buf, int buflen)
return -1;
}
- int len = min (buflen, (int) strlen (pathbuf.get_win32 ()));
+ ssize_t len = min (buflen, strlen (pathbuf.get_win32 ()));
memcpy (buf, pathbuf.get_win32 (), len);
/* errno set by symlink.check if error */
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 28533a58b..1a2572186 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -61,6 +61,7 @@ details. */
#include "cpuid.h"
#include "registry.h"
#include "environ.h"
+#include "tls_pbuf.h"
#undef _close
#undef _lseek
@@ -3490,3 +3491,278 @@ pclose (FILE *fp)
return status;
}
+
+/* Preliminary(?) implementation of the openat family of functions. */
+
+static int
+gen_full_path_at (char *path_ret, int dirfd, const char *pathname)
+{
+ if (!*pathname)
+ {
+ set_errno (ENOENT);
+ return -1;
+ }
+ if (strlen (pathname) >= PATH_MAX)
+ {
+ set_errno (ENAMETOOLONG);
+ return -1;
+ }
+ if (isdirsep (*pathname))
+ stpcpy (path_ret, pathname);
+ else
+ {
+ char *p;
+
+ if (dirfd == AT_FDCWD)
+ p = stpcpy (path_ret, cygheap->cwd.posix);
+ else
+ {
+ cygheap_fdget cfd (dirfd);
+ if (cfd < 0)
+ return -1;
+ if (!cfd->pc.isdir ())
+ {
+ set_errno (ENOTDIR);
+ return -1;
+ }
+ p = stpcpy (path_ret, cfd->get_name ());
+ }
+ if (!p)
+ {
+ set_errno (ENOTDIR);
+ return -1;
+ }
+ if (p[-1] != '/')
+ *p++ = '/';
+ stpcpy (p, pathname);
+ }
+ return 0;
+}
+
+extern "C" int
+openat (int dirfd, const char *pathname, int flags, ...)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+ tmp_pathbuf tp;
+ char *path = tp.c_get ();
+ if (gen_full_path_at (path, dirfd, pathname))
+ return -1;
+
+ va_list ap;
+ mode_t mode;
+
+ va_start (ap, flags);
+ mode = va_arg (ap, mode_t);
+ va_end (ap);
+ return open (path, flags, mode);
+}
+
+extern "C" int
+faccessat (int dirfd, const char *pathname, int mode, int flags)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+
+ int res = -1;
+ tmp_pathbuf tp;
+ char *path = tp.c_get ();
+ if (!gen_full_path_at (path, dirfd, pathname))
+ {
+ if (flags & ~(F_OK|R_OK|W_OK|X_OK))
+ set_errno (EINVAL);
+ else
+ {
+ fhandler_base *fh = build_fh_name (path, NULL,
+ (flags & AT_SYMLINK_NOFOLLOW)
+ ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW,
+ stat_suffixes);
+ if (fh)
+ {
+ res = fh->fhaccess (mode);
+ delete fh;
+ }
+ }
+ }
+ debug_printf ("returning %d", res);
+ return res;
+}
+
+extern "C" int
+fchmodat (int dirfd, const char *pathname, mode_t mode, int flags)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+ tmp_pathbuf tp;
+ char *path = tp.c_get ();
+ if (gen_full_path_at (path, dirfd, pathname))
+ return -1;
+ return chmod (path, mode);
+}
+
+extern "C" int
+fchownat (int dirfd, const char *pathname, __uid32_t uid, __gid32_t gid,
+ int flags)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+ tmp_pathbuf tp;
+ char *path = tp.c_get ();
+ if (gen_full_path_at (path, dirfd, pathname))
+ return -1;
+ return chown_worker (path, (flags & AT_SYMLINK_NOFOLLOW)
+ ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW, uid, gid);
+}
+
+extern "C" int
+fstatat (int dirfd, const char *pathname, struct __stat64 *st, int flags)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+ tmp_pathbuf tp;
+ char *path = tp.c_get ();
+ if (gen_full_path_at (path, dirfd, pathname))
+ return -1;
+ return (flags & AT_SYMLINK_NOFOLLOW) ? lstat64 (path, st) : stat64 (path, st);
+}
+
+extern "C" int
+futimesat (int dirfd, const char *pathname, const struct timeval *times)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+ tmp_pathbuf tp;
+ char *path = tp.c_get ();
+ if (gen_full_path_at (path, dirfd, pathname))
+ return -1;
+ return utimes (path, times);
+}
+
+extern "C" int
+linkat (int olddirfd, const char *oldpathname,
+ int newdirfd, const char *newpathname,
+ int flags)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+ tmp_pathbuf tp;
+ char *oldpath = tp.c_get ();
+ if (gen_full_path_at (oldpath, olddirfd, oldpathname))
+ return -1;
+ char *newpath = tp.c_get ();
+ if (gen_full_path_at (newpath, newdirfd, newpathname))
+ return -1;
+ if (flags & AT_SYMLINK_FOLLOW)
+ {
+ path_conv old_name (oldpath, PC_SYM_FOLLOW | PC_POSIX, stat_suffixes);
+ if (old_name.error)
+ {
+ set_errno (old_name.error);
+ return -1;
+ }
+ strcpy (oldpath, old_name.normalized_path);
+ }
+ return link (oldpath, newpath);
+}
+
+extern "C" int
+mkdirat (int dirfd, const char *pathname, mode_t mode)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+ tmp_pathbuf tp;
+ char *path = tp.c_get ();
+ if (gen_full_path_at (path, dirfd, pathname))
+ return -1;
+ return mkdir (path, mode);
+}
+
+extern "C" int
+mkfifoat (int dirfd, const char *pathname, mode_t mode)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+ tmp_pathbuf tp;
+ char *path = tp.c_get ();
+ if (gen_full_path_at (path, dirfd, pathname))
+ return -1;
+ return mkfifo (path, mode);
+}
+
+extern "C" int
+mknodat (int dirfd, const char *pathname, mode_t mode, __dev32_t dev)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+ tmp_pathbuf tp;
+ char *path = tp.c_get ();
+ if (gen_full_path_at (path, dirfd, pathname))
+ return -1;
+ return mknod32 (path, mode, dev);
+}
+
+extern "C" ssize_t
+readlinkat (int dirfd, const char *pathname, char *buf, size_t bufsize)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+ tmp_pathbuf tp;
+ char *path = tp.c_get ();
+ if (gen_full_path_at (path, dirfd, pathname))
+ return -1;
+ return readlink (path, buf, bufsize);
+}
+
+extern "C" int
+renameat (int olddirfd, const char *oldpathname,
+ int newdirfd, const char *newpathname)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+ tmp_pathbuf tp;
+ char *oldpath = tp.c_get ();
+ if (gen_full_path_at (oldpath, olddirfd, oldpathname))
+ return -1;
+ char *newpath = tp.c_get ();
+ if (gen_full_path_at (newpath, newdirfd, newpathname))
+ return -1;
+ return rename (oldpath, newpath);
+}
+
+extern "C" int
+symlinkat (const char *oldpath, int newdirfd, const char *newpathname)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+ tmp_pathbuf tp;
+ char *newpath = tp.c_get ();
+ if (gen_full_path_at (newpath, newdirfd, newpathname))
+ return -1;
+ return symlink (oldpath, newpath);
+}
+
+extern "C" int
+unlinkat (int dirfd, const char *pathname, int flags)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+ tmp_pathbuf tp;
+ char *path = tp.c_get ();
+ if (gen_full_path_at (path, dirfd, pathname))
+ return -1;
+ return (flags & AT_REMOVEDIR) ? rmdir (path) : unlink (path);
+}