Print this page
4270 ld(1) argument error reporting is still pretty bad
4227 ld --library-path is translated to -l-path, not -L

@@ -299,13 +299,13 @@
         optarg = str;
         return (c);
 }
 
 /*
- * Determine whether this string, possibly with an associated option, should be
- * translated to an option character.  If so, update the optind and optarg
- * as described for short options in getopt(3c).
+ * Determine whether this string, possibly with an associated option, should
+ * be translated to an option character.  If so, update the optind and optarg
+ * and optopt as described for short options in getopt(3c).
  *
  * entry:
  *      lml - Link map list for debug messages
  *      ndx - Starting optind for current item
  *      argc, argv - Command line arguments

@@ -327,14 +327,15 @@
                  * argument).
                  */
                 if (strcmp(arg, opt) == 0) {
                         DBG_CALL(Dbg_args_str2chr(lml, ndx, opt, c));
                         optind += 1;
+                        optopt = c;
                         return (c);
                 }
-
-        } else if (strncmp(arg, opt, optsz) == 0) {
+        } else if ((strcmp(arg, opt) == 0) ||
+            ((arg[optsz] == '=') && strncmp(arg, opt, optsz) == 0)) {
                 /*
                  * Otherwise, compare the option name, which may be
                  * concatenated with the option argument.
                  */
                 DBG_CALL(Dbg_args_str2chr(lml, ndx, opt, c));

@@ -343,34 +344,41 @@
                         /*
                          * Optarg is the next argument (white space separated).
                          * Make sure an optarg is available, and if not return
                          * a failure to prevent any fall-through to the generic
                          * getopt() processing.
+                         *
+                         * Since we'll be completely failing this option we
+                         * don't want to update optopt with the translation,
+                         * but also need to set it to _something_.  Setting it
+                         * to the '-' of the argument causes us to behave
+                         * correctly.
                          */
                         if ((++optind + 1) > argc) {
+                                optopt = arg[0];
                                 return ('?');
                         }
                         optarg = argv[optind];
                         optind++;
                 } else {
                         /*
-                         * Optarg concatenated to option (no white space).
                          * GNU option/option argument pairs can be represented
                          * with a "=" separator.  If this is the case, remove
                          * the separator.
                          */
                         optarg = &arg[optsz];
                         optind++;
                         if (*optarg == '=') {
                                 if (*(++optarg) == '\0')
+                                        optopt = arg[0];
                                         return ('?');
                         }
                 }
 
                 if (cbfunc != NULL)
                         c = (*cbfunc)(c);
-
+                optopt = c;
                 return (c);
         }
         return (0);
 }