Thanks again for your comments!

Roland Mainz wrote:
> Sumanth Naropanth wrote:
> [CC:'ing shell-discuss at opensolaris.org (please make sure to keep this
> list in the CC:)]
>> Jeffrey Hutzelman wrote on 10/31/08 14:29:
>>> I'd also consider whether you want an interface like that of execve(),
>>> which takes a char ** rather than a variable number of char * arguments,
>>> and/or a variant that accepts a single va_list instead of a variable
>>> number of arguments, to make it easier to write wrappers.
>> I am considering this in my revised proposal.
> 
> What about the following API:
> 
> Prototype:
> |int exec_system(const char *commandargs, const char **envp, uint32_t
> flags, int *child_returncode, ...);|
> 
> Arguments would be:
> |commandargs| would be a chain of C strings (each terminated with a '\0'
> byte) which is itself terminated by a '\0'-byte.
> For example if you want to execute the shell equivalent of $ ls -l
> /etc/profile # you set the string to:
> "/usr/bin/ls\0-l\0/etc/profile\0\0"
> ('\0' represents a '\0'-byte, not that the string is passed though
> |sprintf()| or something similar!)
> 

Several folks have commented on why this would be hard to implement and
use, and I think I agree. It may also confuse the argument parsing when
developers use it with string.h functions (other than sprintf()).
White-space delimited code is also more readable and verifiable.

[...]
> 
> |envp| points to an optional array of C strings representing the child
> process's environment variables. If the pointer is |NULL| the parents
> environment is used.
> 

This, and the 'child_returncode' (below) features are valid
functionalities that can be added on, but what would be the practical
use cases? I'd like system_noshell() to be a secure alternative to
system(3C), without encroaching too much into posix_spawn() or exec*e()
extended functionalities.

Current uses of system() in OpenSolaris for instance, and the nature of
security bugs resulting from improper use of the function justify the
need for a secure and simple interface.

> 
> |child_returncode| points to the child process's return code (this is
> seperated here to avoid the mess of dismanteling the value via macros
> etc.). The pointer may be |NULL| 
> 

The system_noshell() function will harvest the child process's return
code via wait*(). It'll be similar to the implementation of the
system(3C) function.

> 
> |flags| is a flag to modify the behaviour of the function on demand
> (e.g. for future usage).

My revised proposal include prototypes with 'flags' to implement
possible extensions in the future.

> 
> 
> |...| allows to define more arguments in the future if matching bits in
> |flags| are set
> 

The system_noshell_x() and the system_noshell_xv() functions give users
the flexibility to supply arguments in varargs or argv[] style, when
arguments have special characters. I also agree that the 'flags' field
is useful to support extended functionalities (priv management and other
extensions in the future), but introducing more arguments in the
prototype is likely to digress from the aim of the project and the use
cases I'm targeting.

-Sumanth


Reply via email to