summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Blandy <jimb@codesourcery.com>2006-03-17 20:36:14 +0000
committerJim Blandy <jimb@codesourcery.com>2006-03-17 20:36:14 +0000
commit4fbd9684321d472af2ebc4d4a27b2fc34b7bdc22 (patch)
tree035ea8a0aedc7a3de1b02e5560a3fd60c31d2359
parentc192517ca3376089fe47439cfb63248e0165668e (diff)
downloadbinutils-redhat-4fbd9684321d472af2ebc4d4a27b2fc34b7bdc22.tar.gz
gdb/ChangeLog:
2006-03-17 Jim Blandy <jimb@codesourcery.com> Add support for 'target remote |' on MinGW. * ser-mingw.c (struct pipe_state): New structure. (make_pipe_state, free_pipe_state, cleanup_pipe_state) (pipe_windows_open, pipe_windows_close, pipe_windows_read) (pipe_windows_write, pipe_wait_handle): New functions. (_initialize_ser_windows): Register a "pipe" interface based on them. include/ChangeLog: 2006-03-15 Jim Blandy <jimb@codesourcery.com> * libiberty.h (pex_write_input): New declaration. libiberty/ChangeLog: 2006-03-15 Jim Blandy <jimb@codesourcery.com> * pex-common.c (pex_write_input): New function. * pexecute.txh (pex_write_input): Document it. * pex-common.h (struct pex_funcs): New function ptr fdopenw. * pex-unix.c (pex_unix_fdopenw): New function. (funcs): List it as our fdopenw function. * pex-win32.c (pex_win32_fdopenw): New function. (funcs): List it as our fdopenw function. * pex-djgpp.c (funcs): Leave fdopenw null. * pex-msdos (funcs): Same. * functions.texi: Regenerated. 2006-03-12 Jim Blandy <jimb@red-bean.com> * pex-common.h (struct pex_obj): Doc fixes. 2006-03-11 Jim Blandy <jimb@red-bean.com> * functions.texi: Regenerate.
-rw-r--r--include/ChangeLog4
-rw-r--r--include/libiberty.h27
-rw-r--r--libiberty/ChangeLog21
-rw-r--r--libiberty/functions.texi69
-rw-r--r--libiberty/pex-common.c46
-rw-r--r--libiberty/pex-common.h32
-rw-r--r--libiberty/pex-djgpp.c1
-rw-r--r--libiberty/pex-msdos.c1
-rw-r--r--libiberty/pex-unix.c11
-rw-r--r--libiberty/pex-win32.c14
-rw-r--r--libiberty/pexecute.txh29
11 files changed, 233 insertions, 22 deletions
diff --git a/include/ChangeLog b/include/ChangeLog
index 3c6907f56d..f0bc4b37be 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
+2006-03-15 Jim Blandy <jimb@codesourcery.com>
+
+ * libiberty.h (pex_write_input): New declaration.
+
2006-02-17 Shrirang Khisti <shrirangk@kpitcummins.com>
Anil Paranjape <anilp1@kpitcummins.com>
Shilin Shakti <shilins@kpitcummins.com>
diff --git a/include/libiberty.h b/include/libiberty.h
index c264cb2ab0..6fdc6e9d0c 100644
--- a/include/libiberty.h
+++ b/include/libiberty.h
@@ -448,6 +448,33 @@ extern const char *pex_run (struct pex_obj *obj, int flags,
const char *outname, const char *errname,
int *err);
+/* Return a `FILE' pointer FP for the standard input of the first
+ program in the pipeline; FP is opened for writing. You must have
+ passed `PEX_USE_PIPES' to the `pex_init' call that returned OBJ.
+ You must close FP yourself with `fclose' to indicate that the
+ pipeline's input is complete.
+
+ The file descriptor underlying FP is marked not to be inherited by
+ child processes.
+
+ This call is not supported on systems which do not support pipes;
+ it returns with an error. (We could implement it by writing a
+ temporary file, but then you would need to write all your data and
+ close FP before your first call to `pex_run' -- and that wouldn't
+ work on systems that do support pipes: the pipe would fill up, and
+ you would block. So there isn't any easy way to conceal the
+ differences between the two types of systems.)
+
+ If you call both `pex_write_input' and `pex_read_output', be
+ careful to avoid deadlock. If the output pipe fills up, so that
+ each program in the pipeline is waiting for the next to read more
+ data, and you fill the input pipe by writing more data to FP, then
+ there is no way to make progress: the only process that could read
+ data from the output pipe is you, but you are blocked on the input
+ pipe. */
+
+extern FILE *pex_write_input (struct pex_obj *obj, int binary);
+
/* Read the standard output of the last program to be executed.
pex_run can not be called after this. BINARY should be non-zero if
the file should be opened in binary mode; this is ignored on Unix.
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index acdfad0657..549e9b6609 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,24 @@
+2006-03-15 Jim Blandy <jimb@codesourcery.com>
+
+ * pex-common.c (pex_write_input): New function.
+ * pexecute.txh (pex_write_input): Document it.
+ * pex-common.h (struct pex_funcs): New function ptr fdopenw.
+ * pex-unix.c (pex_unix_fdopenw): New function.
+ (funcs): List it as our fdopenw function.
+ * pex-win32.c (pex_win32_fdopenw): New function.
+ (funcs): List it as our fdopenw function.
+ * pex-djgpp.c (funcs): Leave fdopenw null.
+ * pex-msdos (funcs): Same.
+ * functions.texi: Regenerated.
+
+2006-03-12 Jim Blandy <jimb@red-bean.com>
+
+ * pex-common.h (struct pex_obj): Doc fixes.
+
+2006-03-11 Jim Blandy <jimb@red-bean.com>
+
+ * functions.texi: Regenerate.
+
2006-02-21 Ben Elliston <bje@au.ibm.com>
* pexecute.c (pwait): Syntax fix for previous change.
diff --git a/libiberty/functions.texi b/libiberty/functions.texi
index 8b4a50ef45..ab2461dc8d 100644
--- a/libiberty/functions.texi
+++ b/libiberty/functions.texi
@@ -214,6 +214,26 @@ symbolic name or message.
@end deftypefn
+@c argv.c:293
+@deftypefn Extension void expandargv (int *@var{argcp}, char ***@var{argvp})
+
+The @var{argcp} and @code{argvp} arguments are pointers to the usual
+@code{argc} and @code{argv} arguments to @code{main}. This function
+looks for arguments that begin with the character @samp{@@}. Any such
+arguments are interpreted as ``response files''. The contents of the
+response file are interpreted as additional command line options. In
+particular, the file is separated into whitespace-separated strings;
+each such string is taken as a command-line option. The new options
+are inserted in place of the option naming the response file, and
+@code{*argcp} and @code{*argvp} will be updated. If the value of
+@code{*argvp} is modified by this function, then the new value has
+been dynamically allocated and can be deallocated by the caller with
+@code{freeargv}. However, most callers will simply call
+@code{expandargv} near the beginning of @code{main} and allow the
+operating system to free the memory when the program exits.
+
+@end deftypefn
+
@c fdmatch.c:23
@deftypefn Extension int fdmatch (int @var{fd1}, int @var{fd2})
@@ -648,14 +668,14 @@ reading and writing.
@end deftypefn
-@c pexecute.txh:169
+@c pexecute.txh:198
@deftypefn Extension void pex_free (struct pex_obj @var{obj})
Clean up and free all data associated with @var{obj}.
@end deftypefn
-@c pexecute.txh:144
+@c pexecute.txh:173
@deftypefn Extension int pex_get_status (struct pex_obj *@var{obj}, int @var{count}, int *@var{vector})
Returns the exit status of all programs run using @var{obj}.
@@ -665,7 +685,7 @@ to @code{pex_run}. Returns 0 on error, 1 on success.
@end deftypefn
-@c pexecute.txh:153
+@c pexecute.txh:182
@deftypefn Extension int pex_get_times (struct pex_obj *@var{obj}, int @var{count}, struct pex_time *@var{vector})
Returns the process execution times of all programs run using
@@ -682,7 +702,7 @@ process times, all the fields will be set to @code{0}.
@end deftypefn
-@c pexecute.txh:1
+@c pexecute.txh:2
@deftypefn Extension {struct pex_obj *} pex_init (int @var{flags}, const char *@var{pname}, const char *@var{tempbase})
Prepare to execute one or more programs, with standard output of each
@@ -714,7 +734,7 @@ temporary files; it may be @code{NULL} to use a randomly chosen name.
@end deftypefn
-@c pexecute.txh:175
+@c pexecute.txh:204
@deftypefn Extension {const char *} pex_one (int @var{flags}, const char *@var{executable}, char * const *@var{argv}, const char *@var{pname}, const char *@var{outname}, const char *@var{errname}, int *@var{status}, int *@var{err})
An interface to permit the easy execution of a
@@ -727,7 +747,7 @@ be set to the exit status of the program.
@end deftypefn
-@c pexecute.txh:132
+@c pexecute.txh:161
@deftypefn Extension {FILE *} pex_read_output (struct pex_obj *@var{obj}, int @var{binary})
Returns a @code{FILE} pointer which may be used to read the standard
@@ -740,7 +760,7 @@ it will be closed by @code{pex_free}.
@end deftypefn
-@c pexecute.txh:32
+@c pexecute.txh:33
@deftypefn Extension {const char *} pex_run (struct pex_obj *@var{obj}, int @var{flags}, const char *@var{executable}, char * const *@var{argv}, const char *@var{outname}, const char *@var{errname}, int *@var{err})
Execute one program in a pipeline. On success this returns
@@ -841,7 +861,36 @@ value, or to 0 if there is no relevant @code{errno}.
@end deftypefn
-@c pexecute.txh:187
+@c pexecute.txh:133
+@deftypefn Extension {FILE *} pex_write_input (struct pex_obj *@var{obj}, int @var{binary})
+
+Return a @code{FILE} pointer @var{fp} for the standard input of the
+first program in the pipeline; @var{fp} is opened for writing. You
+must have passed @code{PEX_USE_PIPES} to the @code{pex_init} call that
+returned @var{obj}. You must close @var{fp} yourself with
+@code{fclose} to indicate that the pipeline's input is complete.
+
+The file descriptor underlying @var{fp} is marked not to be inherited
+by child processes.
+
+This call is not supported on systems which do not support pipes; it
+returns with an error. (We could implement it by writing a temporary
+file, but then you would need to write all your data and close
+@var{fp} before your first call to @code{pex_run} --- and that
+wouldn't work on systems that do support pipes: the pipe would fill
+up, and you would block. So there isn't any easy way to conceal the
+differences between the two types of systems.)
+
+If you call both @code{pex_write_input} and @code{pex_read_output}, be
+careful to avoid deadlock. If the output pipe fills up, so that each
+program in the pipeline is waiting for the next to read more data, and
+you fill the input pipe by writing more data to @var{fp}, then there
+is no way to make progress: the only process that could read data from
+the output pipe is you, but you are blocked on the input pipe.
+
+@end deftypefn
+
+@c pexecute.txh:216
@deftypefn Extension int pexecute (const char *@var{program}, char * const *@var{argv}, const char *@var{this_pname}, const char *@var{temp_base}, char **@var{errmsg_fmt}, char **@var{errmsg_arg}, int flags)
This is the old interface to execute one or more programs. It is
@@ -869,7 +918,7 @@ name is unset/removed.
@end deftypefn
-@c pexecute.txh:195
+@c pexecute.txh:224
@deftypefn Extension int pwait (int @var{pid}, int *@var{status}, int @var{flags})
Another part of the old execution interface.
@@ -1194,7 +1243,7 @@ translation is found, returns 0.
@end deftypefn
-@c strverscmp.c:24
+@c strverscmp.c:25
@deftypefun int strverscmp (const char *@var{s1}, const char *@var{s2})
The @code{strverscmp} function compares the string @var{s1} against
@var{s2}, considering them as holding indices/version numbers. Return
diff --git a/libiberty/pex-common.c b/libiberty/pex-common.c
index b2ca6e08ce..38e3ac7695 100644
--- a/libiberty/pex-common.c
+++ b/libiberty/pex-common.c
@@ -297,6 +297,52 @@ pex_run (struct pex_obj *obj, int flags, const char *executable,
return errmsg;
}
+/* Return a FILE pointer for the input of the first program
+ executed. */
+
+FILE *
+pex_write_input (struct pex_obj *obj, int binary)
+{
+ int p[2];
+ FILE *write_input;
+
+ /* You must call pex_write_input before the first pex_run or pex_one. */
+ if (obj->count > 0)
+ goto usage_error;
+
+ /* You must be using pipes. Implementations that don't support
+ pipes clear this flag before calling pex_init_common. */
+ if (! (obj->flags & PEX_USE_PIPES))
+ goto usage_error;
+
+ /* If we have somehow already selected other input, that's a
+ mistake. */
+ if ((obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
+ || obj->next_input_name)
+ goto usage_error;
+
+ if (obj->funcs->pipe (obj, p, binary != 0) < 0)
+ return NULL;
+
+ write_input = obj->funcs->fdopenw (obj, p[WRITE_PORT], binary != 0);
+ if (! write_input)
+ {
+ int saved_errno = errno;
+ obj->funcs->close (obj, p[READ_PORT]);
+ obj->funcs->close (obj, p[WRITE_PORT]);
+ errno = saved_errno;
+ return NULL;
+ }
+
+ obj->next_input = p[READ_PORT];
+
+ return write_input;
+
+ usage_error:
+ errno = EINVAL;
+ return NULL;
+}
+
/* Return a FILE pointer for the output of the last program
executed. */
diff --git a/libiberty/pex-common.h b/libiberty/pex-common.h
index bd4f908769..13ec98149e 100644
--- a/libiberty/pex-common.h
+++ b/libiberty/pex-common.h
@@ -61,7 +61,7 @@ struct pex_obj
int next_input_name_allocated;
/* Number of child processes. */
int count;
- /* PIDs of child processes; array allocated using maloc. */
+ /* PIDs of child processes; array allocated using malloc. */
long *children;
/* Exit statuses of child processes; array allocated using malloc. */
int *status;
@@ -88,10 +88,11 @@ struct pex_funcs
{
/* Open file NAME for reading. If BINARY is non-zero, open in
binary mode. Return >= 0 on success, -1 on error. */
- int (*open_read) (struct pex_obj *, const char *name, int binary);
+ int (*open_read) (struct pex_obj *, const char */* name */, int /* binary */);
/* Open file NAME for writing. If BINARY is non-zero, open in
binary mode. Return >= 0 on success, -1 on error. */
- int (*open_write) (struct pex_obj *, const char *name, int binary);
+ int (*open_write) (struct pex_obj *, const char */* name */,
+ int /* binary */);
/* Execute a child process. FLAGS, EXECUTABLE, ARGV, ERR are from
pex_run. IN, OUT, ERRDES are each a descriptor, from open_read,
open_write, or pipe, or they are one of STDIN_FILE_NO,
@@ -99,25 +100,32 @@ struct pex_funcs
should be closed. The function should handle the
PEX_STDERR_TO_STDOUT flag. Return >= 0 on success, or -1 on
error and set *ERRMSG and *ERR. */
- long (*exec_child) (struct pex_obj *, int flags, const char *executable,
- char * const * argv, int in, int out, int errdes,
- const char **errmsg, int *err);
+ long (*exec_child) (struct pex_obj *, int /* flags */,
+ const char */* executable */, char * const * /* argv */,
+ int /* in */, int /* out */, int /* errdes */,
+ const char **/* errmsg */, int */* err */);
/* Close a descriptor. Return 0 on success, -1 on error. */
int (*close) (struct pex_obj *, int);
/* Wait for a child to complete, returning exit status in *STATUS
and time in *TIME (if it is not null). CHILD is from fork. DONE
is 1 if this is called via pex_free. ERRMSG and ERR are as in
fork. Return 0 on success, -1 on error. */
- int (*wait) (struct pex_obj *, long, int *status, struct pex_time *time,
- int done, const char **errmsg, int *err);
+ int (*wait) (struct pex_obj *, long /* child */, int * /* status */,
+ struct pex_time * /* time */, int /* done */,
+ const char ** /* errmsg */, int * /* err */);
/* Create a pipe (only called if PEX_USE_PIPES is set) storing two
- descriptin in *P. If BINARY is non-zero, open in binary mode.
- Return 0 on success, -1 on error. */
- int (*pipe) (struct pex_obj *, int *p, int binary);
+ descriptors in P[0] and P[1]. If BINARY is non-zero, open in
+ binary mode. Return 0 on success, -1 on error. */
+ int (*pipe) (struct pex_obj *, int * /* p */, int /* binary */);
/* Get a FILE pointer to read from a file descriptor (only called if
PEX_USE_PIPES is set). If BINARY is non-zero, open in binary
mode. Return pointer on success, NULL on error. */
- FILE * (*fdopenr) (struct pex_obj *, int fd, int binary);
+ FILE * (*fdopenr) (struct pex_obj *, int /* fd */, int /* binary */);
+ /* Get a FILE pointer to write to the file descriptor FD (only
+ called if PEX_USE_PIPES is set). If BINARY is non-zero, open in
+ binary mode. Arrange for FD not to be inherited by the child
+ processes. Return pointer on success, NULL on error. */
+ FILE * (*fdopenw) (struct pex_obj *, int /* fd */, int /* binary */);
/* Free any system dependent data associated with OBJ. May be
NULL if there is nothing to do. */
void (*cleanup) (struct pex_obj *);
diff --git a/libiberty/pex-djgpp.c b/libiberty/pex-djgpp.c
index 6e58e3fd8d..17fbf2cc7e 100644
--- a/libiberty/pex-djgpp.c
+++ b/libiberty/pex-djgpp.c
@@ -62,6 +62,7 @@ const struct pex_funcs funcs =
pex_djgpp_wait,
NULL, /* pipe */
NULL, /* fdopenr */
+ NULL, /* fdopenw */
NULL /* cleanup */
};
diff --git a/libiberty/pex-msdos.c b/libiberty/pex-msdos.c
index 2256117d1b..db22337aa2 100644
--- a/libiberty/pex-msdos.c
+++ b/libiberty/pex-msdos.c
@@ -73,6 +73,7 @@ const struct pex_funcs funcs =
pex_msdos_wait,
NULL, /* pipe */
NULL, /* fdopenr */
+ NULL, /* fdopenw */
pex_msdos_cleanup
};
diff --git a/libiberty/pex-unix.c b/libiberty/pex-unix.c
index 35a545cb17..c92a429797 100644
--- a/libiberty/pex-unix.c
+++ b/libiberty/pex-unix.c
@@ -277,6 +277,7 @@ static int pex_unix_wait (struct pex_obj *, long, int *, struct pex_time *,
int, const char **, int *);
static int pex_unix_pipe (struct pex_obj *, int *, int);
static FILE *pex_unix_fdopenr (struct pex_obj *, int, int);
+static FILE *pex_unix_fdopenw (struct pex_obj *, int, int);
static void pex_unix_cleanup (struct pex_obj *);
/* The list of functions we pass to the common routines. */
@@ -290,6 +291,7 @@ const struct pex_funcs funcs =
pex_unix_wait,
pex_unix_pipe,
pex_unix_fdopenr,
+ pex_unix_fdopenw,
pex_unix_cleanup
};
@@ -495,6 +497,15 @@ pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
return fdopen (fd, "r");
}
+static FILE *
+pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
+ int binary ATTRIBUTE_UNUSED)
+{
+ if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
+ return NULL;
+ return fdopen (fd, "w");
+}
+
static void
pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED)
{
diff --git a/libiberty/pex-win32.c b/libiberty/pex-win32.c
index ed45e5b8bb..221e1b2f09 100644
--- a/libiberty/pex-win32.c
+++ b/libiberty/pex-win32.c
@@ -191,6 +191,7 @@ static int pex_win32_wait (struct pex_obj *, long, int *,
struct pex_time *, int, const char **, int *);
static int pex_win32_pipe (struct pex_obj *, int *, int);
static FILE *pex_win32_fdopenr (struct pex_obj *, int, int);
+static FILE *pex_win32_fdopenw (struct pex_obj *, int, int);
/* The list of functions we pass to the common routines. */
@@ -203,6 +204,7 @@ const struct pex_funcs funcs =
pex_win32_wait,
pex_win32_pipe,
pex_win32_fdopenr,
+ pex_win32_fdopenw,
NULL /* cleanup */
};
@@ -702,6 +704,18 @@ pex_win32_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
return fdopen (fd, binary ? "rb" : "r");
}
+static FILE *
+pex_win32_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
+ int binary)
+{
+ HANDLE h = (HANDLE) _get_osfhandle (fd);
+ if (h == INVALID_HANDLE_VALUE)
+ return NULL;
+ if (! SetHandleInformation (h, HANDLE_FLAG_INHERIT, 0))
+ return NULL;
+ return fdopen (fd, binary ? "wb" : "w");
+}
+
#ifdef MAIN
#include <stdio.h>
diff --git a/libiberty/pexecute.txh b/libiberty/pexecute.txh
index 461ff33d01..2bfad0c8b7 100644
--- a/libiberty/pexecute.txh
+++ b/libiberty/pexecute.txh
@@ -1,3 +1,4 @@
+@c -*- mode: texinfo -*-
@deftypefn Extension {struct pex_obj *} pex_init (int @var{flags}, const char *@var{pname}, const char *@var{tempbase})
Prepare to execute one or more programs, with standard output of each
@@ -129,6 +130,34 @@ value, or to 0 if there is no relevant @code{errno}.
@end deftypefn
+@deftypefn Extension {FILE *} pex_write_input (struct pex_obj *@var{obj}, int @var{binary})
+
+Return a @code{FILE} pointer @var{fp} for the standard input of the
+first program in the pipeline; @var{fp} is opened for writing. You
+must have passed @code{PEX_USE_PIPES} to the @code{pex_init} call that
+returned @var{obj}. You must close @var{fp} yourself with
+@code{fclose} to indicate that the pipeline's input is complete.
+
+The file descriptor underlying @var{fp} is marked not to be inherited
+by child processes.
+
+This call is not supported on systems which do not support pipes; it
+returns with an error. (We could implement it by writing a temporary
+file, but then you would need to write all your data and close
+@var{fp} before your first call to @code{pex_run} --- and that
+wouldn't work on systems that do support pipes: the pipe would fill
+up, and you would block. So there isn't any easy way to conceal the
+differences between the two types of systems.)
+
+If you call both @code{pex_write_input} and @code{pex_read_output}, be
+careful to avoid deadlock. If the output pipe fills up, so that each
+program in the pipeline is waiting for the next to read more data, and
+you fill the input pipe by writing more data to @var{fp}, then there
+is no way to make progress: the only process that could read data from
+the output pipe is you, but you are blocked on the input pipe.
+
+@end deftypefn
+
@deftypefn Extension {FILE *} pex_read_output (struct pex_obj *@var{obj}, int @var{binary})
Returns a @code{FILE} pointer which may be used to read the standard