1

the question is pretty clear, I wonder because the man says

The getopt() function parses the command-line arguments.

And I am trying to use it with another function which has the same signature as the main and the argc and argv are obtained with wordexp so everythings seems the same, but when calling getopt I get a segmentation fault immediately after calling getopt_long.

#define   OPT_HELP    'h'
#define   OPTL_HELP   "help"
#define   OPT_MESS    'm'
#define   OPTL_MESS   "message"

#define   OPT_STRING  "hm:"

struct option longopts[] = {
  {OPTL_HELP,     no_argument, 0, OPT_HELP},
  {OPTL_MESS,     required_argument, 0, OPT_MESS},
  {0, 0, 0, 0}
};

#define FLAG_MESS 1

void cmd_chat(int argc, char **argv)
{
  int c, indexptr;
  short flag = 0;
  char message[481];
  while ((c = getopt_long(argc, argv, OPT_STRING,
          longopts, &indexptr)) != -1) {
    debug(MAGENTA "cmd_chat", MAGENTA "c value: %d", c);
    switch (c) {
      case OPT_HELP:
        debug(MAGENTA "cmd_chat", MAGENTA "calling help");
        help(argv[0]);
        return;
        break;
      case OPT_MESS:
        flag |= FLAG_MESS;
        strncpy(message, optarg, 481);
        break;
      default:
        usage(argv[0]);
        break;
    }
  }


[...]

It might be that, but if so I wonder why it is like that also why we should pass the argc and argv to getopt(_long).

Thank you.

  • The one assumption that isn't often stated is that you call `getopt()` et al consistently with the same values for `argc` and `argv`, rather than changing the list on each call. If you use `getopt()` to process command line arguments, and then subsequently use it to access some other set of arguments, you could — not necessarily will — run into problems. Are you doing anything like that? (Basically, there's no provision for concurrency — it isn't thread-safe — and there's no provision for reuse. There usually is a semi-undocumented way to reset the system so it starts over, but it varies.) – Jonathan Leffler Apr 20 '16 at 21:26
  • No calls to `getopt` come from the same thread and so are done sequentially. – Nicolas Scotto Di Perto Apr 20 '16 at 21:30

1 Answers1

3

Both getopt() and getopt_long() will work with every proper char ** and int, there is no difference between argv and any other char **. If you'll pass argv and argc, or their copies from main to your function and call getopt() from there it will work. Show how your function got argc and argv;

sheikh_anton
  • 3,422
  • 2
  • 15
  • 23
  • Okay cool. I really don't see where that segmentation fault come from... I have printed `argv` values before a call to the command (it is a shell program) `chat -h`, the argv is well parsed and argc is set to 2. I have tried a simple call to getopt without any `while` loop followed immediately by a print of the returned value, and I still get the segmentation fault. I can see it come from the call to `getopt_long` because the print isn't done. – Nicolas Scotto Di Perto Apr 20 '16 at 21:14
  • So do you call getopt twice in your program? If you call it twice, you need to set `optind` to `0` before second call. And provide mcve: https://stackoverflow.com/help/mcve – sheikh_anton Apr 20 '16 at 21:19
  • I have commented the while loop and replaced it with a single call to getopt_long and I get the segmentation fault, so without twice calls, but I have tried to set optind to 0 before the first call and it works. I don't see it in the man. – Nicolas Scotto Di Perto Apr 20 '16 at 21:28