getopt_long
,
getopt_long_only
—
get long options from command line argument
list
#include
<getopt.h>
extern char *optarg;
extern int optind;
extern int optopt;
extern int opterr;
int
getopt_long
(
int
argc,
char * const *argv,
const char *optstring,
const struct option *longopts,
int *longindex);
int
getopt_long_only
(
int
argc,
char * const *argv,
const char *optstring,
const struct option *longopts,
int *longindex);
int
getopt_long_clip
(
int
argc,
char * const *argv,
const char *optstring,
const struct option *longopts,
int *longindex);
The
getopt_long
() function is similar to
getopt(3C) but it accepts options in two forms:
words and characters. The
getopt_long
()
function provides a superset of the functionality of
getopt(3C). The
getopt_long
() function can be used in two
ways.
In the first way, every long option understood by the program has a
corresponding short option, and the option structure is only used to translate
from long options to short options. When used in this fashion,
getopt_long
() behaves identically to
getopt(3C). This is a good way to add long option
processing to an existing program with the minimum of rewriting.
In the second mechanism, a long option sets a flag in the
option structure passed, or will store a
pointer to the command line argument in the
option structure passed to it for options
that take arguments. Additionally, the long option's argument may be specified
as a single argument with an equal sign, e.g.,
myprogram
--myoption=somevalue
When a long option is processed, the call to
getopt_long
() will return 0. For this
reason, long option processing without shortcuts is not backwards compatible
with
getopt(3C).
It is possible to combine these methods, providing for long options processing
with short option equivalents for some options. Less frequently used options
would be processed as long options only.
In
getopt_long
() and
getopt_long_only
(),
optstring acts similar to
optstring in
getopt(3C). In addition,
optstring can begin with
‘
+
’ or
‘
-
’. If
optstring begins with
‘
+
’, the first non-option terminates
option processing. This is equivalent to setting the environment variable
POSIXLY_CORRECT
. If
optstring begins with
‘
-
’, non-options are treated as options
to the argument ‘
\1
’.
If
optstring does not begin with
‘
+
’ and
POSIXLY_CORRECT
is not set, if
‘
W;
’ appears in
optstring, ‘
-W
myoption
’ is treated the same as
‘
--myoption
’ and
optarg is set to
‘
myoption
’.
In
getopt_long_clip
(),
‘
+
’ and
‘
-
’ are ignored at the beginning of a
string.
The
getopt_long
(),
getopt_long_only
(), and
getopt_long_clip
() functions require a
structure to be initialized describing the long options. The structure is:
struct option {
char *name;
int has_arg;
int *flag;
int val;
};
The
name field should contain the option name
without the leading double dash.
The
has_arg field should be one of:
If
flag is not
NULL
, then the integer pointed to by it
will be set to the value in the
val field and
optopt will be set to
0. If the
flag
field is
NULL
, then the
val field will be returned and
optopt is set to the value in the
val field. Setting
flag to
NULL
and setting
val to the corresponding short option will
make this function act just like
getopt(3C).
If the
longindex field is not
NULL
, then the integer pointed to by it
will be set to the index of the long option relative to
longopts.
The last element of the
longopts array has to
be filled with zeroes.
The
getopt_long_only
() function behaves
identically to
getopt_long
() with the
exception that long options may start with
‘
-
’ in addition to
‘
--
’. If an option starting with
‘
-
’ does not match a long option but
does match a single-character option, the single-character option is returned.
The
getopt_long_clip
() function is a
variation of
getopt_long
() except that
options must also adhere to the Sun CLIP specification. Specifically, the
major differences from
getopt_long
() are:
- All option arguments are required
(
optional_argument
is treated the same
as required_argument
).
- Long options cannot be abbreviated on the command line.
- Long options must use a double dash
(‘
--
’).
- Option processing stops at the first non-option.
- All long options must have an eqivalent short option (single character)
and vice-versa.
- A leading ‘
+
’ or
‘-
’ in
optstring is ignored.
optstring is treated as if it began after
the leading ‘+
’ or
‘-
’.
On each call to
getopt_long
(),
getopt_long_only
(), or
getopt_long
(),
optind is set to the
argv index of the
next argument to be processed.
optind is initialized to
1 prior to the first invocation of
getopt_long
(),
getopt_long_only
(), or
getopt_long_clip
().
If
opterr is set to a non-zero value and
optstring does not start with
‘
:
’,
getopt_long
(),
getopt_long_only
(), and
getopt_long_clip
() will print an error
message to
stderr when an error or invalid option
is encountered.
If the
flag field in
struct option is
NULL
,
getopt_long
() and
getopt_long_only
() return the value
specified in the
val field, which is usually
just the corresponding short option. If
flag
is not
NULL
, these functions return 0 and
store
val in the location pointed to by
flag. These functions return
‘
:
’ if there was a missing option
argument, ‘
?
’ if the user specified an
unknown or ambiguous option, and -1 when the argument list has been exhausted.
If a long option to
getopt_long_clip
() is
missing its equivalent short option (or vice-versa),-1 is returned on the
first call to
getopt_long_clip
(), and
errno
is set to
EINVAL
. If
opterr is set to a non-zero value and
optstring does not start with
‘
:
’, an error message will be written to
stderr.
If
optstring does not start with
‘
:
’ and
getopt_long
(),
getopt_long_only
(), or
getopt_long_clip
() return
‘
:
’ or
‘
?
’, if
opterr is set to a non-zero value, an error
message is written to
stderr
.
The following environment variables can effect the execution of
getopt_long
,
getopt_long_only
, and
getopt_long_clip
:
LANG
,
LC_ALL
,
LC_MESSAGES
. See
environ(5).
-
-
POSIXLY_CORRECT
- If set, option processing stops when the first non-option is found and a
leading ‘
-
’ or
‘+
’ in the
optstring is ignored.
Similar to
getopt(3C), since there is no
unambiguous way to detect a missing option-argument except when the option is
the last option on the command line, the
getopt_long
(),
getopt_long_only
(), and
getopt_long_clip
() functions cannot fully
check for mandatory arguments. For example, the option string
‘
ho:
’ with an input of
‘
-o
-h
’ will assume that
‘
-h
’
is the required argument to
-o
instead of
assuming that
-o
is missing its
option-argument.
Like
getopt(3C), grouping options taking or
requiring arguments with other options is a violation of the Basic Utility
Command syntax standard (see
Intro(1)). For
example, given the option string ‘
cde:
’,
running:
cmd
-cde
ieio
is incorrect. Current versions of
getopt_long
,
getopt_long_only
, and
getopt_long_clip
accept this, however
future versions may not support this. The correct invocation would be:
cmd
-cd
-e
ieio
int bflag, ch, fd;
int daggerset;
/* options descriptor */
static struct option longopts[] = {
{ "buffy", no_argument, NULL, 'b' },
{ "fluoride", required_argument, NULL, 'f' },
{ "daggerset", no_argument, &daggerset, 1 },
{ NULL, 0, NULL, 0 }
};
bflag = 0;
while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1) {
switch (ch) {
case 'b':
bflag = 1;
break;
case 'f':
if ((fd = open(optarg, O_RDONLY, 0)) == -1)
err(1, "unable to open %s", optarg);
break;
case 0:
if (daggerset) {
fprintf(stderr,"Buffy will use her dagger to "
"apply fluoride to dracula's teeth\n");
}
break;
default:
usage();
}
}
argc -= optind;
argv += optind;
The
getopt_long_clip
() function will fail if:
-
-
EINVAL
- A short option is missing a corresponding long option, or vice-versa.
There are no errors defined for
getopt_long
()
and
getopt_long_only
().
While the illumos implementations of
getopt_long
and
getopt_long_only
are broadly compatible
with other implementations, the following edge cases have historically been
known to vary among implementations:
- The setting of optopt for long options
with flag !=
NULL
in
struct option. In illumos,
optopt is set to 0 (since
val would never be returned).
- The setting of optarg for long options
without an argument that are invoked via
‘
-W
’
(‘W;
’ in
optstring). illumos sets
optarg to the option name (the argument
of ‘-W
’).
- The handling of ‘
-W
’ with an
argument that is not (a prefix to) a known long option
(‘W;
’ in
optstring). illumos treats this as an
error (unknown option) and returns
‘?
’ with
optopt set to 0 and
optarg set to
NULL
.
- illumos may not permute the argument vector at the same points in the
calling sequence as other implementations. The aspects normally used by
the caller (ordering after -1 is returned, the value of
optind relative to current positions) are
the same, though. (We often do fewer variable swaps.)
Committed
Unsafe
getopt(3C)
The
argv argument is not really
const as its elements may be permuted (unless
POSIXLY_CORRECT
is set).