Skip to content

Commit 3f2e229

Browse files
peffgitster
authored andcommitted
add an extra level of indirection to main()
There are certain startup tasks that we expect every git process to do. In some cases this is just to improve the quality of the program (e.g., setting up gettext()). In others it is a requirement for using certain functions in libgit.a (e.g., system_path() expects that you have called git_extract_argv0_path()). Most commands are builtins and are covered by the git.c version of main(). However, there are still a few external commands that use their own main(). Each of these has to remember to include the correct startup sequence, and we are not always consistent. Rather than just fix the inconsistencies, let's make this harder to get wrong by providing a common main() that can run this standard startup. We basically have two options to do this: - the compat/mingw.h file already does something like this by adding a #define that replaces the definition of main with a wrapper that calls mingw_startup(). The upside is that the code in each program doesn't need to be changed at all; it's rewritten on the fly by the preprocessor. The downside is that it may make debugging of the startup sequence a bit more confusing, as the preprocessor is quietly inserting new code. - the builtin functions are all of the form cmd_foo(), and git.c's main() calls them. This is much more explicit, which may make things more obvious to somebody reading the code. It's also more flexible (because of course we have to figure out _which_ cmd_foo() to call). The downside is that each of the builtins must define cmd_foo(), instead of just main(). This patch chooses the latter option, preferring the more explicit approach, even though it is more invasive. We introduce a new file common-main.c, with the "real" main. It expects to call cmd_main() from whatever other objects it is linked against. We link common-main.o against anything that links against libgit.a, since we know that such programs will need to do this setup. Note that common-main.o can't actually go inside libgit.a, as the linker would not pick up its main() function automatically (it has no callers). The rest of the patch is just adjusting all of the various external programs (mostly in t/helper) to use cmd_main(). I've provided a global declaration for cmd_main(), which means that all of the programs also need to match its signature. In particular, many functions need to switch to "const char **" instead of "char **" for argv. This effect ripples out to a few other variables and functions, as well. This makes the patch even more invasive, but the end result is much better. We should be treating argv strings as const anyway, and now all programs conform to the same signature (which also matches the way builtins are defined). Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0b65a8d commit 3f2e229

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+91
-69
lines changed

Makefile

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,7 @@ BUILTIN_OBJS += builtin/verify-tag.o
943943
BUILTIN_OBJS += builtin/worktree.o
944944
BUILTIN_OBJS += builtin/write-tree.o
945945

946-
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
946+
GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB)
947947
EXTLIBS =
948948

949949
GIT_USER_AGENT = git/$(GIT_VERSION)
@@ -1572,7 +1572,15 @@ TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
15721572
DIFF_SQ = $(subst ','\'',$(DIFF))
15731573
PERLLIB_EXTRA_SQ = $(subst ','\'',$(PERLLIB_EXTRA))
15741574

1575-
LIBS = $(GITLIBS) $(EXTLIBS)
1575+
# We must filter out any object files from $(GITLIBS),
1576+
# as it is typically used like:
1577+
#
1578+
# foo: foo.o $(GITLIBS)
1579+
# $(CC) $(filter %.o,$^) $(LIBS)
1580+
#
1581+
# where we use it as a dependency. Since we also pull object files
1582+
# from the dependency list, that would make each entry appear twice.
1583+
LIBS = $(filter-out %.o, $(GITLIBS)) $(EXTLIBS)
15761584

15771585
BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' \
15781586
$(COMPAT_CFLAGS)
@@ -1708,8 +1716,8 @@ git.sp git.s git.o: EXTRA_CPPFLAGS = \
17081716
'-DGIT_INFO_PATH="$(infodir_relative_SQ)"'
17091717

17101718
git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)
1711-
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) git.o \
1712-
$(BUILTIN_OBJS) $(LIBS)
1719+
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \
1720+
$(filter %.o,$^) $(LIBS)
17131721

17141722
help.sp help.s help.o: common-cmds.h
17151723

@@ -1902,6 +1910,7 @@ TEST_OBJS := $(patsubst test-%$X,test-%.o,$(TEST_PROGRAMS))
19021910
OBJECTS := $(LIB_OBJS) $(BUILTIN_OBJS) $(PROGRAM_OBJS) $(TEST_OBJS) \
19031911
$(XDIFF_OBJS) \
19041912
$(VCSSVN_OBJS) \
1913+
common-main.o \
19051914
git.o
19061915
ifndef NO_CURL
19071916
OBJECTS += http.o http-walker.o remote-curl.o

common-main.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include "git-compat-util.h"
2+
3+
int main(int argc, char **av)
4+
{
5+
/*
6+
* This const trickery is explained in
7+
* 84d32bf7678259c08406571cd6ce4b7a6724dcba
8+
*/
9+
const char **argv = (const char **)av;
10+
11+
return cmd_main(argc, argv);
12+
}

credential-cache--daemon.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ static void init_socket_directory(const char *path)
257257
free(path_copy);
258258
}
259259

260-
int main(int argc, const char **argv)
260+
int cmd_main(int argc, const char **argv)
261261
{
262262
const char *socket_path;
263263
int ignore_sighup = 0;

credential-cache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ static void do_cache(const char *socket, const char *action, int timeout,
8383
strbuf_release(&buf);
8484
}
8585

86-
int main(int argc, const char **argv)
86+
int cmd_main(int argc, const char **argv)
8787
{
8888
char *socket_path = NULL;
8989
int timeout = 900;

credential-store.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ static void lookup_credential(const struct string_list *fns, struct credential *
142142
return; /* Found credential */
143143
}
144144

145-
int main(int argc, char **argv)
145+
int cmd_main(int argc, const char **argv)
146146
{
147147
const char * const usage[] = {
148148
"git credential-store [<options>] <action>",

daemon.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static const char daemon_usage[] =
3232
" [<directory>...]";
3333

3434
/* List of acceptable pathname prefixes */
35-
static char **ok_paths;
35+
static const char **ok_paths;
3636
static int strict_paths;
3737

3838
/* If this is set, git-daemon-export-ok is not required */
@@ -240,7 +240,7 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)
240240
}
241241

242242
if ( ok_paths && *ok_paths ) {
243-
char **pp;
243+
const char **pp;
244244
int pathlen = strlen(path);
245245

246246
/* The validation is done on the paths after enter_repo
@@ -1178,7 +1178,7 @@ static int serve(struct string_list *listen_addr, int listen_port,
11781178
return service_loop(&socklist);
11791179
}
11801180

1181-
int main(int argc, char **argv)
1181+
int cmd_main(int argc, const char **argv)
11821182
{
11831183
int listen_port = 0;
11841184
struct string_list listen_addr = STRING_LIST_INIT_NODUP;
@@ -1193,7 +1193,7 @@ int main(int argc, char **argv)
11931193
git_extract_argv0_path(argv[0]);
11941194

11951195
for (i = 1; i < argc; i++) {
1196-
char *arg = argv[i];
1196+
const char *arg = argv[i];
11971197
const char *v;
11981198

11991199
if (skip_prefix(arg, "--listen=", &v)) {

fast-import.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ static int failure;
300300
static FILE *pack_edges;
301301
static unsigned int show_stats = 1;
302302
static int global_argc;
303-
static char **global_argv;
303+
static const char **global_argv;
304304

305305
/* Memory pools */
306306
static size_t mem_pool_alloc = 2*1024*1024 - sizeof(struct mem_pool);
@@ -3381,7 +3381,7 @@ static void parse_argv(void)
33813381
read_marks();
33823382
}
33833383

3384-
int main(int argc, char **argv)
3384+
int cmd_main(int argc, const char **argv)
33853385
{
33863386
unsigned int i;
33873387

git-compat-util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,3 +1043,5 @@ struct tm *git_gmtime_r(const time_t *, struct tm *);
10431043
#endif
10441044

10451045
#endif
1046+
1047+
extern int cmd_main(int, const char **);

git.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -630,9 +630,8 @@ static void restore_sigpipe_to_default(void)
630630
signal(SIGPIPE, SIG_DFL);
631631
}
632632

633-
int main(int argc, char **av)
633+
int cmd_main(int argc, const char **argv)
634634
{
635-
const char **argv = (const char **) av;
636635
const char *cmd;
637636
int done_help = 0;
638637

http-backend.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ static struct service_cmd {
632632
{"POST", "/git-receive-pack$", service_rpc}
633633
};
634634

635-
int main(int argc, char **argv)
635+
int cmd_main(int argc, const char **argv)
636636
{
637637
char *method = getenv("REQUEST_METHOD");
638638
char *dir;

0 commit comments

Comments
 (0)