Cygwin: open: support Linux-specific O_PATH flag

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2019-01-07 19:33:11 +01:00
parent 91ca95ae4a
commit b93022a82d
8 changed files with 74 additions and 4 deletions

View File

@ -35,6 +35,7 @@ extern "C" {
#if defined (__CYGWIN__) #if defined (__CYGWIN__)
#define _FTMPFILE 0x800000 #define _FTMPFILE 0x800000
#define _FNOATIME 0x1000000 #define _FNOATIME 0x1000000
#define _FPATH 0x2000000
#endif #endif
#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) #define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
@ -80,6 +81,7 @@ extern "C" {
#if __GNU_VISIBLE #if __GNU_VISIBLE
#define O_TMPFILE _FTMPFILE #define O_TMPFILE _FTMPFILE
#define O_NOATIME _FNOATIME #define O_NOATIME _FNOATIME
#define O_PATH _FPATH
#endif #endif
#endif #endif

View File

@ -549,6 +549,9 @@ fhandler_base::open (int flags, mode_t mode)
syscall_printf ("(%S, %y)", pc.get_nt_native_path (), flags); syscall_printf ("(%S, %y)", pc.get_nt_native_path (), flags);
if (flags & O_PATH)
query_open (query_read_attributes);
/* Allow to reopen from handle. This is utilized by /* Allow to reopen from handle. This is utilized by
open ("/proc/PID/fd/DESCRIPTOR", ...); */ open ("/proc/PID/fd/DESCRIPTOR", ...); */
if (get_handle ()) if (get_handle ())

View File

@ -32,6 +32,11 @@ ioctl (int fd, int cmd, ...)
debug_printf ("ioctl(fd %d, cmd %y)", fd, cmd); debug_printf ("ioctl(fd %d, cmd %y)", fd, cmd);
int res; int res;
if (cfd->get_flags () & O_PATH)
{
set_errno (EBADF);
return -1;
}
/* FIXME: This stinks. There are collisions between cmd types /* FIXME: This stinks. There are collisions between cmd types
depending on whether fd is associated with a pty master or not. depending on whether fd is associated with a pty master or not.
Something to fix for Cygwin2. CGF 2006-06-04 */ Something to fix for Cygwin2. CGF 2006-06-04 */

View File

@ -930,6 +930,11 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, off_t off)
cygheap_fdget cfd (fd); cygheap_fdget cfd (fd);
if (cfd < 0) if (cfd < 0)
goto out; goto out;
if (cfd->get_flags () & O_PATH)
{
set_errno (EBADF);
goto out;
}
fh = cfd; fh = cfd;

View File

@ -426,6 +426,11 @@ fgetxattr (int fd, const char *name, void *value, size_t size)
cygheap_fdget cfd (fd); cygheap_fdget cfd (fd);
if (cfd < 0) if (cfd < 0)
res = -1; res = -1;
else if (cfd->get_flags () & O_PATH)
{
set_errno (EBADF);
res = -1;
}
else else
res = cfd->fgetxattr (name, value, size); res = cfd->fgetxattr (name, value, size);
return res; return res;
@ -453,6 +458,11 @@ flistxattr (int fd, char *list, size_t size)
cygheap_fdget cfd (fd); cygheap_fdget cfd (fd);
if (cfd < 0) if (cfd < 0)
res = -1; res = -1;
else if (cfd->get_flags () & O_PATH)
{
set_errno (EBADF);
res = -1;
}
else else
res = cfd->fgetxattr (NULL, list, size); res = cfd->fgetxattr (NULL, list, size);
return res; return res;
@ -523,6 +533,11 @@ fsetxattr (int fd, const char *name, const void *value, size_t size, int flags)
cygheap_fdget cfd (fd); cygheap_fdget cfd (fd);
if (cfd < 0) if (cfd < 0)
res = -1; res = -1;
else if (cfd->get_flags () & O_PATH)
{
set_errno (EBADF);
res = -1;
}
else else
res = cfd->fsetxattr (name, value, size, flags); res = cfd->fsetxattr (name, value, size, flags);
return res; return res;
@ -550,6 +565,11 @@ fremovexattr (int fd, const char *name)
cygheap_fdget cfd (fd); cygheap_fdget cfd (fd);
if (cfd < 0) if (cfd < 0)
res = -1; res = -1;
else if (cfd->get_flags () & O_PATH)
{
set_errno (EBADF);
res = -1;
}
else else
res = cfd->fsetxattr (name, NULL, 0, 0); res = cfd->fsetxattr (name, NULL, 0, 0);
return res; return res;

View File

@ -20,6 +20,8 @@ What's new:
- Support for exFAT. - Support for exFAT.
- Support Linux-specific open(2) flag O_PATH.
What changed: What changed:
------------- -------------

View File

@ -1193,7 +1193,8 @@ read (int fd, void *ptr, size_t len)
if (cfd < 0) if (cfd < 0)
__leave; __leave;
if ((cfd->get_flags () & O_ACCMODE) == O_WRONLY) if ((cfd->get_flags () & O_PATH)
|| (cfd->get_flags () & O_ACCMODE) == O_WRONLY)
{ {
set_errno (EBADF); set_errno (EBADF);
__leave; __leave;
@ -1235,7 +1236,8 @@ readv (int fd, const struct iovec *const iov, const int iovcnt)
__leave; __leave;
} }
if ((cfd->get_flags () & O_ACCMODE) == O_WRONLY) if ((cfd->get_flags () & O_PATH)
|| (cfd->get_flags () & O_ACCMODE) == O_WRONLY)
{ {
set_errno (EBADF); set_errno (EBADF);
__leave; __leave;
@ -1263,6 +1265,11 @@ pread (int fd, void *ptr, size_t len, off_t off)
cygheap_fdget cfd (fd); cygheap_fdget cfd (fd);
if (cfd < 0) if (cfd < 0)
res = -1; res = -1;
else if (cfd->get_flags () & O_PATH)
{
set_errno (EBADF);
res = -1;
}
else else
res = cfd->pread (ptr, len, off); res = cfd->pread (ptr, len, off);
@ -1283,7 +1290,8 @@ write (int fd, const void *ptr, size_t len)
if (cfd < 0) if (cfd < 0)
__leave; __leave;
if ((cfd->get_flags () & O_ACCMODE) == O_RDONLY) if ((cfd->get_flags () & O_PATH)
|| (cfd->get_flags () & O_ACCMODE) == O_RDONLY)
{ {
set_errno (EBADF); set_errno (EBADF);
__leave; __leave;
@ -1326,7 +1334,8 @@ writev (const int fd, const struct iovec *const iov, const int iovcnt)
__leave; __leave;
} }
if ((cfd->get_flags () & O_ACCMODE) == O_RDONLY) if ((cfd->get_flags () & O_PATH)
|| (cfd->get_flags () & O_ACCMODE) == O_RDONLY)
{ {
set_errno (EBADF); set_errno (EBADF);
__leave; __leave;
@ -1358,6 +1367,11 @@ pwrite (int fd, void *ptr, size_t len, off_t off)
cygheap_fdget cfd (fd); cygheap_fdget cfd (fd);
if (cfd < 0) if (cfd < 0)
res = -1; res = -1;
else if (cfd->get_flags () & O_PATH)
{
set_errno (EBADF);
res = -1;
}
else else
res = cfd->pwrite (ptr, len, off); res = cfd->pwrite (ptr, len, off);
@ -1398,6 +1412,11 @@ open (const char *unix_path, int flags, ...)
if (fd < 0) if (fd < 0)
__leave; /* errno already set */ __leave; /* errno already set */
/* When O_PATH is specified in flags, flag bits other than O_CLOEXEC,
O_DIRECTORY, and O_NOFOLLOW are ignored. */
if (flags & O_PATH)
flags &= (O_PATH | O_CLOEXEC | O_DIRECTORY | O_NOFOLLOW);
int opt = PC_OPEN | PC_SYM_NOFOLLOW_PROCFD; int opt = PC_OPEN | PC_SYM_NOFOLLOW_PROCFD;
opt |= (flags & (O_NOFOLLOW | O_EXCL)) ? PC_SYM_NOFOLLOW opt |= (flags & (O_NOFOLLOW | O_EXCL)) ? PC_SYM_NOFOLLOW
: PC_SYM_FOLLOW; : PC_SYM_FOLLOW;
@ -1685,6 +1704,11 @@ fchown32 (int fd, uid_t uid, gid_t gid)
syscall_printf ("-1 = fchown (%d,...)", fd); syscall_printf ("-1 = fchown (%d,...)", fd);
return -1; return -1;
} }
else if (cfd->get_flags () & O_PATH)
{
set_errno (EBADF);
return -1;
}
int res = cfd->fchown (uid, gid); int res = cfd->fchown (uid, gid);
@ -1756,6 +1780,11 @@ fchmod (int fd, mode_t mode)
syscall_printf ("-1 = fchmod (%d, 0%o)", fd, mode); syscall_printf ("-1 = fchmod (%d, 0%o)", fd, mode);
return -1; return -1;
} }
else if (cfd->get_flags () & O_PATH)
{
set_errno (EBADF);
return -1;
}
return cfd->fchmod (FILTERED_MODE (mode)); return cfd->fchmod (FILTERED_MODE (mode));
} }

View File

@ -37,6 +37,10 @@ aforementioned new ioctl's on the command line.
Support for exFAT. Support for exFAT.
</para></listitem> </para></listitem>
<listitem><para>
Support Linux-specific open(2) flag O_PATH.
</para></listitem>
<listitem><para> <listitem><para>
clock_nanosleep, pthread_condattr_setclock and timer_create now support clock_nanosleep, pthread_condattr_setclock and timer_create now support
all clocks, except CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID. all clocks, except CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID.