From: Gianluca Anzolin <gianluca@sottospazio.it>
To: musl@lists.openwall.com
Cc: Gianluca Anzolin <gianluca@sottospazio.it>
Subject: [PATCH] getopt: add support for non-option arguments
Date: Mon, 24 Nov 2014 19:39:05 +0100 [thread overview]
Message-ID: <1416854345-5252-1-git-send-email-gianluca@sottospazio.it> (raw)
Currently getopt() doesn't handle the GNU getopt extension that allows
to parse non-option arguments when optstring starts with '-'.
This extensions is used by some common utilities, notably iptables, that
currently return with errors even with perfectly valid invocations, for
example:
$ iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
The patch add the code needed to implement this extension to getopt.c
and getopt_long.c
Signed-off-by: Gianluca Anzolin <gianluca@sottospazio.it>
---
src/misc/getopt.c | 17 ++++++++++++++++-
src/misc/getopt_long.c | 6 +++++-
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/src/misc/getopt.c b/src/misc/getopt.c
index f94c4f7..a698c8d 100644
--- a/src/misc/getopt.c
+++ b/src/misc/getopt.c
@@ -24,8 +24,20 @@ int getopt(int argc, char * const argv[], const char *optstring)
optind = 1;
}
- if (optind >= argc || !argv[optind] || argv[optind][0] != '-' || !argv[optind][1])
+ if (optind >= argc || !argv[optind])
return -1;
+
+ if (argv[optind][0] != '-') {
+ if (optstring[0] == '-') {
+ optarg = argv[optind++];
+ return 1;
+ }
+ return -1;
+ }
+
+ if (!argv[optind][1])
+ return -1;
+
if (argv[optind][1] == '-' && !argv[optind][2])
return optind++, -1;
@@ -43,6 +55,9 @@ int getopt(int argc, char * const argv[], const char *optstring)
optpos = 0;
}
+ if (optstring[0] == '-')
+ optstring++;
+
for (i=0; (l = mbtowc(&d, optstring+i, MB_LEN_MAX)) && d!=c; i+=l>0?l:1);
if (d != c) {
diff --git a/src/misc/getopt_long.c b/src/misc/getopt_long.c
index 4ef5a5c..d8b2b66 100644
--- a/src/misc/getopt_long.c
+++ b/src/misc/getopt_long.c
@@ -12,7 +12,11 @@ static int __getopt_long(int argc, char *const *argv, const char *optstring, con
__optpos = 0;
optind = 1;
}
- if (optind >= argc || !argv[optind] || argv[optind][0] != '-') return -1;
+ if (optind >= argc || !argv[optind]) return -1;
+
+ if (argv[optind][0] != '-')
+ return getopt(argc, argv, optstring);
+
if ((longonly && argv[optind][1]) ||
(argv[optind][1] == '-' && argv[optind][2]))
{
--
2.1.3
next reply other threads:[~2014-11-24 18:39 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-24 18:39 Gianluca Anzolin [this message]
2014-11-25 2:48 ` Rich Felker
2014-11-25 7:33 ` Gianluca Anzolin
2014-11-25 7:39 ` Rich Felker
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1416854345-5252-1-git-send-email-gianluca@sottospazio.it \
--to=gianluca@sottospazio.it \
--cc=musl@lists.openwall.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/musl/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).