Thread: argc, argv

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    4

    argc, argv

    Hi everyone,

    i have this problem. im using in my program input variables argc and argv. when im firstime start program with some input parameters which fill out argv everything is ok (BTW : argc and argv are input parametres for my subprogram which im calling in my main function) but when im calling that subprogram again in that main with another argv parametres it works bad. i think that problem is that when im going back from that subprogram by return it will not erase variables in that subprogram and when im calling it secondly than with another parametres he dont know what to do So my question is: Is there some possible way how to erase all those variables before that second calling?? or some another way how to solve this problem??

    In that code below you can see that when i start program i put parametres similar like for char *mP only IP address is on second place so mujAVG1 i get without any problems but then when i put for Xping another arguments in that form what you can see ( there has to be IP on the last place couse at the end of first calling Xping parameters in argv are in this sequence) and program will retype that argv but in result of ping isnt 5 echo massages like it should be but only one it dont have lengh 20 data bytes but same like in first start 32 and if i took a look what is inside argv after all of this there is still that first sequence of parametres what i put on the beginig of program.


    Code:
    #include <stdio.h>
    #include </home/ping.c>
    
    int main(int argc, char *argv[]){
        float mujAVG1 = Xping(argc, argv);  // return avg RTT from Xping function from ping.c
    
        char *mP[] = {"./program", "-s", "20", "-c", "5", "192.168.1.102"}; 
        float mujAVG2 = Xping(argc, mP);
    }

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You don't need to erase them, because you're not actually passing them again. You're just passing another array of character pointers, and some random integer. You should instead be doing something like:
    Code:
    Xping( 6, mP );
    The value of argc is the number of arguments in argv, not the number of pointers in the array mP.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Nov 2009
    Posts
    4
    yea i thought like that also. And i already tried to do it like that but result was same... Here is the code of that Xping function

    Code:
    Xping(int argc, char *argv[])
    
    {
    
    	struct timeval timeout;
    
    	struct hostent *hp;
    
    	struct sockaddr_in *to;
    
    	struct protoent *proto;
    
    	struct in_addr ifaddr;
    
    	int i;
    
    	int ch, fdmask, hold, packlen, preload;
    
    	u_char *datap, *packet;
    
    	char *target, hnamebuf[MAXHOSTNAMELEN];
    
    	u_char ttl, loop;
    
    	int am_i_root;
    
    #ifdef IP_OPTIONS
    
    	char rspace[3 + 4 * NROUTES + 1];	/* record route space */
    
    #endif
    
    
    
    	static char *null = NULL;
    
    	__environ = &null;
    
    	am_i_root = (getuid()==0);
    
    
    
    	/*
    
    	 * Pull this stuff up front so we can drop root if desired.
    
    	 */
    
    	if (!(proto = getprotobyname("icmp"))) {
    
    		(void)fprintf(stderr, "ping: unknown protocol icmp.\n");
    
    		exit(2);
    
    	}
    
    	if ((s = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) {
    
    		if (errno==EPERM) {
    
    			fprintf(stderr, "ping: ping must run as root\n");
    
    		}
    
    		else perror("ping: socket");
    
    		exit(2);
    
    	}
    
    
    
    #ifdef SAFE_TO_DROP_ROOT
    
    	setuid(getuid());
    
    #endif
    	
    
    	preload = 0;
    
    	datap = &outpack[8 + sizeof(struct timeval)];
    
    	while ((ch = getopt(argc, argv, "I:LRc:dfh:i:l:np:qrs:t:v")) != EOF)
    
    		switch(ch) {
    
    		case 'c':
    
    			npackets = atoi(optarg);
    
    			if (npackets <= 0) {
    
    				(void)fprintf(stderr,
    
    				    "ping: bad number of packets to transmit.\n");
    
    				exit(2);
    
    			}
    
    			break;
    
    		case 'd':
    
    			options |= F_SO_DEBUG;
    
    			break;
    
    		case 'f':
    
    			if (!am_i_root) {
    
    				(void)fprintf(stderr,
    
    				    "ping: %s\n", strerror(EPERM));
    
    				exit(2);
    
    			}
    
    			options |= F_FLOOD;
    
    			setbuf(stdout, NULL);
    
    			break;
    
    		case 'i':		/* wait between sending packets */
    
    			interval = atoi(optarg);
    
    			if (interval <= 0) {
    
    				(void)fprintf(stderr,
    
    				    "ping: bad timing interval.\n");
    
    				exit(2);
    
    			}
    
    			options |= F_INTERVAL;
    
    			break;
    
    		case 'l':
    
    			if (!am_i_root) {
    
    				(void)fprintf(stderr,
    
    				    "ping: %s\n", strerror(EPERM));
    
    				exit(2);
    
    			}
    
    			preload = atoi(optarg);
    
    			if (preload < 0) {
    
    				(void)fprintf(stderr,
    
    				    "ping: bad preload value.\n");
    
    				exit(2);
    
    			}
    
    			break;
    
    		case 'n':
    
    			options |= F_NUMERIC;
    
    			break;
    
    		case 'p':		/* fill buffer with user pattern */
    
    			options |= F_PINGFILLED;
    
    			fill(datap, optarg);
    
    			break;
    
    		case 'q':
    
    			options |= F_QUIET;
    
    			break;
    
    		case 'R':
    
    			options |= F_RROUTE;
    
    			break;
    
    		case 'r':
    
    			options |= F_SO_DONTROUTE;
    
    			break;
    
    		case 's':		/* size of packet to send */
    
    			datalen = atoi(optarg);
    
    			if (datalen > MAXPACKET) {
    
    				(void)fprintf(stderr,
    
    				    "ping: packet size too large.\n");
    
    				exit(2);
    
    			}
    
    			if (datalen <= 0) {
    
    				(void)fprintf(stderr,
    
    				    "ping: illegal packet size.\n");
    
    				exit(2);
    
    			}
    
    			break;
    
    		case 'v':
    
    			options |= F_VERBOSE;
    
    			break;
    
    		case 'L':
    
    			moptions |= MULTICAST_NOLOOP;
    
    			loop = 0;
    
    			break;
    
    		case 't':
    
    			moptions |= MULTICAST_TTL;
    
    			i = atoi(optarg);
    
    			if (i < 0 || i > 255) {
    
    				printf("ttl %u out of range\n", i);
    
    				exit(2);
    
    			}
    
    			ttl = i;
    
    			break;
    
    		case 'I':
    
    			moptions |= MULTICAST_IF;
    
    			{
    
    				int i1, i2, i3, i4;
    
    				char junk;
    
    
    
    				if (sscanf(optarg, "%u.%u.%u.%u%c",
    
    					   &i1, &i2, &i3, &i4, &junk) != 4) {
    
    					printf("bad interface address '%s'\n",
    
    					       optarg);
    
    					exit(2);
    
    				}
    
    				ifaddr.s_addr = (i1<<24)|(i2<<16)|(i3<<8)|i4;
    
    				ifaddr.s_addr = htonl(ifaddr.s_addr);
    
    			}
    
    			break;
    
    		default:
    
    			usage();
    
    		}
    
    	argc -= optind;
    	argv += optind;
    
    	if (argc != 1)
    
    		usage();
    
    	target = *argv;
    
    	memset(&whereto, 0, sizeof(struct sockaddr));
    
    	to = (struct sockaddr_in *)&whereto;
    
    	to->sin_family = AF_INET;
    
    	if (inet_aton(target, &to->sin_addr)) {
    
    		hostname = target;
    
    	}
    
    	else {
    
    		hp = gethostbyname(target);
    
    		if (!hp) {
    
    			(void)fprintf(stderr,
    
    			    "ping: unknown host %s\n", target);
    
    			exit(2);
    
    		}
    
    		to->sin_family = hp->h_addrtype;
    
    		if (hp->h_length > (int)sizeof(to->sin_addr)) {
    
    			hp->h_length = sizeof(to->sin_addr);
    
    		}
    
    		memcpy(&to->sin_addr, hp->h_addr, hp->h_length);
    
    		(void)strncpy(hnamebuf, hp->h_name, sizeof(hnamebuf) - 1);
    
    		hostname = hnamebuf;
    
    	}
    
    
    
    	if (options & F_FLOOD && options & F_INTERVAL) {
    
    		(void)fprintf(stderr,
    
    		    "ping: -f and -i incompatible options.\n");
    
    		exit(2);
    
    	}
    
    
    
    	if (datalen >= (int)sizeof(struct timeval)) /* can we time transfer */
    
    		timing = 1;
    
    	packlen = datalen + MAXIPLEN + MAXICMPLEN;
    
    	packet = malloc((u_int)packlen);
    
    	if (!packet) {
    
    		(void)fprintf(stderr, "ping: out of memory.\n");
    
    		exit(2);
    
    	}
    
    	if (!(options & F_PINGFILLED))
    
    		for (i = 8; i < datalen; ++i)
    
    			*datap++ = i;
    
    
    
    	ident = getpid() & 0xFFFF;
    
    	hold = 1;
    
    
    
    	if (options & F_SO_DEBUG)
    
    		(void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold,
    
    		    sizeof(hold));
    
    
    
    	if (options & F_SO_DONTROUTE)
    
    		(void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&hold,
    
    		    sizeof(hold));
    
    
    
    	/* this is necessary for broadcast pings to work */
    
    	setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&hold, sizeof(hold));
    
    
    
    	/* record route option */
    
    	if (options & F_RROUTE) {
    
    #ifdef IP_OPTIONS
    
    	        memset(rspace, 0, sizeof(rspace));
    
    		rspace[IPOPT_OPTVAL] = IPOPT_RR;
    
    		rspace[IPOPT_OLEN] = sizeof(rspace)-1;
    
    		rspace[IPOPT_OFFSET] = IPOPT_MINOFF;
    
    		if (setsockopt(s, IPPROTO_IP, IP_OPTIONS, rspace,
    
    		    sizeof(rspace)) < 0) {
    
    			perror("ping: record route");
    
    			exit(2);
    
    		}
    
    #else
    
    		(void)fprintf(stderr,
    
    		  "ping: record route not available in this implementation.\n");
    
    		exit(2);
    
    #endif /* IP_OPTIONS */
    
    	}
    
    
    
    	/*
    
    	 * When pinging the broadcast address, you can get a lot of answers.
    
    	 * Doing something so evil is useful if you are trying to stress the
    
    	 * ethernet, or just want to fill the arp cache to get some stuff for
    
    	 * /etc/ethers.
    
    	 */
    
    	hold = 48 * 1024;
    
    	(void)setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&hold,
    
    	    sizeof(hold));
    
    
    
    /*#if 0*/
    
    	if (moptions & MULTICAST_NOLOOP) {
    
    		if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP,
    
    							&loop, 1) == -1) {
    
    			perror ("can't disable multicast loopback");
    
    			exit(92);
    
    		}
    
    	}
    
    	if (moptions & MULTICAST_TTL) {
    
    		if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL,
    
    							&ttl, 1) == -1) {
    
    			perror ("can't set multicast time-to-live");
    
    			exit(93);
    
    		}
    
    	}
    
    	if (moptions & MULTICAST_IF) {
    
    		if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF,
    
    					&ifaddr, sizeof(ifaddr)) == -1) {
    
    			perror ("can't set multicast source interface");
    
    			exit(94);
    
    		}
    
    	}
    
    /*#endif*/
    
    
    
    	if (to->sin_family == AF_INET)
    
    		(void)printf("PING %s (%s): %d data bytes\n", hostname,
    
    		    inet_ntoa(*(struct in_addr *)&to->sin_addr.s_addr),
    
    		    datalen);
    
    	else
    
    		(void)printf("PING %s: %d data bytes\n", hostname, datalen);
    
    
    
    	(void)signal(SIGINT, finish);
    
    	(void)signal(SIGALRM, catcher);
    
    
    
    	while (preload--)		/* fire off them quickies */
    
    		pinger();
    
    
    
    	if ((options & F_FLOOD) == 0)
    
    		catcher(0);		/* start things going */
    
    
    
    	for (;;) {
    
    		struct sockaddr_in from;
    
    		register int cc;
    
    		size_t fromlen;
    
    
    
    		if (options & F_FLOOD) {
    
    			pinger();
    
    			timeout.tv_sec = 0;
    
    			timeout.tv_usec = 10000;
    
    			fdmask = 1 << s;
    
    			if (select(s + 1, (fd_set *)&fdmask, (fd_set *)NULL,
    
    			    (fd_set *)NULL, &timeout) < 1)
    
    				continue;
    
    		}
    
    		fromlen = sizeof(from);
    
    		if ((cc = recvfrom(s, (char *)packet, packlen, 0,
    
    		    (struct sockaddr *)&from, &fromlen)) < 0) {
    
    			if (errno == EINTR)
    
    				continue;
    
    			perror("ping: recvfrom");
    
    			continue;
    
    		}
    
    		pr_pack((char *)packet, cc, &from);
    
    		if (npackets && nreceived >= npackets)
    
    			break;
    
    	}
    	
    	finish(0);
    	
    	/* NOTREACHED */
    
    	return(avg);

  4. #4
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Code:
    {"./program", "-s", "20", "-c", "5", "192.168.1.102"};
    I believe it should be
    Code:
    {"program", "-s", "20", "-c", "5", "192.168.1.102"};
    Try printing argv[0] to be sure

  5. #5
    Registered User
    Join Date
    Nov 2009
    Posts
    4
    It is ok like that. And i think that it really doesnt metter that array take like a one string and "dont care" what is inside but anyway i try to change but without any effect

  6. #6
    Registered User
    Join Date
    Nov 2009
    Posts
    4
    I tried to write out contents of argv in Xping before it return to main and result is this.

    Code:
    ARGc: 6
    ARGV[0]: ./program
    ARGV[1]: 192.168.1.103
    ARGV[2]: -s
    ARGV[3]: 32
    ARGV[4]: -c
    ARGV[5]: 5
    PING 192.168.1.103 (192.168.1.103): 32 data bytes
    40 bytes from 192.168.1.103: icmp_seq=0 ttl=128 time=4.8 ms
    40 bytes from 192.168.1.103: icmp_seq=1 ttl=128 time=0.7 ms
    40 bytes from 192.168.1.103: icmp_seq=2 ttl=128 time=0.7 ms
    40 bytes from 192.168.1.103: icmp_seq=3 ttl=128 time=0.7 ms
    40 bytes from 192.168.1.103: icmp_seq=4 ttl=128 time=0.7 ms
    ARGc: 1
    ARGV[0]: 192.168.1.103
    ARGV[1]: (null)
    ARGV[2]: ORBIT_SOCKETDIR=/tmp/orbit-Martin
    ARGV[3]: HOSTNAME=FedoraAthlon
    ARGV[4]: IMSETTINGS_INTEGRATE_DESKTOP=yes
    ARGV[5]: SHELL=/bin/bash
    
    --- 192.168.1.103 ping statistics ---
    5 packets transmitted, 5 packets received, 0% packet loss
    round-trip min/avg/max = 0.7/1.5/4.8 ms
    AVG1: 1.000000
    AVG2: 5.000000
    AVG: 1.500000
    AVG: 1.500000
    
    DRUHA IP
    
    ARGc: 6
    ARGV[0]: ./program
    ARGV[1]: -s
    ARGV[2]: 20
    ARGV[3]: -c
    ARGV[4]: 3
    ARGV[5]: 192.168.1.102
    PING 192.168.1.102 (192.168.1.102): 32 data bytes
    40 bytes from 192.168.1.102: icmp_seq=5 ttl=128 time=1.2 ms
    ARGc: 1
    ARGV[0]: 192.168.1.102
    Neoprávněný přístup do paměti (SIGSEGV) // unauthorized access to memory
    Last edited by Martas; 11-19-2009 at 08:37 AM.

  7. #7
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Try these things
    A)
    Code:
    int main(int argc, char *argv[]){
        float mujAVG1 = Xping(argc, argv);
        float mujAVG2 = Xping(argc, argv);
    }
    I guess you will get the same wrong results
    B)
    So something is changing the memory argv points at? Try
    Code:
    int main(int argc, char *argv[]){
        char *temp[] = argv;
        int num = argc;
        //Copy every string in argv to temp
        float mujAVG1 = Xping(argc, argv);
        float mujAVG2 = Xping(num, temp);
    }
    I would guess you still get an error. Try also without the copying of the strings
    C)
    My guess is that you just write in a place you shouldn't messing up the memory. Check the two above to be sure though.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help getting a grib on argc and argv
    By elwad in forum C Programming
    Replies: 10
    Last Post: 05-01-2009, 10:13 AM
  2. Using argc and argv data
    By Rad_Turnip in forum C Programming
    Replies: 4
    Last Post: 03-31-2006, 06:09 AM
  3. Converting a argc / argv construct into a va_list
    By chambece in forum C Programming
    Replies: 6
    Last Post: 07-03-2005, 04:47 PM
  4. argc & argv
    By miryellis in forum C Programming
    Replies: 11
    Last Post: 09-19-2004, 11:59 PM
  5. how do i? re: argc - argv
    By luigi40 in forum C Programming
    Replies: 2
    Last Post: 06-11-2004, 10:17 AM