getopt_long(3)
๐ getopt_long(3) โ like, the GLOW UP of command-line parsing ๐
okay bestie so this is the getopt_long(3) page from the Library Functions Manual and I am obsessed with it. it's the girl that takes everything getopt(3) does and then also handles long options. main character behaviour, no cap. ๐
โจ NAME โจ
getopt_long โ parse command-line options ๐ฆ
๐ LIBRARY ๐
Standard C library (libc, -lc) โ so it's right there in your libc, you don't gotta go hunting ๐
๐ธ SYNOPSIS ๐ธ
#define _GNU_SOURCE
#include <getopt.h>
int getopt_long(int argc, char *argv[],
const char *optstring,
const struct option *longopts, int *longindex);
๐ DESCRIPTION ๐
So. getopt_long() does literally everything getopt(3) does, except it also accepts long options, and those start with two dashes. iconic. two dashes, periodt.
and listen โ if your program only accepts long options, then optstring should be given as an empty string (""), not NULL. don't do NULL, bestie, that's not the vibe.
long option names can be abbreviated as long as the abbreviation is unique, or is an exact match for some defined option. so you can be lazy but only in a way that doesn't confuse anyone ๐ซถ
a long option may take a parameter, in the form --arg=param or --arg param. both work, both slay.
longopts is a pointer to the first element of an array of struct option declared in <getopt.h> as
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
now let's unpack the fields because the way that this struct carries itselfโฆ ๐
the fields, one by one ๐ง
nameโ is the name of the long option. that's it. that's the girl.has_argโ isno_argument(or0) if the option does not take an argument;required_argument(or1) if the option requires an argument; oroptional_argument(or2) if the option takes an optional argument.flagโ specifies how results are returned for a long option. ifflagisNULL, thengetopt_long()returnsval. (like, for example, your calling program may setvalto the equivalent short option character โ cute trick, right?) otherwise,getopt_long()returns0, andflagpoints to a variable which is set tovalif the option is found, but left unchanged if the option is not found.valโ is the value to return, or to load into the variable pointed to byflag.
๐จ the last element of the array has to be filled with zeros. yes, all of them. that's your little terminator, the end of the runway, do not skip it.
if longindex is not NULL, it points to a variable which is set to the index of the long option relative to longopts. handy for knowing which one hit. ๐ฅ
and its analogue to getopt(3)'s optopt is argv[(optind - 1)]. exactly that expression, character for character. iykyk. ๐
๐ซ RETURN VALUE ๐ซ
see getopt(3). (she's the blueprint, fr fr.)
getopt_long() also returns the option character when a short option is recognized. for a long option, it returns val if flag is NULL, and 0 otherwise. error and -1 returns are the same as for getopt(3), plus '?' for an ambiguous match or an extraneous parameter. so if you see a '?'โฆ something was giving ambiguous energy. ๐
๐ฑ ENVIRONMENT ๐ฑ
see getopt(3). (same page, same vibes.)
๐ ATTRIBUTES ๐
for an explanation of the terms used in this section, see attributes(7).
- Interface:
getopt_long() - Attribute: Thread safety
- Value:
MT-Unsafe race:getopt env
so yeah, she's MT-Unsafe, race on getopt and the environment. thread-safety? not her era. ๐
โญ STANDARDS โญ
GNU. that's the whole sentence. GNU. ๐
๐ EXAMPLES ๐
the following example program illustrates the use of getopt_long() with most of its features. (most! not all! she's showing off but not everything.)
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
int c;
int digit_optind = 0;
for (;;) {
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] = {
{"add", required_argument, 0, 0 },
{"append", no_argument, 0, 0 },
{"delete", required_argument, 0, 0 },
{"verbose", no_argument, 0, 0 },
{"create", required_argument, 0, 'c'},
{"file", required_argument, 0, 0 },
{0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "abc:d:012",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0:
printf("option %s", long_options[option_index].name);
if (optarg)
printf(" with arg %s", optarg);
printf("\n");
break;
case '0':
case '1':
case '2':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf("option %c\n", c);
break;
case 'a':
printf("option a\n");
break;
case 'b':
printf("option b\n");
break;
case 'c':
printf("option c with value '%s'\n", optarg);
break;
case 'd':
printf("option d with value '%s'\n", optarg);
break;
case '?':
break;
default:
printf("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc)
printf("%s ", argv[optind++]);
printf("\n");
}
exit(EXIT_SUCCESS);
}
look at that terminator line {0, 0, 0, 0 }. we love a clean exit. ๐
๐ SEE ALSO ๐
okay that's the whole page, bestie, you ate it ๐ซถ this was Linux man-pages 6.20, dated 2026-02-14, and the page itself is getopt_long(3) โ go write something iconic with it. ๐ธโจ๐
๐ฆ where this page comes from
- arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- ๐ the page's license: Linux-man-pages-copyleft
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms