Do not use the _syscall5 macro -- use syscall(2) instead
[oweals/busybox.git] / util-linux / getopt.c
index eb28d5d07118ff8d021a009ba88c0324591b99ba..25eeab69be66750b60e8627f16f95894a51ccc6a 100644 (file)
@@ -37,7 +37,7 @@
  *     <misiek@misiek.eu.org>)
  * Ported to Busybox - Alfred M. Szmidt <ams@trillian.itslinux.org>
  *  Removed --version/-V and --help/-h in
- *  Removed prase_error(), using error_msg() from Busybox instead
+ *  Removed prase_error(), using bb_error_msg() from Busybox instead
  *  Replaced our_malloc with xmalloc and our_realloc with xrealloc
  *
  */
@@ -62,20 +62,19 @@ typedef enum {BASH,TCSH} shell_t;
 
 
 /* Some global variables that tells us how to parse. */
-shell_t shell=BASH; /* The shell we generate output for. */
-int quiet_errors=0; /* 0 is not quiet. */
-int quiet_output=0; /* 0 is not quiet. */
-int quote=1; /* 1 is do quote. */
-int alternative=0; /* 0 is getopt_long, 1 is getopt_long_only */
+static shell_t shell=BASH; /* The shell we generate output for. */
+static int quiet_errors=0; /* 0 is not quiet. */
+static int quiet_output=0; /* 0 is not quiet. */
+static int quote=1; /* 1 is do quote. */
+static int alternative=0; /* 0 is getopt_long, 1 is getopt_long_only */
 
 /* Function prototypes */
-const char *normalize(const char *arg);
-int generate_output(char * argv[],int argc,const char *optstr,
+static const char *normalize(const char *arg);
+static int generate_output(char * argv[],int argc,const char *optstr,
                     const struct option *longopts);
-void add_long_options(char *options);
-void add_longopt(const char *name,int has_arg);
-void set_shell(const char *new_shell);
-void set_initial_shell(void);
+static void add_long_options(char *options);
+static void add_longopt(const char *name,int has_arg);
+static void set_shell(const char *new_shell);
 
 
 /*
@@ -93,13 +92,10 @@ const char *normalize(const char *arg)
         const char *argptr=arg;
         char *bufptr;
 
-        if (BUFFER != NULL)
-                free(BUFFER);
+        free(BUFFER);
 
         if (!quote) { /* Just copy arg */
-                BUFFER=xmalloc(strlen(arg)+1);
-
-                strcpy(BUFFER,arg);
+               BUFFER=bb_xstrdup(arg);
                 return BUFFER;
         }
 
@@ -205,7 +201,6 @@ static const int LONG_OPTIONS_INCR = 10;
 /* Register a long option. The contents of name is copied. */
 void add_longopt(const char *name,int has_arg)
 {
-        char *tmp;
         if (!name) { /* init */
                 free(long_options);
                 long_options=NULL;
@@ -229,9 +224,7 @@ void add_longopt(const char *name,int has_arg)
                 long_options[long_options_nr-1].has_arg=has_arg;
                 long_options[long_options_nr-1].flag=NULL;
                 long_options[long_options_nr-1].val=LONG_OPT;
-                tmp = xmalloc(strlen(name)+1);
-                strcpy(tmp,name);
-                long_options[long_options_nr-1].name=tmp;
+               long_options[long_options_nr-1].name=bb_xstrdup(name);
         }
         long_options_nr++;
 }
@@ -244,21 +237,24 @@ void add_longopt(const char *name,int has_arg)
  */
 void add_long_options(char *options)
 {
-        int arg_opt;
+        int arg_opt, tlen;
         char *tokptr=strtok(options,", \t\n");
         while (tokptr) {
                 arg_opt=no_argument;
-                if (strlen(tokptr) > 0) {
-                        if (tokptr[strlen(tokptr)-1] == ':') {
-                                if (tokptr[strlen(tokptr)-2] == ':') {
-                                        tokptr[strlen(tokptr)-2]='\0';
+               tlen=strlen(tokptr);
+                if (tlen > 0) {
+                        if (tokptr[tlen-1] == ':') {
+                                if (tlen > 1 && tokptr[tlen-2] == ':') {
+                                        tokptr[tlen-2]='\0';
+                                       tlen -= 2;
                                         arg_opt=optional_argument;
                                 } else {
-                                        tokptr[strlen(tokptr)-1]='\0';
+                                        tokptr[tlen-1]='\0';
+                                       tlen -= 1;
                                         arg_opt=required_argument;
                                 }
-                                if (strlen(tokptr) == 0)
-                                        error_msg("empty long option after -l or --long argument");
+                                if (tlen == 0)
+                                        bb_error_msg("empty long option after -l or --long argument");
                         }
                         add_longopt(tokptr,arg_opt);
                 }
@@ -277,7 +273,7 @@ void set_shell(const char *new_shell)
         else if (!strcmp(new_shell,"csh"))
                 shell=TCSH;
         else
-                error_msg("unknown shell after -s or --shell argument");
+                bb_error_msg("unknown shell after -s or --shell argument");
 }
 
 
@@ -324,9 +320,9 @@ int getopt_main(int argc, char *argv[])
                         /* For some reason, the original getopt gave no error
                            when there were no arguments. */
                         printf(" --\n");
-                        exit(0);
+                       return 0;
                 } else
-                        error_msg_and_die("missing optstring argument");
+                        bb_error_msg_and_die("missing optstring argument");
         }
 
         if (argv[1][0] != '-' || compatible) {
@@ -334,7 +330,7 @@ int getopt_main(int argc, char *argv[])
                 optstr=xmalloc(strlen(argv[1])+1);
                 strcpy(optstr,argv[1]+strspn(argv[1],"-+"));
                 argv[1]=argv[0];
-                exit(generate_output(argv+1,argc-1,optstr,long_options));
+               return (generate_output(argv+1,argc-1,optstr,long_options));
         }
 
         while ((opt=getopt_long(argc,argv,shortopts,longopts,NULL)) != EOF)
@@ -343,19 +339,15 @@ int getopt_main(int argc, char *argv[])
                         alternative=1;
                         break;
                 case 'o':
-                        if (optstr)
-                                free(optstr);
-                        optstr=xmalloc(strlen(optarg)+1);
-                        strcpy(optstr,optarg);
+                       free(optstr);
+                       optstr=bb_xstrdup(optarg);
                         break;
                 case 'l':
                         add_long_options(optarg);
                         break;
                 case 'n':
-                        if (name)
-                                free(name);
-                        name=xmalloc(strlen(optarg)+1);
-                        strcpy(name,optarg);
+                       free(name);
+                       name=bb_xstrdup(optarg);
                         break;
                 case 'q':
                         quiet_errors=1;
@@ -367,20 +359,19 @@ int getopt_main(int argc, char *argv[])
                         set_shell(optarg);
                         break;
                 case 'T':
-                        exit(4);
+                       return 4;
                 case 'u':
                         quote=0;
                         break;
                 default:
-                        show_usage();
+                        bb_show_usage();
                 }
 
         if (!optstr) {
                 if (optind >= argc)
-                        error_msg_and_die("missing optstring argument");
+                        bb_error_msg_and_die("missing optstring argument");
                 else {
-                        optstr=xmalloc(strlen(argv[optind])+1);
-                        strcpy(optstr,argv[optind]);
+                       optstr=bb_xstrdup(argv[optind]);
                         optind++;
                 }
         }
@@ -388,7 +379,7 @@ int getopt_main(int argc, char *argv[])
                 argv[optind-1]=name;
         else
                 argv[optind-1]=argv[0];
-        exit(generate_output(argv+optind-1,argc-optind+1,optstr,long_options));
+       return (generate_output(argv+optind-1,argc-optind+1,optstr,long_options));
 }
 
 /*