{"thread":{"id":"37363","subject":"[PATCH] run-command: introduce CHILD_PROCESS_INIT","startedAt":"2014-08-16T22:55:23Z","lastAt":"2014-08-19T19:11:43Z","messageCount":11,"participants":["René Scharfe","Jeff King","Johannes Sixt","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"247796","messageId":"53EFE15B.7030805@web.de","threadId":"37363","inReplyTo":null,"subject":"[PATCH] run-command: introduce CHILD_PROCESS_INIT","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-08-16T22:55:23Z","receivedAt":"2014-08-16T22:55:23Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Most struct child_process variables are cleared using memset right after\ndeclaration.  Provide a macro, CHILD_PROCESS_INIT, that can be used to\ninitialize them statically instead.  That's shorter, doesn't require a\nfunction call and is slightly more readable (especially given that we\nalready have similar macros like STRBUF_INIT, ARGV_ARRAY_INIT etc.).\n\nSigned-off-by: Rene Scharfe <l.s.r@web.de>\n---\n Documentation/technical/api-run-command.txt |  4 ++--\n archive-tar.c                               |  3 +--\n builtin/add.c                               |  3 +--\n builtin/commit.c                            |  3 +--\n builtin/help.c                              |  3 +--\n builtin/merge.c                             |  3 +--\n builtin/notes.c                             |  3 +--\n builtin/remote-ext.c                        |  3 +--\n builtin/repack.c                            |  3 +--\n builtin/replace.c                           |  4 ++--\n builtin/verify-pack.c                       |  3 +--\n bundle.c                                    |  6 ++----\n connected.c                                 |  3 +--\n convert.c                                   |  3 +--\n credential-cache.c                          |  3 +--\n credential.c                                |  3 +--\n daemon.c                                    |  8 +++-----\n diff.c                                      |  3 +--\n editor.c                                    |  3 +--\n fetch-pack.c                                |  3 +--\n gpg-interface.c                             |  6 ++----\n http-backend.c                              |  3 +--\n http.c                                      |  3 +--\n imap-send.c                                 |  2 +-\n prompt.c                                    |  3 +--\n remote-curl.c                               |  3 +--\n remote-testsvn.c                            |  3 +--\n run-command.h                               |  2 ++\n send-pack.c                                 |  3 +--\n submodule.c                                 | 21 +++++++--------------\n test-run-command.c                          |  4 +---\n test-subprocess.c                           |  3 +--\n transport.c                                 | 12 ++++--------\n upload-pack.c                               |  3 +--\n wt-status.c                                 |  3 +--\n 35 files changed, 51 insertions(+), 93 deletions(-)\n\ndiff --git a/Documentation/technical/api-run-command.txt b/Documentation/technical/api-run-command.txt\nindex 69510ae..ca066bf 100644\n--- a/Documentation/technical/api-run-command.txt\n+++ b/Documentation/technical/api-run-command.txt\n@@ -96,8 +96,8 @@ command to run in a sub-process.\n \n The caller:\n \n-1. allocates and clears (memset(&chld, 0, sizeof(chld));) a\n-   struct child_process variable;\n+1. allocates and clears (memset(&chld, 0, sizeof(chld)); or\n+   using CHILD_PROCESS_INIT) a struct child_process variable;\n 2. initializes the members;\n 3. calls start_command();\n 4. processes the data;\ndiff --git a/archive-tar.c b/archive-tar.c\nindex 719b629..0d1e6bd 100644\n--- a/archive-tar.c\n+++ b/archive-tar.c\n@@ -395,7 +395,7 @@ static int write_tar_filter_archive(const struct archiver *ar,\n \t\t\t\t    struct archiver_args *args)\n {\n \tstruct strbuf cmd = STRBUF_INIT;\n-\tstruct child_process filter;\n+\tstruct child_process filter = CHILD_PROCESS_INIT;\n \tconst char *argv[2];\n \tint r;\n \n@@ -406,7 +406,6 @@ static int write_tar_filter_archive(const struct archiver *ar,\n \tif (args->compression_level >= 0)\n \t\tstrbuf_addf(&cmd, \" -%d\", args->compression_level);\n \n-\tmemset(&filter, 0, sizeof(filter));\n \targv[0] = cmd.buf;\n \targv[1] = NULL;\n \tfilter.argv = argv;\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 4baf3a5..352b85e 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -180,7 +180,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix)\n \tchar *file = git_pathdup(\"ADD_EDIT.patch\");\n \tconst char *apply_argv[] = { \"apply\", \"--recount\", \"--cached\",\n \t\tNULL, NULL };\n-\tstruct child_process child;\n+\tstruct child_process child = CHILD_PROCESS_INIT;\n \tstruct rev_info rev;\n \tint out;\n \tstruct stat st;\n@@ -214,7 +214,6 @@ static int edit_patch(int argc, const char **argv, const char *prefix)\n \tif (!st.st_size)\n \t\tdie(_(\"Empty patch. Aborted.\"));\n \n-\tmemset(&child, 0, sizeof(child));\n \tchild.git_cmd = 1;\n \tchild.argv = apply_argv;\n \tif (run_command(&child))\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 5ed6036..b8b8663 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -1508,7 +1508,7 @@ static int run_rewrite_hook(const unsigned char *oldsha1,\n {\n \t/* oldsha1 SP newsha1 LF NUL */\n \tstatic char buf[2*40 + 3];\n-\tstruct child_process proc;\n+\tstruct child_process proc = CHILD_PROCESS_INIT;\n \tconst char *argv[3];\n \tint code;\n \tsize_t n;\n@@ -1520,7 +1520,6 @@ static int run_rewrite_hook(const unsigned char *oldsha1,\n \targv[1] = \"amend\";\n \targv[2] = NULL;\n \n-\tmemset(&proc, 0, sizeof(proc));\n \tproc.argv = argv;\n \tproc.in = -1;\n \tproc.stdout_to_stderr = 1;\ndiff --git a/builtin/help.c b/builtin/help.c\nindex 1fdefeb..8343b40 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -79,12 +79,11 @@ static const char *get_man_viewer_info(const char *name)\n static int check_emacsclient_version(void)\n {\n \tstruct strbuf buffer = STRBUF_INIT;\n-\tstruct child_process ec_process;\n+\tstruct child_process ec_process = CHILD_PROCESS_INIT;\n \tconst char *argv_ec[] = { \"emacsclient\", \"--version\", NULL };\n \tint version;\n \n \t/* emacsclient prints its version number on stderr */\n-\tmemset(&ec_process, 0, sizeof(ec_process));\n \tec_process.argv = argv_ec;\n \tec_process.err = -1;\n \tec_process.stdout_to_stderr = 1;\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex ce82eb2..9da9e30 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -237,11 +237,10 @@ static void drop_save(void)\n static int save_state(unsigned char *stash)\n {\n \tint len;\n-\tstruct child_process cp;\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tstruct strbuf buffer = STRBUF_INIT;\n \tconst char *argv[] = {\"stash\", \"create\", NULL};\n \n-\tmemset(&cp, 0, sizeof(cp));\n \tcp.argv = argv;\n \tcp.out = -1;\n \tcp.git_cmd = 1;\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 820c341..c25a412 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -122,12 +122,11 @@ static void write_commented_object(int fd, const unsigned char *object)\n {\n \tconst char *show_args[5] =\n \t\t{\"show\", \"--stat\", \"--no-notes\", sha1_to_hex(object), NULL};\n-\tstruct child_process show;\n+\tstruct child_process show = CHILD_PROCESS_INIT;\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct strbuf cbuf = STRBUF_INIT;\n \n \t/* Invoke \"git show --stat --no-notes $object\" */\n-\tmemset(&show, 0, sizeof(show));\n \tshow.argv = show_args;\n \tshow.no_stdin = 1;\n \tshow.out = -1;\ndiff --git a/builtin/remote-ext.c b/builtin/remote-ext.c\nindex 692c834..d699d28 100644\n--- a/builtin/remote-ext.c\n+++ b/builtin/remote-ext.c\n@@ -179,9 +179,8 @@ static void send_git_request(int stdin_fd, const char *serv, const char *repo,\n static int run_child(const char *arg, const char *service)\n {\n \tint r;\n-\tstruct child_process child;\n+\tstruct child_process child = CHILD_PROCESS_INIT;\n \n-\tmemset(&child, 0, sizeof(child));\n \tchild.in = -1;\n \tchild.out = -1;\n \tchild.err = 0;\ndiff --git a/builtin/repack.c b/builtin/repack.c\nindex a77e743..fc088db 100644\n--- a/builtin/repack.c\n+++ b/builtin/repack.c\n@@ -133,7 +133,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t{\".idx\"},\n \t\t{\".bitmap\", 1},\n \t};\n-\tstruct child_process cmd;\n+\tstruct child_process cmd = CHILD_PROCESS_INIT;\n \tstruct string_list_item *item;\n \tstruct argv_array cmd_args = ARGV_ARRAY_INIT;\n \tstruct string_list names = STRING_LIST_INIT_DUP;\n@@ -250,7 +250,6 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \n \targv_array_push(&cmd_args, packtmp);\n \n-\tmemset(&cmd, 0, sizeof(cmd));\n \tcmd.argv = cmd_args.argv;\n \tcmd.git_cmd = 1;\n \tcmd.out = -1;\ndiff --git a/builtin/replace.c b/builtin/replace.c\nindex 294b61b..d2aac64 100644\n--- a/builtin/replace.c\n+++ b/builtin/replace.c\n@@ -197,7 +197,7 @@ static int replace_object(const char *object_ref, const char *replace_ref, int f\n static void export_object(const unsigned char *sha1, enum object_type type,\n \t\t\t  int raw, const char *filename)\n {\n-\tstruct child_process cmd = { NULL };\n+\tstruct child_process cmd = CHILD_PROCESS_INIT;\n \tint fd;\n \n \tfd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);\n@@ -234,7 +234,7 @@ static void import_object(unsigned char *sha1, enum object_type type,\n \n \tif (!raw && type == OBJ_TREE) {\n \t\tconst char *argv[] = { \"mktree\", NULL };\n-\t\tstruct child_process cmd = { argv };\n+\t\tstruct child_process cmd = CHILD_PROCESS_INIT;\n \t\tstruct strbuf result = STRBUF_INIT;\n \n \t\tcmd.argv = argv;\ndiff --git a/builtin/verify-pack.c b/builtin/verify-pack.c\nindex 972579f..7747537 100644\n--- a/builtin/verify-pack.c\n+++ b/builtin/verify-pack.c\n@@ -8,7 +8,7 @@\n \n static int verify_one_pack(const char *path, unsigned int flags)\n {\n-\tstruct child_process index_pack;\n+\tstruct child_process index_pack = CHILD_PROCESS_INIT;\n \tconst char *argv[] = {\"index-pack\", NULL, NULL, NULL };\n \tstruct strbuf arg = STRBUF_INIT;\n \tint verbose = flags & VERIFY_PACK_VERBOSE;\n@@ -32,7 +32,6 @@ static int verify_one_pack(const char *path, unsigned int flags)\n \t\tstrbuf_addstr(&arg, \".pack\");\n \targv[2] = arg.buf;\n \n-\tmemset(&index_pack, 0, sizeof(index_pack));\n \tindex_pack.argv = argv;\n \tindex_pack.git_cmd = 1;\n \ndiff --git a/bundle.c b/bundle.c\nindex 71a21a6..d6b4df8 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -240,7 +240,7 @@ int create_bundle(struct bundle_header *header, const char *path,\n \tint i, ref_count = 0;\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct rev_info revs;\n-\tstruct child_process rls;\n+\tstruct child_process rls = CHILD_PROCESS_INIT;\n \tFILE *rls_fout;\n \n \tbundle_to_stdout = !strcmp(path, \"-\");\n@@ -258,7 +258,6 @@ int create_bundle(struct bundle_header *header, const char *path,\n \tinit_revisions(&revs, NULL);\n \n \t/* write prerequisites */\n-\tmemset(&rls, 0, sizeof(rls));\n \targv_array_pushl(&rls.args,\n \t\t\t \"rev-list\", \"--boundary\", \"--pretty=oneline\",\n \t\t\t NULL);\n@@ -417,14 +416,13 @@ int unbundle(struct bundle_header *header, int bundle_fd, int flags)\n {\n \tconst char *argv_index_pack[] = {\"index-pack\",\n \t\t\t\t\t \"--fix-thin\", \"--stdin\", NULL, NULL};\n-\tstruct child_process ip;\n+\tstruct child_process ip = CHILD_PROCESS_INIT;\n \n \tif (flags & BUNDLE_VERBOSE)\n \t\targv_index_pack[3] = \"-v\";\n \n \tif (verify_bundle(header, 0))\n \t\treturn -1;\n-\tmemset(&ip, 0, sizeof(ip));\n \tip.argv = argv_index_pack;\n \tip.in = bundle_fd;\n \tip.no_stdout = 1;\ndiff --git a/connected.c b/connected.c\nindex dae9c99..299c560 100644\n--- a/connected.c\n+++ b/connected.c\n@@ -25,7 +25,7 @@ static int check_everything_connected_real(sha1_iterate_fn fn,\n \t\t\t\t\t   struct transport *transport,\n \t\t\t\t\t   const char *shallow_file)\n {\n-\tstruct child_process rev_list;\n+\tstruct child_process rev_list = CHILD_PROCESS_INIT;\n \tconst char *argv[9];\n \tchar commit[41];\n \tunsigned char sha1[20];\n@@ -60,7 +60,6 @@ static int check_everything_connected_real(sha1_iterate_fn fn,\n \t\targv[ac++] = \"--quiet\";\n \targv[ac] = NULL;\n \n-\tmemset(&rev_list, 0, sizeof(rev_list));\n \trev_list.argv = argv;\n \trev_list.git_cmd = 1;\n \trev_list.in = -1;\ndiff --git a/convert.c b/convert.c\nindex cb5fbb4..aa7a139 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -321,7 +321,7 @@ static int filter_buffer(int in, int out, void *data)\n \t/*\n \t * Spawn cmd and feed the buffer contents through its stdin.\n \t */\n-\tstruct child_process child_process;\n+\tstruct child_process child_process = CHILD_PROCESS_INIT;\n \tstruct filter_params *params = (struct filter_params *)data;\n \tint write_err, status;\n \tconst char *argv[] = { NULL, NULL };\n@@ -344,7 +344,6 @@ static int filter_buffer(int in, int out, void *data)\n \n \targv[0] = cmd.buf;\n \n-\tmemset(&child_process, 0, sizeof(child_process));\n \tchild_process.argv = argv;\n \tchild_process.use_shell = 1;\n \tchild_process.in = -1;\ndiff --git a/credential-cache.c b/credential-cache.c\nindex 9a03792..8689a15 100644\n--- a/credential-cache.c\n+++ b/credential-cache.c\n@@ -37,12 +37,11 @@ static int send_request(const char *socket, const struct strbuf *out)\n \n static void spawn_daemon(const char *socket)\n {\n-\tstruct child_process daemon;\n+\tstruct child_process daemon = CHILD_PROCESS_INIT;\n \tconst char *argv[] = { NULL, NULL, NULL };\n \tchar buf[128];\n \tint r;\n \n-\tmemset(&daemon, 0, sizeof(daemon));\n \targv[0] = \"git-credential-cache--daemon\";\n \targv[1] = socket;\n \tdaemon.argv = argv;\ndiff --git a/credential.c b/credential.c\nindex 4d79d32..1886ea5 100644\n--- a/credential.c\n+++ b/credential.c\n@@ -205,11 +205,10 @@ static int run_credential_helper(struct credential *c,\n \t\t\t\t const char *cmd,\n \t\t\t\t int want_output)\n {\n-\tstruct child_process helper;\n+\tstruct child_process helper = CHILD_PROCESS_INIT;\n \tconst char *argv[] = { NULL, NULL };\n \tFILE *fp;\n \n-\tmemset(&helper, 0, sizeof(helper));\n \targv[0] = cmd;\n \thelper.argv = argv;\n \thelper.use_shell = 1;\ndiff --git a/daemon.c b/daemon.c\nindex e6b51ed..a5953de 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -259,7 +259,7 @@ static const char *access_hook;\n \n static int run_access_hook(struct daemon_service *service, const char *dir, const char *path)\n {\n-\tstruct child_process child;\n+\tstruct child_process child = CHILD_PROCESS_INIT;\n \tstruct strbuf buf = STRBUF_INIT;\n \tconst char *argv[8];\n \tconst char **arg = argv;\n@@ -277,7 +277,6 @@ static int run_access_hook(struct daemon_service *service, const char *dir, cons\n \t*arg = NULL;\n #undef STRARG\n \n-\tmemset(&child, 0, sizeof(child));\n \tchild.use_shell = 1;\n \tchild.argv = argv;\n \tchild.no_stdin = 1;\n@@ -406,9 +405,8 @@ static void copy_to_log(int fd)\n \n static int run_service_command(const char **argv)\n {\n-\tstruct child_process cld;\n+\tstruct child_process cld = CHILD_PROCESS_INIT;\n \n-\tmemset(&cld, 0, sizeof(cld));\n \tcld.argv = argv;\n \tcld.git_cmd = 1;\n \tcld.err = -1;\n@@ -733,7 +731,7 @@ static void check_dead_children(void)\n static char **cld_argv;\n static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)\n {\n-\tstruct child_process cld = { NULL };\n+\tstruct child_process cld = CHILD_PROCESS_INIT;\n \tchar addrbuf[300] = \"REMOTE_ADDR=\", portbuf[300];\n \tchar *env[] = { addrbuf, portbuf, NULL };\n \ndiff --git a/diff.c b/diff.c\nindex 867f034..e7d4d42 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -4931,7 +4931,7 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,\n \tstruct diff_tempfile *temp;\n \tconst char *argv[3];\n \tconst char **arg = argv;\n-\tstruct child_process child;\n+\tstruct child_process child = CHILD_PROCESS_INIT;\n \tstruct strbuf buf = STRBUF_INIT;\n \tint err = 0;\n \n@@ -4940,7 +4940,6 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,\n \t*arg++ = temp->name;\n \t*arg = NULL;\n \n-\tmemset(&child, 0, sizeof(child));\n \tchild.use_shell = 1;\n \tchild.argv = argv;\n \tchild.out = -1;\ndiff --git a/editor.c b/editor.c\nindex 0abbd8d..01c644c 100644\n--- a/editor.c\n+++ b/editor.c\n@@ -38,10 +38,9 @@ int launch_editor(const char *path, struct strbuf *buffer, const char *const *en\n \n \tif (strcmp(editor, \":\")) {\n \t\tconst char *args[] = { editor, real_path(path), NULL };\n-\t\tstruct child_process p;\n+\t\tstruct child_process p = CHILD_PROCESS_INIT;\n \t\tint ret, sig;\n \n-\t\tmemset(&p, 0, sizeof(p));\n \t\tp.argv = args;\n \t\tp.env = env;\n \t\tp.use_shell = 1;\ndiff --git a/fetch-pack.c b/fetch-pack.c\nindex b8a58fa..18d4c8f 100644\n--- a/fetch-pack.c\n+++ b/fetch-pack.c\n@@ -666,7 +666,7 @@ static int get_pack(struct fetch_pack_args *args,\n \tchar hdr_arg[256];\n \tconst char **av, *cmd_name;\n \tint do_keep = args->keep_pack;\n-\tstruct child_process cmd;\n+\tstruct child_process cmd = CHILD_PROCESS_INIT;\n \tint ret;\n \n \tmemset(&demux, 0, sizeof(demux));\n@@ -685,7 +685,6 @@ static int get_pack(struct fetch_pack_args *args,\n \telse\n \t\tdemux.out = xd[0];\n \n-\tmemset(&cmd, 0, sizeof(cmd));\n \tcmd.argv = argv;\n \tav = argv;\n \t*hdr_arg = 0;\ndiff --git a/gpg-interface.c b/gpg-interface.c\nindex ff07012..1ef73fb 100644\n--- a/gpg-interface.c\n+++ b/gpg-interface.c\n@@ -55,12 +55,11 @@ const char *get_signing_key(void)\n  */\n int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key)\n {\n-\tstruct child_process gpg;\n+\tstruct child_process gpg = CHILD_PROCESS_INIT;\n \tconst char *args[4];\n \tssize_t len;\n \tsize_t i, j, bottom;\n \n-\tmemset(&gpg, 0, sizeof(gpg));\n \tgpg.argv = args;\n \tgpg.in = -1;\n \tgpg.out = -1;\n@@ -116,7 +115,7 @@ int verify_signed_buffer(const char *payload, size_t payload_size,\n \t\t\t const char *signature, size_t signature_size,\n \t\t\t struct strbuf *gpg_output, struct strbuf *gpg_status)\n {\n-\tstruct child_process gpg;\n+\tstruct child_process gpg = CHILD_PROCESS_INIT;\n \tconst char *args_gpg[] = {NULL, \"--status-fd=1\", \"--verify\", \"FILE\", \"-\", NULL};\n \tchar path[PATH_MAX];\n \tint fd, ret;\n@@ -133,7 +132,6 @@ int verify_signed_buffer(const char *payload, size_t payload_size,\n \t\t\t     path, strerror(errno));\n \tclose(fd);\n \n-\tmemset(&gpg, 0, sizeof(gpg));\n \tgpg.argv = args_gpg;\n \tgpg.in = -1;\n \tgpg.out = -1;\ndiff --git a/http-backend.c b/http-backend.c\nindex 80790bb..2d4d105 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -323,7 +323,7 @@ static void run_service(const char **argv)\n \tconst char *host = getenv(\"REMOTE_ADDR\");\n \tstruct argv_array env = ARGV_ARRAY_INIT;\n \tint gzipped_request = 0;\n-\tstruct child_process cld;\n+\tstruct child_process cld = CHILD_PROCESS_INIT;\n \n \tif (encoding && !strcmp(encoding, \"gzip\"))\n \t\tgzipped_request = 1;\n@@ -341,7 +341,6 @@ static void run_service(const char **argv)\n \t\targv_array_pushf(&env, \"GIT_COMMITTER_EMAIL=%s@http.%s\",\n \t\t\t\t user, host);\n \n-\tmemset(&cld, 0, sizeof(cld));\n \tcld.argv = argv;\n \tcld.env = env.argv;\n \tif (gzipped_request)\ndiff --git a/http.c b/http.c\nindex c8cd50d..a23c399 100644\n--- a/http.c\n+++ b/http.c\n@@ -1332,7 +1332,7 @@ int finish_http_pack_request(struct http_pack_request *preq)\n \tstruct packed_git **lst;\n \tstruct packed_git *p = preq->target;\n \tchar *tmp_idx;\n-\tstruct child_process ip;\n+\tstruct child_process ip = CHILD_PROCESS_INIT;\n \tconst char *ip_argv[8];\n \n \tclose_pack_index(p);\n@@ -1355,7 +1355,6 @@ int finish_http_pack_request(struct http_pack_request *preq)\n \tip_argv[3] = preq->tmpfile;\n \tip_argv[4] = NULL;\n \n-\tmemset(&ip, 0, sizeof(ip));\n \tip.argv = ip_argv;\n \tip.git_cmd = 1;\n \tip.no_stdin = 1;\ndiff --git a/imap-send.c b/imap-send.c\nindex 524fbab..d8fb10f 100644\n--- a/imap-send.c\n+++ b/imap-send.c\n@@ -962,7 +962,7 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc)\n \n \tif (srvc->tunnel) {\n \t\tconst char *argv[] = { srvc->tunnel, NULL };\n-\t\tstruct child_process tunnel = {NULL};\n+\t\tstruct child_process tunnel = CHILD_PROCESS_INIT;\n \n \t\timap_info(\"Starting tunnel '%s'... \", srvc->tunnel);\n \ndiff --git a/prompt.c b/prompt.c\nindex d7bb17c..e5b4938 100644\n--- a/prompt.c\n+++ b/prompt.c\n@@ -6,7 +6,7 @@\n \n static char *do_askpass(const char *cmd, const char *prompt)\n {\n-\tstruct child_process pass;\n+\tstruct child_process pass = CHILD_PROCESS_INIT;\n \tconst char *args[3];\n \tstatic struct strbuf buffer = STRBUF_INIT;\n \tint err = 0;\n@@ -15,7 +15,6 @@ static char *do_askpass(const char *cmd, const char *prompt)\n \targs[1]\t= prompt;\n \targs[2] = NULL;\n \n-\tmemset(&pass, 0, sizeof(pass));\n \tpass.argv = args;\n \tpass.out = -1;\n \ndiff --git a/remote-curl.c b/remote-curl.c\nindex 0fcf2ce..017ddd9 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -623,10 +623,9 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)\n \tconst char *svc = rpc->service_name;\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct strbuf *preamble = rpc->stdin_preamble;\n-\tstruct child_process client;\n+\tstruct child_process client = CHILD_PROCESS_INIT;\n \tint err = 0;\n \n-\tmemset(&client, 0, sizeof(client));\n \tclient.in = -1;\n \tclient.out = -1;\n \tclient.git_cmd = 1;\ndiff --git a/remote-testsvn.c b/remote-testsvn.c\nindex 686e07d..48bf6eb 100644\n--- a/remote-testsvn.c\n+++ b/remote-testsvn.c\n@@ -175,7 +175,7 @@ static int cmd_import(const char *line)\n \tchar *note_msg;\n \tunsigned char head_sha1[20];\n \tunsigned int startrev;\n-\tstruct child_process svndump_proc;\n+\tstruct child_process svndump_proc = CHILD_PROCESS_INIT;\n \tconst char *command = \"svnrdump\";\n \n \tif (read_ref(private_ref, head_sha1))\n@@ -200,7 +200,6 @@ static int cmd_import(const char *line)\n \t\tif(dumpin_fd < 0)\n \t\t\tdie_errno(\"Couldn't open svn dump file %s.\", url);\n \t} else {\n-\t\tmemset(&svndump_proc, 0, sizeof(struct child_process));\n \t\tsvndump_proc.out = -1;\n \t\targv_array_push(&svndump_proc.args, command);\n \t\targv_array_push(&svndump_proc.args, \"dump\");\ndiff --git a/run-command.h b/run-command.h\nindex ea73de3..95a8fb8 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -44,6 +44,8 @@ struct child_process {\n \tunsigned clean_on_exit:1;\n };\n \n+#define CHILD_PROCESS_INIT { NULL }\n+\n int start_command(struct child_process *);\n int finish_command(struct child_process *);\n int run_command(struct child_process *);\ndiff --git a/send-pack.c b/send-pack.c\nindex 6129b0f..8b4cbf0 100644\n--- a/send-pack.c\n+++ b/send-pack.c\n@@ -47,7 +47,7 @@ static int pack_objects(int fd, struct ref *refs, struct sha1_array *extra, stru\n \t\tNULL,\n \t\tNULL,\n \t};\n-\tstruct child_process po;\n+\tstruct child_process po = CHILD_PROCESS_INIT;\n \tint i;\n \n \ti = 4;\n@@ -59,7 +59,6 @@ static int pack_objects(int fd, struct ref *refs, struct sha1_array *extra, stru\n \t\targv[i++] = \"-q\";\n \tif (args->progress)\n \t\targv[i++] = \"--progress\";\n-\tmemset(&po, 0, sizeof(po));\n \tpo.argv = argv;\n \tpo.in = -1;\n \tpo.out = args->stateless_rpc ? -1 : fd;\ndiff --git a/submodule.c b/submodule.c\nindex c3a61e7..0690dc5 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -433,13 +433,12 @@ static int submodule_needs_pushing(const char *path, const unsigned char sha1[20\n \t\treturn 0;\n \n \tif (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {\n-\t\tstruct child_process cp;\n+\t\tstruct child_process cp = CHILD_PROCESS_INIT;\n \t\tconst char *argv[] = {\"rev-list\", NULL, \"--not\", \"--remotes\", \"-n\", \"1\" , NULL};\n \t\tstruct strbuf buf = STRBUF_INIT;\n \t\tint needs_pushing = 0;\n \n \t\targv[1] = sha1_to_hex(sha1);\n-\t\tmemset(&cp, 0, sizeof(cp));\n \t\tcp.argv = argv;\n \t\tcp.env = local_repo_env;\n \t\tcp.git_cmd = 1;\n@@ -524,10 +523,9 @@ static int push_submodule(const char *path)\n \t\treturn 1;\n \n \tif (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {\n-\t\tstruct child_process cp;\n+\t\tstruct child_process cp = CHILD_PROCESS_INIT;\n \t\tconst char *argv[] = {\"push\", NULL};\n \n-\t\tmemset(&cp, 0, sizeof(cp));\n \t\tcp.argv = argv;\n \t\tcp.env = local_repo_env;\n \t\tcp.git_cmd = 1;\n@@ -569,12 +567,11 @@ static int is_submodule_commit_present(const char *path, unsigned char sha1[20])\n \tif (!add_submodule_odb(path) && lookup_commit_reference(sha1)) {\n \t\t/* Even if the submodule is checked out and the commit is\n \t\t * present, make sure it is reachable from a ref. */\n-\t\tstruct child_process cp;\n+\t\tstruct child_process cp = CHILD_PROCESS_INIT;\n \t\tconst char *argv[] = {\"rev-list\", \"-n\", \"1\", NULL, \"--not\", \"--all\", NULL};\n \t\tstruct strbuf buf = STRBUF_INIT;\n \n \t\targv[3] = sha1_to_hex(sha1);\n-\t\tmemset(&cp, 0, sizeof(cp));\n \t\tcp.argv = argv;\n \t\tcp.env = local_repo_env;\n \t\tcp.git_cmd = 1;\n@@ -695,7 +692,7 @@ int fetch_populated_submodules(const struct argv_array *options,\n \t\t\t       int quiet)\n {\n \tint i, result = 0;\n-\tstruct child_process cp;\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tstruct argv_array argv = ARGV_ARRAY_INIT;\n \tstruct string_list_item *name_for_path;\n \tconst char *work_tree = get_git_work_tree();\n@@ -711,7 +708,6 @@ int fetch_populated_submodules(const struct argv_array *options,\n \targv_array_push(&argv, \"--recurse-submodules-default\");\n \t/* default value, \"--submodule-prefix\" and its value are added later */\n \n-\tmemset(&cp, 0, sizeof(cp));\n \tcp.env = local_repo_env;\n \tcp.git_cmd = 1;\n \tcp.no_stdin = 1;\n@@ -794,7 +790,7 @@ out:\n unsigned is_submodule_modified(const char *path, int ignore_untracked)\n {\n \tssize_t len;\n-\tstruct child_process cp;\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tconst char *argv[] = {\n \t\t\"status\",\n \t\t\"--porcelain\",\n@@ -821,7 +817,6 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)\n \tif (ignore_untracked)\n \t\targv[2] = \"-uno\";\n \n-\tmemset(&cp, 0, sizeof(cp));\n \tcp.argv = argv;\n \tcp.env = local_repo_env;\n \tcp.git_cmd = 1;\n@@ -862,7 +857,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)\n \n int submodule_uses_gitfile(const char *path)\n {\n-\tstruct child_process cp;\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tconst char *argv[] = {\n \t\t\"submodule\",\n \t\t\"foreach\",\n@@ -883,7 +878,6 @@ int submodule_uses_gitfile(const char *path)\n \tstrbuf_release(&buf);\n \n \t/* Now test that all nested submodules use a gitfile too */\n-\tmemset(&cp, 0, sizeof(cp));\n \tcp.argv = argv;\n \tcp.env = local_repo_env;\n \tcp.git_cmd = 1;\n@@ -901,7 +895,7 @@ int ok_to_remove_submodule(const char *path)\n {\n \tstruct stat st;\n \tssize_t len;\n-\tstruct child_process cp;\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tconst char *argv[] = {\n \t\t\"status\",\n \t\t\"--porcelain\",\n@@ -918,7 +912,6 @@ int ok_to_remove_submodule(const char *path)\n \tif (!submodule_uses_gitfile(path))\n \t\treturn 0;\n \n-\tmemset(&cp, 0, sizeof(cp));\n \tcp.argv = argv;\n \tcp.env = local_repo_env;\n \tcp.git_cmd = 1;\ndiff --git a/test-run-command.c b/test-run-command.c\nindex 37918e1..89c7de2 100644\n--- a/test-run-command.c\n+++ b/test-run-command.c\n@@ -15,9 +15,7 @@\n \n int main(int argc, char **argv)\n {\n-\tstruct child_process proc;\n-\n-\tmemset(&proc, 0, sizeof(proc));\n+\tstruct child_process proc = CHILD_PROCESS_INIT;\n \n \tif (argc < 3)\n \t\treturn 1;\ndiff --git a/test-subprocess.c b/test-subprocess.c\nindex 93525eb..56881a0 100644\n--- a/test-subprocess.c\n+++ b/test-subprocess.c\n@@ -3,7 +3,7 @@\n \n int main(int argc, char **argv)\n {\n-\tstruct child_process cp;\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tint nogit = 0;\n \n \tsetup_git_directory_gently(&nogit);\n@@ -13,7 +13,6 @@ int main(int argc, char **argv)\n \t\tsetup_work_tree();\n \t\targv++;\n \t}\n-\tmemset(&cp, 0, sizeof(cp));\n \tcp.git_cmd = 1;\n \tcp.argv = (const char **)argv + 1;\n \treturn run_command(&cp);\ndiff --git a/transport.c b/transport.c\nindex 662421b..7388bb8 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -201,7 +201,7 @@ static struct ref *get_refs_via_rsync(struct transport *transport, int for_push)\n {\n \tstruct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;\n \tstruct ref dummy = {NULL}, *tail = &dummy;\n-\tstruct child_process rsync;\n+\tstruct child_process rsync = CHILD_PROCESS_INIT;\n \tconst char *args[5];\n \tint temp_dir_len;\n \n@@ -218,7 +218,6 @@ static struct ref *get_refs_via_rsync(struct transport *transport, int for_push)\n \tstrbuf_addstr(&buf, rsync_url(transport->url));\n \tstrbuf_addstr(&buf, \"/refs\");\n \n-\tmemset(&rsync, 0, sizeof(rsync));\n \trsync.argv = args;\n \trsync.stdout_to_stderr = 1;\n \targs[0] = \"rsync\";\n@@ -263,9 +262,8 @@ static struct ref *get_refs_via_rsync(struct transport *transport, int for_push)\n static int fetch_objs_via_rsync(struct transport *transport,\n \t\t\t\tint nr_objs, struct ref **to_fetch)\n {\n-\tstruct child_process rsync;\n+\tstruct child_process rsync = CHILD_PROCESS_INIT;\n \n-\tmemset(&rsync, 0, sizeof(rsync));\n \trsync.stdout_to_stderr = 1;\n \targv_array_push(&rsync.args, \"rsync\");\n \targv_array_push(&rsync.args, (transport->verbose > 1) ? \"-rv\" : \"-r\");\n@@ -327,7 +325,7 @@ static int rsync_transport_push(struct transport *transport,\n {\n \tstruct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;\n \tint result = 0, i;\n-\tstruct child_process rsync;\n+\tstruct child_process rsync = CHILD_PROCESS_INIT;\n \tconst char *args[10];\n \n \tif (flags & TRANSPORT_PUSH_MIRROR)\n@@ -338,7 +336,6 @@ static int rsync_transport_push(struct transport *transport,\n \tstrbuf_addstr(&buf, rsync_url(transport->url));\n \tstrbuf_addch(&buf, '/');\n \n-\tmemset(&rsync, 0, sizeof(rsync));\n \trsync.argv = args;\n \trsync.stdout_to_stderr = 1;\n \ti = 0;\n@@ -1056,7 +1053,7 @@ static int run_pre_push_hook(struct transport *transport,\n {\n \tint ret = 0, x;\n \tstruct ref *r;\n-\tstruct child_process proc;\n+\tstruct child_process proc = CHILD_PROCESS_INIT;\n \tstruct strbuf buf;\n \tconst char *argv[4];\n \n@@ -1067,7 +1064,6 @@ static int run_pre_push_hook(struct transport *transport,\n \targv[2] = transport->url;\n \targv[3] = NULL;\n \n-\tmemset(&proc, 0, sizeof(proc));\n \tproc.argv = argv;\n \tproc.in = -1;\n \ndiff --git a/upload-pack.c b/upload-pack.c\nindex 01de944..3c5aebc 100644\n--- a/upload-pack.c\n+++ b/upload-pack.c\n@@ -80,7 +80,7 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data)\n \n static void create_pack_file(void)\n {\n-\tstruct child_process pack_objects;\n+\tstruct child_process pack_objects = CHILD_PROCESS_INIT;\n \tchar data[8193], progress[128];\n \tchar abort_msg[] = \"aborting due to possible repository \"\n \t\t\"corruption on the remote side.\";\n@@ -108,7 +108,6 @@ static void create_pack_file(void)\n \t\targv[arg++] = \"--include-tag\";\n \targv[arg++] = NULL;\n \n-\tmemset(&pack_objects, 0, sizeof(pack_objects));\n \tpack_objects.in = -1;\n \tpack_objects.out = -1;\n \tpack_objects.err = -1;\ndiff --git a/wt-status.c b/wt-status.c\nindex 27da529..1bf5d72 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -725,7 +725,7 @@ static void wt_status_print_changed(struct wt_status *s)\n \n static void wt_status_print_submodule_summary(struct wt_status *s, int uncommitted)\n {\n-\tstruct child_process sm_summary;\n+\tstruct child_process sm_summary = CHILD_PROCESS_INIT;\n \tstruct argv_array env = ARGV_ARRAY_INIT;\n \tstruct argv_array argv = ARGV_ARRAY_INIT;\n \tstruct strbuf cmd_stdout = STRBUF_INIT;\n@@ -744,7 +744,6 @@ static void wt_status_print_submodule_summary(struct wt_status *s, int uncommitt\n \tif (!uncommitted)\n \t\targv_array_push(&argv, s->amend ? \"HEAD^\" : \"HEAD\");\n \n-\tmemset(&sm_summary, 0, sizeof(sm_summary));\n \tsm_summary.argv = argv.argv;\n \tsm_summary.env = env.argv;\n \tsm_summary.git_cmd = 1;\n-- \n2.1.0\n"},{"id":"247800","messageId":"20140817071230.GB23808@peff.net","threadId":"37363","inReplyTo":"53EFE15B.7030805@web.de","subject":"Re: [PATCH] run-command: introduce CHILD_PROCESS_INIT","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-08-17T07:12:31Z","receivedAt":"2014-08-17T07:12:31Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Aug 17, 2014 at 12:55:23AM +0200, René Scharfe wrote:\n\n> Most struct child_process variables are cleared using memset right after\n> declaration.  Provide a macro, CHILD_PROCESS_INIT, that can be used to\n> initialize them statically instead.  That's shorter, doesn't require a\n> function call and is slightly more readable (especially given that we\n> already have similar macros like STRBUF_INIT, ARGV_ARRAY_INIT etc.).\n\nI think one reason we never had an INIT macro here is that you cannot\nsimply use the struct after zero-ing it anyway. That's just the first\nstep, and then you have to tweak a bunch of fields to get what you want.\nSo the memset is just one setup line out of many.\n\nStill, I think this is probably an improvement for the reasons you give\nabove, and we can still memset() in any cases where it makes sense.\n\nPatch itself looks obviously correct.\n\n-Peff\n"},{"id":"247802","messageId":"53F05906.9070909@web.de","threadId":"37363","inReplyTo":"20140817071230.GB23808@peff.net","subject":"Re: [PATCH] run-command: introduce CHILD_PROCESS_INIT","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-08-17T07:25:58Z","receivedAt":"2014-08-17T07:25:58Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 17.08.2014 um 09:12 schrieb Jeff King:\n> On Sun, Aug 17, 2014 at 12:55:23AM +0200, René Scharfe wrote:\n>\n>> Most struct child_process variables are cleared using memset right after\n>> declaration.  Provide a macro, CHILD_PROCESS_INIT, that can be used to\n>> initialize them statically instead.  That's shorter, doesn't require a\n>> function call and is slightly more readable (especially given that we\n>> already have similar macros like STRBUF_INIT, ARGV_ARRAY_INIT etc.).\n>\n> I think one reason we never had an INIT macro here is that you cannot\n> simply use the struct after zero-ing it anyway. That's just the first\n> step, and then you have to tweak a bunch of fields to get what you want.\n> So the memset is just one setup line out of many.\n\nSome (or most?) of these steps could be converted to named\ninitializers -- once all supported platforms provide them..\n\nRené\n"},{"id":"247804","messageId":"20140817072909.GE23808@peff.net","threadId":"37363","inReplyTo":"53F05906.9070909@web.de","subject":"Re: [PATCH] run-command: introduce CHILD_PROCESS_INIT","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-08-17T07:29:09Z","receivedAt":"2014-08-17T07:29:09Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Aug 17, 2014 at 09:25:58AM +0200, René Scharfe wrote:\n\n> >I think one reason we never had an INIT macro here is that you cannot\n> >simply use the struct after zero-ing it anyway. That's just the first\n> >step, and then you have to tweak a bunch of fields to get what you want.\n> >So the memset is just one setup line out of many.\n> \n> Some (or most?) of these steps could be converted to named\n> initializers -- once all supported platforms provide them..\n\nYeah, I'd be fine with that, but I am not holding my breath on the\n\"once...\" in your statement. :)\n\n-Peff\n"},{"id":"247807","messageId":"53F05DE2.5080806@kdbg.org","threadId":"37363","inReplyTo":"53EFE15B.7030805@web.de","subject":"Re: [PATCH] run-command: introduce CHILD_PROCESS_INIT","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2014-08-17T07:46:42Z","receivedAt":"2014-08-17T07:46:42Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 17.08.2014 00:55, schrieb René Scharfe:\n> Most struct child_process variables are cleared using memset right after\n> declaration.  Provide a macro, CHILD_PROCESS_INIT, that can be used to\n> initialize them statically instead.  That's shorter, doesn't require a\n> function call and is slightly more readable (especially given that we\n> already have similar macros like STRBUF_INIT, ARGV_ARRAY_INIT etc.).\n\nThis is a step in the right direction, IMO. This way to initialize the\nstruct feels mucth better because it does not depend on that the bit\npattern of the NULL pointer is all zeros.\n\n> Signed-off-by: Rene Scharfe <l.s.r@web.de>\n> ---\n>  Documentation/technical/api-run-command.txt |  4 ++--\n>  archive-tar.c                               |  3 +--\n>  builtin/add.c                               |  3 +--\n>  builtin/commit.c                            |  3 +--\n>  builtin/help.c                              |  3 +--\n>  builtin/merge.c                             |  3 +--\n>  builtin/notes.c                             |  3 +--\n>  builtin/remote-ext.c                        |  3 +--\n>  builtin/repack.c                            |  3 +--\n>  builtin/replace.c                           |  4 ++--\n>  builtin/verify-pack.c                       |  3 +--\n>  bundle.c                                    |  6 ++----\n>  connected.c                                 |  3 +--\n>  convert.c                                   |  3 +--\n>  credential-cache.c                          |  3 +--\n>  credential.c                                |  3 +--\n>  daemon.c                                    |  8 +++-----\n>  diff.c                                      |  3 +--\n>  editor.c                                    |  3 +--\n>  fetch-pack.c                                |  3 +--\n>  gpg-interface.c                             |  6 ++----\n>  http-backend.c                              |  3 +--\n>  http.c                                      |  3 +--\n>  imap-send.c                                 |  2 +-\n>  prompt.c                                    |  3 +--\n>  remote-curl.c                               |  3 +--\n>  remote-testsvn.c                            |  3 +--\n>  run-command.h                               |  2 ++\n>  send-pack.c                                 |  3 +--\n>  submodule.c                                 | 21 +++++++--------------\n>  test-run-command.c                          |  4 +---\n>  test-subprocess.c                           |  3 +--\n>  transport.c                                 | 12 ++++--------\n>  upload-pack.c                               |  3 +--\n>  wt-status.c                                 |  3 +--\n>  35 files changed, 51 insertions(+), 93 deletions(-)\n\nYou missed a few instances in builtin/receive-pack.c. Is this deliberate?\n\nAnother one is in transport-helper.c::fetch_with_import() that is\ncurrently initialized in get_importer(), and another one in\npush_refs_with_export() that is initialized in get_exporter().\n\nShould the static struct child_process variables in pager.c and\nconnect.c use the macro? It would just be for completeness, but does not\nchange the correctness. I dunno.\n\n> diff --git a/run-command.h b/run-command.h\n> index ea73de3..95a8fb8 100644\n> --- a/run-command.h\n> +++ b/run-command.h\n> @@ -44,6 +44,8 @@ struct child_process {\n>  \tunsigned clean_on_exit:1;\n>  };\n>  \n> +#define CHILD_PROCESS_INIT { NULL }\n\nI would have expected this to read\n\n#define CHILD_PROCESS_INIT { NULL, ARGV_ARRAY_INIT }\n\nIt does change the bit pattern of the initialized struct child_process\nbecause ARGV_ARRAY_INIT uses a non-NULL address. But IMHO\nARGV_ARRAY_INIT should be used here as a defensive measure.\n\n-- Hannes\n"},{"id":"247812","messageId":"20140817084832.GL23808@peff.net","threadId":"37363","inReplyTo":"53F05DE2.5080806@kdbg.org","subject":"Re: [PATCH] run-command: introduce CHILD_PROCESS_INIT","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-08-17T08:48:32Z","receivedAt":"2014-08-17T08:48:32Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Aug 17, 2014 at 09:46:42AM +0200, Johannes Sixt wrote:\n\n> This is a step in the right direction, IMO. This way to initialize the\n> struct feels mucth better because it does not depend on that the bit\n> pattern of the NULL pointer is all zeros.\n\nI think platforms with NULL as something besides all-bits-zero are a\nlost cause with git. There are so many struct memsets that depend on\nthis (and it's probably not actually worth caring about).\n\n> > +#define CHILD_PROCESS_INIT { NULL }\n> \n> I would have expected this to read\n> \n> #define CHILD_PROCESS_INIT { NULL, ARGV_ARRAY_INIT }\n> \n> It does change the bit pattern of the initialized struct child_process\n> because ARGV_ARRAY_INIT uses a non-NULL address. But IMHO\n> ARGV_ARRAY_INIT should be used here as a defensive measure.\n\nI'd be OK with that.  The argv_array code is specifically OK with an\nall-bits-zero initialization. The only thing you don't get is that an\nempty array is non-NULL, but that should never matter here (true, we'd\nsegfault if you didn't add anything to the array, but that is clearly a\nbug that needs to be fixed either way).\n\nI'm a little worried, though, that use sites without initializers would\nbe left behind. For example, git_proxy_connect uses xcalloc to allocate\nthe child_process, which results in all-bits-zero. If we want to start\ncaring about the initialization, we probably need to provide a\nchild_process_init() function and use it consistently.\n\n-Peff\n"},{"id":"247849","messageId":"xmqq61hpybs9.fsf@gitster.dls.corp.google.com","threadId":"37363","inReplyTo":"20140817084832.GL23808@peff.net","subject":"Re: [PATCH] run-command: introduce CHILD_PROCESS_INIT","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-08-18T16:59:02Z","receivedAt":"2014-08-18T16:59:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> I'm a little worried, though, that use sites without initializers would\n> be left behind. For example, git_proxy_connect uses xcalloc to allocate\n> the child_process, which results in all-bits-zero. If we want to start\n> caring about the initialization, we probably need to provide a\n> child_process_init() function and use it consistently.\n\nThanks.  Perhaps I can expect a v2 from René?\n"},{"id":"247957","messageId":"53F3A0EF.7050107@web.de","threadId":"37363","inReplyTo":"xmqq61hpybs9.fsf@gitster.dls.corp.google.com","subject":"[PATCH v2 1/4] run-command: introduce CHILD_PROCESS_INIT","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-08-19T19:09:35Z","receivedAt":"2014-08-19T19:09:35Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Most struct child_process variables are cleared using memset first after\ndeclaration.  Provide a macro, CHILD_PROCESS_INIT, that can be used to\ninitialize them statically instead.  That's shorter, doesn't require a\nfunction call and is slightly more readable (especially given that we\nalready have STRBUF_INIT, ARGV_ARRAY_INIT etc.).\n\nHelped-by: Johannes Sixt <j6t@kdbg.org>\nSigned-off-by: Rene Scharfe <l.s.r@web.de>\n---\nNow with ARGV_ARRAY_INIT and more conversions.\n\n Documentation/technical/api-run-command.txt |  4 ++--\n archive-tar.c                               |  3 +--\n builtin/add.c                               |  3 +--\n builtin/commit.c                            |  3 +--\n builtin/help.c                              |  3 +--\n builtin/merge.c                             |  3 +--\n builtin/notes.c                             |  3 +--\n builtin/receive-pack.c                      | 12 ++++--------\n builtin/remote-ext.c                        |  3 +--\n builtin/repack.c                            |  3 +--\n builtin/replace.c                           |  4 ++--\n builtin/verify-pack.c                       |  3 +--\n bundle.c                                    |  6 ++----\n column.c                                    |  2 +-\n connect.c                                   |  2 +-\n connected.c                                 |  3 +--\n convert.c                                   |  3 +--\n credential-cache.c                          |  3 +--\n credential.c                                |  3 +--\n daemon.c                                    |  8 +++-----\n diff.c                                      |  3 +--\n editor.c                                    |  3 +--\n fetch-pack.c                                |  3 +--\n gpg-interface.c                             |  6 ++----\n http-backend.c                              |  3 +--\n http.c                                      |  3 +--\n imap-send.c                                 |  2 +-\n pager.c                                     |  2 +-\n prompt.c                                    |  3 +--\n remote-curl.c                               |  3 +--\n remote-testsvn.c                            |  3 +--\n run-command.c                               |  3 +--\n run-command.h                               |  2 ++\n send-pack.c                                 |  3 +--\n submodule.c                                 | 21 +++++++--------------\n test-run-command.c                          |  4 +---\n test-subprocess.c                           |  3 +--\n transport.c                                 | 12 ++++--------\n upload-pack.c                               |  5 ++---\n wt-status.c                                 |  3 +--\n 40 files changed, 60 insertions(+), 107 deletions(-)\n\ndiff --git a/Documentation/technical/api-run-command.txt b/Documentation/technical/api-run-command.txt\nindex 69510ae..ca066bf 100644\n--- a/Documentation/technical/api-run-command.txt\n+++ b/Documentation/technical/api-run-command.txt\n@@ -96,8 +96,8 @@ command to run in a sub-process.\n \n The caller:\n \n-1. allocates and clears (memset(&chld, 0, sizeof(chld));) a\n-   struct child_process variable;\n+1. allocates and clears (memset(&chld, 0, sizeof(chld)); or\n+   using CHILD_PROCESS_INIT) a struct child_process variable;\n 2. initializes the members;\n 3. calls start_command();\n 4. processes the data;\ndiff --git a/archive-tar.c b/archive-tar.c\nindex 719b629..0d1e6bd 100644\n--- a/archive-tar.c\n+++ b/archive-tar.c\n@@ -395,7 +395,7 @@ static int write_tar_filter_archive(const struct archiver *ar,\n \t\t\t\t    struct archiver_args *args)\n {\n \tstruct strbuf cmd = STRBUF_INIT;\n-\tstruct child_process filter;\n+\tstruct child_process filter = CHILD_PROCESS_INIT;\n \tconst char *argv[2];\n \tint r;\n \n@@ -406,7 +406,6 @@ static int write_tar_filter_archive(const struct archiver *ar,\n \tif (args->compression_level >= 0)\n \t\tstrbuf_addf(&cmd, \" -%d\", args->compression_level);\n \n-\tmemset(&filter, 0, sizeof(filter));\n \targv[0] = cmd.buf;\n \targv[1] = NULL;\n \tfilter.argv = argv;\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 4baf3a5..352b85e 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -180,7 +180,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix)\n \tchar *file = git_pathdup(\"ADD_EDIT.patch\");\n \tconst char *apply_argv[] = { \"apply\", \"--recount\", \"--cached\",\n \t\tNULL, NULL };\n-\tstruct child_process child;\n+\tstruct child_process child = CHILD_PROCESS_INIT;\n \tstruct rev_info rev;\n \tint out;\n \tstruct stat st;\n@@ -214,7 +214,6 @@ static int edit_patch(int argc, const char **argv, const char *prefix)\n \tif (!st.st_size)\n \t\tdie(_(\"Empty patch. Aborted.\"));\n \n-\tmemset(&child, 0, sizeof(child));\n \tchild.git_cmd = 1;\n \tchild.argv = apply_argv;\n \tif (run_command(&child))\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 5ed6036..b8b8663 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -1508,7 +1508,7 @@ static int run_rewrite_hook(const unsigned char *oldsha1,\n {\n \t/* oldsha1 SP newsha1 LF NUL */\n \tstatic char buf[2*40 + 3];\n-\tstruct child_process proc;\n+\tstruct child_process proc = CHILD_PROCESS_INIT;\n \tconst char *argv[3];\n \tint code;\n \tsize_t n;\n@@ -1520,7 +1520,6 @@ static int run_rewrite_hook(const unsigned char *oldsha1,\n \targv[1] = \"amend\";\n \targv[2] = NULL;\n \n-\tmemset(&proc, 0, sizeof(proc));\n \tproc.argv = argv;\n \tproc.in = -1;\n \tproc.stdout_to_stderr = 1;\ndiff --git a/builtin/help.c b/builtin/help.c\nindex 1fdefeb..8343b40 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -79,12 +79,11 @@ static const char *get_man_viewer_info(const char *name)\n static int check_emacsclient_version(void)\n {\n \tstruct strbuf buffer = STRBUF_INIT;\n-\tstruct child_process ec_process;\n+\tstruct child_process ec_process = CHILD_PROCESS_INIT;\n \tconst char *argv_ec[] = { \"emacsclient\", \"--version\", NULL };\n \tint version;\n \n \t/* emacsclient prints its version number on stderr */\n-\tmemset(&ec_process, 0, sizeof(ec_process));\n \tec_process.argv = argv_ec;\n \tec_process.err = -1;\n \tec_process.stdout_to_stderr = 1;\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex ce82eb2..9da9e30 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -237,11 +237,10 @@ static void drop_save(void)\n static int save_state(unsigned char *stash)\n {\n \tint len;\n-\tstruct child_process cp;\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tstruct strbuf buffer = STRBUF_INIT;\n \tconst char *argv[] = {\"stash\", \"create\", NULL};\n \n-\tmemset(&cp, 0, sizeof(cp));\n \tcp.argv = argv;\n \tcp.out = -1;\n \tcp.git_cmd = 1;\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 820c341..c25a412 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -122,12 +122,11 @@ static void write_commented_object(int fd, const unsigned char *object)\n {\n \tconst char *show_args[5] =\n \t\t{\"show\", \"--stat\", \"--no-notes\", sha1_to_hex(object), NULL};\n-\tstruct child_process show;\n+\tstruct child_process show = CHILD_PROCESS_INIT;\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct strbuf cbuf = STRBUF_INIT;\n \n \t/* Invoke \"git show --stat --no-notes $object\" */\n-\tmemset(&show, 0, sizeof(show));\n \tshow.argv = show_args;\n \tshow.no_stdin = 1;\n \tshow.out = -1;\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex f93ac45..5ad9075 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -255,7 +255,7 @@ static int copy_to_sideband(int in, int out, void *arg)\n typedef int (*feed_fn)(void *, const char **, size_t *);\n static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_state)\n {\n-\tstruct child_process proc;\n+\tstruct child_process proc = CHILD_PROCESS_INIT;\n \tstruct async muxer;\n \tconst char *argv[2];\n \tint code;\n@@ -266,7 +266,6 @@ static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_sta\n \n \targv[1] = NULL;\n \n-\tmemset(&proc, 0, sizeof(proc));\n \tproc.argv = argv;\n \tproc.in = -1;\n \tproc.stdout_to_stderr = 1;\n@@ -350,7 +349,7 @@ static int run_receive_hook(struct command *commands, const char *hook_name,\n static int run_update_hook(struct command *cmd)\n {\n \tconst char *argv[5];\n-\tstruct child_process proc;\n+\tstruct child_process proc = CHILD_PROCESS_INIT;\n \tint code;\n \n \targv[0] = find_hook(\"update\");\n@@ -362,7 +361,6 @@ static int run_update_hook(struct command *cmd)\n \targv[3] = sha1_to_hex(cmd->new_sha1);\n \targv[4] = NULL;\n \n-\tmemset(&proc, 0, sizeof(proc));\n \tproc.no_stdin = 1;\n \tproc.stdout_to_stderr = 1;\n \tproc.err = use_sideband ? -1 : 0;\n@@ -598,7 +596,7 @@ static void run_update_post_hook(struct command *commands)\n \tstruct command *cmd;\n \tint argc;\n \tconst char **argv;\n-\tstruct child_process proc;\n+\tstruct child_process proc = CHILD_PROCESS_INIT;\n \tchar *hook;\n \n \thook = find_hook(\"post-update\");\n@@ -621,7 +619,6 @@ static void run_update_post_hook(struct command *commands)\n \t}\n \targv[argc] = NULL;\n \n-\tmemset(&proc, 0, sizeof(proc));\n \tproc.no_stdin = 1;\n \tproc.stdout_to_stderr = 1;\n \tproc.err = use_sideband ? -1 : 0;\n@@ -911,7 +908,7 @@ static const char *unpack(int err_fd, struct shallow_info *si)\n \tconst char *hdr_err;\n \tint status;\n \tchar hdr_arg[38];\n-\tstruct child_process child;\n+\tstruct child_process child = CHILD_PROCESS_INIT;\n \tint fsck_objects = (receive_fsck_objects >= 0\n \t\t\t    ? receive_fsck_objects\n \t\t\t    : transfer_fsck_objects >= 0\n@@ -933,7 +930,6 @@ static const char *unpack(int err_fd, struct shallow_info *si)\n \t\targv_array_pushl(&av, \"--shallow-file\", alt_shallow_file, NULL);\n \t}\n \n-\tmemset(&child, 0, sizeof(child));\n \tif (ntohl(hdr.hdr_entries) < unpack_limit) {\n \t\targv_array_pushl(&av, \"unpack-objects\", hdr_arg, NULL);\n \t\tif (quiet)\ndiff --git a/builtin/remote-ext.c b/builtin/remote-ext.c\nindex 692c834..d699d28 100644\n--- a/builtin/remote-ext.c\n+++ b/builtin/remote-ext.c\n@@ -179,9 +179,8 @@ static void send_git_request(int stdin_fd, const char *serv, const char *repo,\n static int run_child(const char *arg, const char *service)\n {\n \tint r;\n-\tstruct child_process child;\n+\tstruct child_process child = CHILD_PROCESS_INIT;\n \n-\tmemset(&child, 0, sizeof(child));\n \tchild.in = -1;\n \tchild.out = -1;\n \tchild.err = 0;\ndiff --git a/builtin/repack.c b/builtin/repack.c\nindex a77e743..fc088db 100644\n--- a/builtin/repack.c\n+++ b/builtin/repack.c\n@@ -133,7 +133,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t{\".idx\"},\n \t\t{\".bitmap\", 1},\n \t};\n-\tstruct child_process cmd;\n+\tstruct child_process cmd = CHILD_PROCESS_INIT;\n \tstruct string_list_item *item;\n \tstruct argv_array cmd_args = ARGV_ARRAY_INIT;\n \tstruct string_list names = STRING_LIST_INIT_DUP;\n@@ -250,7 +250,6 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \n \targv_array_push(&cmd_args, packtmp);\n \n-\tmemset(&cmd, 0, sizeof(cmd));\n \tcmd.argv = cmd_args.argv;\n \tcmd.git_cmd = 1;\n \tcmd.out = -1;\ndiff --git a/builtin/replace.c b/builtin/replace.c\nindex 294b61b..d2aac64 100644\n--- a/builtin/replace.c\n+++ b/builtin/replace.c\n@@ -197,7 +197,7 @@ static int replace_object(const char *object_ref, const char *replace_ref, int f\n static void export_object(const unsigned char *sha1, enum object_type type,\n \t\t\t  int raw, const char *filename)\n {\n-\tstruct child_process cmd = { NULL };\n+\tstruct child_process cmd = CHILD_PROCESS_INIT;\n \tint fd;\n \n \tfd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);\n@@ -234,7 +234,7 @@ static void import_object(unsigned char *sha1, enum object_type type,\n \n \tif (!raw && type == OBJ_TREE) {\n \t\tconst char *argv[] = { \"mktree\", NULL };\n-\t\tstruct child_process cmd = { argv };\n+\t\tstruct child_process cmd = CHILD_PROCESS_INIT;\n \t\tstruct strbuf result = STRBUF_INIT;\n \n \t\tcmd.argv = argv;\ndiff --git a/builtin/verify-pack.c b/builtin/verify-pack.c\nindex 972579f..7747537 100644\n--- a/builtin/verify-pack.c\n+++ b/builtin/verify-pack.c\n@@ -8,7 +8,7 @@\n \n static int verify_one_pack(const char *path, unsigned int flags)\n {\n-\tstruct child_process index_pack;\n+\tstruct child_process index_pack = CHILD_PROCESS_INIT;\n \tconst char *argv[] = {\"index-pack\", NULL, NULL, NULL };\n \tstruct strbuf arg = STRBUF_INIT;\n \tint verbose = flags & VERIFY_PACK_VERBOSE;\n@@ -32,7 +32,6 @@ static int verify_one_pack(const char *path, unsigned int flags)\n \t\tstrbuf_addstr(&arg, \".pack\");\n \targv[2] = arg.buf;\n \n-\tmemset(&index_pack, 0, sizeof(index_pack));\n \tindex_pack.argv = argv;\n \tindex_pack.git_cmd = 1;\n \ndiff --git a/bundle.c b/bundle.c\nindex 71a21a6..d6b4df8 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -240,7 +240,7 @@ int create_bundle(struct bundle_header *header, const char *path,\n \tint i, ref_count = 0;\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct rev_info revs;\n-\tstruct child_process rls;\n+\tstruct child_process rls = CHILD_PROCESS_INIT;\n \tFILE *rls_fout;\n \n \tbundle_to_stdout = !strcmp(path, \"-\");\n@@ -258,7 +258,6 @@ int create_bundle(struct bundle_header *header, const char *path,\n \tinit_revisions(&revs, NULL);\n \n \t/* write prerequisites */\n-\tmemset(&rls, 0, sizeof(rls));\n \targv_array_pushl(&rls.args,\n \t\t\t \"rev-list\", \"--boundary\", \"--pretty=oneline\",\n \t\t\t NULL);\n@@ -417,14 +416,13 @@ int unbundle(struct bundle_header *header, int bundle_fd, int flags)\n {\n \tconst char *argv_index_pack[] = {\"index-pack\",\n \t\t\t\t\t \"--fix-thin\", \"--stdin\", NULL, NULL};\n-\tstruct child_process ip;\n+\tstruct child_process ip = CHILD_PROCESS_INIT;\n \n \tif (flags & BUNDLE_VERBOSE)\n \t\targv_index_pack[3] = \"-v\";\n \n \tif (verify_bundle(header, 0))\n \t\treturn -1;\n-\tmemset(&ip, 0, sizeof(ip));\n \tip.argv = argv_index_pack;\n \tip.in = bundle_fd;\n \tip.no_stdout = 1;\ndiff --git a/column.c b/column.c\nindex ca878bc..76b615d 100644\n--- a/column.c\n+++ b/column.c\n@@ -367,7 +367,7 @@ int parseopt_column_callback(const struct option *opt,\n }\n \n static int fd_out = -1;\n-static struct child_process column_process;\n+static struct child_process column_process = CHILD_PROCESS_INIT;\n \n int run_column_filter(int colopts, const struct column_options *opts)\n {\ndiff --git a/connect.c b/connect.c\nindex 5047402..f5b930a 100644\n--- a/connect.c\n+++ b/connect.c\n@@ -639,7 +639,7 @@ static enum protocol parse_connect_url(const char *url_orig, char **ret_host,\n \treturn protocol;\n }\n \n-static struct child_process no_fork;\n+static struct child_process no_fork = CHILD_PROCESS_INIT;\n \n /*\n  * This returns a dummy child_process if the transport protocol does not\ndiff --git a/connected.c b/connected.c\nindex dae9c99..299c560 100644\n--- a/connected.c\n+++ b/connected.c\n@@ -25,7 +25,7 @@ static int check_everything_connected_real(sha1_iterate_fn fn,\n \t\t\t\t\t   struct transport *transport,\n \t\t\t\t\t   const char *shallow_file)\n {\n-\tstruct child_process rev_list;\n+\tstruct child_process rev_list = CHILD_PROCESS_INIT;\n \tconst char *argv[9];\n \tchar commit[41];\n \tunsigned char sha1[20];\n@@ -60,7 +60,6 @@ static int check_everything_connected_real(sha1_iterate_fn fn,\n \t\targv[ac++] = \"--quiet\";\n \targv[ac] = NULL;\n \n-\tmemset(&rev_list, 0, sizeof(rev_list));\n \trev_list.argv = argv;\n \trev_list.git_cmd = 1;\n \trev_list.in = -1;\ndiff --git a/convert.c b/convert.c\nindex cb5fbb4..aa7a139 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -321,7 +321,7 @@ static int filter_buffer(int in, int out, void *data)\n \t/*\n \t * Spawn cmd and feed the buffer contents through its stdin.\n \t */\n-\tstruct child_process child_process;\n+\tstruct child_process child_process = CHILD_PROCESS_INIT;\n \tstruct filter_params *params = (struct filter_params *)data;\n \tint write_err, status;\n \tconst char *argv[] = { NULL, NULL };\n@@ -344,7 +344,6 @@ static int filter_buffer(int in, int out, void *data)\n \n \targv[0] = cmd.buf;\n \n-\tmemset(&child_process, 0, sizeof(child_process));\n \tchild_process.argv = argv;\n \tchild_process.use_shell = 1;\n \tchild_process.in = -1;\ndiff --git a/credential-cache.c b/credential-cache.c\nindex 9a03792..8689a15 100644\n--- a/credential-cache.c\n+++ b/credential-cache.c\n@@ -37,12 +37,11 @@ static int send_request(const char *socket, const struct strbuf *out)\n \n static void spawn_daemon(const char *socket)\n {\n-\tstruct child_process daemon;\n+\tstruct child_process daemon = CHILD_PROCESS_INIT;\n \tconst char *argv[] = { NULL, NULL, NULL };\n \tchar buf[128];\n \tint r;\n \n-\tmemset(&daemon, 0, sizeof(daemon));\n \targv[0] = \"git-credential-cache--daemon\";\n \targv[1] = socket;\n \tdaemon.argv = argv;\ndiff --git a/credential.c b/credential.c\nindex 4d79d32..1886ea5 100644\n--- a/credential.c\n+++ b/credential.c\n@@ -205,11 +205,10 @@ static int run_credential_helper(struct credential *c,\n \t\t\t\t const char *cmd,\n \t\t\t\t int want_output)\n {\n-\tstruct child_process helper;\n+\tstruct child_process helper = CHILD_PROCESS_INIT;\n \tconst char *argv[] = { NULL, NULL };\n \tFILE *fp;\n \n-\tmemset(&helper, 0, sizeof(helper));\n \targv[0] = cmd;\n \thelper.argv = argv;\n \thelper.use_shell = 1;\ndiff --git a/daemon.c b/daemon.c\nindex e6b51ed..a5953de 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -259,7 +259,7 @@ static const char *access_hook;\n \n static int run_access_hook(struct daemon_service *service, const char *dir, const char *path)\n {\n-\tstruct child_process child;\n+\tstruct child_process child = CHILD_PROCESS_INIT;\n \tstruct strbuf buf = STRBUF_INIT;\n \tconst char *argv[8];\n \tconst char **arg = argv;\n@@ -277,7 +277,6 @@ static int run_access_hook(struct daemon_service *service, const char *dir, cons\n \t*arg = NULL;\n #undef STRARG\n \n-\tmemset(&child, 0, sizeof(child));\n \tchild.use_shell = 1;\n \tchild.argv = argv;\n \tchild.no_stdin = 1;\n@@ -406,9 +405,8 @@ static void copy_to_log(int fd)\n \n static int run_service_command(const char **argv)\n {\n-\tstruct child_process cld;\n+\tstruct child_process cld = CHILD_PROCESS_INIT;\n \n-\tmemset(&cld, 0, sizeof(cld));\n \tcld.argv = argv;\n \tcld.git_cmd = 1;\n \tcld.err = -1;\n@@ -733,7 +731,7 @@ static void check_dead_children(void)\n static char **cld_argv;\n static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)\n {\n-\tstruct child_process cld = { NULL };\n+\tstruct child_process cld = CHILD_PROCESS_INIT;\n \tchar addrbuf[300] = \"REMOTE_ADDR=\", portbuf[300];\n \tchar *env[] = { addrbuf, portbuf, NULL };\n \ndiff --git a/diff.c b/diff.c\nindex 867f034..e7d4d42 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -4931,7 +4931,7 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,\n \tstruct diff_tempfile *temp;\n \tconst char *argv[3];\n \tconst char **arg = argv;\n-\tstruct child_process child;\n+\tstruct child_process child = CHILD_PROCESS_INIT;\n \tstruct strbuf buf = STRBUF_INIT;\n \tint err = 0;\n \n@@ -4940,7 +4940,6 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,\n \t*arg++ = temp->name;\n \t*arg = NULL;\n \n-\tmemset(&child, 0, sizeof(child));\n \tchild.use_shell = 1;\n \tchild.argv = argv;\n \tchild.out = -1;\ndiff --git a/editor.c b/editor.c\nindex 0abbd8d..01c644c 100644\n--- a/editor.c\n+++ b/editor.c\n@@ -38,10 +38,9 @@ int launch_editor(const char *path, struct strbuf *buffer, const char *const *en\n \n \tif (strcmp(editor, \":\")) {\n \t\tconst char *args[] = { editor, real_path(path), NULL };\n-\t\tstruct child_process p;\n+\t\tstruct child_process p = CHILD_PROCESS_INIT;\n \t\tint ret, sig;\n \n-\t\tmemset(&p, 0, sizeof(p));\n \t\tp.argv = args;\n \t\tp.env = env;\n \t\tp.use_shell = 1;\ndiff --git a/fetch-pack.c b/fetch-pack.c\nindex b8a58fa..18d4c8f 100644\n--- a/fetch-pack.c\n+++ b/fetch-pack.c\n@@ -666,7 +666,7 @@ static int get_pack(struct fetch_pack_args *args,\n \tchar hdr_arg[256];\n \tconst char **av, *cmd_name;\n \tint do_keep = args->keep_pack;\n-\tstruct child_process cmd;\n+\tstruct child_process cmd = CHILD_PROCESS_INIT;\n \tint ret;\n \n \tmemset(&demux, 0, sizeof(demux));\n@@ -685,7 +685,6 @@ static int get_pack(struct fetch_pack_args *args,\n \telse\n \t\tdemux.out = xd[0];\n \n-\tmemset(&cmd, 0, sizeof(cmd));\n \tcmd.argv = argv;\n \tav = argv;\n \t*hdr_arg = 0;\ndiff --git a/gpg-interface.c b/gpg-interface.c\nindex ff07012..1ef73fb 100644\n--- a/gpg-interface.c\n+++ b/gpg-interface.c\n@@ -55,12 +55,11 @@ const char *get_signing_key(void)\n  */\n int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key)\n {\n-\tstruct child_process gpg;\n+\tstruct child_process gpg = CHILD_PROCESS_INIT;\n \tconst char *args[4];\n \tssize_t len;\n \tsize_t i, j, bottom;\n \n-\tmemset(&gpg, 0, sizeof(gpg));\n \tgpg.argv = args;\n \tgpg.in = -1;\n \tgpg.out = -1;\n@@ -116,7 +115,7 @@ int verify_signed_buffer(const char *payload, size_t payload_size,\n \t\t\t const char *signature, size_t signature_size,\n \t\t\t struct strbuf *gpg_output, struct strbuf *gpg_status)\n {\n-\tstruct child_process gpg;\n+\tstruct child_process gpg = CHILD_PROCESS_INIT;\n \tconst char *args_gpg[] = {NULL, \"--status-fd=1\", \"--verify\", \"FILE\", \"-\", NULL};\n \tchar path[PATH_MAX];\n \tint fd, ret;\n@@ -133,7 +132,6 @@ int verify_signed_buffer(const char *payload, size_t payload_size,\n \t\t\t     path, strerror(errno));\n \tclose(fd);\n \n-\tmemset(&gpg, 0, sizeof(gpg));\n \tgpg.argv = args_gpg;\n \tgpg.in = -1;\n \tgpg.out = -1;\ndiff --git a/http-backend.c b/http-backend.c\nindex 80790bb..2d4d105 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -323,7 +323,7 @@ static void run_service(const char **argv)\n \tconst char *host = getenv(\"REMOTE_ADDR\");\n \tstruct argv_array env = ARGV_ARRAY_INIT;\n \tint gzipped_request = 0;\n-\tstruct child_process cld;\n+\tstruct child_process cld = CHILD_PROCESS_INIT;\n \n \tif (encoding && !strcmp(encoding, \"gzip\"))\n \t\tgzipped_request = 1;\n@@ -341,7 +341,6 @@ static void run_service(const char **argv)\n \t\targv_array_pushf(&env, \"GIT_COMMITTER_EMAIL=%s@http.%s\",\n \t\t\t\t user, host);\n \n-\tmemset(&cld, 0, sizeof(cld));\n \tcld.argv = argv;\n \tcld.env = env.argv;\n \tif (gzipped_request)\ndiff --git a/http.c b/http.c\nindex c8cd50d..a23c399 100644\n--- a/http.c\n+++ b/http.c\n@@ -1332,7 +1332,7 @@ int finish_http_pack_request(struct http_pack_request *preq)\n \tstruct packed_git **lst;\n \tstruct packed_git *p = preq->target;\n \tchar *tmp_idx;\n-\tstruct child_process ip;\n+\tstruct child_process ip = CHILD_PROCESS_INIT;\n \tconst char *ip_argv[8];\n \n \tclose_pack_index(p);\n@@ -1355,7 +1355,6 @@ int finish_http_pack_request(struct http_pack_request *preq)\n \tip_argv[3] = preq->tmpfile;\n \tip_argv[4] = NULL;\n \n-\tmemset(&ip, 0, sizeof(ip));\n \tip.argv = ip_argv;\n \tip.git_cmd = 1;\n \tip.no_stdin = 1;\ndiff --git a/imap-send.c b/imap-send.c\nindex 524fbab..d8fb10f 100644\n--- a/imap-send.c\n+++ b/imap-send.c\n@@ -962,7 +962,7 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc)\n \n \tif (srvc->tunnel) {\n \t\tconst char *argv[] = { srvc->tunnel, NULL };\n-\t\tstruct child_process tunnel = {NULL};\n+\t\tstruct child_process tunnel = CHILD_PROCESS_INIT;\n \n \t\timap_info(\"Starting tunnel '%s'... \", srvc->tunnel);\n \ndiff --git a/pager.c b/pager.c\nindex 8b5cbc5..d0e4bc8 100644\n--- a/pager.c\n+++ b/pager.c\n@@ -18,7 +18,7 @@ struct pager_config {\n  */\n \n static const char *pager_argv[] = { NULL, NULL };\n-static struct child_process pager_process;\n+static struct child_process pager_process = CHILD_PROCESS_INIT;\n \n static void wait_for_pager(void)\n {\ndiff --git a/prompt.c b/prompt.c\nindex d7bb17c..e5b4938 100644\n--- a/prompt.c\n+++ b/prompt.c\n@@ -6,7 +6,7 @@\n \n static char *do_askpass(const char *cmd, const char *prompt)\n {\n-\tstruct child_process pass;\n+\tstruct child_process pass = CHILD_PROCESS_INIT;\n \tconst char *args[3];\n \tstatic struct strbuf buffer = STRBUF_INIT;\n \tint err = 0;\n@@ -15,7 +15,6 @@ static char *do_askpass(const char *cmd, const char *prompt)\n \targs[1]\t= prompt;\n \targs[2] = NULL;\n \n-\tmemset(&pass, 0, sizeof(pass));\n \tpass.argv = args;\n \tpass.out = -1;\n \ndiff --git a/remote-curl.c b/remote-curl.c\nindex 0fcf2ce..017ddd9 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -623,10 +623,9 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)\n \tconst char *svc = rpc->service_name;\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct strbuf *preamble = rpc->stdin_preamble;\n-\tstruct child_process client;\n+\tstruct child_process client = CHILD_PROCESS_INIT;\n \tint err = 0;\n \n-\tmemset(&client, 0, sizeof(client));\n \tclient.in = -1;\n \tclient.out = -1;\n \tclient.git_cmd = 1;\ndiff --git a/remote-testsvn.c b/remote-testsvn.c\nindex 686e07d..48bf6eb 100644\n--- a/remote-testsvn.c\n+++ b/remote-testsvn.c\n@@ -175,7 +175,7 @@ static int cmd_import(const char *line)\n \tchar *note_msg;\n \tunsigned char head_sha1[20];\n \tunsigned int startrev;\n-\tstruct child_process svndump_proc;\n+\tstruct child_process svndump_proc = CHILD_PROCESS_INIT;\n \tconst char *command = \"svnrdump\";\n \n \tif (read_ref(private_ref, head_sha1))\n@@ -200,7 +200,6 @@ static int cmd_import(const char *line)\n \t\tif(dumpin_fd < 0)\n \t\t\tdie_errno(\"Couldn't open svn dump file %s.\", url);\n \t} else {\n-\t\tmemset(&svndump_proc, 0, sizeof(struct child_process));\n \t\tsvndump_proc.out = -1;\n \t\targv_array_push(&svndump_proc.args, command);\n \t\targv_array_push(&svndump_proc.args, \"dump\");\ndiff --git a/run-command.c b/run-command.c\nindex 35a3ebf..a29a34f 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -763,14 +763,13 @@ char *find_hook(const char *name)\n \n int run_hook_ve(const char *const *env, const char *name, va_list args)\n {\n-\tstruct child_process hook;\n+\tstruct child_process hook = CHILD_PROCESS_INIT;\n \tconst char *p;\n \n \tp = find_hook(name);\n \tif (!p)\n \t\treturn 0;\n \n-\tmemset(&hook, 0, sizeof(hook));\n \targv_array_push(&hook.args, p);\n \twhile ((p = va_arg(args, const char *)))\n \t\targv_array_push(&hook.args, p);\ndiff --git a/run-command.h b/run-command.h\nindex ea73de3..5484400 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -44,6 +44,8 @@ struct child_process {\n \tunsigned clean_on_exit:1;\n };\n \n+#define CHILD_PROCESS_INIT { NULL, ARGV_ARRAY_INIT }\n+\n int start_command(struct child_process *);\n int finish_command(struct child_process *);\n int run_command(struct child_process *);\ndiff --git a/send-pack.c b/send-pack.c\nindex 6129b0f..8b4cbf0 100644\n--- a/send-pack.c\n+++ b/send-pack.c\n@@ -47,7 +47,7 @@ static int pack_objects(int fd, struct ref *refs, struct sha1_array *extra, stru\n \t\tNULL,\n \t\tNULL,\n \t};\n-\tstruct child_process po;\n+\tstruct child_process po = CHILD_PROCESS_INIT;\n \tint i;\n \n \ti = 4;\n@@ -59,7 +59,6 @@ static int pack_objects(int fd, struct ref *refs, struct sha1_array *extra, stru\n \t\targv[i++] = \"-q\";\n \tif (args->progress)\n \t\targv[i++] = \"--progress\";\n-\tmemset(&po, 0, sizeof(po));\n \tpo.argv = argv;\n \tpo.in = -1;\n \tpo.out = args->stateless_rpc ? -1 : fd;\ndiff --git a/submodule.c b/submodule.c\nindex c3a61e7..0690dc5 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -433,13 +433,12 @@ static int submodule_needs_pushing(const char *path, const unsigned char sha1[20\n \t\treturn 0;\n \n \tif (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {\n-\t\tstruct child_process cp;\n+\t\tstruct child_process cp = CHILD_PROCESS_INIT;\n \t\tconst char *argv[] = {\"rev-list\", NULL, \"--not\", \"--remotes\", \"-n\", \"1\" , NULL};\n \t\tstruct strbuf buf = STRBUF_INIT;\n \t\tint needs_pushing = 0;\n \n \t\targv[1] = sha1_to_hex(sha1);\n-\t\tmemset(&cp, 0, sizeof(cp));\n \t\tcp.argv = argv;\n \t\tcp.env = local_repo_env;\n \t\tcp.git_cmd = 1;\n@@ -524,10 +523,9 @@ static int push_submodule(const char *path)\n \t\treturn 1;\n \n \tif (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {\n-\t\tstruct child_process cp;\n+\t\tstruct child_process cp = CHILD_PROCESS_INIT;\n \t\tconst char *argv[] = {\"push\", NULL};\n \n-\t\tmemset(&cp, 0, sizeof(cp));\n \t\tcp.argv = argv;\n \t\tcp.env = local_repo_env;\n \t\tcp.git_cmd = 1;\n@@ -569,12 +567,11 @@ static int is_submodule_commit_present(const char *path, unsigned char sha1[20])\n \tif (!add_submodule_odb(path) && lookup_commit_reference(sha1)) {\n \t\t/* Even if the submodule is checked out and the commit is\n \t\t * present, make sure it is reachable from a ref. */\n-\t\tstruct child_process cp;\n+\t\tstruct child_process cp = CHILD_PROCESS_INIT;\n \t\tconst char *argv[] = {\"rev-list\", \"-n\", \"1\", NULL, \"--not\", \"--all\", NULL};\n \t\tstruct strbuf buf = STRBUF_INIT;\n \n \t\targv[3] = sha1_to_hex(sha1);\n-\t\tmemset(&cp, 0, sizeof(cp));\n \t\tcp.argv = argv;\n \t\tcp.env = local_repo_env;\n \t\tcp.git_cmd = 1;\n@@ -695,7 +692,7 @@ int fetch_populated_submodules(const struct argv_array *options,\n \t\t\t       int quiet)\n {\n \tint i, result = 0;\n-\tstruct child_process cp;\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tstruct argv_array argv = ARGV_ARRAY_INIT;\n \tstruct string_list_item *name_for_path;\n \tconst char *work_tree = get_git_work_tree();\n@@ -711,7 +708,6 @@ int fetch_populated_submodules(const struct argv_array *options,\n \targv_array_push(&argv, \"--recurse-submodules-default\");\n \t/* default value, \"--submodule-prefix\" and its value are added later */\n \n-\tmemset(&cp, 0, sizeof(cp));\n \tcp.env = local_repo_env;\n \tcp.git_cmd = 1;\n \tcp.no_stdin = 1;\n@@ -794,7 +790,7 @@ out:\n unsigned is_submodule_modified(const char *path, int ignore_untracked)\n {\n \tssize_t len;\n-\tstruct child_process cp;\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tconst char *argv[] = {\n \t\t\"status\",\n \t\t\"--porcelain\",\n@@ -821,7 +817,6 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)\n \tif (ignore_untracked)\n \t\targv[2] = \"-uno\";\n \n-\tmemset(&cp, 0, sizeof(cp));\n \tcp.argv = argv;\n \tcp.env = local_repo_env;\n \tcp.git_cmd = 1;\n@@ -862,7 +857,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)\n \n int submodule_uses_gitfile(const char *path)\n {\n-\tstruct child_process cp;\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tconst char *argv[] = {\n \t\t\"submodule\",\n \t\t\"foreach\",\n@@ -883,7 +878,6 @@ int submodule_uses_gitfile(const char *path)\n \tstrbuf_release(&buf);\n \n \t/* Now test that all nested submodules use a gitfile too */\n-\tmemset(&cp, 0, sizeof(cp));\n \tcp.argv = argv;\n \tcp.env = local_repo_env;\n \tcp.git_cmd = 1;\n@@ -901,7 +895,7 @@ int ok_to_remove_submodule(const char *path)\n {\n \tstruct stat st;\n \tssize_t len;\n-\tstruct child_process cp;\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tconst char *argv[] = {\n \t\t\"status\",\n \t\t\"--porcelain\",\n@@ -918,7 +912,6 @@ int ok_to_remove_submodule(const char *path)\n \tif (!submodule_uses_gitfile(path))\n \t\treturn 0;\n \n-\tmemset(&cp, 0, sizeof(cp));\n \tcp.argv = argv;\n \tcp.env = local_repo_env;\n \tcp.git_cmd = 1;\ndiff --git a/test-run-command.c b/test-run-command.c\nindex 37918e1..89c7de2 100644\n--- a/test-run-command.c\n+++ b/test-run-command.c\n@@ -15,9 +15,7 @@\n \n int main(int argc, char **argv)\n {\n-\tstruct child_process proc;\n-\n-\tmemset(&proc, 0, sizeof(proc));\n+\tstruct child_process proc = CHILD_PROCESS_INIT;\n \n \tif (argc < 3)\n \t\treturn 1;\ndiff --git a/test-subprocess.c b/test-subprocess.c\nindex 93525eb..56881a0 100644\n--- a/test-subprocess.c\n+++ b/test-subprocess.c\n@@ -3,7 +3,7 @@\n \n int main(int argc, char **argv)\n {\n-\tstruct child_process cp;\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tint nogit = 0;\n \n \tsetup_git_directory_gently(&nogit);\n@@ -13,7 +13,6 @@ int main(int argc, char **argv)\n \t\tsetup_work_tree();\n \t\targv++;\n \t}\n-\tmemset(&cp, 0, sizeof(cp));\n \tcp.git_cmd = 1;\n \tcp.argv = (const char **)argv + 1;\n \treturn run_command(&cp);\ndiff --git a/transport.c b/transport.c\nindex 662421b..7388bb8 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -201,7 +201,7 @@ static struct ref *get_refs_via_rsync(struct transport *transport, int for_push)\n {\n \tstruct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;\n \tstruct ref dummy = {NULL}, *tail = &dummy;\n-\tstruct child_process rsync;\n+\tstruct child_process rsync = CHILD_PROCESS_INIT;\n \tconst char *args[5];\n \tint temp_dir_len;\n \n@@ -218,7 +218,6 @@ static struct ref *get_refs_via_rsync(struct transport *transport, int for_push)\n \tstrbuf_addstr(&buf, rsync_url(transport->url));\n \tstrbuf_addstr(&buf, \"/refs\");\n \n-\tmemset(&rsync, 0, sizeof(rsync));\n \trsync.argv = args;\n \trsync.stdout_to_stderr = 1;\n \targs[0] = \"rsync\";\n@@ -263,9 +262,8 @@ static struct ref *get_refs_via_rsync(struct transport *transport, int for_push)\n static int fetch_objs_via_rsync(struct transport *transport,\n \t\t\t\tint nr_objs, struct ref **to_fetch)\n {\n-\tstruct child_process rsync;\n+\tstruct child_process rsync = CHILD_PROCESS_INIT;\n \n-\tmemset(&rsync, 0, sizeof(rsync));\n \trsync.stdout_to_stderr = 1;\n \targv_array_push(&rsync.args, \"rsync\");\n \targv_array_push(&rsync.args, (transport->verbose > 1) ? \"-rv\" : \"-r\");\n@@ -327,7 +325,7 @@ static int rsync_transport_push(struct transport *transport,\n {\n \tstruct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;\n \tint result = 0, i;\n-\tstruct child_process rsync;\n+\tstruct child_process rsync = CHILD_PROCESS_INIT;\n \tconst char *args[10];\n \n \tif (flags & TRANSPORT_PUSH_MIRROR)\n@@ -338,7 +336,6 @@ static int rsync_transport_push(struct transport *transport,\n \tstrbuf_addstr(&buf, rsync_url(transport->url));\n \tstrbuf_addch(&buf, '/');\n \n-\tmemset(&rsync, 0, sizeof(rsync));\n \trsync.argv = args;\n \trsync.stdout_to_stderr = 1;\n \ti = 0;\n@@ -1056,7 +1053,7 @@ static int run_pre_push_hook(struct transport *transport,\n {\n \tint ret = 0, x;\n \tstruct ref *r;\n-\tstruct child_process proc;\n+\tstruct child_process proc = CHILD_PROCESS_INIT;\n \tstruct strbuf buf;\n \tconst char *argv[4];\n \n@@ -1067,7 +1064,6 @@ static int run_pre_push_hook(struct transport *transport,\n \targv[2] = transport->url;\n \targv[3] = NULL;\n \n-\tmemset(&proc, 0, sizeof(proc));\n \tproc.argv = argv;\n \tproc.in = -1;\n \ndiff --git a/upload-pack.c b/upload-pack.c\nindex 01de944..c9ea1d3 100644\n--- a/upload-pack.c\n+++ b/upload-pack.c\n@@ -80,7 +80,7 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data)\n \n static void create_pack_file(void)\n {\n-\tstruct child_process pack_objects;\n+\tstruct child_process pack_objects = CHILD_PROCESS_INIT;\n \tchar data[8193], progress[128];\n \tchar abort_msg[] = \"aborting due to possible repository \"\n \t\t\"corruption on the remote side.\";\n@@ -108,7 +108,6 @@ static void create_pack_file(void)\n \t\targv[arg++] = \"--include-tag\";\n \targv[arg++] = NULL;\n \n-\tmemset(&pack_objects, 0, sizeof(pack_objects));\n \tpack_objects.in = -1;\n \tpack_objects.out = -1;\n \tpack_objects.err = -1;\n@@ -448,7 +447,7 @@ static void check_non_tip(void)\n \tstatic const char *argv[] = {\n \t\t\"rev-list\", \"--stdin\", NULL,\n \t};\n-\tstatic struct child_process cmd;\n+\tstatic struct child_process cmd = CHILD_PROCESS_INIT;\n \tstruct object *o;\n \tchar namebuf[42]; /* ^ + SHA-1 + LF */\n \tint i;\ndiff --git a/wt-status.c b/wt-status.c\nindex 27da529..1bf5d72 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -725,7 +725,7 @@ static void wt_status_print_changed(struct wt_status *s)\n \n static void wt_status_print_submodule_summary(struct wt_status *s, int uncommitted)\n {\n-\tstruct child_process sm_summary;\n+\tstruct child_process sm_summary = CHILD_PROCESS_INIT;\n \tstruct argv_array env = ARGV_ARRAY_INIT;\n \tstruct argv_array argv = ARGV_ARRAY_INIT;\n \tstruct strbuf cmd_stdout = STRBUF_INIT;\n@@ -744,7 +744,6 @@ static void wt_status_print_submodule_summary(struct wt_status *s, int uncommitt\n \tif (!uncommitted)\n \t\targv_array_push(&argv, s->amend ? \"HEAD^\" : \"HEAD\");\n \n-\tmemset(&sm_summary, 0, sizeof(sm_summary));\n \tsm_summary.argv = argv.argv;\n \tsm_summary.env = env.argv;\n \tsm_summary.git_cmd = 1;\n-- \n2.1.0\n"},{"id":"247958","messageId":"53F3A138.4000009@web.de","threadId":"37363","inReplyTo":"xmqq61hpybs9.fsf@gitster.dls.corp.google.com","subject":"[PATCH v2 2/4] run-command: introduce child_process_init()","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-08-19T19:10:48Z","receivedAt":"2014-08-19T19:10:48Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Add a helper function for initializing those struct child_process\nvariables for which the macro CHILD_PROCESS_INIT can't be used.\n\nSuggested-by: Jeff King <peff@peff.net>\nSigned-off-by: Rene Scharfe <l.s.r@web.de>\n---\n Documentation/technical/api-run-command.txt | 8 ++++++--\n connect.c                                   | 6 ++++--\n run-command.c                               | 6 ++++++\n run-command.h                               | 1 +\n transport-helper.c                          | 5 +++--\n 5 files changed, 20 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/technical/api-run-command.txt b/Documentation/technical/api-run-command.txt\nindex ca066bf..842b838 100644\n--- a/Documentation/technical/api-run-command.txt\n+++ b/Documentation/technical/api-run-command.txt\n@@ -13,6 +13,10 @@ produces in the caller in order to process it.\n Functions\n ---------\n \n+`child_process_init`\n+\n+\tInitialize a struct child_process variable.\n+\n `start_command`::\n \n \tStart a sub-process. Takes a pointer to a `struct child_process`\n@@ -96,8 +100,8 @@ command to run in a sub-process.\n \n The caller:\n \n-1. allocates and clears (memset(&chld, 0, sizeof(chld)); or\n-   using CHILD_PROCESS_INIT) a struct child_process variable;\n+1. allocates and clears (using child_process_init() or\n+   CHILD_PROCESS_INIT) a struct child_process variable;\n 2. initializes the members;\n 3. calls start_command();\n 4. processes the data;\ndiff --git a/connect.c b/connect.c\nindex f5b930a..87b5202 100644\n--- a/connect.c\n+++ b/connect.c\n@@ -537,7 +537,8 @@ static struct child_process *git_proxy_connect(int fd[2], char *host)\n \n \tget_host_and_port(&host, &port);\n \n-\tproxy = xcalloc(1, sizeof(*proxy));\n+\tproxy = xmalloc(sizeof(*proxy));\n+\tchild_process_init(proxy);\n \targv_array_push(&proxy->args, git_proxy_command);\n \targv_array_push(&proxy->args, host);\n \targv_array_push(&proxy->args, port);\n@@ -694,7 +695,8 @@ struct child_process *git_connect(int fd[2], const char *url,\n \t\t\t     target_host, 0);\n \t\tfree(target_host);\n \t} else {\n-\t\tconn = xcalloc(1, sizeof(*conn));\n+\t\tconn = xmalloc(sizeof(*conn));\n+\t\tchild_process_init(conn);\n \n \t\tstrbuf_addstr(&cmd, prog);\n \t\tstrbuf_addch(&cmd, ' ');\ndiff --git a/run-command.c b/run-command.c\nindex a29a34f..47ab21b 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -8,6 +8,12 @@\n # define SHELL_PATH \"/bin/sh\"\n #endif\n \n+void child_process_init(struct child_process *child)\n+{\n+\tmemset(child, 0, sizeof(*child));\n+\targv_array_init(&child->args);\n+}\n+\n struct child_to_clean {\n \tpid_t pid;\n \tstruct child_to_clean *next;\ndiff --git a/run-command.h b/run-command.h\nindex 5484400..1b135d1 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -45,6 +45,7 @@ struct child_process {\n };\n \n #define CHILD_PROCESS_INIT { NULL, ARGV_ARRAY_INIT }\n+void child_process_init(struct child_process *);\n \n int start_command(struct child_process *);\n int finish_command(struct child_process *);\ndiff --git a/transport-helper.c b/transport-helper.c\nindex 3d8fe7d..080a7a6 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -118,7 +118,8 @@ static struct child_process *get_helper(struct transport *transport)\n \tif (data->helper)\n \t\treturn data->helper;\n \n-\thelper = xcalloc(1, sizeof(*helper));\n+\thelper = xmalloc(sizeof(*helper));\n+\tchild_process_init(helper);\n \thelper->in = -1;\n \thelper->out = -1;\n \thelper->err = 0;\n@@ -395,7 +396,7 @@ static int get_importer(struct transport *transport, struct child_process *fasti\n \tstruct child_process *helper = get_helper(transport);\n \tstruct helper_data *data = transport->data;\n \tint cat_blob_fd, code;\n-\tmemset(fastimport, 0, sizeof(*fastimport));\n+\tchild_process_init(fastimport);\n \tfastimport->in = helper->out;\n \targv_array_push(&fastimport->args, \"fast-import\");\n \targv_array_push(&fastimport->args, debug ? \"--stats\" : \"--quiet\");\n-- \n2.1.0\n"},{"id":"247959","messageId":"53F3A144.4030307@web.de","threadId":"37363","inReplyTo":"xmqq61hpybs9.fsf@gitster.dls.corp.google.com","subject":"[PATCH v2 3/4] run-command: call run_command_v_opt_cd_env() instead of duplicating it","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-08-19T19:11:00Z","receivedAt":"2014-08-19T19:11:00Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Signed-off-by: Rene Scharfe <l.s.r@web.de>\n---\n run-command.c | 4 +---\n 1 file changed, 1 insertion(+), 3 deletions(-)\n\ndiff --git a/run-command.c b/run-command.c\nindex 47ab21b..9196ee0 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -577,9 +577,7 @@ static void prepare_run_command_v_opt(struct child_process *cmd,\n \n int run_command_v_opt(const char **argv, int opt)\n {\n-\tstruct child_process cmd;\n-\tprepare_run_command_v_opt(&cmd, argv, opt);\n-\treturn run_command(&cmd);\n+\treturn run_command_v_opt_cd_env(argv, opt, NULL, NULL);\n }\n \n int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env)\n-- \n2.1.0\n"},{"id":"247960","messageId":"53F3A16F.10303@web.de","threadId":"37363","inReplyTo":"xmqq61hpybs9.fsf@gitster.dls.corp.google.com","subject":"[PATCH v2 4/4] run-command: inline prepare_run_command_v_opt()","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-08-19T19:11:43Z","receivedAt":"2014-08-19T19:11:43Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Merge prepare_run_command_v_opt() and its only caller.  This removes a\npointer indirection and allows to initialize the struct child_process\nusing CHILD_PROCESS_INIT.\n\nSigned-off-by: Rene Scharfe <l.s.r@web.de>\n---\n run-command.c | 24 ++++++++----------------\n 1 file changed, 8 insertions(+), 16 deletions(-)\n\ndiff --git a/run-command.c b/run-command.c\nindex 9196ee0..761f0fd 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -561,20 +561,6 @@ int run_command(struct child_process *cmd)\n \treturn finish_command(cmd);\n }\n \n-static void prepare_run_command_v_opt(struct child_process *cmd,\n-\t\t\t\t      const char **argv,\n-\t\t\t\t      int opt)\n-{\n-\tmemset(cmd, 0, sizeof(*cmd));\n-\tcmd->argv = argv;\n-\tcmd->no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0;\n-\tcmd->git_cmd = opt & RUN_GIT_CMD ? 1 : 0;\n-\tcmd->stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0;\n-\tcmd->silent_exec_failure = opt & RUN_SILENT_EXEC_FAILURE ? 1 : 0;\n-\tcmd->use_shell = opt & RUN_USING_SHELL ? 1 : 0;\n-\tcmd->clean_on_exit = opt & RUN_CLEAN_ON_EXIT ? 1 : 0;\n-}\n-\n int run_command_v_opt(const char **argv, int opt)\n {\n \treturn run_command_v_opt_cd_env(argv, opt, NULL, NULL);\n@@ -582,8 +568,14 @@ int run_command_v_opt(const char **argv, int opt)\n \n int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env)\n {\n-\tstruct child_process cmd;\n-\tprepare_run_command_v_opt(&cmd, argv, opt);\n+\tstruct child_process cmd = CHILD_PROCESS_INIT;\n+\tcmd.argv = argv;\n+\tcmd.no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0;\n+\tcmd.git_cmd = opt & RUN_GIT_CMD ? 1 : 0;\n+\tcmd.stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0;\n+\tcmd.silent_exec_failure = opt & RUN_SILENT_EXEC_FAILURE ? 1 : 0;\n+\tcmd.use_shell = opt & RUN_USING_SHELL ? 1 : 0;\n+\tcmd.clean_on_exit = opt & RUN_CLEAN_ON_EXIT ? 1 : 0;\n \tcmd.dir = dir;\n \tcmd.env = env;\n \treturn run_command(&cmd);\n-- \n2.1.0\n"}]}