21.03.2013 Views

Problem - Kevin Tafuro

Problem - Kevin Tafuro

Problem - Kevin Tafuro

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

The two easiest and safest functions to use are execv( ) and execve( ); the only difference<br />

between the two is that execv( ) calls execve( ), passing environ for the environment<br />

pointer. If you have already sanitized the environment (see Recipe 1.1), it’s<br />

reasonable to call execv( ) without explicitly specifying an environment to use. Otherwise,<br />

a new environment can be built and passed to execve( ).<br />

The argument lists for the functions are built just as they will be received by main( ).<br />

The first element of the array is the name of the program that is running, and the last<br />

element of the array must be a NULL. The environment is built in the same manner as<br />

described in Recipe 1.1. The first argument to the two functions is the full path and<br />

filename of the executable file to load and execute.<br />

As a courtesy to the new program, before executing it you should close any file<br />

descriptors that are open unless there are descriptors that you intentionally want to<br />

pass along to it. Be sure to leave stdin, stdout, and stderr open. (See Recipe 1.5 for a<br />

discussion of file descriptors.)<br />

Finally, if your program was executed setuid or setgid and the extra privileges have<br />

not yet been dropped, or they have been dropped only temporarily, you should drop<br />

them permanently before executing the new program. Otherwise, the new program<br />

will inherit the extra privileges when it should not. If you use the spc_fork( ) function<br />

from Recipe 1.6, the file descriptors and privileges will be handled for you.<br />

Another function provided by the standard C runtime library for executing programs<br />

is system( ). This function hides the details of calling fork( ) and the appropriate<br />

exec*( ) function to execute the program. There are two reasons why you should<br />

never use the system( ) function:<br />

• It uses the shell to launch the program.<br />

• It passes the command to execute to the shell, leaving the task of breaking up the<br />

command’s arguments to the shell.<br />

The system( ) function works differently from the exec*( ) functions; instead of<br />

replacing the currently executing program, it creates a new process with fork( ). The<br />

new process executes the shell with execve( ) while the original process waits for the<br />

new process to terminate. The system( ) function therefore does not return control to<br />

the caller until the specified program has completed.<br />

Yet another function, popen( ), works somewhat similarly to system( ). It also uses<br />

the shell to launch the program, passing the command to execute to the shell and<br />

leaving the task of breaking up the command’s arguments to the shell. What it does<br />

differently is create an anonymous pipe that is attached to either the new program’s<br />

stdin or its stdout file descriptor. The new program’s stderr file descriptor is always<br />

inherited from the parent. In addition, it returns control to the caller immediately<br />

with a FILE object connected to the created pipe so that the caller can communicate<br />

with the new program. When communication with the new program is finished, you<br />

30 | Chapter 1: Safe Initialization<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!