[git commit] link: new applet

Denys Vlasenko vda.linux at googlemail.com
Wed Jan 25 23:27:53 UTC 2017


commit: https://git.busybox.net/busybox/commit/?id=06f20bf675cdd415c2f796ebea9fc55030ef49cc
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

coreutils grew itself a tiny simplistic alternative to ln:

	Usage: link FILE LINK

	Create hard LINK to FILE

function                                             old     new   delta
link_main                                              -      75     +75
packed_usage                                       31114   31131     +17
applet_names                                        2564    2569      +5
applet_main                                         1480    1484      +4
applet_install_loc                                   185     186      +1
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 4/0 up/down: 102/0)             Total: 102 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 archival/libarchive/data_extract_all.c |  6 +++--
 coreutils/link.c                       | 41 ++++++++++++++++++++++++++++++++++
 docs/nofork_noexec.txt                 | 32 +++++++++++++++++++++-----
 3 files changed, 71 insertions(+), 8 deletions(-)

diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c
index bd034af..1830ffb 100644
--- a/archival/libarchive/data_extract_all.c
+++ b/archival/libarchive/data_extract_all.c
@@ -127,8 +127,9 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
 	if (hard_link) {
 		res = link(hard_link, dst_name);
 		if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
+			/* shared message */
 			bb_perror_msg("can't create %slink "
-					"from %s to %s", "hard",
+					"%s to %s", "hard",
 					dst_name,
 					hard_link);
 		}
@@ -181,8 +182,9 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
 		if (res != 0
 		 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
 		) {
+			/* shared message */
 			bb_perror_msg("can't create %slink "
-				"from %s to %s", "sym",
+				"%s to %s", "sym",
 				dst_name,
 				file_header->link_target);
 		}
diff --git a/coreutils/link.c b/coreutils/link.c
new file mode 100644
index 0000000..ac3ef85
--- /dev/null
+++ b/coreutils/link.c
@@ -0,0 +1,41 @@
+/*
+ * link implementation for busybox
+ *
+ * Copyright (C) 2017 Denys Vlasenko <vda.linux at googlemail.com>
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree.
+ */
+//config:config LINK
+//config:	bool "link"
+//config:	default y
+//config:	help
+//config:	  link creates hard links between files.
+
+//applet:IF_LINK(APPLET_NOFORK(link, link, BB_DIR_BIN, BB_SUID_DROP, link))
+
+//kbuild:lib-$(CONFIG_LINK) += link.o
+
+//usage:#define link_trivial_usage
+//usage:       "FILE LINK"
+//usage:#define link_full_usage "\n\n"
+//usage:       "Create hard LINK to FILE"
+
+#include "libbb.h"
+
+/* This is a NOFORK applet. Be very careful! */
+
+int link_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int link_main(int argc UNUSED_PARAM, char **argv)
+{
+	opt_complementary = "=2"; /* exactly 2 params */
+	getopt32(argv, "");
+	argv += optind;
+	if (link(argv[0], argv[1]) != 0) {
+		/* shared message */
+		bb_perror_msg_and_die("can't create %slink "
+					"%s to %s", "hard",
+					argv[1], argv[0]
+		);
+	}
+	return EXIT_SUCCESS;
+}
diff --git a/docs/nofork_noexec.txt b/docs/nofork_noexec.txt
index c58f5a8..2fb184a 100644
--- a/docs/nofork_noexec.txt
+++ b/docs/nofork_noexec.txt
@@ -33,6 +33,7 @@ roughly are:
 * do not expect shared global variables/buffers to be in their
   "initialized" state. Examples: xfunc_error_retval can be != 1,
   bb_common_bufsiz1 can be scribbled over, ...
+  (although usually xfunc_error_retval's state is not a problem).
 * do not expect that stdio wasn't used before. Calling set[v]buf()
   can be disastrous.
 * ...
@@ -81,18 +82,37 @@ are probably not worth the effort.
 Any NOFORK applet is also a NOEXEC applet.
 
 
+	Calling NOFORK applets
+
+API to call NOFORK applets is two functions:
+
+	run_nofork_applet(appno, argv)
+	spawn_and_wait(argv) // only if FEATURE_PREFER_APPLETS=y
+
+First one is directly used by shells if FEATURE_SH_NOFORK=y.
+Second one is used by many applets, but main users are xargs and find.
+It itself calls run_nofork_applet(), if argv[0] turned out to be a name
+of a NOFORK applet.
+
+run_nofork_applet() saves/inits/restores option parsing, xfunc_error_retval,
+applet_name. Thus, for example, caller does not need to worry about
+option_mask32 getting trashed.
+
+
 	Relevant CONFIG options
 
 FEATURE_PREFER_APPLETS
   BB_EXECVP(cmd, argv) will try to exec /proc/self/exe
-    if command's name matches some applet name
-  applet tables will contain NOFORK/NOEXEC bits
+  if command's name matches some applet name;
   spawn_and_wait(argv) will do NOFORK/NOEXEC tricks
 
-FEATURE_SH_STANDALONE (needs FEATURE_PREFER_APPLETS=y)
+//TODO: the above two things probably should have separate options?
+
+FEATURE_SH_STANDALONE
   shells will try to exec /proc/self/exe if command's name matches
-    some applet name
-  shells will do NOEXEC trick on NOEXEC applets
+  some applet name; shells will do NOEXEC trick on NOEXEC applets
+
+//TODO: split (same as for PREFER_APPLETS)
 
-FEATURE_SH_NOFORK (needs FEATURE_PREFER_APPLETS=y)
+FEATURE_SH_NOFORK
   shells will do NOFORK trick on NOFORK applets


More information about the busybox-cvs mailing list