From 4f27e288c55cd54a2759a59d06a52ed44dac494b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 31 Jan 2005 10:28:55 +0000 Subject: [PATCH] * cygheap.h (class cygheap_fdenum): New class to enumerate used fhandlers. * dtable.h (class dtable): Add cygheap_fdenum as friend class. * fhandler.h (fhandler_base::get_proc_fd_name): New virtual method to return a name for /proc//fd. (fhandler_socket::get_proc_fd_name): Ditto. (fhandler_pipe::get_proc_fd_name): Ditto. (fhandler_virtual::opendir): Make virtual method. (fhandler_process::opendir): New method. * fhandler.cc (fhandler_base::get_proc_fd_name): New method. * fhandler_process.cc: Include ctype.h. (PROCESS_FD): Define. (process_listing): Add "fd". (fhandler_process::exists): Fix comment. Return 1 in case of "fd" directory. Handle files below "fd". (fhandler_process::fstat): Drop "self" handling. Set correct link count for directories. (fhandler_process::opendir): New method to handle "fd" directory. (fhandler_process::readdir): Add "fd" handling. (fhandler_process::open): Drop "self" handling. (fhandler_process::fill_filebuf): Ditto. Add "fd" handling. Fix "maps" output string. * fhandler_registry.cc (fhandler_registry::fstat): Set correct link count for directories. * fhandler_socket.cc (fhandler_socket::get_proc_fd_name): New method. * path.cc (symlink_info::set): Fix thinko. * pinfo.cc (_pinfo::commune_recv): Rename pathbuf to path throughout. Drop local path variable in PICOM_FIFO case. Fix debug output. Close handles as early as possible. Add PICOM_FDS and PICOM_FD handling. (_pinfo::commune_send): Add PICOM_FDS and PICOM_FD handling. (_pinfo::fd): New method. (_pinfo::fds): New method. * pinfo.h (enum picom): Add PICOM_FDS and PICOM_FD. (_pinfo::fd): Declare. (_pinfo::fds): Declare. * pipe.cc (fhandler_pipe::get_proc_fd_name): New method. --- winsup/cygwin/ChangeLog | 40 +++++++++ winsup/cygwin/cygheap.h | 23 +++++ winsup/cygwin/dtable.h | 1 + winsup/cygwin/fhandler.cc | 10 +++ winsup/cygwin/fhandler.h | 7 +- winsup/cygwin/fhandler_process.cc | 112 +++++++++++++++++------- winsup/cygwin/fhandler_registry.cc | 2 +- winsup/cygwin/fhandler_socket.cc | 9 ++ winsup/cygwin/path.cc | 16 +--- winsup/cygwin/pinfo.cc | 133 ++++++++++++++++++++++++++--- winsup/cygwin/pinfo.h | 6 +- winsup/cygwin/pipe.cc | 6 ++ 12 files changed, 307 insertions(+), 58 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index ff4b3bd59..0f390e4cc 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,43 @@ +2005-01-31 Corinna Vinschen + + * cygheap.h (class cygheap_fdenum): New class to enumerate used + fhandlers. + * dtable.h (class dtable): Add cygheap_fdenum as friend class. + * fhandler.h (fhandler_base::get_proc_fd_name): New virtual method + to return a name for /proc//fd. + (fhandler_socket::get_proc_fd_name): Ditto. + (fhandler_pipe::get_proc_fd_name): Ditto. + (fhandler_virtual::opendir): Make virtual method. + (fhandler_process::opendir): New method. + * fhandler.cc (fhandler_base::get_proc_fd_name): New method. + * fhandler_process.cc: Include ctype.h. + (PROCESS_FD): Define. + (process_listing): Add "fd". + (fhandler_process::exists): Fix comment. Return 1 in case of "fd" + directory. Handle files below "fd". + (fhandler_process::fstat): Drop "self" handling. Set correct link + count for directories. + (fhandler_process::opendir): New method to handle "fd" directory. + (fhandler_process::readdir): Add "fd" handling. + (fhandler_process::open): Drop "self" handling. + (fhandler_process::fill_filebuf): Ditto. Add "fd" handling. Fix + "maps" output string. + * fhandler_registry.cc (fhandler_registry::fstat): Set correct link + count for directories. + * fhandler_socket.cc (fhandler_socket::get_proc_fd_name): New method. + * path.cc (symlink_info::set): Fix thinko. + * pinfo.cc (_pinfo::commune_recv): Rename pathbuf to path throughout. + Drop local path variable in PICOM_FIFO case. Fix debug output. + Close handles as early as possible. Add PICOM_FDS and PICOM_FD + handling. + (_pinfo::commune_send): Add PICOM_FDS and PICOM_FD handling. + (_pinfo::fd): New method. + (_pinfo::fds): New method. + * pinfo.h (enum picom): Add PICOM_FDS and PICOM_FD. + (_pinfo::fd): Declare. + (_pinfo::fds): Declare. + * pipe.cc (fhandler_pipe::get_proc_fd_name): New method. + 2005-01-29 Corinna Vinschen * smallprint.c (rn): Change uval to unsigned long long to fix 64 bit diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index d3baae329..43723244d 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -384,6 +384,29 @@ class cygheap_fdget : public cygheap_fdmanip } }; +class cygheap_fdenum : public cygheap_fdmanip +{ + int start_fd; + public: + cygheap_fdenum (int start_fd = -1, bool lockit = false) + { + if (lockit) + cygheap->fdtab.lock (); + this->start_fd = fd = start_fd < 0 ? -1 : start_fd; + } + int next () + { + while (++fd < (int) cygheap->fdtab.size) + if (*(fh = cygheap->fdtab + fd) != NULL) + return fd; + return -1; + } + void rewind () + { + fd = start_fd; + } +}; + class child_info; void *__stdcall cygheap_setup_for_child (child_info *ci, bool dup_later) __attribute__ ((regparm(2))); void __stdcall cygheap_setup_for_child_cleanup (void *, child_info *, bool) __attribute__ ((regparm(3))); diff --git a/winsup/cygwin/dtable.h b/winsup/cygwin/dtable.h index 0c6153aae..f7ae7740f 100644 --- a/winsup/cygwin/dtable.h +++ b/winsup/cygwin/dtable.h @@ -88,6 +88,7 @@ public: friend class cygheap_fdmanip; friend class cygheap_fdget; friend class cygheap_fdnew; + friend class cygheap_fdenum; }; fhandler_base *build_fh_dev (const device&, const char * = NULL); diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 4438a5d2c..ba539a33e 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -154,6 +154,16 @@ fhandler_base::set_name (path_conv &in_pc) pc.set_normalized_path (in_pc.normalized_path, false); } +char *fhandler_base::get_proc_fd_name (char *buf) +{ + if (get_name ()) + return strcpy (buf, get_name ()); + if (dev ().name) + return strcpy (buf, dev ().name); + __small_sprintf (buf, "device:[%d:%d]", get_major (), get_minor ()); + return buf; +} + /* Detect if we are sitting at EOF for conditions where Windows returns an error but UNIX doesn't. */ static int __stdcall diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index f1041c68c..3879e067e 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -218,6 +218,8 @@ class fhandler_base const char *get_name () const { return pc.normalized_path; } const char *get_win32_name () { return pc.get_win32 (); } __ino64_t get_namehash () { return namehash ?: namehash = hash_path_name (0, get_win32_name ()); } + /* Returns name used for /proc//fd in buf. */ + virtual char *get_proc_fd_name (char *buf); virtual void hclose (HANDLE h) {CloseHandle (h);} virtual void set_no_inheritance (HANDLE &h, int not_inheriting); @@ -398,6 +400,7 @@ class fhandler_socket: public fhandler_base void fixup_after_fork (HANDLE); void fixup_after_exec (); bool need_fixup_before () const {return true;} + char *get_proc_fd_name (char *buf); select_record *select_read (select_record *s); select_record *select_write (select_record *s); @@ -432,6 +435,7 @@ public: select_record *select_read (select_record *s); select_record *select_write (select_record *s); select_record *select_except (select_record *s); + char *get_proc_fd_name (char *buf); void set_close_on_exec (bool val); void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); int close (); @@ -1105,7 +1109,7 @@ class fhandler_virtual : public fhandler_base virtual ~fhandler_virtual(); virtual int exists(); - DIR *opendir (); + virtual DIR *opendir (); _off64_t telldir (DIR *); void seekdir (DIR *, _off64_t); void rewinddir (DIR *); @@ -1164,6 +1168,7 @@ class fhandler_process: public fhandler_proc public: fhandler_process (); int exists(); + DIR *opendir (); struct dirent *readdir (DIR *); int open (int flags, mode_t mode = 0); int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 0115a4eb2..fda7e52a1 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -25,6 +25,7 @@ details. */ #include #include #include +#include #include #define _COMPILING_NEWLIB @@ -43,10 +44,11 @@ static const int PROCESS_STAT = 11; static const int PROCESS_STATM = 12; static const int PROCESS_CMDLINE = 13; static const int PROCESS_MAPS = 14; +static const int PROCESS_FD = 15; /* Keep symlinks always the last entries. */ -static const int PROCESS_ROOT = 15; -static const int PROCESS_EXE = 16; -static const int PROCESS_CWD = 17; +static const int PROCESS_ROOT = 16; +static const int PROCESS_EXE = 17; +static const int PROCESS_CWD = 18; /* The position of "root" defines the beginning of symlik entries. */ #define is_symlink(nr) ((nr) >= PROCESS_ROOT) @@ -68,6 +70,7 @@ static const char * const process_listing[] = "statm", "cmdline", "maps", + "fd", /* Keep symlinks always the last entries. */ "root", "exe", @@ -89,7 +92,7 @@ static bool get_mem_values (DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmshare); /* Returns 0 if path doesn't exist, >0 if path is a directory, - * <0 if path is a file. + * -1 if path is a file, -2 if path is a symlink. */ int fhandler_process::exists () @@ -106,8 +109,14 @@ fhandler_process::exists () if (pathmatch (path + 1, process_listing[i])) { fileid = i; - return is_symlink (i) ? -2 : -1; + return is_symlink (i) ? -2 : (i == PROCESS_FD) ? 1 : -1; } + if (pathnmatch (strchr (path, '/') + 1, "fd/", 3)) + { + fileid = PROCESS_FD; + if (fill_filebuf ()) + return -2; + } return 0; } @@ -123,10 +132,7 @@ fhandler_process::fstat (struct __stat64 *buf) int file_type = exists (); (void) fhandler_base::fstat (buf); path += proc_len + 1; - if (path_prefix_p ("self", path, 4)) - pid = getpid (); - else - pid = atoi (path); + pid = atoi (path); pinfo p (pid); if (!p) { @@ -142,8 +148,6 @@ fhandler_process::fstat (struct __stat64 *buf) set_errno (ENOENT); return -1; case 1: - buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; - return 0; case 2: buf->st_ctime = buf->st_mtime = p->start_time; buf->st_ctim.tv_nsec = buf->st_mtim.tv_nsec = 0; @@ -151,7 +155,10 @@ fhandler_process::fstat (struct __stat64 *buf) buf->st_uid = p->uid; buf->st_gid = p->gid; buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; - buf->st_nlink = PROCESS_LINK_COUNT; + if (file_type == 1) + buf->st_nlink = 2; + else + buf->st_nlink = 3; return 0; case -2: buf->st_uid = p->uid; @@ -167,14 +174,38 @@ fhandler_process::fstat (struct __stat64 *buf) } } +DIR * +fhandler_process::opendir () +{ + DIR *dir = fhandler_virtual::opendir (); + if (dir && fileid == PROCESS_FD) + fill_filebuf (); + return dir; +} + struct dirent * fhandler_process::readdir (DIR * dir) { - if (dir->__d_position >= PROCESS_LINK_COUNT) + if (fileid == PROCESS_FD) + { + if (dir->__d_position >= 2 + filesize / sizeof (int)) + return NULL; + } + else if (dir->__d_position >= PROCESS_LINK_COUNT) return NULL; - strcpy (dir->__d_dirent->d_name, process_listing[dir->__d_position++]); - syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir, - dir->__d_dirent->d_name); + if (fileid == PROCESS_FD && dir->__d_position > 1) + { + int *p = (int *) filebuf; + __small_sprintf (dir->__d_dirent->d_name, "%d", p[dir->__d_position++ - 2]); + syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir, + dir->__d_dirent->d_name); + } + else + { + strcpy (dir->__d_dirent->d_name, process_listing[dir->__d_position++]); + syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir, + dir->__d_dirent->d_name); + } return dir->__d_dirent; } @@ -191,10 +222,7 @@ fhandler_process::open (int flags, mode_t mode) const char *path; path = get_name () + proc_len + 1; - if (path_prefix_p ("self", path, 4)) - pid = getpid (); - else - pid = atoi (path); + pid = atoi (path); while (*path != 0 && !isdirsep (*path)) path++; @@ -272,15 +300,11 @@ out: bool fhandler_process::fill_filebuf () { + const char *path; + path = get_name () + proc_len + 1; if (!pid) - { - const char *path; - path = get_name () + proc_len + 1; - if (path_prefix_p ("self", path, 4)) - pid = getpid (); - else - pid = atoi (path); - } + pid = atoi (path); + pinfo p (pid); if (!p) @@ -291,6 +315,36 @@ fhandler_process::fill_filebuf () switch (fileid) { + case PROCESS_FD: + { + size_t fs; + char *fdp = strrchr (path, '/'); + if (!fdp || *++fdp == 'f') /* The "fd" directory itself. */ + { + if (filebuf) + free (filebuf); + filebuf = p->fds (fs); + } + else + { + if (filebuf) + free (filebuf); + int fd = atoi (fdp); + if (fd < 0 || (fd == 0 && !isdigit (*fdp))) + { + set_errno (ENOENT); + return false; + } + filebuf = p->fd (fd, fs); + if (!filebuf || !*filebuf) + { + filebuf = strdup (""); + fs = strlen (filebuf) + 1; + } + } + filesize = fs; + break; + } case PROCESS_UID: case PROCESS_GID: case PROCESS_PGID: @@ -502,7 +556,7 @@ format_process_maps (_pinfo *p, char *destbuf, size_t maxsize) st.st_ino); while (written++ < 61) destbuf[len + written] = ' '; - len += written; + len += written - 1; len += __small_sprintf (destbuf + len, "%s\n", posix_modname); } out: diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc index c15882176..92f7f8e42 100644 --- a/winsup/cygwin/fhandler_registry.cc +++ b/winsup/cygwin/fhandler_registry.cc @@ -236,7 +236,7 @@ fhandler_registry::fstat (struct __stat64 *buf) buf->st_ctim = buf->st_mtim; time_as_timestruc_t (&buf->st_atim); if (file_type > 0) - buf->st_nlink = subkey_count; + buf->st_nlink = subkey_count + 2; else { int pathlen = strlen (path); diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 803ba44cb..a7e52936e 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -147,6 +147,15 @@ fhandler_socket::~fhandler_socket () cfree (sun_path); } +char *fhandler_socket::get_proc_fd_name (char *buf) +{ + if (get_sun_path ()) + __small_sprintf (buf, "%s", get_sun_path ()); + else + __small_sprintf (buf, "socket:[%d]", get_socket ()); + return buf; +} + void fhandler_socket::set_connect_secret () { diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 0d2637537..5d5d1eade 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -3135,22 +3135,10 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt) int symlink_info::set (char *path, int type) { - extern suffix_info stat_suffixes[]; - strcpy (contents, path); pflags = PATH_SYMLINK; - if (type == -3) /* /proc/self */ - { - fileattr = FILE_ATTRIBUTE_DIRECTORY; - error = 0; - } - else - { - /* That's save since a virtual symlink doesn't point to itself. */ - path_conv pc (contents, PC_SYM_NOFOLLOW | PC_FULL, stat_suffixes); - fileattr = pc; - error = pc.error; - } + fileattr = FILE_ATTRIBUTE_NORMAL; + error = 0; is_symlink = true; ext_tacked_on = case_clash = false; ext_here = NULL; diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index fa440aa39..6df0f5e0c 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -380,7 +380,7 @@ extern char **__argv; void _pinfo::commune_recv () { - char pathbuf[CYG_MAX_PATH]; + char path[CYG_MAX_PATH + 1]; DWORD nr; DWORD code; HANDLE hp; @@ -460,33 +460,78 @@ _pinfo::commune_recv () } case PICOM_CWD: { - unsigned int n = strlen (cygheap->cwd.get (pathbuf, 1, 1, CYG_MAX_PATH)) + 1; CloseHandle (__fromthem); __fromthem = NULL; CloseHandle (hp); + unsigned int n = strlen (cygheap->cwd.get (path, 1, 1, + CYG_MAX_PATH)) + 1; if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL)) - sigproc_printf ("WriteFile sizeof argv failed, %E"); - else if (!WriteFile (__tothem, pathbuf, n, &nr, NULL)) - sigproc_printf ("WriteFile sizeof argv failed, %E"); + sigproc_printf ("WriteFile sizeof cwd failed, %E"); + else if (!WriteFile (__tothem, path, n, &nr, NULL)) + sigproc_printf ("WriteFile cwd failed, %E"); break; } case PICOM_ROOT: { + CloseHandle (__fromthem); __fromthem = NULL; + CloseHandle (hp); unsigned int n; if (cygheap->root.exists ()) - n = strlen (strcpy (pathbuf, cygheap->root.posix_path ())) + 1; + n = strlen (strcpy (path, cygheap->root.posix_path ())) + 1; else - n = strlen (strcpy (pathbuf, "/")) + 1; + n = strlen (strcpy (path, "/")) + 1; + if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL)) + sigproc_printf ("WriteFile sizeof root failed, %E"); + else if (!WriteFile (__tothem, path, n, &nr, NULL)) + sigproc_printf ("WriteFile root failed, %E"); + break; + } + case PICOM_FDS: + { CloseHandle (__fromthem); __fromthem = NULL; CloseHandle (hp); + unsigned int n = 0; + int fd; + cygheap_fdenum cfd; + while ((fd = cfd.next ()) >= 0) + n += sizeof (int); + cfd.rewind (); if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL)) - sigproc_printf ("WriteFile sizeof argv failed, %E"); - else if (!WriteFile (__tothem, pathbuf, n, &nr, NULL)) - sigproc_printf ("WriteFile sizeof argv failed, %E"); - break; + sigproc_printf ("WriteFile sizeof fds failed, %E"); + else + while ((fd = cfd.next ()) >= 0) + if (!WriteFile (__tothem, &fd, sizeof fd, &nr, NULL)) + { + sigproc_printf ("WriteFile fd %d failed, %E", fd); + break; + } + break; + } + case PICOM_FD: + { + int fd; + if (!ReadFile (__fromthem, &fd, sizeof fd, &nr, NULL) + || nr != sizeof fd) + { + sigproc_printf ("ReadFile fd failed, %E"); + CloseHandle (hp); + goto out; + } + CloseHandle (__fromthem); __fromthem = NULL; + CloseHandle (hp); + unsigned int n; + cygheap_fdget cfd (fd); + if (cfd < 0) + n = strlen (strcpy (path, "")) + 1; + else + n = strlen (cfd->get_proc_fd_name (path)) + 1; + if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL)) + sigproc_printf ("WriteFile sizeof fd failed, %E"); + else if (!WriteFile (__tothem, path, n, &nr, NULL)) + sigproc_printf ("WriteFile fd failed, %E"); + break; } case PICOM_FIFO: { - char path[CYG_MAX_PATH + 1]; unsigned len; if (!ReadFile (__fromthem, &len, sizeof len, &nr, NULL) || nr != sizeof len) @@ -614,9 +659,21 @@ _pinfo::commune_send (DWORD code, ...) size_t n; switch (code) { + case PICOM_FD: + { + int fd = va_arg (args, int); + if (!WriteFile (tothem, &fd, sizeof fd, &nr, NULL) + || nr != sizeof fd) + { + __seterrno (); + goto err; + } + } + /*FALLTHRU*/ case PICOM_CMDLINE: case PICOM_CWD: case PICOM_ROOT: + case PICOM_FDS: if (!ReadFile (fromthem, &n, sizeof n, &nr, NULL) || nr != sizeof n) { __seterrno (); @@ -683,6 +740,58 @@ out: return res; } +char * +_pinfo::fd (int fd, size_t &n) +{ + char *s; + if (!this || !pid) + return NULL; + if (pid != myself->pid) + { + commune_result cr = commune_send (PICOM_FD, fd); + s = cr.s; + n = cr.n; + } + else + { + cygheap_fdget cfd (fd); + if (cfd < 0) + s = strdup (""); + else + s = cfd->get_proc_fd_name ((char *) malloc (CYG_MAX_PATH + 1)); + n = strlen (s) + 1; + } + return s; +} + +char * +_pinfo::fds (size_t &n) +{ + char *s; + if (!this || !pid) + return NULL; + if (pid != myself->pid) + { + commune_result cr = commune_send (PICOM_FDS); + s = cr.s; + n = cr.n; + } + else + { + n = 0; + int fd; + cygheap_fdenum cfd; + while ((fd = cfd.next ()) >= 0) + n += sizeof (int); + cfd.rewind (); + s = (char *) malloc (n); + int *p = (int *) s; + while ((fd = cfd.next ()) >= 0 && (char *) p - s < (int) n) + *p++ = fd; + } + return s; +} + char * _pinfo::root (size_t& n) { diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index 88442ca22..705a1a599 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -25,7 +25,9 @@ enum picom PICOM_CMDLINE = 1, PICOM_FIFO = 2, PICOM_CWD = 3, - PICOM_ROOT = 4 + PICOM_ROOT = 4, + PICOM_FDS = 5, + PICOM_FD = 6 }; #define EXITCODE_SET 0x80000000 @@ -108,6 +110,8 @@ public: void commune_recv (); commune_result commune_send (DWORD, ...); bool alive (); + char *fd (int fd, size_t &); + char *fds (size_t &); char *root (size_t &); char *cwd (size_t &); char *cmdline (size_t &); diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index ad5131d36..c2d633afc 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -53,6 +53,12 @@ fhandler_pipe::set_close_on_exec (bool val) set_no_inheritance (writepipe_exists, val); } +char *fhandler_pipe::get_proc_fd_name (char *buf) +{ + __small_sprintf (buf, "pipe:[%d]", get_handle ()); + return buf; +} + struct pipeargs { fhandler_base *fh; -- 2.43.5