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
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2005-01-31 13:28:55 +0300
committerCorinna Vinschen <corinna@vinschen.de>2005-01-31 13:28:55 +0300
commit4f27e288c55cd54a2759a59d06a52ed44dac494b (patch)
treee2f6752ee7c755d7dd29612c439c2a13d4d88338 /winsup
parentd0ae095b8cebb70f5c73783e816fc41779902913 (diff)
* 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/<pid>/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.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog40
-rw-r--r--winsup/cygwin/cygheap.h23
-rw-r--r--winsup/cygwin/dtable.h1
-rw-r--r--winsup/cygwin/fhandler.cc10
-rw-r--r--winsup/cygwin/fhandler.h7
-rw-r--r--winsup/cygwin/fhandler_process.cc112
-rw-r--r--winsup/cygwin/fhandler_registry.cc2
-rw-r--r--winsup/cygwin/fhandler_socket.cc9
-rw-r--r--winsup/cygwin/path.cc16
-rw-r--r--winsup/cygwin/pinfo.cc133
-rw-r--r--winsup/cygwin/pinfo.h6
-rw-r--r--winsup/cygwin/pipe.cc6
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 <corinna@vinschen.de>
+
+ * 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/<pid>/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 <corinna@vinschen.de>
* 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/<pid>/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 <sys/param.h>
#include <assert.h>
#include <sys/sysmacros.h>
+#include <ctype.h>
#include <psapi.h>
#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 ("<disconnected>");
+ 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, "<disconnected>")) + 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 ();
@@ -684,6 +741,58 @@ out:
}
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 ("<disconnected>");
+ 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)
{
char *s;
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;