mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-07 06:50:24 +08:00
Return unique inode numbers when calling stat/fstat on pipes and IP sockets
* fhandler.h (class fhandler_base): Convert unique_id to int64_t. (fhandler_base::set_ino): New protected inline method. (fhandler_base::get_unique_id): Convert to int64_t. (fhandler_base::set_unique_id): New inline method taking int64_t. (fhandler_pipe::fstat): Declare. (fhandler_pipe::init): Take extra parameter. (fhandler_pipe::create): Ditto. * fhandler_socket.cc (fhandler_socket::init_events): Set inode number to serial number. (fhandler_socket::fstat): Set device to DEV_TCP_MAJOR. Create st_ino from get_ino. * include/cygwin/signal.h (struct _sigcommune): Replace _si_pipe_fhandler with _si_pipe_unique_id. * pinfo.h (_pinfo::pipe_fhandler): Take unique id instead of HANDLE. * pinfo.cc (commune_process): Accommodate change to _si_pipe_unique_id. (_pinfo::commune_request): Ditto. (_pinfo::pipe_fhandler): Ditto. * pipe.cc (fhandler_pipe::init): Take unique id as argument and set inode number and unique_id from there. (fhandler_pipe::open): Rework to find any matching pipe from unique id in filename. (fhandler_pipe::get_proc_fd_name): Create filename using inode number. (fhandler_pipe::create): Generate and return unique id from process pid and pipe_unique_id. In outer method, call init with additional unique id as parameter. (fhandler_pipe::fstat): New method. (pipe_worker): Accommodate using 64 bit inode number in filename. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
20ddde2f55
commit
a10d969231
@ -182,8 +182,9 @@ class fhandler_base
|
|||||||
size_t rabuflen;
|
size_t rabuflen;
|
||||||
|
|
||||||
/* Used for advisory file locking. See flock.cc. */
|
/* Used for advisory file locking. See flock.cc. */
|
||||||
long long unique_id;
|
int64_t unique_id;
|
||||||
void del_my_locks (del_lock_called_from);
|
void del_my_locks (del_lock_called_from);
|
||||||
|
void set_ino (ino_t i) { ino = i; }
|
||||||
|
|
||||||
HANDLE read_state;
|
HANDLE read_state;
|
||||||
|
|
||||||
@ -304,7 +305,7 @@ class fhandler_base
|
|||||||
const char *get_win32_name () { return pc.get_win32 (); }
|
const char *get_win32_name () { return pc.get_win32 (); }
|
||||||
virtual dev_t get_dev () { return get_device (); }
|
virtual dev_t get_dev () { return get_device (); }
|
||||||
ino_t get_ino () { return ino ?: ino = hash_path_name (0, pc.get_nt_native_path ()); }
|
ino_t get_ino () { return ino ?: ino = hash_path_name (0, pc.get_nt_native_path ()); }
|
||||||
long long get_unique_id () const { return unique_id; }
|
int64_t get_unique_id () const { return unique_id; }
|
||||||
/* Returns name used for /proc/<pid>/fd in buf. */
|
/* Returns name used for /proc/<pid>/fd in buf. */
|
||||||
virtual char *get_proc_fd_name (char *buf);
|
virtual char *get_proc_fd_name (char *buf);
|
||||||
|
|
||||||
@ -319,6 +320,7 @@ class fhandler_base
|
|||||||
int open_null (int flags);
|
int open_null (int flags);
|
||||||
virtual int open (int, mode_t);
|
virtual int open (int, mode_t);
|
||||||
virtual void open_setup (int flags);
|
virtual void open_setup (int flags);
|
||||||
|
void set_unique_id (int64_t u) { unique_id = u; }
|
||||||
void set_unique_id () { NtAllocateLocallyUniqueId ((PLUID) &unique_id); }
|
void set_unique_id () { NtAllocateLocallyUniqueId ((PLUID) &unique_id); }
|
||||||
|
|
||||||
int close_with_arch ();
|
int close_with_arch ();
|
||||||
@ -731,13 +733,14 @@ public:
|
|||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
int dup (fhandler_base *child, int);
|
int dup (fhandler_base *child, int);
|
||||||
int ioctl (unsigned int cmd, void *);
|
int ioctl (unsigned int cmd, void *);
|
||||||
|
int __reg2 fstat (struct stat *buf);
|
||||||
int __reg2 fstatvfs (struct statvfs *buf);
|
int __reg2 fstatvfs (struct statvfs *buf);
|
||||||
int __reg3 fadvise (off_t, off_t, int);
|
int __reg3 fadvise (off_t, off_t, int);
|
||||||
int __reg3 ftruncate (off_t, bool);
|
int __reg3 ftruncate (off_t, bool);
|
||||||
int init (HANDLE, DWORD, mode_t);
|
int init (HANDLE, DWORD, mode_t, int64_t);
|
||||||
static int create (fhandler_pipe *[2], unsigned, int);
|
static int create (fhandler_pipe *[2], unsigned, int);
|
||||||
static DWORD create (LPSECURITY_ATTRIBUTES, HANDLE *, HANDLE *, DWORD,
|
static DWORD create (LPSECURITY_ATTRIBUTES, HANDLE *, HANDLE *, DWORD,
|
||||||
const char *, DWORD);
|
const char *, DWORD, int64_t *unique_id = NULL);
|
||||||
fhandler_pipe (void *) {}
|
fhandler_pipe (void *) {}
|
||||||
|
|
||||||
void copyto (fhandler_base *x)
|
void copyto (fhandler_base *x)
|
||||||
|
@ -594,6 +594,7 @@ fhandler_socket::init_events ()
|
|||||||
InterlockedIncrement (&socket_serial_number);
|
InterlockedIncrement (&socket_serial_number);
|
||||||
if (!new_serial_number) /* 0 is reserved for global mutex */
|
if (!new_serial_number) /* 0 is reserved for global mutex */
|
||||||
InterlockedIncrement (&socket_serial_number);
|
InterlockedIncrement (&socket_serial_number);
|
||||||
|
set_ino (new_serial_number);
|
||||||
RtlInitUnicodeString (&uname, sock_shared_name (name, new_serial_number));
|
RtlInitUnicodeString (&uname, sock_shared_name (name, new_serial_number));
|
||||||
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF,
|
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF,
|
||||||
get_session_parent_dir (),
|
get_session_parent_dir (),
|
||||||
@ -937,8 +938,8 @@ fhandler_socket::fstat (struct stat *buf)
|
|||||||
res = fhandler_base::fstat (buf);
|
res = fhandler_base::fstat (buf);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
buf->st_dev = 0;
|
buf->st_dev = FHDEV (DEV_TCP_MAJOR, 0);
|
||||||
buf->st_ino = (ino_t) ((uintptr_t) get_handle ());
|
buf->st_ino = (ino_t) get_ino ();
|
||||||
buf->st_mode = S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO;
|
buf->st_mode = S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO;
|
||||||
buf->st_size = 0;
|
buf->st_size = 0;
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ struct _sigcommune
|
|||||||
__extension__ union
|
__extension__ union
|
||||||
{
|
{
|
||||||
int _si_fd;
|
int _si_fd;
|
||||||
void *_si_pipe_fhandler;
|
int64_t _si_pipe_unique_id;
|
||||||
char *_si_str;
|
char *_si_str;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -622,11 +622,11 @@ commune_process (void *arg)
|
|||||||
case PICOM_PIPE_FHANDLER:
|
case PICOM_PIPE_FHANDLER:
|
||||||
{
|
{
|
||||||
sigproc_printf ("processing PICOM_FDS");
|
sigproc_printf ("processing PICOM_FDS");
|
||||||
HANDLE hdl = si._si_commune._si_pipe_fhandler;
|
int64_t unique_id = si._si_commune._si_pipe_unique_id;
|
||||||
unsigned int n = 0;
|
unsigned int n = 0;
|
||||||
cygheap_fdenum cfd;
|
cygheap_fdenum cfd;
|
||||||
while (cfd.next () >= 0)
|
while (cfd.next () >= 0)
|
||||||
if (cfd->get_handle () == hdl)
|
if (cfd->get_unique_id () == unique_id)
|
||||||
{
|
{
|
||||||
fhandler_pipe *fh = cfd;
|
fhandler_pipe *fh = cfd;
|
||||||
n = sizeof *fh;
|
n = sizeof *fh;
|
||||||
@ -701,7 +701,7 @@ _pinfo::commune_request (__uint32_t code, ...)
|
|||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case PICOM_PIPE_FHANDLER:
|
case PICOM_PIPE_FHANDLER:
|
||||||
si._si_commune._si_pipe_fhandler = va_arg (args, HANDLE);
|
si._si_commune._si_pipe_unique_id = va_arg (args, int64_t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICOM_FD:
|
case PICOM_FD:
|
||||||
@ -781,13 +781,13 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
fhandler_pipe *
|
fhandler_pipe *
|
||||||
_pinfo::pipe_fhandler (HANDLE hdl, size_t &n)
|
_pinfo::pipe_fhandler (int64_t unique_id, size_t &n)
|
||||||
{
|
{
|
||||||
if (!this || !pid)
|
if (!this || !pid)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (pid == myself->pid)
|
if (pid == myself->pid)
|
||||||
return NULL;
|
return NULL;
|
||||||
commune_result cr = commune_request (PICOM_PIPE_FHANDLER, hdl);
|
commune_result cr = commune_request (PICOM_PIPE_FHANDLER, unique_id);
|
||||||
n = cr.n;
|
n = cr.n;
|
||||||
return (fhandler_pipe *) cr.s;
|
return (fhandler_pipe *) cr.s;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ public:
|
|||||||
|
|
||||||
commune_result commune_request (__uint32_t, ...);
|
commune_result commune_request (__uint32_t, ...);
|
||||||
bool alive ();
|
bool alive ();
|
||||||
fhandler_pipe *pipe_fhandler (HANDLE, size_t &);
|
fhandler_pipe *pipe_fhandler (int64_t, size_t &);
|
||||||
char *fd (int fd, size_t &);
|
char *fd (int fd, size_t &);
|
||||||
char *fds (size_t &);
|
char *fds (size_t &);
|
||||||
char *root (size_t &);
|
char *root (size_t &);
|
||||||
|
@ -31,7 +31,7 @@ fhandler_pipe::fhandler_pipe ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode)
|
fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode, int64_t uniq_id)
|
||||||
{
|
{
|
||||||
/* FIXME: Have to clean this up someday
|
/* FIXME: Have to clean this up someday
|
||||||
FIXME: Do we have to check for both !get_win32_name() and
|
FIXME: Do we have to check for both !get_win32_name() and
|
||||||
@ -54,6 +54,8 @@ fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode)
|
|||||||
a &= ~FILE_CREATE_PIPE_INSTANCE;
|
a &= ~FILE_CREATE_PIPE_INSTANCE;
|
||||||
fhandler_base::init (f, a, mode);
|
fhandler_base::init (f, a, mode);
|
||||||
close_on_exec (mode & O_CLOEXEC);
|
close_on_exec (mode & O_CLOEXEC);
|
||||||
|
set_ino (uniq_id);
|
||||||
|
set_unique_id (uniq_id | !!(mode & GENERIC_WRITE));
|
||||||
if (opened_properly)
|
if (opened_properly)
|
||||||
setup_overlapped ();
|
setup_overlapped ();
|
||||||
else
|
else
|
||||||
@ -66,27 +68,33 @@ extern "C" int sscanf (const char *, const char *, ...);
|
|||||||
int
|
int
|
||||||
fhandler_pipe::open (int flags, mode_t mode)
|
fhandler_pipe::open (int flags, mode_t mode)
|
||||||
{
|
{
|
||||||
HANDLE proc, pipe_hdl, nio_hdl = NULL;
|
HANDLE proc, nio_hdl = NULL;
|
||||||
fhandler_pipe *fh = NULL;
|
int64_t uniq_id;
|
||||||
|
fhandler_pipe *fh = NULL, *fhr = NULL, *fhw = NULL;
|
||||||
size_t size;
|
size_t size;
|
||||||
int pid, rwflags = (flags & O_ACCMODE);
|
int pid, rwflags = (flags & O_ACCMODE);
|
||||||
bool inh;
|
bool inh;
|
||||||
|
bool got_one = false;
|
||||||
|
|
||||||
sscanf (get_name (), "/proc/%d/fd/pipe:[%lu]",
|
sscanf (get_name (), "/proc/%d/fd/pipe:[%lld]",
|
||||||
&pid, (unsigned long *) &pipe_hdl);
|
&pid, (long long *) &uniq_id);
|
||||||
if (pid == myself->pid)
|
if (pid == myself->pid)
|
||||||
{
|
{
|
||||||
cygheap_fdenum cfd (true);
|
cygheap_fdenum cfd (true);
|
||||||
while (cfd.next () >= 0)
|
while (cfd.next () >= 0)
|
||||||
{
|
{
|
||||||
if (cfd->get_handle () != pipe_hdl)
|
/* Windows doesn't allow to copy a pipe HANDLE with another access
|
||||||
|
mode. So we check for read and write side of pipe and try to
|
||||||
|
find the one matching the requested access mode. */
|
||||||
|
if (cfd->get_unique_id () == uniq_id)
|
||||||
|
got_one = true;
|
||||||
|
else if (cfd->get_unique_id () == uniq_id + 1)
|
||||||
|
got_one = true;
|
||||||
|
else
|
||||||
continue;
|
continue;
|
||||||
if ((rwflags == O_RDONLY && !(cfd->get_access () & GENERIC_READ))
|
if ((rwflags == O_RDONLY && !(cfd->get_access () & GENERIC_READ))
|
||||||
|| (rwflags == O_WRONLY && !(cfd->get_access () & GENERIC_WRITE)))
|
|| (rwflags == O_WRONLY && !(cfd->get_access () & GENERIC_WRITE)))
|
||||||
{
|
continue;
|
||||||
set_errno (EACCES);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
cfd->copyto (this);
|
cfd->copyto (this);
|
||||||
set_io_handle (NULL);
|
set_io_handle (NULL);
|
||||||
pc.reset_conv_handle ();
|
pc.reset_conv_handle ();
|
||||||
@ -94,7 +102,9 @@ fhandler_pipe::open (int flags, mode_t mode)
|
|||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
set_errno (ENOENT);
|
/* Found the pipe but access mode didn't match? EACCES.
|
||||||
|
Otherwise ENOENT */
|
||||||
|
set_errno (got_one ? EACCES : ENOENT);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,27 +119,30 @@ fhandler_pipe::open (int flags, mode_t mode)
|
|||||||
__seterrno ();
|
__seterrno ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!(fh = p->pipe_fhandler (pipe_hdl, size)) || !size)
|
fhr = p->pipe_fhandler (uniq_id, size);
|
||||||
|
if (fhr && rwflags == O_RDONLY)
|
||||||
|
fh = fhr;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
set_errno (ENOENT);
|
fhw = p->pipe_fhandler (uniq_id + 1, size);
|
||||||
goto out;
|
if (fhw && rwflags == O_WRONLY)
|
||||||
|
fh = fhw;
|
||||||
}
|
}
|
||||||
/* Too bad, but Windows only allows the same access mode when dup'ing
|
if (!fh)
|
||||||
the pipe. */
|
|
||||||
if ((rwflags == O_RDONLY && !(fh->get_access () & GENERIC_READ))
|
|
||||||
|| (rwflags == O_WRONLY && !(fh->get_access () & GENERIC_WRITE)))
|
|
||||||
{
|
{
|
||||||
set_errno (EACCES);
|
/* Too bad, but Windows only allows the same access mode when dup'ing
|
||||||
|
the pipe. */
|
||||||
|
set_errno (fhr || fhw ? EACCES : ENOENT);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
inh = !(flags & O_CLOEXEC);
|
inh = !(flags & O_CLOEXEC);
|
||||||
if (!DuplicateHandle (proc, pipe_hdl, GetCurrentProcess (), &nio_hdl,
|
if (!DuplicateHandle (proc, fh->get_handle (), GetCurrentProcess (),
|
||||||
0, inh, DUPLICATE_SAME_ACCESS))
|
&nio_hdl, 0, inh, DUPLICATE_SAME_ACCESS))
|
||||||
{
|
{
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
init (nio_hdl, fh->get_access (), mode & O_TEXT ?: O_BINARY);
|
init (nio_hdl, fh->get_access (), mode & O_TEXT ?: O_BINARY, fh->get_ino ());
|
||||||
cfree (fh);
|
cfree (fh);
|
||||||
CloseHandle (proc);
|
CloseHandle (proc);
|
||||||
return 1;
|
return 1;
|
||||||
@ -168,7 +181,7 @@ fhandler_pipe::ftruncate (off_t length, bool allow_truncate)
|
|||||||
char *
|
char *
|
||||||
fhandler_pipe::get_proc_fd_name (char *buf)
|
fhandler_pipe::get_proc_fd_name (char *buf)
|
||||||
{
|
{
|
||||||
__small_sprintf (buf, "pipe:[%lu]", get_handle ());
|
__small_sprintf (buf, "pipe:[%D]", get_ino ());
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +212,8 @@ fhandler_pipe::dup (fhandler_base *child, int flags)
|
|||||||
unlike CreatePipe, which returns a bool for success or failure. */
|
unlike CreatePipe, which returns a bool for success or failure. */
|
||||||
DWORD
|
DWORD
|
||||||
fhandler_pipe::create (LPSECURITY_ATTRIBUTES sa_ptr, PHANDLE r, PHANDLE w,
|
fhandler_pipe::create (LPSECURITY_ATTRIBUTES sa_ptr, PHANDLE r, PHANDLE w,
|
||||||
DWORD psize, const char *name, DWORD open_mode)
|
DWORD psize, const char *name, DWORD open_mode,
|
||||||
|
int64_t *unique_id)
|
||||||
{
|
{
|
||||||
/* Default to error. */
|
/* Default to error. */
|
||||||
if (r)
|
if (r)
|
||||||
@ -241,8 +255,12 @@ fhandler_pipe::create (LPSECURITY_ATTRIBUTES sa_ptr, PHANDLE r, PHANDLE w,
|
|||||||
{
|
{
|
||||||
static volatile ULONG pipe_unique_id;
|
static volatile ULONG pipe_unique_id;
|
||||||
if (!name)
|
if (!name)
|
||||||
__small_sprintf (pipename + len, "pipe-%p",
|
{
|
||||||
InterlockedIncrement ((LONG *) &pipe_unique_id));
|
LONG id = InterlockedIncrement ((LONG *) &pipe_unique_id);
|
||||||
|
__small_sprintf (pipename + len, "pipe-%p", id);
|
||||||
|
if (unique_id)
|
||||||
|
*unique_id = ((int64_t) id << 32 | GetCurrentProcessId ());
|
||||||
|
}
|
||||||
|
|
||||||
debug_printf ("name %s, size %u, mode %s", pipename, psize,
|
debug_printf ("name %s, size %u, mode %s", pipename, psize,
|
||||||
(pipe_mode & PIPE_TYPE_MESSAGE)
|
(pipe_mode & PIPE_TYPE_MESSAGE)
|
||||||
@ -341,8 +359,9 @@ fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode)
|
|||||||
HANDLE r, w;
|
HANDLE r, w;
|
||||||
SECURITY_ATTRIBUTES *sa = sec_none_cloexec (mode);
|
SECURITY_ATTRIBUTES *sa = sec_none_cloexec (mode);
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
int64_t unique_id;
|
||||||
|
|
||||||
int ret = create (sa, &r, &w, psize, NULL, FILE_FLAG_OVERLAPPED);
|
int ret = create (sa, &r, &w, psize, NULL, FILE_FLAG_OVERLAPPED, &unique_id);
|
||||||
if (ret)
|
if (ret)
|
||||||
__seterrno_from_win_error (ret);
|
__seterrno_from_win_error (ret);
|
||||||
else if ((fhs[0] = (fhandler_pipe *) build_fh_dev (*piper_dev)) == NULL)
|
else if ((fhs[0] = (fhandler_pipe *) build_fh_dev (*piper_dev)) == NULL)
|
||||||
@ -358,8 +377,10 @@ fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
mode |= mode & O_TEXT ?: O_BINARY;
|
mode |= mode & O_TEXT ?: O_BINARY;
|
||||||
fhs[0]->init (r, FILE_CREATE_PIPE_INSTANCE | GENERIC_READ, mode);
|
fhs[0]->init (r, FILE_CREATE_PIPE_INSTANCE | GENERIC_READ, mode,
|
||||||
fhs[1]->init (w, FILE_CREATE_PIPE_INSTANCE | GENERIC_WRITE, mode);
|
unique_id);
|
||||||
|
fhs[1]->init (w, FILE_CREATE_PIPE_INSTANCE | GENERIC_WRITE, mode,
|
||||||
|
unique_id);
|
||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,6 +415,21 @@ fhandler_pipe::ioctl (unsigned int cmd, void *p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __reg2
|
||||||
|
fhandler_pipe::fstat (struct stat *buf)
|
||||||
|
{
|
||||||
|
int ret = fhandler_base::fstat (buf);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
buf->st_dev = FH_PIPE;
|
||||||
|
/* Don't use get_ino, it doesn't return 0 but a hash instead. */
|
||||||
|
if (!(buf->st_ino = get_unique_id ()))
|
||||||
|
sscanf (get_name (), "/proc/%*d/fd/pipe:[%lld]",
|
||||||
|
(long long *) &buf->st_ino);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_pipe::fstatvfs (struct statvfs *sfs)
|
fhandler_pipe::fstatvfs (struct statvfs *sfs)
|
||||||
{
|
{
|
||||||
@ -410,10 +446,10 @@ pipe_worker (int filedes[2], unsigned int psize, int mode)
|
|||||||
{
|
{
|
||||||
cygheap_fdnew fdin;
|
cygheap_fdnew fdin;
|
||||||
cygheap_fdnew fdout (fdin, false);
|
cygheap_fdnew fdout (fdin, false);
|
||||||
char buf[sizeof ("/dev/fd/pipe:[2147483647]")];
|
char buf[sizeof ("/dev/fd/pipe:[9223372036854775807]")];
|
||||||
__small_sprintf (buf, "/dev/fd/pipe:[%d]", (int) fdin);
|
__small_sprintf (buf, "/dev/fd/pipe:[%D]", fhs[0]->get_ino ());
|
||||||
fhs[0]->pc.set_posix (buf);
|
fhs[0]->pc.set_posix (buf);
|
||||||
__small_sprintf (buf, "pipe:[%d]", (int) fdout);
|
__small_sprintf (buf, "pipe:[%D]", fhs[1]->get_ino ());
|
||||||
fhs[1]->pc.set_posix (buf);
|
fhs[1]->pc.set_posix (buf);
|
||||||
fdin = fhs[0];
|
fdin = fhs[0];
|
||||||
fdout = fhs[1];
|
fdout = fhs[1];
|
||||||
|
@ -81,3 +81,6 @@ Bug Fixes
|
|||||||
- *Always* zero out descriptor arrays when returning from select due to
|
- *Always* zero out descriptor arrays when returning from select due to
|
||||||
timeout, per POSIX.
|
timeout, per POSIX.
|
||||||
Addresses: https://cygwin.com/ml/cygwin/2015-12/msg00332.html
|
Addresses: https://cygwin.com/ml/cygwin/2015-12/msg00332.html
|
||||||
|
|
||||||
|
- Return unique inode numbers when calling stat/fstat on pipes and IP sockets.
|
||||||
|
Addresses: https://cygwin.com/ml/cygwin/2015-12/msg00310.html
|
||||||
|
Loading…
x
Reference in New Issue
Block a user