How can I execute a shell script or executable?

This is a school project I'm working on.

I am writing a web server. If the requested resource has the extension "cgi", I need to fork and execute the program. If cgi is a compiled executable, this works:

execl(path, (char*) 0); 

But if the cgi program is a script that needs to be interpreted, I need to do something like this:

 execl("/bin/sh", path, path, (char*) 0); 

How can I write my code so that it works with any script? How does my shell do this? Should I use the file program to determine if it is an executable file or text, and if it is text, then suppose it needs to be interpreted?

+4
source share
3 answers

Why do you need to explicitly call "/bin/sh" if this is a script?

As long as the script has execute permission and the correct shebang at the top, you can execute it as if it were an executable.

+6
source

You can ask the shell to execute the command for you using the -c option.

If the command is an inline shell or a shell script, the shell will run it; if it is an external command, the shell will execute the binary.

Try this and see if it works for you:

 execl("/bin/sh", "/bin/sh", "-c", path, (char*) 0); 

EDIT: fixed the above call. This should work now; I tested with

 execl("/bin/sh", "/bin/sh", "-c", "set", NULL); 

and my test program repeated shell variables. Then I tested with

 execl("/bin/sh", "/bin/sh", "-c", "/usr/bin/clear", NULL); 

and my test program cleared the terminal emulator screen.

NOTE. The good thing about this answer is that it will run everything that you can run from the shell. This way it will run shell built-in commands, and it will run shell scripts that don't have the correct #!/path/to/interpreter first line. If all shell scripts you ever want to run have the correct #! first line, you do not need it. This offers a slightly more reliable solution due to the execution of the shell, which may not be needed.

0
source

You should check if the file has exec permission if you have not warned the user. You can use the GlibC lstat function to accomplish this. Then use execve from GlibC, which feeds it using the path and argument list (you can also get env var from the main one, I recommend that you provide an environment for your programs instead of giving (char *) 0, which is a NULL pointer)

0
source

All Articles