From: Junio C Hamano Date: Fri, 9 Sep 2016 04:35:50 +0000 (-0700) Subject: Merge branch 'jk/common-main' into maint X-Git-Tag: v2.9.4~24 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/faacc8efe503a470c0c549c7949824728d7f1461?ds=inline;hp=-c Merge branch 'jk/common-main' into maint There are certain house-keeping tasks that need to be performed at the very beginning of any Git program, and programs that are not built-in commands had to do them exactly the same way as "git" potty does. It was easy to make mistakes in one-off standalone programs (like test helpers). A common "main()" function that calls cmd_main() of individual program has been introduced to make it harder to make mistakes. * jk/common-main: mingw: declare main()'s argv as const common-main: call git_setup_gettext() common-main: call restore_sigpipe_to_default() common-main: call sanitize_stdfds() common-main: call git_extract_argv0_path() add an extra level of indirection to main() --- faacc8efe503a470c0c549c7949824728d7f1461 diff --combined Makefile index 4579eab43b,717dc344ab..13ed57fd08 --- a/Makefile +++ b/Makefile @@@ -939,7 -939,7 +939,7 @@@ BUILTIN_OBJS += builtin/verify-tag. BUILTIN_OBJS += builtin/worktree.o BUILTIN_OBJS += builtin/write-tree.o - GITLIBS = $(LIB_FILE) $(XDIFF_LIB) + GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) EXTLIBS = GIT_USER_AGENT = git/$(GIT_VERSION) @@@ -1572,7 -1572,15 +1572,15 @@@ TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_ DIFF_SQ = $(subst ','\'',$(DIFF)) PERLLIB_EXTRA_SQ = $(subst ','\'',$(PERLLIB_EXTRA)) - LIBS = $(GITLIBS) $(EXTLIBS) + # We must filter out any object files from $(GITLIBS), + # as it is typically used like: + # + # foo: foo.o $(GITLIBS) + # $(CC) $(filter %.o,$^) $(LIBS) + # + # where we use it as a dependency. Since we also pull object files + # from the dependency list, that would make each entry appear twice. + LIBS = $(filter-out %.o, $(GITLIBS)) $(EXTLIBS) BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' \ $(COMPAT_CFLAGS) @@@ -1708,8 -1716,8 +1716,8 @@@ git.sp git.s git.o: EXTRA_CPPFLAGS = '-DGIT_INFO_PATH="$(infodir_relative_SQ)"' git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS) - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) git.o \ - $(BUILTIN_OBJS) $(LIBS) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \ + $(filter %.o,$^) $(LIBS) help.sp help.s help.o: common-cmds.h @@@ -1902,6 -1910,7 +1910,7 @@@ TEST_OBJS := $(patsubst %$X,%.o,$(TEST_ OBJECTS := $(LIB_OBJS) $(BUILTIN_OBJS) $(PROGRAM_OBJS) $(TEST_OBJS) \ $(XDIFF_OBJS) \ $(VCSSVN_OBJS) \ + common-main.o \ git.o ifndef NO_CURL OBJECTS += http.o http-walker.o remote-curl.o @@@ -2225,9 -2234,17 +2234,9 @@@ perf: al .PHONY: test perf -t/helper/test-ctype$X: ctype.o +t/helper/test-line-buffer$X: $(VCSSVN_LIB) -t/helper/test-date$X: date.o ctype.o - -t/helper/test-delta$X: diff-delta.o patch-delta.o - -t/helper/test-line-buffer$X: vcs-svn/lib.a - -t/helper/test-parse-options$X: parse-options.o parse-options-cb.o - -t/helper/test-svn-fe$X: vcs-svn/lib.a +t/helper/test-svn-fe$X: $(VCSSVN_LIB) .PRECIOUS: $(TEST_OBJS) diff --combined compat/mingw.h index ef22cbb05d,1ac9086a82..95e128fcfd --- a/compat/mingw.h +++ b/compat/mingw.h @@@ -73,9 -73,6 +73,9 @@@ typedef int pid_t #ifndef ECONNABORTED #define ECONNABORTED WSAECONNABORTED #endif +#ifndef ENOTSOCK +#define ENOTSOCK WSAENOTSOCK +#endif struct passwd { char *pw_name; @@@ -535,10 -532,10 +535,10 @@@ extern CRITICAL_SECTION pinfo_cs * A replacement of main() that adds win32 specific initialization. */ -void mingw_startup(); -#define main(c,v) dummy_decl_mingw_main(); \ +void mingw_startup(void); +#define main(c,v) dummy_decl_mingw_main(void); \ static int mingw_main(c,v); \ - int main(int argc, char **argv) \ + int main(int argc, const char **argv) \ { \ mingw_startup(); \ return mingw_main(__argc, (void *)__argv); \ diff --combined daemon.c index a84495113e,569997c98f..425aad0507 --- a/daemon.c +++ b/daemon.c @@@ -1,6 -1,5 +1,5 @@@ #include "cache.h" #include "pkt-line.h" - #include "exec_cmd.h" #include "run-command.h" #include "strbuf.h" #include "string-list.h" @@@ -32,7 -31,7 +31,7 @@@ static const char daemon_usage[] " [...]"; /* List of acceptable pathname prefixes */ - static char **ok_paths; + static const char **ok_paths; static int strict_paths; /* If this is set, git-daemon-export-ok is not required */ @@@ -240,7 -239,7 +239,7 @@@ static const char *path_ok(const char * } if ( ok_paths && *ok_paths ) { - char **pp; + const char **pp; int pathlen = strlen(path); /* The validation is done on the paths after enter_repo @@@ -669,17 -668,6 +668,17 @@@ static void hostinfo_clear(struct hosti strbuf_release(&hi->tcp_port); } +static void set_keep_alive(int sockfd) +{ + int ka = 1; + + if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &ka, sizeof(ka)) < 0) { + if (errno != ENOTSOCK) + logerror("unable to set SO_KEEPALIVE on socket: %s", + strerror(errno)); + } +} + static int execute(void) { char *line = packet_buffer; @@@ -692,7 -680,6 +691,7 @@@ if (addr) loginfo("Connection from %s:%s", addr, port); + set_keep_alive(0); alarm(init_timeout ? init_timeout : timeout); pktlen = packet_read(0, NULL, NULL, packet_buffer, sizeof(packet_buffer), 0); alarm(0); @@@ -963,8 -950,6 +962,8 @@@ static int setup_named_sock(char *liste continue; } + set_keep_alive(sockfd); + if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) { logerror("Could not bind to %s: %s", ip2str(ai->ai_family, ai->ai_addr, ai->ai_addrlen), @@@ -1024,8 -1009,6 +1023,8 @@@ static int setup_named_sock(char *liste return 0; } + set_keep_alive(sockfd); + if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) { logerror("Could not bind to %s: %s", ip2str(AF_INET, (struct sockaddr *)&sin, sizeof(sin)), @@@ -1194,7 -1177,7 +1193,7 @@@ static int serve(struct string_list *li return service_loop(&socklist); } - int main(int argc, char **argv) + int cmd_main(int argc, const char **argv) { int listen_port = 0; struct string_list listen_addr = STRING_LIST_INIT_NODUP; @@@ -1204,12 -1187,8 +1203,8 @@@ struct credentials *cred = NULL; int i; - git_setup_gettext(); - - git_extract_argv0_path(argv[0]); - for (i = 1; i < argc; i++) { - char *arg = argv[i]; + const char *arg = argv[i]; const char *v; if (skip_prefix(arg, "--listen=", &v)) { @@@ -1383,8 -1362,7 +1378,7 @@@ if (detach) { if (daemonize()) die("--detach not supported on this platform"); - } else - sanitize_stdfds(); + } if (pid_file) write_file(pid_file, "%"PRIuMAX, (uintmax_t) getpid()); diff --combined http-push.c index d0b29ac982,dacada9094..704b1c837c --- a/http-push.c +++ b/http-push.c @@@ -1137,7 -1137,7 +1137,7 @@@ static void remote_ls(const char *path ls.userData = userData; ls.userFunc = userFunc; - strbuf_addf(&out_buffer.buf, PROPFIND_ALL_REQUEST); + strbuf_addstr(&out_buffer.buf, PROPFIND_ALL_REQUEST); dav_headers = curl_slist_append(dav_headers, "Depth: 1"); dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml"); @@@ -1692,12 -1692,12 +1692,12 @@@ static void run_request_queue(void #endif } - int main(int argc, char **argv) + int cmd_main(int argc, const char **argv) { struct transfer_request *request; struct transfer_request *next_request; int nr_refspec = 0; - char **refspec = NULL; + const char **refspec = NULL; struct remote_lock *ref_lock = NULL; struct remote_lock *info_ref_lock = NULL; struct rev_info revs; @@@ -1709,15 -1709,11 +1709,11 @@@ int new_refs; struct ref *ref, *local_refs; - git_setup_gettext(); - - git_extract_argv0_path(argv[0]); - repo = xcalloc(1, sizeof(*repo)); argv++; for (i = 1; i < argc; i++, argv++) { - char *arg = *argv; + const char *arg = *argv; if (*arg == '-') { if (!strcmp(arg, "--all")) { diff --combined t/helper/test-date.c index d9ab360909,0f3cfb1721..506054bcd5 --- a/t/helper/test-date.c +++ b/t/helper/test-date.c @@@ -1,12 -1,11 +1,12 @@@ #include "cache.h" static const char *usage_msg = "\n" -" test-date show [time_t]...\n" +" test-date relative [time_t]...\n" +" test-date show: [time_t]...\n" " test-date parse [date]...\n" " test-date approxidate [date]...\n"; - static void show_relative_dates(char **argv, struct timeval *now) -static void show_dates(const char **argv, struct timeval *now) ++static void show_relative_dates(const char **argv, struct timeval *now) { struct strbuf buf = STRBUF_INIT; @@@ -18,30 -17,7 +18,30 @@@ strbuf_release(&buf); } - static void show_dates(char **argv, const char *format) ++static void show_dates(const char **argv, const char *format) +{ + struct date_mode mode; + + parse_date_format(format, &mode); + for (; *argv; argv++) { - char *arg = *argv; ++ char *arg; + time_t t; + int tz; + + /* + * Do not use our normal timestamp parsing here, as the point + * is to test the formatting code in isolation. + */ - t = strtol(arg, &arg, 10); ++ t = strtol(*argv, &arg, 10); + while (*arg == ' ') + arg++; + tz = atoi(arg); + + printf("%s -> %s\n", *argv, show_date(t, tz, &mode)); + } +} + - static void parse_dates(char **argv, struct timeval *now) + static void parse_dates(const char **argv, struct timeval *now) { struct strbuf result = STRBUF_INIT; @@@ -60,7 -36,7 +60,7 @@@ strbuf_release(&result); } - static void parse_approxidate(char **argv, struct timeval *now) + static void parse_approxidate(const char **argv, struct timeval *now) { for (; *argv; argv++) { time_t t; @@@ -69,7 -45,7 +69,7 @@@ } } - int main(int argc, char **argv) + int cmd_main(int argc, const char **argv) { struct timeval now; const char *x; @@@ -85,10 -61,8 +85,10 @@@ argv++; if (!*argv) usage(usage_msg); - if (!strcmp(*argv, "show")) - show_dates(argv+1, &now); + if (!strcmp(*argv, "relative")) + show_relative_dates(argv+1, &now); + else if (skip_prefix(*argv, "show:", &x)) + show_dates(argv+1, x); else if (!strcmp(*argv, "parse")) parse_dates(argv+1, &now); else if (!strcmp(*argv, "approxidate")) diff --combined t/helper/test-regex.c index eff26f534f,37b7f06e55..b5ea8a97c5 --- a/t/helper/test-regex.c +++ b/t/helper/test-regex.c @@@ -1,23 -1,6 +1,23 @@@ #include "git-compat-util.h" +#include "gettext.h" -int cmd_main(int argc, const char **argv) +struct reg_flag { + const char *name; + int flag; +}; + +static struct reg_flag reg_flags[] = { + { "EXTENDED", REG_EXTENDED }, + { "NEWLINE", REG_NEWLINE }, + { "ICASE", REG_ICASE }, + { "NOTBOL", REG_NOTBOL }, +#ifdef REG_STARTEND + { "STARTEND", REG_STARTEND }, +#endif + { NULL, 0 } +}; + +static int test_regex_bug(void) { char *pat = "[^={} \t]+"; char *str = "={}\nfred"; @@@ -33,43 -16,5 +33,43 @@@ if (m[0].rm_so == 3) /* matches '\n' when it should not */ die("regex bug confirmed: re-build git with NO_REGEX=1"); - exit(0); + return 0; +} + - int main(int argc, char **argv) ++int cmd_main(int argc, const char **argv) +{ + const char *pat; + const char *str; + int flags = 0; + regex_t r; + regmatch_t m[1]; + + if (argc == 2 && !strcmp(argv[1], "--bug")) + return test_regex_bug(); + else if (argc < 3) + usage("test-regex --bug\n" + "test-regex []"); + + argv++; + pat = *argv++; + str = *argv++; + while (*argv) { + struct reg_flag *rf; + for (rf = reg_flags; rf->name; rf++) + if (!strcmp(*argv, rf->name)) { + flags |= rf->flag; + break; + } + if (!rf->name) + die("do not recognize %s", *argv); + argv++; + } + git_setup_gettext(); + + if (regcomp(&r, pat, flags)) + die("failed regcomp() for pattern '%s'", pat); + if (regexec(&r, str, 1, m, 0)) + return 1; + + return 0; } diff --combined t/helper/test-run-command.c index 6bb53da3c0,c71ea4f759..d24d157379 --- a/t/helper/test-run-command.c +++ b/t/helper/test-run-command.c @@@ -26,7 -26,7 +26,7 @@@ static int parallel_next(struct child_p return 0; argv_array_pushv(&cp->args, d->argv); - strbuf_addf(err, "preloaded output of a child\n"); + strbuf_addstr(err, "preloaded output of a child\n"); number_callbacks++; return 1; } @@@ -36,7 -36,7 +36,7 @@@ static int no_job(struct child_process void *cb, void **task_cb) { - strbuf_addf(err, "no further jobs available\n"); + strbuf_addstr(err, "no further jobs available\n"); return 0; } @@@ -45,11 -45,11 +45,11 @@@ static int task_finished(int result void *pp_cb, void *pp_task_cb) { - strbuf_addf(err, "asking for a quick stop\n"); + strbuf_addstr(err, "asking for a quick stop\n"); return 1; } - int main(int argc, char **argv) + int cmd_main(int argc, const char **argv) { struct child_process proc = CHILD_PROCESS_INIT; int jobs; diff --combined t/helper/test-submodule-config.c index a4e4098a0f,2cffded116..2a50217bf5 --- a/t/helper/test-submodule-config.c +++ b/t/helper/test-submodule-config.c @@@ -2,7 -2,7 +2,7 @@@ #include "submodule-config.h" #include "submodule.h" - static void die_usage(int argc, char **argv, const char *msg) + static void die_usage(int argc, const char **argv, const char *msg) { fprintf(stderr, "%s\n", msg); fprintf(stderr, "Usage: %s [ ] ...\n", argv[0]); @@@ -14,16 -14,16 +14,16 @@@ static int git_test_config(const char * return parse_submodule_config_option(var, value); } - int main(int argc, char **argv) + int cmd_main(int argc, const char **argv) { - char **arg = argv; + const char **arg = argv; int my_argc = argc; int output_url = 0; int lookup_name = 0; arg++; my_argc--; - while (starts_with(arg[0], "--")) { + while (arg[0] && starts_with(arg[0], "--")) { if (!strcmp(arg[0], "--url")) output_url = 1; if (!strcmp(arg[0], "--name")) diff --combined upload-pack.c index 44d63fba41,b97a7659d1..26746f67e2 --- a/upload-pack.c +++ b/upload-pack.c @@@ -58,21 -58,20 +58,21 @@@ static void reset_timeout(void alarm(timeout); } -static ssize_t send_client_data(int fd, const char *data, ssize_t sz) +static void send_client_data(int fd, const char *data, ssize_t sz) { - if (use_sideband) - return send_sideband(1, fd, data, sz, use_sideband); + if (use_sideband) { + send_sideband(1, fd, data, sz, use_sideband); + return; + } if (fd == 3) /* emergency quit */ fd = 2; if (fd == 2) { /* XXX: are we happy to lose stuff here? */ xwrite(fd, data, sz); - return sz; + return; } write_or_die(fd, data, sz); - return sz; } static int write_one_shallow(const struct commit_graft *graft, void *cb_data) @@@ -230,7 -229,9 +230,7 @@@ static void create_pack_file(void } else buffered = -1; - sz = send_client_data(1, data, sz); - if (sz < 0) - goto fail; + send_client_data(1, data, sz); } /* @@@ -257,7 -258,9 +257,7 @@@ /* flush the data */ if (0 <= buffered) { data[0] = buffered; - sz = send_client_data(1, data, 1); - if (sz < 0) - goto fail; + send_client_data(1, data, 1); fprintf(stderr, "flushed.\n"); } if (use_sideband) @@@ -813,20 -816,17 +813,17 @@@ static int upload_pack_config(const cha return parse_hide_refs_config(var, value, "uploadpack"); } - int main(int argc, char **argv) + int cmd_main(int argc, const char **argv) { - char *dir; + const char *dir; int i; int strict = 0; - git_setup_gettext(); - packet_trace_identity("upload-pack"); - git_extract_argv0_path(argv[0]); check_replace_refs = 0; for (i = 1; i < argc; i++) { - char *arg = argv[i]; + const char *arg = argv[i]; if (arg[0] != '-') break;