{"thread":{"id":"7178","subject":"[PATCH 5/8] Teach run_command how to setup a stdin pipe","startedAt":"2007-03-10T08:28:08Z","lastAt":"2007-03-11T02:07:11Z","messageCount":4,"participants":["Shawn O. Pearce","Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":8},"messages":[{"id":"36736","messageId":"20070310082808.GE4133@spearce.org","threadId":"7178","inReplyTo":null,"subject":"[PATCH 5/8] Teach run_command how to setup a stdin pipe","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-03-10T08:28:08Z","receivedAt":"2007-03-10T08:28:08Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Sometimes callers trying to use run_command to execute a child\nprocess will want to setup a pipe or file descriptor to redirect\ninto the child's stdin.\n\nThis idea is completely stolen from builtin-bundle's fork_with_pipe,\nwritten by Johannes Schindelin.  All credit (and blame) should lie\nwith Dscho.  ;-)\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n run-command.c |   35 ++++++++++++++++++++++++++++++++++-\n run-command.h |    3 +++\n 2 files changed, 37 insertions(+), 1 deletions(-)\n\ndiff --git a/run-command.c b/run-command.c\nindex a866a06..03ff7bc 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -4,15 +4,39 @@\n \n int start_command(struct child_process *cmd)\n {\n+\tint need_in = !cmd->no_stdin && cmd->in < 0;\n+\tint fdin[2];\n+\n+\tif (need_in) {\n+\t\tif (pipe(fdin) < 0)\n+\t\t\treturn -ERR_RUN_COMMAND_PIPE;\n+\t\tcmd->in = fdin[1];\n+\t\tcmd->close_in = 1;\n+\t}\n+\n \tcmd->pid = fork();\n-\tif (cmd->pid < 0)\n+\tif (cmd->pid < 0) {\n+\t\tif (need_in) {\n+\t\t\tclose(fdin[0]);\n+\t\t\tclose(fdin[1]);\n+\t\t}\n \t\treturn -ERR_RUN_COMMAND_FORK;\n+\t}\n+\n \tif (!cmd->pid) {\n \t\tif (cmd->no_stdin) {\n \t\t\tint fd = open(\"/dev/null\", O_RDWR);\n \t\t\tdup2(fd, 0);\n \t\t\tclose(fd);\n+\t\t} else if (need_in) {\n+\t\t\tdup2(fdin[0], 0);\n+\t\t\tclose(fdin[0]);\n+\t\t\tclose(fdin[1]);\n+\t\t} else if (cmd->in) {\n+\t\t\tdup2(cmd->in, 0);\n+\t\t\tclose(cmd->in);\n \t\t}\n+\n \t\tif (cmd->stdout_to_stderr)\n \t\t\tdup2(2, 1);\n \t\tif (cmd->git_cmd) {\n@@ -22,11 +46,20 @@ int start_command(struct child_process *cmd)\n \t\t}\n \t\tdie(\"exec %s failed.\", cmd->argv[0]);\n \t}\n+\n+\tif (need_in)\n+\t\tclose(fdin[0]);\n+\telse if (cmd->in)\n+\t\tclose(cmd->in);\n+\n \treturn 0;\n }\n \n int finish_command(struct child_process *cmd)\n {\n+\tif (cmd->close_in)\n+\t\tclose(cmd->in);\n+\n \tfor (;;) {\n \t\tint status, code;\n \t\tpid_t waiting = waitpid(cmd->pid, &status, 0);\ndiff --git a/run-command.h b/run-command.h\nindex 24cdb4e..ff09067 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -4,6 +4,7 @@\n enum {\n \tERR_RUN_COMMAND_FORK = 10000,\n \tERR_RUN_COMMAND_EXEC,\n+\tERR_RUN_COMMAND_PIPE,\n \tERR_RUN_COMMAND_WAITPID,\n \tERR_RUN_COMMAND_WAITPID_WRONG_PID,\n \tERR_RUN_COMMAND_WAITPID_SIGNAL,\n@@ -13,6 +14,8 @@ enum {\n struct child_process {\n \tconst char **argv;\n \tpid_t pid;\n+\tint in;\n+\tunsigned close_in:1;\n \tunsigned no_stdin:1;\n \tunsigned git_cmd:1; /* if this is to be git sub-command */\n \tunsigned stdout_to_stderr:1;\n-- \n1.5.0.3.942.g299f\n"},{"id":"36748","messageId":"Pine.LNX.4.63.0703101753440.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7178","inReplyTo":"20070310082808.GE4133@spearce.org","subject":"Re: [PATCH 5/8] Teach run_command how to setup a stdin pipe","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-10T16:54:42Z","receivedAt":"2007-03-10T16:54:42Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 10 Mar 2007, Shawn O. Pearce wrote:\n\n> Sometimes callers trying to use run_command to execute a child process \n> will want to setup a pipe or file descriptor to redirect into the \n> child's stdin.\n> \n> This idea is completely stolen from builtin-bundle's fork_with_pipe, \n> written by Johannes Schindelin.  All credit (and blame) should lie with \n> Dscho.  ;-)\n\n;-)\n\nThank you for starting this thread. I think it makes a lot of sense in the \nface of the MinGW port. (I am not interested in the hook stuff personally, \nso I'll not comment on that.)\n\nCiao,\nDscho\n"},{"id":"36771","messageId":"20070311014533.GA10343@spearce.org","threadId":"7178","inReplyTo":"Pine.LNX.4.63.0703101753440.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH 5/8] Teach run_command how to setup a stdin pipe","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-03-11T01:45:33Z","receivedAt":"2007-03-11T01:45:33Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> On Sat, 10 Mar 2007, Shawn O. Pearce wrote:\n> \n> > Sometimes callers trying to use run_command to execute a child process \n> > will want to setup a pipe or file descriptor to redirect into the \n> > child's stdin.\n> > \n> > This idea is completely stolen from builtin-bundle's fork_with_pipe, \n> > written by Johannes Schindelin.  All credit (and blame) should lie with \n> > Dscho.  ;-)\n> \n> ;-)\n> \n> Thank you for starting this thread. I think it makes a lot of sense in the \n> face of the MinGW port. (I am not interested in the hook stuff personally, \n> so I'll not comment on that.)\n\nI'd like to see run_command learn how to also redirect stdout,\nthen replace fork_with_pipe in builtin-bundle with run_command.\nWe should be able to also improve some of our other more direct\nuses of fork to use run_command at that point too.\n\nI don't know squat about MinGW, so I don't know if having the\nrun_command abstraction really helps there or not, but I know we\ntried to make it with the good intentions of being able to use it\nto wrap that asinine CreateProcess() thing that Win32 has...\n\n-- \nShawn.\n"},{"id":"36775","messageId":"Pine.LNX.4.63.0703110305000.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7178","inReplyTo":"20070311014533.GA10343@spearce.org","subject":"Re: [PATCH 5/8] Teach run_command how to setup a stdin pipe","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-11T02:07:11Z","receivedAt":"2007-03-11T02:07:11Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 10 Mar 2007, Shawn O. Pearce wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> > On Sat, 10 Mar 2007, Shawn O. Pearce wrote:\n> > \n> > > Sometimes callers trying to use run_command to execute a child \n> > > process will want to setup a pipe or file descriptor to redirect \n> > > into the child's stdin.\n> > > \n> > > This idea is completely stolen from builtin-bundle's fork_with_pipe, \n> > > written by Johannes Schindelin.  All credit (and blame) should lie \n> > > with Dscho.  ;-)\n> > \n> > ;-)\n> > \n> > Thank you for starting this thread. I think it makes a lot of sense in \n> > the face of the MinGW port. (I am not interested in the hook stuff \n> > personally, so I'll not comment on that.)\n> \n> I'd like to see run_command learn how to also redirect stdout, then \n> replace fork_with_pipe in builtin-bundle with run_command. We should be \n> able to also improve some of our other more direct uses of fork to use \n> run_command at that point too.\n\nI concur.\n\n> I don't know squat about MinGW, so I don't know if having the \n> run_command abstraction really helps there or not, but I know we tried \n> to make it with the good intentions of being able to use it to wrap that \n> asinine CreateProcess() thing that Win32 has...\n\nThere is only one place that I am aware of, where this is not enough: For \nthe shallow thing, upload-pack fork()s but does not execute another \nprogram, but lists all the objects to be uploaded. (For shallow, this \n_cannot_ be an external process, since it mucks with the commits which are \nto be treated as shallow).\n\nCiao,\nDscho\n"}]}