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?

Était-ce utile?

La 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top