start_command(), .in/.out/.err = -1: Callers must close the file descriptor

By setting .in, .out, or .err members of struct child_process to -1, the
callers of start_command() can request that a pipe is allocated that talks
to the child process and one end is returned by replacing -1 with the
file descriptor.

Previously, a flag was set (for .in and .out, but not .err) to signal
finish_command() to close the pipe end that start_command() had handed out,
so it was optional for callers to close the pipe, and many already do so.
Now we make it mandatory to close the pipe.

Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Johannes Sixt 2008-02-16 18:36:38 +01:00 коммит произвёл Junio C Hamano
Родитель 923d44aeb7
Коммит e72ae28895
8 изменённых файлов: 9 добавлений и 11 удалений

Просмотреть файл

@ -538,8 +538,10 @@ static int get_pack(int xd[2], char **pack_lockfile)
cmd.git_cmd = 1; cmd.git_cmd = 1;
if (start_command(&cmd)) if (start_command(&cmd))
die("fetch-pack: unable to fork off %s", argv[0]); die("fetch-pack: unable to fork off %s", argv[0]);
if (do_keep && pack_lockfile) if (do_keep && pack_lockfile) {
*pack_lockfile = index_pack_lockfile(cmd.out); *pack_lockfile = index_pack_lockfile(cmd.out);
close(cmd.out);
}
if (finish_command(&cmd)) if (finish_command(&cmd))
die("%s failed", argv[0]); die("%s failed", argv[0]);

Просмотреть файл

@ -71,6 +71,7 @@ static int pack_objects(int fd, struct ref *refs)
refs = refs->next; refs = refs->next;
} }
close(po.in);
if (finish_command(&po)) if (finish_command(&po))
return error("pack-objects died with strange error"); return error("pack-objects died with strange error");
return 0; return 0;

Просмотреть файл

@ -226,12 +226,13 @@ static int do_sign(struct strbuf *buffer)
if (write_in_full(gpg.in, buffer->buf, buffer->len) != buffer->len) { if (write_in_full(gpg.in, buffer->buf, buffer->len) != buffer->len) {
close(gpg.in); close(gpg.in);
close(gpg.out);
finish_command(&gpg); finish_command(&gpg);
return error("gpg did not accept the tag data"); return error("gpg did not accept the tag data");
} }
close(gpg.in); close(gpg.in);
gpg.close_in = 0;
len = strbuf_read(buffer, gpg.out, 1024); len = strbuf_read(buffer, gpg.out, 1024);
close(gpg.out);
if (finish_command(&gpg) || !len || len < 0) if (finish_command(&gpg) || !len || len < 0)
return error("gpg failed to sign the tag"); return error("gpg failed to sign the tag");

Просмотреть файл

@ -52,7 +52,6 @@ static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
write_in_full(gpg.in, buf, len); write_in_full(gpg.in, buf, len);
close(gpg.in); close(gpg.in);
gpg.close_in = 0;
ret = finish_command(&gpg); ret = finish_command(&gpg);
unlink(path); unlink(path);

Просмотреть файл

@ -333,6 +333,7 @@ int create_bundle(struct bundle_header *header, const char *path,
write_or_die(rls.in, sha1_to_hex(object->sha1), 40); write_or_die(rls.in, sha1_to_hex(object->sha1), 40);
write_or_die(rls.in, "\n", 1); write_or_die(rls.in, "\n", 1);
} }
close(rls.in);
if (finish_command(&rls)) if (finish_command(&rls))
return error ("pack-objects died"); return error ("pack-objects died");

Просмотреть файл

@ -132,6 +132,7 @@ static int run_hook(const char *hook_name)
break; break;
} }
} }
close(proc.in);
return hook_status(finish_command(&proc), hook_name); return hook_status(finish_command(&proc), hook_name);
} }
@ -414,6 +415,7 @@ static const char *unpack(void)
if (start_command(&ip)) if (start_command(&ip))
return "index-pack fork failed"; return "index-pack fork failed";
pack_lockfile = index_pack_lockfile(ip.out); pack_lockfile = index_pack_lockfile(ip.out);
close(ip.out);
status = finish_command(&ip); status = finish_command(&ip);
if (!status) { if (!status) {
reprepare_packed_git(); reprepare_packed_git();

Просмотреть файл

@ -25,7 +25,6 @@ int start_command(struct child_process *cmd)
if (pipe(fdin) < 0) if (pipe(fdin) < 0)
return -ERR_RUN_COMMAND_PIPE; return -ERR_RUN_COMMAND_PIPE;
cmd->in = fdin[1]; cmd->in = fdin[1];
cmd->close_in = 1;
} }
need_out = !cmd->no_stdout need_out = !cmd->no_stdout
@ -38,7 +37,6 @@ int start_command(struct child_process *cmd)
return -ERR_RUN_COMMAND_PIPE; return -ERR_RUN_COMMAND_PIPE;
} }
cmd->out = fdout[0]; cmd->out = fdout[0];
cmd->close_out = 1;
} }
need_err = !cmd->no_stderr && cmd->err < 0; need_err = !cmd->no_stderr && cmd->err < 0;
@ -157,10 +155,6 @@ static int wait_or_whine(pid_t pid)
int finish_command(struct child_process *cmd) int finish_command(struct child_process *cmd)
{ {
if (cmd->close_in)
close(cmd->in);
if (cmd->close_out)
close(cmd->out);
return wait_or_whine(cmd->pid); return wait_or_whine(cmd->pid);
} }

Просмотреть файл

@ -19,8 +19,6 @@ struct child_process {
int err; int err;
const char *dir; const char *dir;
const char *const *env; const char *const *env;
unsigned close_in:1;
unsigned close_out:1;
unsigned no_stdin:1; unsigned no_stdin:1;
unsigned no_stdout:1; unsigned no_stdout:1;
unsigned no_stderr:1; unsigned no_stderr:1;