Thread: execve() Command help

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    6

    execve() Command help

    My question is concerning a snippet of code that I am trying to execute. My goal is to create a simple shell program for Unix that will read in all commands. I was told that I must use the execve() command in order to do this. So far my program parses the inputs into an array. It will then fork and within that child process it SHOULD get the command and execute it. For instance if you type ls -l, it should list all files in your current directory. This again is done using the execve() command. My program was working fine until I had to make it a very generalized command. For instance, my program was working fine when I had the following...

    Code:
    execve("/bin/ls/",eargv[0],eargv[1]);
    where eargv[0] held "ls", and eargv[1] held "-l". However I had to change the code to the following

    Code:
    execve("/bin/",eargv[0],eargv[1]);
    For a much more generalized approach. Now what it should do in my mind is search in the path, ie /bin/ for the argument of eargv[0] which is "ls" with the switch "-l". Yet it is not doing this and I continually get error -1 when I print it out. What could be the problem and how do I resolve it? I am truly stuck here and have been working all day on it without much success at all!

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The problem is your understanding of what execve() does is incorrect. The first argument is the path to the binary to be executed, not the path to search. execve() does not search a path, it executes the program given by its first argument.

    (Not to be confused with the argument array to the program itself. Traditionally, the first element of that list is the program name, but it could be "elephant" for all anyone cares)
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Registered User
    Join Date
    Sep 2009
    Posts
    6
    So what you are saying is that the code worked correctly when i directly specified the path being /bin/ls, and did not work when I told it /bin/ because it was looking for the executable there. Yet I was under the assumption from my teacher that that the command was as follows:

    Code:
    execve("Path to search", Argument, switch);
    I asked her this a few times and it is what she told me... Which led to my confusion. It does make sense though the way you are explaining it. However it does lead to me to two other questions...

    1. Is there a command that will search a path that is put in and find a argument with the switch parameters that are specified? If there is could someone provide a link or snippet so I can research this.

    2. I ended up using the execve command just in a very brute force way. I ended up concatenating /bin/ with what ever the user wrote to the program. For instance if I wanted to do a pwd in Unix, the user writes "pwd" The program will then concatenate pwd with /bin/ to make /bin/pwd and pass that into the execve command and the program ended up working. Yet I am then confused as to whether this is good programming technique cause from experience I do not believe it is. And also, what does the second and third parameters of the method execve actually do then. Because when I enter a command such as " ls -l" my execve command is set up to receive the information in the following way...

    Code:
    execve("/bin/ls", ls, -l);
    This works as well. Does that mean the third parameter is used for switch statements? I then get confused as to what the second parameter is used for. Again if anyone can provide insight to this question I would be very grateful or even a link that can explain the command very well. I looked it up in unix and the explanation did not clear anything truly up.

  4. #4
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Here's a link that might come handy.

  5. #5
    Registered User
    Join Date
    Sep 2009
    Posts
    6
    Quote Originally Posted by itCbitC View Post
    Here's a link that might come handy.
    Thank you for the link. I already did look at something exactly like this, and it did no quite settle with me. There is a lot of formality that I am just not familiar with yet. So that is the reason why I was asking the question above. If anyone else can provide a definition in layman terms I would be very appreciative.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    One obvious solution would be to make all three elements variables, so you can set the first one properly.

    To that end you may need to use whereis -- a shell, not C command:
    Code:
    [root~/C/experimental] whereis ls
    ls: /bin/ls /usr/share/man/man1p/ls.1p.gz /usr/share/man/man1/ls.1.gz
    and parse the output.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    I can only hope that you/your instructor misinterpreted each other; the first argument to execve() is the path to the program you want to run, not a directory to search. If she claims it is the latter, you're going to have to forget what you learned during this class.

    The exec functions with a "p" in the name search $PATH as you would expect. If you need to change the path, it's probably easiest just to use setenv() to change $PATH, remembering to set it back to the original value if necessary. But if you know the directory beforehand, you can just directly call the binary (as in "/bin/ls" or whatever).

    Also, when you use the exec functions, your list must be terminated with a null pointer. That is, the following is bad:
    Code:
    execl("/bin/ls", "ls", "-l");
    Instead, you want:
    Code:
    execl("/bin/ls", "ls", "-l", (char *)NULL);
    Unfortunately, that cast is necessary.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. execve() and the compiler
    By kizyle502 in forum C Programming
    Replies: 4
    Last Post: 09-10-2009, 10:07 PM
  2. execv or execve?
    By jcafaro10 in forum C Programming
    Replies: 6
    Last Post: 04-12-2009, 11:18 AM
  3. Trouble with execve
    By Nositi in forum C Programming
    Replies: 14
    Last Post: 02-04-2008, 10:41 AM
  4. problems with fork() and execve()
    By kristy in forum C Programming
    Replies: 4
    Last Post: 12-21-2003, 08:18 AM
  5. Returning PID from execve family of functions?
    By ruairi in forum Linux Programming
    Replies: 2
    Last Post: 03-12-2003, 08:47 AM