link: new applet
authorDenys Vlasenko <vda.linux@googlemail.com>
Wed, 25 Jan 2017 23:27:53 +0000 (00:27 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 25 Jan 2017 23:27:53 +0000 (00:27 +0100)
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@googlemail.com>
archival/libarchive/data_extract_all.c
coreutils/link.c [new file with mode: 0644]
docs/nofork_noexec.txt

index bd034afdca5ed795c37f32f3e2bb03d18cb8a771..1830ffb8d0f786be7abe4ac4636fde932c87d6a5 100644 (file)
@@ -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 (file)
index 0000000..ac3ef85
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * link implementation for busybox
+ *
+ * Copyright (C) 2017 Denys Vlasenko <vda.linux@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;
+}
index c58f5a83f139ef0fe78bcfff3f2f78a238df8f5c..2fb184a0308f4a53ad8884a53aef596d212f4a12 100644 (file)
@@ -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