Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

argv prints out environment variables

Tags:

c

linux

I was experimenting randomly with argc and argv in c, however this program(try.c):

/* Trying to understand argc and argv.*/

#include<stdio.h>

int main(int argc,char *argv[])
{
  int i=0;

  /*
    argv[4]="arg4";
    argv[5]="arg5";
    argv[6]="arg6";
    argv[7]="arg7";
    argv[8]="arg8";
    argv[9]="arg9";;
  */

   for(i=0;i<(argc+20);i++)
   {
       printf("arg %d: %s\n", i,argv[i]);
   }

  return 0;
}

when run as

./try arg1 arg2 arg3

prints out this:

arg 0: ./try
arg 1: arg1
arg 2: arg2
arg 3: arg3
arg 4: (null)
arg 5: XDG_VTNR=7
arg 6: XDG_SESSION_ID=c2
arg 7: CLUTTER_IM_MODULE=xim
arg 8: SELINUX_INIT=YES
arg 9: XDG_GREETER_DATA_DIR=/var/lib/lightdm-data/raman
arg 10: GPG_AGENT_INFO=/run/user/1000/keyring-FAajwI/gpg:0:1
arg 11: TERM=xterm
arg 12: SHELL=/bin/bash
arg 13: VTE_VERSION=3409
arg 14: WINDOWID=58720268
arg 15: UPSTART_SESSION=unix:abstract=/com/ubuntu/upstartsession/1000/1775
arg 16: GNOME_KEYRING_CONTROL=/run/user/1000/keyring-FAajwI
arg 17: GTK_MODULES=overlay-scrollbar:unity-gtk-module
arg 18: USER=raman
arg 19: LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:
arg 20: XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0
arg 21: XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0
arg 22: SSH_AUTH_SOCK=/run/user/1000/keyring-FAajwI/ssh
arg 23: DEFAULTS_PATH=/usr/share/gconf/ubuntu.default.path`

I was expecting a segmentation fault but it worked.It worked for upto argc+63 and then gives segmentation fault.I tried googling but with no success. Someone please explain why is this happening i.e why are the environment variables(seems so) getting printed here? If I decomment the code, I get even weirder results.

like image 854
BitFlip Avatar asked Sep 16 '25 23:09

BitFlip


1 Answers

Going outside the limits of any array leads to undefined behavior. What happens in reality, is that many UNIX-like systems (like Linux) actually have a third argument to the main function, an array of string for the environment variable. So the complete prototype of main on such systems is

int main(int argc, char *argv[], char *envp[])

What you do when you go out of bounds of the argv array is that you cross over into the environ array.

It should be noted that this isn't actually in any standard, but it's there for backwards compatibility with old UNIX systems where this was common.

It's also mentioned in this reference, and also documented in the GNU libc manual.

like image 130
Some programmer dude Avatar answered Sep 18 '25 13:09

Some programmer dude