User interacts with shell by giving commands and some arguments to those commands. These commands are generally some C program located in /bin,/usr/bin,/usr/local/bin folder. We generally do not give full path of the command. So the shell of the OS maintains an environment variable called PATH to search for a binary executable when a full path is not given. Shell is a process that collects these arguments and creates a new task with this given command string/binary name. It also passes user arguments and environment variables. fork is used to spawn a new task and a series of execxxcalls are there to overwrite process with new binary and to pass new arguments and environments.
We all know C program starts with a main() routine. Here we can access these arguments via argv also known as argument vector. Argument vector is a pointer to a pointer which contains a list of strings. This list or array contains a series of pointers starting from 0 which is program name/path the arguments placed at one after another. Argc or argument count is the first argument which holds the total number of elements in this argv. This is all about user arguments. Now C runtime also maintains a similar vector for environment strings. This vector is named as environ. This vector contains a name value pair separated by ‘=”. One point to note here is this vector contains a NULL entry at the end. This is to indicate that it is the last entry. We have two demo application code to exchange this thoughts.
Lastly one question: Is main() the actual starting entry point of C program? The answer is no. Actually main() is not the entry point of the process. A process generally starts with a symbol _start(). Every C program has a hidden startup routine. This is mainly written with assembly and C and a part of C compiler/linker. Compiler binds this small code with the output binary as a a part of static linking process. This part of the code sets segment registers and several init stuffs including construct stack and user mode portion of memory allocator. It also constructs this argument vector and environment vector.
$ gcc env_argv.c -o env_argv $ ./env_argv arg1 arg2 arg3 Program arguments: argv  = ./env_argv argv  = arg1 argv  = arg2 argv  = arg3 Environment variables: USER=user1 LOGNAME=user1 HOME=/u/user1 PATH=/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin MAIL=/var/spool/mail/user1 SHELL=/bin/csh SSH_CLIENT=10.73.7.21 4632 22 SSH_CONNECTION=10.73.7.21 4632 10.72.9.232 22 SSH_TTY=/dev/pts/191 TERM=xterm HOSTTYPE=x86_64-linux VENDOR=unknown OSTYPE=linux MACHTYPE=x86_64 SHLVL=1 PWD=/u/user1 GROUP=engr HOST=host1 REMOTEHOST=remote1 HOSTNAME=host1 INPUTRC=/etc/inputrc G_BROKEN_FILENAMES=1 SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass KDE_IS_PRELINKED=1 KDEDIR=/usr LANG=en_US.UTF-8 LESSOPEN=|/usr/bin/lesspipe.sh %s QTDIR=/usr/lib64/qt-3.3 QTINC=/usr/lib64/qt-3.3/include QTLIB=/usr/lib64/qt-3.3/lib
$ gcc printenv.c -o printenv $ ./printenv PATH Env name: PATH = /usr/software/utils/bin:/usr/software/bin: /usr/software/rats/bin:/usr/lib64/qt-3.3/bin:/usr/kerberos/bin: /usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin $ ./printenv ABCE Env name: ABCE not present. $ ./printenv SHELL Env name: SHELL = /bin/csh
About our authors: Team EQA
You have viewed 1 page out of 248. Your C learning is 0.00% complete. Login to check your learning progress.
Learn on Youtube