Question

I'm trying to create a basic shell with builtin commands, and I'm having some issues with getopt. Here is the output (using valgrind):

$ mkdir -p foo/bar
mkdir
-p
foo/bar
FLAGON
$ mkdir -p foo/test
mkdir
-p
foo/test
==15377== Invalid read of size 1
==15377==    at 0x5201BBE: _getopt_internal_r (in /usr/lib/libc-2.17.so)
==15377==    by 0x5202CEA: _getopt_internal (in /usr/lib/libc-2.17.so)
==15377==    by 0x5202D37: getopt (in /usr/lib/libc-2.17.so)
==15377==    by 0x40351A: shell_ns_cmd_mkdir (shell.c:542)
==15377==    by 0x403AB4: normal_shell_cb (shell.c:610)
==15377==    by 0x402E8E: shell_mainloop (shell.c:402)
==15377==    by 0x401B67: main (main.c:52)
==15377==  Address 0x54e0912 is 2 bytes inside a block of size 3 free'd
==15377==    at 0x4C2AD3C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==15377==    by 0x402C93: shell_mainloop (shell.c:384)
==15377==    by 0x401B67: main (main.c:52)
==15377== 
$ 

And here is the source (clipped):

for (i = 0; i < argc; i++) {
    puts(argv[i]);
}
while ((c = getopt(argc, argv, "p")) != -1) {
    switch (c) {
        case 'p':
            puts("FLAGON");
            mkparents = true;
            break;
        case '?':
            fprintf(stderr, "invalid option -- %c", optopt);
            ret = 127;
            goto end;
            break;
    }
}

So the first time it runs it (mkdir -p) recognizes it (-p) and the second time it runs, it doesn't. Any ideas?

Was it helpful?

Solution

If you want to scan multiple vectors you need to reset getopt by setting optind to 1.

The variable optind is the index of the next element of the argv[] vector to be processed. It shall be initialized to 1 by the system, and getopt() shall update it when it finishes with each element of argv[].

If setting optind to 1 doesn't work, also try 0, I think I remember reading about that somewhere.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top