diff options
-rw-r--r-- | winsup/cygwin/ChangeLog | 35 | ||||
-rw-r--r-- | winsup/cygwin/cygwin.din | 16 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/version.h | 5 | ||||
-rw-r--r-- | winsup/cygwin/path.cc | 6 | ||||
-rw-r--r-- | winsup/cygwin/syscalls.cc | 276 |
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); +} |