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.

#include<stdio.h>
extern char **environ;
int main (int argc, char *argv[])
{
  int count;
  char *env;
  printf ("Program arguments:\n");
  for (count = 0; count <argc; count++)
10    {
11      printf ("argv [%d] = %s\n", count, argv [count]);
12    }
13    count = 0;
14    printf ("Environment variables:\n");
15    while (env = environ [count++])
16    {
17      printf ("%s\n", env);
18    }
19    return 0;
20  }
21 

Output:

$ gcc env_argv.c -o env_argv
$ ./env_argv arg1 arg2 arg3
Program arguments:
argv [0] = ./env_argv
argv [1] = arg1
argv [2] = arg2
argv [3] = 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
#include <stdio.h>
#include <stdlib.h>
int main (intargc, char * argv[])
{
  char * env_val ;
  if (argc>1)
  {
    env_val = getenv(argv [1]);
10      if (env_val )
11      {
12        printf ("Env name: %s = %s\n", argv [1],  env_val);
13        return 0;
14      }
15      else
16      {
17        printf ("Env name: %s not present.\n", argv [1]);
18        return -1;
19      }
20    }
21    else
22    {
23      printf ("At least one argument needed.\n");
24      printf ("Syntax: printenv\n");
25      return -1;
26    }
27  }
28 

Output:

$ 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

You have viewed 1 page out of 248. Your C learning is 0.00% complete. Login to check your learning progress.

 Vote 0

Similar topics related to this section

Merge sort, Radix Sort, argc and argv, C startup routine, argv environ getenv, system(), atexit, raise signal,

# C Programming Language (Prentice Hall Software)
# Let Us C Paperback - 2006 by Yashavant Kanetkar
# Understanding and Using C Pointers Core techniques for memory management
# Data Structures Using C and C++ Paperback - 1998
# Data Structures In C Paperback - August 11, 2008 by Noel Kalicharan