Command-Line Values

Table of contents:

Part of the processing environment of every process are the values passed to the process in the function main . These values can be from the command line or may be passed to a child process from the parent via an exec system call. These values are stored in a ragged character array referenced by a character pointer array that, by tradition, is called argv . The number of elements in the argv array is stored as an integer value, which (again by tradition) is referenced by the identifier argc . Program 2.5, which displays command line values, takes advantage of the fact that in newer ANSI standard versions of Linux, the last element of the argv array (i.e., argv[argc] ) is guaranteed to be a NULL pointer. However, in most programming situations, especially when backward compatibility is a concern, it is best to use the value in argc as a limit when stepping through argv . If we run the program as p2.5 and place some arbitrary values on the command line, we obtain the output shown in Figure 2.17.

Program 2.5 Displaying command line arguments.

File : p2.5.cxx
 /*
 Displaying the contents of argv[ ] (the command line)
 */
 #include 
 + using namespace std;
 int
 main(int argc, char *argv[ ]){
 for ( ; *argv; ++argv )
 cout << *argv << endl;
 10 return 0;
 }

Figure 2.17 Output of Program 2.5.

linux$ p2.5 This is a test.
p2.5
This
is
a
test.

We can envision the system as storing these command-line values in argc and argv as shown in Figure 2.18.

Figure 2.18. Storage of command line values.

graphics/02fig18.gif

In this situation (where the system fills the argv array), argc will always be greater than 0, and the first value referenced by argv will be the name of the program that is executing. The system automatically terminates each string with a null character and places a 0 as the last address in the argv array.

In programs, it is a common practice to scan the command line to ascertain its contents (such as when looking for command-line options). At one time programmers wishing to check the contents of the command line for options had to write their own command-line parsing code. However, there is a general-purpose library function called getopt that will do this. [10] The getopt library function is somewhat analogous to the Swiss army knifeit can do many things, but to the uninitiated, upon first exposure, it appears unduly complex (Table 2.22).

[10] If you do shell programming, you should find that your system supports a shell version of this library function called getopt . The shell version uses the library function version to do its parsing.

Table 2.22. Summary of the getopt Library Function.

Include File(s)

Manual Section

3

Summary

int getopt( int argc, char * const argv[],
 char *optstring );
extern char *optarg;
extern int optind, opterr, optopt;

Return

Success

Failure

Sets errno

Next option letter

-1 or ?

 

The getopt function requires three arguments. The first is an integer value argc (the number of elements in the second argument). The second argument is a pointer to a pointer to an array of characters strings. Usually this is the array of character strings referenced by argv . The third argument is a pointer to a string of valid option letters (characters) that getopt should recognize. As noted, in most settings the values for argc and argv are the same as those for main 's first and second arguments. However, nothing prevents users from generating these two arguments to getopt on their own.

The format of optstring 's content bears further explanation. If an option letter expects a following argument, the option letter in optstring is followed by a colon . For example, if the option letter s (which, say, stands for size ) is to be followed by an integer size value, the corresponding optstring entry would be s: . On the command line, the user would enter -s 200 to indicate a size of 200. For a command-line option to be processed properly by getopt , it must be preceded with a hyphen(-), while the argument(s) to the option should have no leading hyphen and may or may not be separated by whitespace from the option.

The getopt function returns, as an integer, one of three values:

  • -1 indicating all options have been processed.
  • ? indicating an option letter has been processed that was not in the optstring or an option argument was specified (with the : notation in the optstring ) but none was found when processing the command line. When a ? is returned, getopt also displays an error message on standard error. The automatic display of the error message can be disabled by changing the value stored in the external identifier opterr to 0 (it is set to 1 by default). The offending character (stored as an integer) is referenced by the optopt variable.
  • The next option letter in argv that matches a letter in optstring . If the letter matched in optstring is followed by a colon, then the external character pointer optarg references the argument value. Remember that if the argument value is to be treated as a numeric value (versus a string), it must be converted.

The external integer optind is initialized by the system to 1 before the first call to getopt . It will contain the index of the next argument in argv that is not an option. By default getopt processes the argument array in a manner that all non-options are placed at the end of the list. A comparison of the value in optind to the value in argc can be used to determine if all items on the command line have been processed. The getopt function has a relative called getopt_long , which is similar in function to getopt but will process long (those with two leading dashes) command-line arguments. Check the manual page on this function for details. A program demonstrating the use of getopt is shown in Program 2.6.

Program 2.6 Using the library function getopt .

File : p2.6.cxx
 /*
 Command line using getopt
 */
 #define _GNU_SOURCE
 + #include 
 #include 
 #include 
 using namespace std;
 extern char *optarg;
 10 extern int optind, opterr, optopt;
 int
 main(int argc, char *argv[ ]){
 int c;
 char optstring[] = "abs:";
 + opterr = 0; // turn off auto err mesg
 while ((c = getopt(argc, argv, optstring)) != -1)
 switch (c) {
 case 'a':
 cout << "Found option a
";
 20 break;
 case 'b':
 cout << "Found option b
";
 break;
 case 's':
 + cout << "Found option s with an argument of: ";
 cout << atoi(optarg) << endl; // convert to integer
 break;
 case '?':
 cout << "Found an option that was not in optstring.
";
 30 cout << "The offending character was " << char(optopt) << endl;
 }
 if (optind < argc){
 cout << (argcoptind) << " arguments not processed.
";
 cout << "Left off at: " << argv[optind] << endl;
 + }
 return 0;
 }

A run of the program with some sample command-line options is shown in Figure 2.19.

Figure 2.19 Output of Program 2.6.

linux$ p2.6 -abc -s 34 -b joe -a student
Found option a
Found option b
Found an option that was not in optstring.
The offending character was c
Found option s with an argument of: 34
Found option b
Found option a
2 arguments not processed.
Left off at: joe

As the output shows, getopt can process options in groups (e.g., -abc ) or as singletons (e.g., -b ), and is not concerned with the alphabetic order of options. When processing stops, optind can be checked to determine if any command-line options were not part of the specified options.

EXERCISE

Modify Program 2.3 to accept command-line options that will be processed with the library call getopt . Where appropriate, allow the user to specify arguments to change values of specific limits (use the setrlimit system call). Consider using getopt_long to support a --help option that would provide the user with some minimal help about how to run the program.

Programs and Processes

Processing Environment

Using Processes

Primitive Communications

Pipes

Message Queues

Semaphores

Shared Memory

Remote Procedure Calls

Sockets

Threads

Appendix A. Using Linux Manual Pages

Appendix B. UNIX Error Messages

Appendix C. RPC Syntax Diagrams

Appendix D. Profiling Programs



Interprocess Communication in Linux
Interprocess Communications in Linux: The Nooks and Crannies
ISBN: 0130460427
EAN: 2147483647
Year: 2001
Pages: 136

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net