tags:

views:

295

answers:

3

For a project in C, we need to build a shell over a Unix server.

It needs to be able to execute functionality native to Unix, and not bash (or any other Unix shell).

I am writing a method in the hopes to generalize a call to a command. into a general function:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <limits.h>

void execCmd(char* cmd,char* options)
{
   char directory[MAX_CANON] = "/bin/"; //currently is just set to /bin
   char* toExec = strcat(directory,cmd);

I would like to set the variable 'directory' to the proper directory for the Unix command I'm calling.

So, in essence, I would like to be able to use something like char directory[MAX_CANON] = which(cmd);

so that the which function will return me the directory of the command I'm trying to call.

If you feel this is not a good solution, please recommend some other way.

Thanks

EDIT: I guess at worst I could do a massive if-else statement, setting the 'directory' vbl based on the cmd parameter.

+2  A: 

What you're asking for is the command 'which', ie

me@stackoverflow:~$ which which
/usr/bin/which

On linux it's a shell script, so take a look a gander.

However, I don't think this is required to make a UNIX shell. If you type

man 3 exec

you'll find that execlp() and execvp() take care of the details of searching PATH for the given command and executing it.

Paul
Thanks, execlp(cmd,cmd,NULL); did the trick!
SauceMaster
+1  A: 

To implement this natively, I would:

  • Use getenv to acquire the PATH
  • parse the PATH into a list of candidate components (strtok for all its faults is the classic tool),
  • For each PATH component: form /possible/path/to/cmd and use a stat family function to test fif this file exists and the user has execute permission. Continue until you find it or run out of PATH...

Edit: You may want to follow symlinks, too.

dmckee
+1  A: 

Not that I'm aware off, but you can mimic the which functionality on a helper function. I'll need to search over all paths in the PATH environment variable for a file named as your command, and after that check if that file is executable, then you probably found your executable.

To get the PATH variable you can use getenv(). You'll need to split it with strtok(). For searching a directory you can use opendir(), will be something like this:

#include <sys/types.h>
#include <dirent.h>

...
    DIR *dir;
    struct dirent *dp;
...
    if ((dir = opendir (".")) == NULL) {
        perror ("Cannot open .");
        exit (1);
    }


    while ((dp = readdir (dir)) != NULL) {
    }
...

Check for dirent struct on the readdir() function man page.

Augusto Radtke