git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 1/5] common-main: split init and exit code into new files

From
Josh Steadmon <steadmon@google.com>
Date
Aug 9, 2024, 22:41 UTC
Message-ID
<800b37d16b8324faed8b7f84d30f797fc5664bf7.1723242556.git.steadmon@google.com>
In-Reply-To
<cover.1723242556.git.steadmon@google.com>

Currently, object files in libgit.a reference common_exit(), which is contained in common-main.o. However, common-main.o also includes main(), which references cmd_main() in git.o, which in turn depends on all the builtin/*.o objects.

We would like to allow external users to link libgit.a without needing to include so many extra objects. Enable this by splitting common_exit() and check_bug_if_BUG() into a new file common-exit.c, and add common-exit.o to LIB_OBJS so that these are included in libgit.a.

This split has previously been proposed ([1], [2]) to support fuzz tests and unit tests by avoiding conflicting definitions for main(). However, both of those issues were resolved by other methods of avoiding symbol conflicts. Now we are trying to make libgit.a more self-contained, so hopefully we can revisit this approach.

Additionally, move the initialization code out of main() into a new init_git() function in its own file. Include this in libgit.a as well, so that external users can share our setup code without calling our main().

[1] https://lore.kernel.org/git/Yp+wjCPhqieTku3X@google.com/ [2] https://lore.kernel.org/git/20230517-unit-tests-v2-v2-1-21b5b60f4b32@google.com/

Signed-off-by: Josh Steadmon <steadmon@google.com>
---
 Makefile      |  2 ++
 common-exit.c | 26 ++++++++++++++++
 common-init.c | 63 ++++++++++++++++++++++++++++++++++++++
 common-init.h |  6 ++++
 common-main.c | 83 ++-------------------------------------------------
 5 files changed, 99 insertions(+), 81 deletions(-)
 create mode 100644 common-exit.c
 create mode 100644 common-init.c
 create mode 100644 common-init.h
diff --git a/Makefile b/Makefile
index 3eab701b10..7caeb3c872 100644
--- a/Makefile
+++ b/Makefile
@@ -979,6 +979,8 @@ LIB_OBJS += combine-diff.o
 LIB_OBJS += commit-graph.o
 LIB_OBJS += commit-reach.o
 LIB_OBJS += commit.o
+LIB_OBJS += common-exit.o
+LIB_OBJS += common-init.o
 LIB_OBJS += compat/nonblock.o
 LIB_OBJS += compat/obstack.o
 LIB_OBJS += compat/terminal.o
diff --git a/common-exit.c b/common-exit.c
new file mode 100644
index 0000000000..1aaa538be3
--- /dev/null
+++ b/common-exit.c
@@ -0,0 +1,26 @@
+#include "git-compat-util.h"
+#include "trace2.h"
+
+static void check_bug_if_BUG(void)
+{
+	if (!bug_called_must_BUG)
+		return;
+	BUG("on exit(): had bug() call(s) in this process without explicit BUG_if_bug()");
+}
+
+/* We wrap exit() to call common_exit() in git-compat-util.h */
+int common_exit(const char *file, int line, int code)
+{
+	/*
+	 * For non-POSIX systems: Take the lowest 8 bits of the "code"
+	 * to e.g. turn -1 into 255. On a POSIX system this is
+	 * redundant, see exit(3) and wait(2), but as it doesn't harm
+	 * anything there we don't need to guard this with an "ifdef".
+	 */
+	code &= 0xff;
+
+	check_bug_if_BUG();
+	trace2_cmd_exit_fl(file, line, code);
+
+	return code;
+}
diff --git a/common-init.c b/common-init.c
new file mode 100644
index 0000000000..5cc73f058c
--- /dev/null
+++ b/common-init.c
@@ -0,0 +1,63 @@
+#define USE_THE_REPOSITORY_VARIABLE
+
+#include "git-compat-util.h"
+#include "common-init.h"
+#include "exec-cmd.h"
+#include "gettext.h"
+#include "attr.h"
+#include "repository.h"
+#include "setup.h"
+#include "strbuf.h"
+#include "trace2.h"
+
+/*
+ * Many parts of Git have subprograms communicate via pipe, expect the
+ * upstream of a pipe to die with SIGPIPE when the downstream of a
+ * pipe does not need to read all that is written.  Some third-party
+ * programs that ignore or block SIGPIPE for their own reason forget
+ * to restore SIGPIPE handling to the default before spawning Git and
+ * break this carefully orchestrated machinery.
+ *
+ * Restore the way SIGPIPE is handled to default, which is what we
+ * expect.
+ */
+static void restore_sigpipe_to_default(void)
+{
+	sigset_t unblock;
+
+	sigemptyset(&unblock);
+	sigaddset(&unblock, SIGPIPE);
+	sigprocmask(SIG_UNBLOCK, &unblock, NULL);
+	signal(SIGPIPE, SIG_DFL);
+}
+
+void init_git(const char **argv)
+{
+	struct strbuf tmp = STRBUF_INIT;
+
+	trace2_initialize_clock();
+
+	/*
+	 * Always open file descriptors 0/1/2 to avoid clobbering files
+	 * in die().  It also avoids messing up when the pipes are dup'ed
+	 * onto stdin/stdout/stderr in the child processes we spawn.
+	 */
+	sanitize_stdfds();
+	restore_sigpipe_to_default();
+
+	git_resolve_executable_dir(argv[0]);
+
+	setlocale(LC_CTYPE, "");
+	git_setup_gettext();
+
+	initialize_repository(the_repository);
+
+	attr_start();
+
+	trace2_initialize();
+	trace2_cmd_start(argv);
+	trace2_collect_process_info(TRACE2_PROCESS_INFO_STARTUP);
+
+	if (!strbuf_getcwd(&tmp))
+		tmp_original_cwd = strbuf_detach(&tmp, NULL);
+}
diff --git a/common-init.h b/common-init.h
new file mode 100644
index 0000000000..3e6db20cae
--- /dev/null
+++ b/common-init.h
@@ -0,0 +1,6 @@
+#ifndef COMMON_INIT_H
+#define COMMON_INIT_H
+
+void init_git(const char **argv);
+
+#endif /* COMMON_INIT_H */
diff --git a/common-main.c b/common-main.c
index 8e68ac9e42..6b7ab077b0 100644
--- a/common-main.c
+++ b/common-main.c
@@ -1,92 +1,13 @@
-#define USE_THE_REPOSITORY_VARIABLE
-
 #include "git-compat-util.h"
-#include "exec-cmd.h"
-#include "gettext.h"
-#include "attr.h"
-#include "repository.h"
-#include "setup.h"
-#include "strbuf.h"
-#include "trace2.h"
-
-/*
- * Many parts of Git have subprograms communicate via pipe, expect the
- * upstream of a pipe to die with SIGPIPE when the downstream of a
- * pipe does not need to read all that is written.  Some third-party
- * programs that ignore or block SIGPIPE for their own reason forget
- * to restore SIGPIPE handling to the default before spawning Git and
- * break this carefully orchestrated machinery.
- *
- * Restore the way SIGPIPE is handled to default, which is what we
- * expect.
- */
-static void restore_sigpipe_to_default(void)
-{
-	sigset_t unblock;
-
-	sigemptyset(&unblock);
-	sigaddset(&unblock, SIGPIPE);
-	sigprocmask(SIG_UNBLOCK, &unblock, NULL);
-	signal(SIGPIPE, SIG_DFL);
-}
+#include "common-init.h"
 
 int main(int argc, const char **argv)
 {
 	int result;
-	struct strbuf tmp = STRBUF_INIT;
-
-	trace2_initialize_clock();
-
-	/*
-	 * Always open file descriptors 0/1/2 to avoid clobbering files
-	 * in die().  It also avoids messing up when the pipes are dup'ed
-	 * onto stdin/stdout/stderr in the child processes we spawn.
-	 */
-	sanitize_stdfds();
-	restore_sigpipe_to_default();
-
-	git_resolve_executable_dir(argv[0]);
-
-	setlocale(LC_CTYPE, "");
-	git_setup_gettext();
-
-	initialize_repository(the_repository);
-
-	attr_start();
-
-	trace2_initialize();
-	trace2_cmd_start(argv);
-	trace2_collect_process_info(TRACE2_PROCESS_INFO_STARTUP);
-
-	if (!strbuf_getcwd(&tmp))
-		tmp_original_cwd = strbuf_detach(&tmp, NULL);
 
+	init_git(argv);
 	result = cmd_main(argc, argv);
 
 	/* Not exit(3), but a wrapper calling our common_exit() */
 	exit(result);
 }
-
-static void check_bug_if_BUG(void)
-{
-	if (!bug_called_must_BUG)
-		return;
-	BUG("on exit(): had bug() call(s) in this process without explicit BUG_if_bug()");
-}
-
-/* We wrap exit() to call common_exit() in git-compat-util.h */
-int common_exit(const char *file, int line, int code)
-{
-	/*
-	 * For non-POSIX systems: Take the lowest 8 bits of the "code"
-	 * to e.g. turn -1 into 255. On a POSIX system this is
-	 * redundant, see exit(3) and wait(2), but as it doesn't harm
-	 * anything there we don't need to guard this with an "ifdef".
-	 */
-	code &= 0xff;
-
-	check_bug_if_BUG();
-	trace2_cmd_exit_fl(file, line, code);
-
-	return code;
-}
-- 
2.46.0.76.ge559c4bf1a-goog
Previous: Josh SteadmonNext: Josh Steadmon
Message 65 of 217 in “[RFC] Introduce cgit-rs, a Rust wrapper around libgit.a”
  1. 0/6 [RFC] Introduce cgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Aug 7, 2024
  2. 1/6 common-main: split common_exit() into a new fileJosh Steadmon, Aug 7, 2024
  3. Junio C HamanoAug 7, 2024
  4. Josh SteadmonAug 7, 2024
  5. 2/6 repository: add initialize_repo wrapper without pointerJosh Steadmon, Aug 7, 2024
  6. Mike HommeyAug 7, 2024
  7. Josh SteadmonAug 7, 2024
  8. Mike HommeyAug 7, 2024
  9. Josh SteadmonAug 8, 2024
  10. 3/6 contrib/cgit-rs: introduce Rust wrapper for libgit.aJosh Steadmon, Aug 7, 2024
  11. brian m. carlsonAug 7, 2024
  12. rsbecker@nexbridge.comAug 7, 2024
  13. Josh SteadmonAug 7, 2024
  14. rsbecker@nexbridge.comAug 7, 2024
  15. Josh SteadmonAug 8, 2024
  16. rsbecker@nexbridge.comAug 8, 2024
  17. Junio C HamanoAug 8, 2024
  18. rsbecker@nexbridge.comAug 8, 2024
  19. rsbecker@nexbridge.comAug 12, 2024
  20. Josh SteadmonAug 7, 2024
  21. brian m. carlsonAug 7, 2024
  22. Junio C HamanoAug 8, 2024
  23. Josh SteadmonAug 8, 2024
  24. Josh SteadmonAug 8, 2024
  25. Kyle LippincottAug 8, 2024
  26. Josh SteadmonAug 8, 2024
  27. Mike HommeyAug 7, 2024
  28. Josh SteadmonAug 7, 2024
  29. Mike HommeyAug 8, 2024
  30. Josh SteadmonAug 8, 2024
  31. 4/6 contrib/cgit-rs: add repo initialization and config accessJosh Steadmon, Aug 7, 2024
  32. brian m. carlsonAug 7, 2024
  33. Josh SteadmonAug 7, 2024
  34. brian m. carlsonAug 8, 2024
  35. 5/6 config: add git_configset_allocJosh Steadmon, Aug 7, 2024
  36. 6/6 contrib/cgit-rs: add a subset of configset wrappersJosh Steadmon, Aug 7, 2024
  37. brian m. carlsonAug 7, 2024
  38. Junio C HamanoAug 7, 2024
  39. Josh SteadmonAug 8, 2024
  40. Calvin WanSep 4, 2024
  41. brian m. carlsonSep 4, 2024
  42. Calvin WanSep 6, 2024
  43. brian m. carlsonSep 7, 2024
  44. Junio C HamanoSep 4, 2024
  45. brian m. carlsonSep 4, 2024
  46. Junio C HamanoSep 4, 2024
  47. Josh SteadmonSep 4, 2024
  48. brian m. carlsonAug 7, 2024
  49. Josh SteadmonAug 7, 2024
  50. brian m. carlsonAug 8, 2024
  51. Josh SteadmonAug 9, 2024
  52. Jason A. DonenfeldAug 8, 2024
  53. Dragan SimicAug 8, 2024
  54. rsbecker@nexbridge.comAug 8, 2024
  55. Dragan SimicAug 8, 2024
  56. Junio C HamanoAug 8, 2024
  57. Junio C HamanoAug 9, 2024
  58. Junio C HamanoAug 9, 2024
  59. Josh SteadmonAug 9, 2024
  60. Junio C HamanoAug 9, 2024
  61. Junio C HamanoAug 9, 2024
  62. Josh SteadmonAug 9, 2024
  63. Junio C HamanoAug 9, 2024
  64. 0/5 Introduce cgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Aug 9, 2024
  65. 1/5 common-main: split init and exit code into new filesJosh Steadmon, Aug 9, 2024
  66. 2/5 cgit-sys: introduce Rust wrapper for libgit.aJosh Steadmon, Aug 9, 2024
  67. 3/5 cgit-sys: add repo initialization and config accessJosh Steadmon, Aug 9, 2024
  68. 4/5 config: add git_configset_alloc() and git_configset_clear_and_free()Josh Steadmon, Aug 9, 2024
  69. Phillip WoodAug 12, 2024
  70. Josh SteadmonAug 12, 2024
  71. Kyle LippincottAug 12, 2024
  72. phillip.wood123@gmail.comAug 13, 2024
  73. Junio C HamanoAug 13, 2024
  74. phillip.wood123@gmail.comAug 13, 2024
  75. Josh SteadmonOct 2, 2024
  76. Patrick SteinhardtAug 16, 2024
  77. Josh SteadmonOct 2, 2024
  78. 5/5 cgit: add higher-level cgit crateJosh Steadmon, Aug 9, 2024
  79. Phillip WoodAug 12, 2024
  80. Calvin WanAug 21, 2024
  81. Kyle LippincottAug 21, 2024
  82. Phillip WoodAug 22, 2024
  83. Phillip WoodAug 22, 2024
  84. Josh SteadmonOct 2, 2024
  85. Junio C HamanoAug 9, 2024
  86. Jason A. DonenfeldAug 10, 2024
  87. Dragan SimicAug 11, 2024
  88. Eric SunshineAug 11, 2024
  89. Dragan SimicAug 11, 2024
  90. Eric SunshineAug 11, 2024
  91. Dragan SimicAug 11, 2024
  92. Junio C HamanoAug 12, 2024
  93. Eric SunshineAug 12, 2024
  94. Junio C HamanoAug 12, 2024
  95. Josh SteadmonAug 12, 2024
  96. Patrick SteinhardtAug 16, 2024
  97. brian m. carlsonAug 16, 2024
  98. Eric SunshineAug 17, 2024
  99. Junio C HamanoAug 18, 2024
  100. brian m. carlsonAug 12, 2024
  101. Dragan SimicAug 12, 2024
  102. Josh SteadmonAug 12, 2024
  103. Junio C HamanoAug 12, 2024
  104. Junio C HamanoAug 12, 2024
  105. 0/6 Introduce libgit-rs, a Rust wrapper around libgit.aCalvin Wan, Sep 6, 2024
  106. 1/6 common-main: split init and exit code into new filesCalvin Wan, Sep 6, 2024
  107. 2/6 libgit-sys: introduce Rust wrapper for libgit.aCalvin Wan, Sep 6, 2024
  108. Eric SunshineSep 6, 2024
  109. Mike HommeySep 6, 2024
  110. Junio C HamanoSep 8, 2024
  111. Josh SteadmonSep 18, 2024
  112. Calvin WanSep 10, 2024
  113. Josh SteadmonSep 18, 2024
  114. 3/6 libgit-sys: add repo initialization and config accessCalvin Wan, Sep 6, 2024
  115. Eric SunshineSep 6, 2024
  116. Josh SteadmonSep 18, 2024
  117. Junio C HamanoSep 6, 2024
  118. Josh SteadmonSep 18, 2024
  119. Patrick SteinhardtSep 10, 2024
  120. Josh SteadmonOct 7, 2024
  121. Josh SteadmonOct 8, 2024
  122. 4/6 config: add git_configset_alloc() and git_configset_clear_and_free()Calvin Wan, Sep 6, 2024
  123. Eric SunshineSep 6, 2024
  124. Patrick SteinhardtSep 10, 2024
  125. Phillip WoodSep 10, 2024
  126. Junio C HamanoSep 10, 2024
  127. Calvin WanSep 10, 2024
  128. Josh SteadmonOct 2, 2024
  129. 5/6 libgit: add higher-level libgit crateCalvin Wan, Sep 6, 2024
  130. Junio C HamanoSep 7, 2024
  131. Junio C HamanoSep 9, 2024
  132. Calvin WanSep 10, 2024
  133. Junio C HamanoSep 10, 2024
  134. Josh SteadmonSep 17, 2024
  135. Junio C HamanoSep 18, 2024
  136. Josh SteadmonOct 7, 2024
  137. Josh SteadmonSep 17, 2024
  138. 6/6 Makefile: add option to build and test libgit-rs and libgit-rs-sysCalvin Wan, Sep 6, 2024
  139. Sean AllredSep 7, 2024
  140. Junio C HamanoSep 8, 2024
  141. Calvin WanSep 10, 2024
  142. brian m. carlsonSep 13, 2024
  143. Josh SteadmonOct 7, 2024
  144. Josh SteadmonOct 2, 2024
  145. 0/5 Introduce libgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Oct 8, 2024
  146. 1/5 common-main: split init and exit code into new filesJosh Steadmon, Oct 8, 2024
  147. 2/5 libgit-sys: introduce Rust wrapper for libgit.aJosh Steadmon, Oct 8, 2024
  148. 3/5 libgit-sys: also export some config_set functionsJosh Steadmon, Oct 8, 2024
  149. 4/5 libgit: add higher-level libgit crateJosh Steadmon, Oct 8, 2024
  150. Eric SunshineOct 9, 2024
  151. Josh SteadmonOct 9, 2024
  152. Josh SteadmonOct 9, 2024
  153. 5/5 Makefile: add option to build and test libgit-rs and libgit-rs-sysJosh Steadmon, Oct 8, 2024
  154. Junio C HamanoOct 8, 2024
  155. rsbecker@nexbridge.comOct 9, 2024
  156. Josh SteadmonOct 14, 2024
  157. Junio C HamanoOct 9, 2024
  158. Josh SteadmonOct 9, 2024
  159. Junio C HamanoOct 10, 2024
  160. Josh SteadmonOct 14, 2024
  161. Junio C HamanoOct 9, 2024
  162. Josh SteadmonOct 9, 2024
  163. 0/5 Introduce libgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Oct 15, 2024
  164. 1/5 common-main: split init and exit code into new filesJosh Steadmon, Oct 15, 2024
  165. 2/5 libgit-sys: introduce Rust wrapper for libgit.aJosh Steadmon, Oct 15, 2024
  166. 3/5 libgit-sys: also export some config_set functionsJosh Steadmon, Oct 15, 2024
  167. 4/5 libgit: add higher-level libgit crateJosh Steadmon, Oct 15, 2024
  168. 5/5 Makefile: add option to build and test libgit-rs and libgit-rs-sysJosh Steadmon, Oct 15, 2024
  169. Junio C HamanoDec 3, 2024
  170. 0/5 Introduce libgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Jan 15, 2025
  171. 1/5 common-main: split init and exit code into new filesJosh Steadmon, Jan 15, 2025
  172. Junio C HamanoJan 15, 2025
  173. Junio C HamanoJan 16, 2025
  174. Junio C HamanoJan 16, 2025
  175. Patrick SteinhardtJan 17, 2025
  176. Josh SteadmonJan 21, 2025
  177. 2/5 libgit-sys: introduce Rust wrapper for libgit.aJosh Steadmon, Jan 15, 2025
  178. Junio C HamanoJan 15, 2025
  179. Josh SteadmonJan 22, 2025
  180. Josh SteadmonJan 27, 2025
  181. 3/5 libgit-sys: also export some config_set functionsJosh Steadmon, Jan 15, 2025
  182. 4/5 libgit: add higher-level libgit crateJosh Steadmon, Jan 15, 2025
  183. brian m. carlsonJan 21, 2025
  184. Josh SteadmonJan 22, 2025
  185. 5/5 Makefile: add option to build and test libgit-rs and libgit-rs-sysJosh Steadmon, Jan 15, 2025
  186. Junio C HamanoJan 15, 2025
  187. brian m. carlsonJan 21, 2025
  188. Junio C HamanoJan 21, 2025
  189. 0/4 Introduce libgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Jan 28, 2025
  190. 1/4 common-main: split init and exit code into new filesJosh Steadmon, Jan 28, 2025
  191. 2/4 libgit-sys: introduce Rust wrapper for libgit.aJosh Steadmon, Jan 28, 2025
  192. Phillip WoodJan 28, 2025
  193. Josh SteadmonJan 28, 2025
  194. Junio C HamanoJan 28, 2025
  195. 3/4 libgit-sys: also export some config_set functionsJosh Steadmon, Jan 28, 2025
  196. Phillip WoodJan 28, 2025
  197. Josh SteadmonJan 28, 2025
  198. 4/4 libgit: add higher-level libgit crateJosh Steadmon, Jan 28, 2025
  199. Junio C HamanoJan 28, 2025
  200. Josh SteadmonJan 28, 2025
  201. Junio C HamanoJan 28, 2025
  202. 0/4 Introduce libgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Jan 28, 2025
  203. 1/4 common-main: split init and exit code into new filesJosh Steadmon, Jan 28, 2025
  204. 2/4 libgit-sys: introduce Rust wrapper for libgit.aJosh Steadmon, Jan 28, 2025
  205. Junio C HamanoJan 28, 2025
  206. Josh SteadmonJan 29, 2025
  207. 3/4 libgit-sys: also export some config_set functionsJosh Steadmon, Jan 28, 2025
  208. 4/4 libgit: add higher-level libgit crateJosh Steadmon, Jan 28, 2025
  209. Phillip WoodJan 29, 2025
  210. Josh SteadmonJan 29, 2025
  211. 0/4 Introduce libgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Jan 29, 2025
  212. 1/4 common-main: split init and exit code into new filesJosh Steadmon, Jan 29, 2025
  213. 2/4 libgit-sys: introduce Rust wrapper for libgit.aJosh Steadmon, Jan 29, 2025
  214. 3/4 libgit-sys: also export some config_set functionsJosh Steadmon, Jan 29, 2025
  215. 4/4 libgit: add higher-level libgit crateJosh Steadmon, Jan 29, 2025
  216. phillip.wood123@gmail.comJan 30, 2025
  217. Junio C HamanoJan 30, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.