310 likes | 448 Views
Herbert G. Mayer, PSU CS Status 1/15/2013. CS 201 Computer Systems Programming Chapter 2 “ argc argv envp, system(), libs ”. argc argv envp. Syllabus. Definitions Samples of argc argv envp Possible argv[] Implementation? References s ystem() Sample Uses of system()
E N D
Herbert G. Mayer, PSU CS Status 1/15/2013 CS 201Computer Systems ProgrammingChapter 2“argc argv envp, system(), libs”
Syllabus • Definitions • Samples of argc argv envp • Possibleargv[] Implementation? • References • system() • Sample Uses of system() • Unix Commands & C Libraries
Definitions • In C the main() function returns an int type result; the formal parameter list may be void, or else contains the specification of command line parameters • In C++ the main() return type is int; the formal parameter list must be specified as void, or else defines the command line parameter types • These are traditionally named argc, argv, and envp; on Apple platforms a fourth parameter can be specified, not surprisingly named “apple” • The names “argc” and argv” may be chosen freely to be any, but “argc” and “argv” are tradition
Definitions • argc • Specified as int argc, is main()’s first formal parameter • argc counts the number of command line arguments that argv[] holds for this current program execution • Includes the object program itself, hence must be >= 1 • argv • Specified as char ** argv, equivalently char * argv[] • is 2nd formal parameter of main(); optional; if specified, the first parameter argc must already be specified • argv is pointer to list of actual const string arguments • envp • Specified as char ** envp, equivalently char * envp[], • is 3rd formal and optional parameter of main() • Holds environment variables as string constants, plus the indicating title: PATH=
Reverse-Print Command Line Args • // output command line arguments • // but in reverse order • int main( int argc, char * argv[] ) • { // main • printf( "%d command line arguments passed.\n", • argc ); • while( --argc > 0 ) { • printf( "argument %d = \"%s\"\n”, • argc, argv[ argc ] ); • } //end while • } //end main • [args] a.out 3 r 55 • 4 command line arguments passed. • argument 3 = "55" • argument 2 = "r" • argument 1 = "3"
Sample argc, argv • a.out 12 '.' "345" E "+" 0 • Number of command line arguments passed = 7 • This includes program name • argv[0] = a.out • argv[1] = 12 • argv[2] = . -- without single quote ‘ • argv[3] = 345 -- without double quote “ • argv[4] = E • argv[5] = + -- without double quote “ • argv[6] = 0 • Note that all “ and ‘ pairs are stripped away • All command args concatenated are = "12.345E+0" • Looks like the floating point number = 12.345
Possible argv[]Implementation? • How are actual parameters passed to main() ? • Which tool passes them from the command line to the run-time-system? • Students think, design, discuss: • 1.) Will on-the-fly creation of assembler source program help? Assumes an assembly step to create another *.o • 2.) Will manipulation of stack, heap, code help, before or while loading provide the actual parameters? • 3.) Other possibilities?
Possible argv[] Implementation? • Your Unix shell executes the a.out command • Let’s say: a.out 100000 “9/12/2012” • The shell sees the command line, verifies that a.out exists and is executable, then loads, executes, continues after return • All work to provide command line parameters is accomplished between shell command and execution • Note that a.out may not be modified from one run to another • So, sometimes argc, argv, envp may be accessed during execution, other times not
Sample envp • The Unix shell command man setenv explains: • man setenv: • NAME • set, unset, setenv, unsetenv, export -shell built-in functions to determine the characteristics for environmental variables of the current shell and its descendents • Current environment variables used in your Unix environment are tracked and can be output for any of your processes • Similar to char * argv[], envp is also a pointer to an array of 0 or more strings, followed by a null string • Each such string contains one of your process’ environment variables
Sample envp Version 1 • #include <iostream.h> // for: cin, cout, endl etc. • int main( int argc, char ** argv, char ** envp ) • { // main • int count = 0; • while( *envp ) { • cout << "envp[" << ++count << "] = \"" • << *envp << '"' << endl; • ++envp; // or envp++ if you prefer • } //end while • cout << "Number of environment variables tracked = “ • << count << endl; • exit( 0 ); • } //end main
Sample envp Version 2 • #include <iostream.h> // for: cin, cout, endl etc. • int main( int argc, char ** argv, char * envp[] ) • { // main • int index = 0; • while( envp[ index ] ) { • cout << "envp[" << index << "] = \"" << envp[ index++ ] << ‘"’ << endl; • } //end while • cout << "Number of environment variables tracked = “ • << index << endl; • exit( 0 ); • } //end main
Sample envp • envp[1] = "USER=herb" • envp[2] = "LOGNAME=herb" • envp[3] = "HOME=/u/herb" • envp[4] = "PATH=.:/usr/lang:/bin/sun4:/usr/etc:/vol/local/rhost/sun4/bin:/usr/ucb:/bin:/vol/local:/vol/local/bin:/vol/local/sun4/bin:/usr/ccs/bin:/usr/ccs:/vol/userlocal/bin:/usr/local/bin:/home/vads/VADS_location/bin" • envp[5] = "MAIL=/var/mail//herb" • envp[6] = "SHELL=/bin/csh" • envp[7] = "TZ=US/Pacific" • . . . Many more • envp[12] = "LC_MONETARY=en_US.ISO8859-1" • envp[13] = "LC_MESSAGES=C" • envp[14] = "LANG=en_US.UTF-8" • envp[15] = "SSH_CLIENT=50.53.47.189 50625 22" • envp[16] = "SSH_CONNECTION=50.53.47.189 50625 131.252.208.127 22" • envp[17] = "SSH_TTY=/dev/pts/33" • envp[18] = "TERM=xterm-256color" • envp[19] = "PWD=/u/herb/progs/args" • envp[20] = "term=vt100=” • Number of environment variables tracked = 20
References • http://crasseux.com/books/ctutorial/argc-and-argv.html • http://en.wikipedia.org/wiki/Main_function • http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fmainf.htm
system( “string” ) • The system() function is a C/C++ function, NOT a shell command; causes error as a shell command • Available in library #include <stdlib.h> • Passes its sole string parameter to the shell, as if that same string had been typed as a shell command • Exit status of last completed command is passed back to the shell • If a null string is given, system( “” ) checks if the shell exists and then terminates
system( “string” ) • Executed command returns with exit status in waitpid(3) format, which is passed to invoking C or C++ program • waitpid() reqires: #include <sys/types.h> and #include <sys/wait.h> • waitpidsuspends execution of calling program until status of terminated child process is available --any of its child processes
Sample Uses of system() • Write C++ program, using system() that prints the Unix man page for system() • Just as if command “man system” had been spelled as a Unix shell command • Sample shown below: • #include <stdlib.h> • int main() • { // main • system( "man system" ); • } //end main
Sample Uses of system() • Write C++ program using system() that: • Changes directory from . named arg_test, to one level up .. • Then lists all files in that .. directory via: ls –la • Changes back to directory arg_test • And finally shows all files listed in that directory arg_test • Sample below: • #include <stdlib.h> • int main( void ) • { // main • system( "cd ..; ls -la; cd arg_test; ls -la" ); • } //end main
Sample Uses of system() • Write C++ program using system() that prints the current working directory, by specifying the const string literal “pwd” • And by passing in the command through argv[] • Sample shown below: • #include <stdlib.h> • #include <iostream.h> • #define command "pwd” • int main( int argc, char * argv[] ) • { // main • cout << "using string const 'pwd'" << endl; • system( command ); • cout << "using argv[ 1 ]" << endl; • system( argv[ 1 ] ); • } //end main
Tricky Sample Use system() • Write C++ program using system() prints the current date/time • Then compiles and runs its own source sys7.cpp • Watch out what happens with C++ file sys7.cpp: • #include <stdlib.h> • #include <iostream.h> • #include <time.h> • // file name: sys7.cpp • int main( void ) • { // main • time_t cur_time = time( '\0' ); • // mix C and C++ I/O • printf( "%s", asctime( localtime( & cur_time ) ) ); • cout << "After being modified" << endl; • system( "g++ -Wno-deprecated sys7.cpp; a.out" ); • cout << "We’ll never get here " << endl; • } //end main
Unix Commands, C++ Libraries • C and C++ are mature languages, widely used, yet offering limited high-level language facilities • No array assignments • No lexically nested functions or procedures • Limited built-in functions, hence the numerous libraries • Libraries render C/C++ language rich and versatile in use; some Unix libs, commands are ubiquitous, e.g.: • ps command • setenv command • signal.h lib • stdlib.h lib • sys/types.h lib • time.h command and lib
Unix Command ps • Name: ps • Purpose: print status of current processes • Functions: prints information about active processes. Without options, lists processes with same effective user ID and controlling terminal as invoker • Output contains process ID, terminal ID, cumulative execution time, and command name • Options are numerous: ps [-aAcdefjlLPyZ] [-g grplist] [-n namelist] [-o format] [-p proclist] [-s sidlist] [-t term] [-u uidlist] [-U uidlist] [-G gidlist] [-z zonelist]
Unix Command setenv • Name: setenv • Purpose: reports of environment variables for the current process and all its descendents • Function: various commands are set unset unsetenv export • Sample Use without arguments: • USER=herb • LOGNAME=herb • HOME=/u/herb • PATH=.:/usr/lang:/bin ... long list of paths • MAIL=/var/mail//herb • SHELL=/bin/csh • TZ=US/Pacific • LC_CTYPE=en_US.ISO8859-1 • LC_COLLATE=en_US.ISO8859-1 ... etc.
$PATH, etc. on PSU’s Odin, Sirius • On Unix shell, issue the command man shell_builtins and learn about several interesting commands, e.g.: • alias • echo $PATH • setenv • Command echo $PATH shows the one line your program did output –plus many more– when scanning through envp[] • That was the line starting with PATH=./user/ . . . • Or just issue command $PATH and observe the error at end • Again you will see a path for all directories searched, in order, to resolve a command --or finding a file-- you specified • Command setenvwithout arguments will provide information that your program outputs, when scanning through envp[] • What if you wish to add directory /u/herb/progsto your search path $PATH? • Issue command setenv PATH $PATH\:/u/herb/progs, will add /u/herb/progsat the end of existing path
C Library signal • Name: #include <signal.h> • Purpose: provide signal management for application processes • Key Functions with 1st argument sig: signal() sigset() sighold() sigrelse() sigignore() sigpause() • Signals are tools for asynchronous interprocess communication in Unix. Signal is sent to process or thread of the same process to notify that a specific event (the signal) has occurred. Some of the functions set, others remove etc. the event recording. If process has registered a signal handler, that handler is executed upon signal set
C Library stdlib • Name: #include <stdlib.h> • Purpose: defines key functions and macros • Key Functions: exit() malloc() printf() ...
C Library types • Name: #include <sys/types.h> • Purpose: defines 100s of types for 32-bit and 64-bit target systems • Key Functions: clock_t time_t pid_t size_t _CHAR_IS_SIGNED (or UNSIGNED)
C Library time • Name: #include <time.h> • Purpose: tracking run-time • Key Functions: localtime() returns: struct tm* single argument: const * clock asctime() returns: char * single argument: const struct tm* • time_t cur_time = time( '\0' ); • printf( "%s", asctime( localtime( & cur_time ) ) );
Unix Command time • Command name: time • Purpose: measures time of command execution • Functions: outputs time to standard error, as: • real time, ie. wall-clock, in float format • user time, in float format • system time, in float format time a.out 41.0u 1.0s 0:42 98% 0+0k 0+0io 0pf+0w