+/* Run a program. */
+
+const char *
+pex_run (struct pex_obj *obj, int flags, const char *executable,
+ char * const * argv, const char *orig_outname, const char *errname,
+ int *err)
+{
+ return pex_run_in_environment (obj, flags, executable, argv, NULL,
+ orig_outname, errname, err);
+}
+
+/* Return a FILE pointer for a temporary file to fill with input for
+ the pipeline. */
+FILE *
+pex_input_file (struct pex_obj *obj, int flags, const char *in_name)
+{
+ char *name = (char *) in_name;
+ FILE *f;
+
+ /* This must be called before the first pipeline stage is run, and
+ there must not have been any other input selected. */
+ if (obj->count != 0
+ || (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
+ || obj->next_input_name)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ name = temp_file (obj, flags, name);
+ if (! name)
+ return NULL;
+
+ f = fopen (name, (flags & PEX_BINARY_OUTPUT) ? "wb" : "w");
+ if (! f)
+ {
+ free (name);
+ return NULL;
+ }
+
+ obj->input_file = f;
+ obj->next_input_name = name;
+ obj->next_input_name_allocated = (name != in_name);
+
+ return f;
+}
+
+/* Return a stream for a pipe connected to the standard input of the
+ first stage of the pipeline. */
+FILE *
+pex_input_pipe (struct pex_obj *obj, int binary)
+{
+ int p[2];
+ FILE *f;
+
+ /* You must call pex_input_pipe 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;
+
+ f = obj->funcs->fdopenw (obj, p[WRITE_PORT], binary != 0);
+ if (! f)
+ {
+ 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 f;
+
+ usage_error:
+ errno = EINVAL;
+ return NULL;
+}
+