The default scanning mode of getopt tries to interpret all option
elements (basically any argv's element that begins with '-'), permuting
the contents of argv as it scans, so that eventually all the nonoptions
are at the end.

This means it's not possible to get something like

    scroll /bin/rc -l

to work, as getopt tries to parse -l as an option for scroll itself.
The better behavior is to stop processing as soon as the
first nonoption argument is encountered (assuming it is the child
program). Then all remaining stuff is the program's name and arguments
that it must take. This better behavior is enabled by prefixing the
optstring given to getopt with "+".
---
 scroll.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scroll.c b/scroll.c
index 8f66d54..3c3643b 100644
--- a/scroll.c
+++ b/scroll.c
@@ -391,7 +391,7 @@ jumpdown(char *buf, size_t size)
 
 void
 usage(void) {
-       die("usage: %s [-Mvh] [-m mem] [program]", argv0);
+       die("usage: %s [-Mvh] [-m mem] [program [arg ...]]", argv0);
 }
 
 int
@@ -405,7 +405,7 @@ main(int argc, char *argv[])
        if (getrlimit(RLIMIT_DATA, &rlimit) == -1)
                die("getrlimit");
 
-       const char *optstring = "Mm:vh";
+       const char *optstring = "+Mm:vh";
        while ((ch = getopt(argc, argv, optstring)) != -1) {
                switch (ch) {
                case 'M':
-- 
2.32.0


Reply via email to