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
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/fhandler.h2
-rw-r--r--winsup/cygwin/fhandler_process_fd.cc18
-rw-r--r--winsup/cygwin/include/cygwin/signal.h5
-rw-r--r--winsup/cygwin/path.h5
-rw-r--r--winsup/cygwin/pinfo.cc11
-rw-r--r--winsup/cygwin/pinfo.h2
6 files changed, 31 insertions, 12 deletions
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index e32c219d3..d02b9a913 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2578,7 +2578,7 @@ class fhandler_process: public fhandler_proc
class fhandler_process_fd : public fhandler_process
{
- fhandler_base *fetch_fh (HANDLE &);
+ fhandler_base *fetch_fh (HANDLE &, uint32_t);
public:
fhandler_process_fd () : fhandler_process () {}
diff --git a/winsup/cygwin/fhandler_process_fd.cc b/winsup/cygwin/fhandler_process_fd.cc
index 06d37c0e6..0c0452ab4 100644
--- a/winsup/cygwin/fhandler_process_fd.cc
+++ b/winsup/cygwin/fhandler_process_fd.cc
@@ -29,7 +29,7 @@ details. */
fhandler_base *
-fhandler_process_fd::fetch_fh (HANDLE &out_hdl)
+fhandler_process_fd::fetch_fh (HANDLE &out_hdl, uint32_t flags)
{
const char *path;
char *e;
@@ -49,6 +49,12 @@ fhandler_process_fd::fetch_fh (HANDLE &out_hdl)
cygheap_fdget cfd (fd, true);
if (cfd < 0)
return NULL;
+ if ((flags & FFH_LINKAT)
+ && (cfd->get_flags () & (O_TMPFILE | O_EXCL)) == (O_TMPFILE | O_EXCL))
+ {
+ set_errno (ENOENT);
+ return NULL;
+ }
proc = GetCurrentProcess ();
pc << cfd->pc;
hdl = cfd->get_handle ();
@@ -68,10 +74,10 @@ fhandler_process_fd::fetch_fh (HANDLE &out_hdl)
return NULL;
}
size_t size;
- void *buf = p->file_pathconv (fd, size);
+ void *buf = p->file_pathconv (fd, FFH_LINKAT, size);
if (size == 0)
{
- set_errno (EPERM);
+ set_errno (ENOENT);
CloseHandle (proc);
return NULL;
}
@@ -103,7 +109,7 @@ fhandler_process_fd::fd_reopen (int flags)
fhandler_base *fh;
HANDLE hdl;
- fh = fetch_fh (hdl);
+ fh = fetch_fh (hdl, 0);
if (!fh)
return NULL;
fh->set_io_handle (hdl);
@@ -126,7 +132,7 @@ fhandler_process_fd::fstat (struct stat *statbuf)
fhandler_base *fh;
HANDLE hdl;
- fh = fetch_fh (hdl);
+ fh = fetch_fh (hdl, 0);
if (!fh)
return -1;
fh->set_io_handle (hdl);
@@ -142,7 +148,7 @@ fhandler_process_fd::link (const char *newpath)
fhandler_base *fh;
HANDLE hdl;
- fh = fetch_fh (hdl);
+ fh = fetch_fh (hdl, FFH_LINKAT);
if (!fh)
return -1;
fh->set_io_handle (hdl);
diff --git a/winsup/cygwin/include/cygwin/signal.h b/winsup/cygwin/include/cygwin/signal.h
index 9d9972740..e659d7ae0 100644
--- a/winsup/cygwin/include/cygwin/signal.h
+++ b/winsup/cygwin/include/cygwin/signal.h
@@ -187,7 +187,10 @@ struct _sigcommune
void *_si_process_handle;
__extension__ union
{
- int _si_fd;
+ struct {
+ int _si_fd;
+ uint32_t _si_flags;
+ };
int64_t _si_pipe_unique_id;
char *_si_str;
};
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index af10321c5..2b885045d 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -73,6 +73,11 @@ enum path_types
PATH_DONT_USE = _BIT (31) /* conversion to signed happens. */
};
+enum fetch_fh_flags
+{
+ FFH_LINKAT = (1 << 0),
+};
+
NTSTATUS file_get_fai (HANDLE, PFILE_ALL_INFORMATION);
int check_reparse_point_target (HANDLE, bool, PREPARSE_DATA_BUFFER,
PUNICODE_STRING);
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 00b3ed623..90dfd2b7c 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -660,9 +660,13 @@ commune_process (void *arg)
{
sigproc_printf ("processing PICOM_FILE_PATHCONV");
int fd = si._si_commune._si_fd;
+ uint32_t flags = si._si_commune._si_flags;
unsigned int n = 0;
cygheap_fdget cfd (fd);
- if (cfd >= 0)
+ if (cfd >= 0
+ && (!(flags & FFH_LINKAT)
+ || (cfd->get_flags () & (O_TMPFILE | O_EXCL))
+ != (O_TMPFILE | O_EXCL)))
{
fhandler_base *fh = cfd;
void *ser_buf = fh->pc.serialize (fh->get_handle (), n);
@@ -763,6 +767,7 @@ _pinfo::commune_request (__uint32_t code, ...)
case PICOM_FD:
case PICOM_FILE_PATHCONV:
si._si_commune._si_fd = va_arg (args, int);
+ si._si_commune._si_flags = va_arg (args, uint32_t);
break;
break;
@@ -852,13 +857,13 @@ _pinfo::pipe_fhandler (int64_t unique_id, size_t &n)
}
void *
-_pinfo::file_pathconv (int fd, size_t &n)
+_pinfo::file_pathconv (int fd, uint32_t flags, size_t &n)
{
if (!pid)
return NULL;
if (pid == myself->pid)
return NULL;
- commune_result cr = commune_request (PICOM_FILE_PATHCONV, fd);
+ commune_result cr = commune_request (PICOM_FILE_PATHCONV, fd, flags);
n = cr.n;
return (void *) cr.s;
}
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index 8eb3c43ea..c4881c7f8 100644
--- a/winsup/cygwin/pinfo.h
+++ b/winsup/cygwin/pinfo.h
@@ -103,7 +103,7 @@ public:
commune_result commune_request (__uint32_t, ...);
bool alive ();
fhandler_pipe *pipe_fhandler (int64_t, size_t &);
- void *file_pathconv (int, size_t &);
+ void *file_pathconv (int, uint32_t, size_t &);
char *fd (int fd, size_t &);
char *fds (size_t &);
char *root (size_t &);