-2

I am trying to build my own shell in C as part of a class project. We are required to use execv and implement our own path. For better understanding here is the question:

The list of paths is empty by default, but may grow to any arbitrary size. You should implement a built-in command to control this variable:

path [+|- /some/dir]
  • path (without arguments) displays all the entries in the list separated by colons, e.g. "/bin:/usr/bin".

  • path + /some/dir appends the given pathname to the path list.

  • path - /some/dir removes the given pathname from the path list.

I have misread the assignment and used execvp so far. Please can you shed some light on how to create my own path variable, and for each command executed search the directory it is in and add it to the path? Or is there any simple shell written using execv I can take a look at?

I saw http://linuxgazette.net/111/ramankutty.html, but I found the search a little too complex, and he uses execve.

so far i have char *mypath variable which is null initially. but the user can add or remove using path + some/dir or path - /some/dir. syntax for execv is execv("/some/dir", argv) how do i search my path for the executable and pass it to execv....for example mypath=/bin/ls ; when i pass execv(mypath, argv) it does not work...so how do i pass the path to execv?

Community
  • 1
  • 1
Anvita Potluri
  • 101
  • 1
  • 1
  • 4
  • Where are you stuck, exactly? Do you conceptually understand the assignment, but don't know actually write the code? Or do you not understand the assignment? Do you grok what a list of paths is, and what you're supposed to do with it? (For each directory in the path list, look for the request command in that directory.) – John Kugelman Sep 13 '14 at 18:38
  • Welcome to Stack Overflow. Help us help you...try your hand at the assignment, and if you get stuck, post code you've tried so far and explain what (one or few) things you're stuck on. – Gutblender Sep 13 '14 at 18:41
  • I understand the assignment I am having difficulty on how to set my own path which is searched when execv is used...! – Anvita Potluri Sep 13 '14 at 18:57
  • You may want to use [access(2)](http://man7.org/linux/man-pages/man2/access.2.html) but you should scan explicitly your path so explicitly build an executable program file name (e.g. with `snprintf` or `asprintf`) from the command name and each element of your path. – Basile Starynkevitch Sep 14 '14 at 06:43

1 Answers1

1

I'm guessing the reason you are supposed to use excev is precisely that it doesn't take into account the path of the environment, but the call has to provide a full path to the function.

Since this is a class project, you are supposed to write your code - writing code is how you learn how to do things, much more than copy-and-paste from the internet, so I'm not going to write code to solve the problem but instead describe the solution.

You will need to keep a list of path entries - adjusted through the path + some/dir and path - some/dir mechanism - so these commands need to be handled inside your shell, of course, and they should add/remove from your list of path entries.

When you then come to executing something, say "mycommand" is entered, you will have to scan the list of path entries, and check if there is a file by the name "mycommand" in the directory specified by the path entry that can be executed (has execute bit set in the directory entry). If so, call execv on the string of current path entry and "mycommand" concatenated. (You can produce the concatenated string and use the stat function to get the information about the file, for example)

Do check for errors, and report if something goes wrong.

Please do not try to find someone else's shell on the internet. That is not how you learn, and if you don't actually learn from the class exercises, you will most likely not succeed once you finish school - and that's ultimately WHY you are going to school, right?

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • i am not looking to copy paste the code. I already implemented my shell but I have used execvp which directly searches PATH. Now I am trying to do it with execv which neaes a local path what I am not able to understand is when I use my own path variable it empty at first but when it recieves a command i am supposed to locate the path of the command and add it to my path. how do i do this? – Anvita Potluri Sep 13 '14 at 18:53
  • I just described that. You have to recognise the path command, and keep a list of entries for the path, then search that list. Try writing some code to handle a list of path entries [list doesn't necessarily mean "linked list", just some way to keep a number of paths - you can of course just make one long string and add/remove from that string...]. Once you have a working path command as a "shell internal" command, you should write some code to search the find which path entry has the command you are looking for. – Mats Petersson Sep 13 '14 at 19:01
  • i understand what is to be done...I dont know how to do it...for example if the user inputs ls... initially my path is empty so where do i search for the location of the command and how do i attach it to my own path? such that execv(path , argv[])... – Anvita Potluri Sep 13 '14 at 19:21
  • 1
    @AnvitaPotluri: As Mats said, your shell program **only** has to search for a command in the directories given in the path list that your shell maintains. So if the user inputs `ls` and your path list is empty, then you print an error message like *ls: command not found*. It's up to the user (or sysadmin) to make sure that the path list is populated correctly, using the internal `path` command your shell provides. Normally this would be done in some startup script, just like bash does with `/etc/profile` and `~/.bashrc`. – PM 2Ring Sep 13 '14 at 22:33
  • @MatsPetersson i have a working path command which is stored in the form of a long string. please can you guide on how to search the path and pass it to execv command....and I dint get the part about stat and readdir... – Anvita Potluri Sep 14 '14 at 06:38
  • Say the user has done `path + /bin` and `path + /usr/bin` so there are two directories in the path. When they type `ls`, you need to see if either of those directories contains an executable called `ls`. Does `/bin/ls` exist? If it does, run it. If not, does `/usr/bin/ls` exist? Is so, run it. If you didn't find `ls` anywhere, print an error message. – John Kugelman Sep 14 '14 at 06:40
  • @AnvitaPotluri: To help you with that, we'd really need to see what your code that you currently have looks like - or at least a very good description of what you have done, and what/why it is not working... – Mats Petersson Sep 14 '14 at 14:01