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