2013-03-02 9 views
6

Sto provando a creare una shell di base con comandi incorporati e ho alcuni problemi con getopt. Ecco l'uscita (utilizzando valgrind):È possibile ripetere getopt

$ 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== 
$ 

E qui è la fonte (tagliata):

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; 
    } 
} 

Così la prima volta che viene eseguito esso (mkdir -p) lo riconosce (-p) e il secondo il tempo corre, non è così. Qualche idea?

+0

Potrebbe essere che il tuo buffer di stdout non viene infilato la seconda volta per qualche motivo? Prova fflush (stdout) dopo le put? –

+2

"la prima volta che [il programma] lo esegue [il programma, o forse' getopt() '?] Riconosce ** it **". Che cos'è*? –

+0

@ Code-Guru, mi dispiace, ** it ** come nella bandiera ('-p') – MiJyn

risposta

13

Se si desidera acquisire più vettori è necessario resettare getopt impostando optind a 1.

L'OPTIND variabile è l'indice del prossimo elemento del argv [] vettore per essere elaborati. Deve essere inizializzato a 1 dal sistema, e getopt() deve aggiornarlo quando termina con ogni elemento di argv [].

Se l'impostazione optind-1 non funziona, provare anche 0, credo di ricordare leggere su che da qualche parte.

+0

Grazie, vedremo se funziona :) – MiJyn

+3

L'impostazione di 'optind' su 1 è stata corretta, ma avevo ancora avvertimenti da valgrind, quindi ho provato a impostarlo su 0, e ora funziona perfettamente. Grazie! – MiJyn

+1

@MiJyn Buono a sapersi :-) – cnicutar