readlink: do not emit errors if file doesnt not exist / not a link
authorDenis Vlasenko <vda.linux@googlemail.com>
Fri, 20 Oct 2006 18:36:55 +0000 (18:36 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Fri, 20 Oct 2006 18:36:55 +0000 (18:36 -0000)
getopt32: add =N support

debianutils/readlink.c
libbb/getopt32.c

index 0d5ad94..9536d32 100644 (file)
 #include <stdlib.h>
 #include <getopt.h>
 
-#define READLINK_FLAG_f        (1 << 0)
-
 int readlink_main(int argc, char **argv)
 {
        char *buf;
-       unsigned opt = ENABLE_FEATURE_READLINK_FOLLOW ?
-                       getopt32(argc, argv, "f") : 0;
-
-       if (argc != (ENABLE_FEATURE_READLINK_FOLLOW ? optind + 1 : 2))
-                       bb_show_usage();
-
-       if (opt & READLINK_FLAG_f)
-               buf = realpath(argv[optind], bb_common_bufsiz1);
-       else
-               buf = xreadlink(argv[ENABLE_FEATURE_READLINK_FOLLOW ? optind : 1]);
+       char *fname;
+
+       USE_FEATURE_READLINK_FOLLOW(
+               unsigned opt;
+               /* We need exactly one non-option argument.  */
+               opt_complementary = "=1";
+               opt = getopt32(argc, argv, "f");
+               fname = argv[optind];
+       )
+       SKIP_FEATURE_READLINK_FOLLOW(
+               const unsigned opt = 0;
+               if (argc != 2) bb_show_usage();
+               fname = argv[1];
+       )
+
+       /* compat: coreutils readlink reports errors silently via exit code */
+       logmode = LOGMODE_NONE;
+
+       if (opt) {
+               buf = realpath(fname, bb_common_bufsiz1);
+       } else {
+               buf = xreadlink(fname);
+       }
 
        if (!buf)
                return EXIT_FAILURE;
@@ -36,5 +47,5 @@ int readlink_main(int argc, char **argv)
        if (ENABLE_FEATURE_CLEAN_UP && buf != bb_common_bufsiz1)
                free(buf);
 
-       return EXIT_SUCCESS;
+       bb_fflush_stdout_and_exit(EXIT_SUCCESS);
 }
index 2f2f0b9..73e6b86 100644 (file)
@@ -188,6 +188,10 @@ Special characters:
         by a single digit (0-9) means that at least N non-option
         arguments must be present on the command line
 
+ "=N"   An equal sign as the first char in a opt_complementary group followed
+        by a single digit (0-9) means that exactly N non-option
+        arguments must be present on the command line
+
  "V-"   An option with dash before colon or end-of-line results in
         bb_show_usage being called if this option is encountered.
         This is typically used to implement "print verbose usage message
@@ -400,6 +404,11 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
                        }
                        continue;
                }
+               if (*s == '=') {
+                       min_arg = max_arg = c - '0';
+                       s++;
+                       continue;
+               }
                for (on_off = complementary; on_off->opt; on_off++)
                        if (on_off->opt == *s)
                                break;