system_safe(3)

πŸ¦‹ system_safe(3) πŸ¦‹

okay bestie, pull up a chair πŸ’– this one lives in the Linux Programmer's Manual, section 3, and it's literally the glow-up that system(3) always needed. no shell, no drama, just vibes.


✨ NAME ✨

system_safe, system_execs, system_nosh β€” run a command plus its arguments straight from a string, without ever touching a shell πŸ’…


🌸 SYNOPSIS 🌸

#include <stdlib.h>
#include <execs.h>

int system_safe(const char *command);
int system_execsp(const char *command);
int system_execsa(const char *command);
int system_execs(const char *path, char const *command);

int system_execsrp(const char *command, int redir[3]);
int system_execsra(const char *command, int redir[3]);
int system_execsr(const char *path, char const *command, int redir[3]);

int system_nosh(const char *command);
int system_execsqp(const char *command);
int system_execsqa(const char *command);

int system_execsqrp(const char *command, int redir[3]);
int system_execsqra(const char *command, int redir[3]);

these cuties are handed to you by libexecs 🫢 so when you link, you link with -lexecs. no cap.


πŸ’– DESCRIPTION πŸ’–

system_safe is the safe replacement for the libc's system(3) 😌 it parses your command string and runs the command directly, no shell in the middle, periodt. the command has to be given as an absolute pathname. and heads up: system_safe does not support variables as arguments. πŸ™ˆ

arguments inside the command string are split on space characters β€” that's blanks, tabs, or newlines, all of them. you can wrap an argument in single or double quotes to let it contain spaces, and a backslash (\) that isn't quoted is the escape character that protects the very next char. πŸŽ€

system_execsa is like system_safe but it also supports variables as arguments ✨ when an argument of a command is a dollar sign followed by a name (like $USER), s2argv drops in the output of the s2argv_getvar function instead. (you can, for example, assign s2argv_getvar=getenv.) but for security reasons the function is NULL by default, and then every variable gets replaced with an empty string 😭 programmers can plug in their own custom function instead, iykyk.

system_execsp hunts down the executable file using the PATH environment variable, exactly as explained over in execlp(3) πŸ”

system_execs is the one that wants the path of the executable as its first parameter, so it does not use the PATH environment variable at all. decisive. πŸ‘‘

system_execsr, system_execsrp and system_execsra work just like their counterparts without the r, except they let you redirect standard input, output and error 🌈 their last parameter is an array of three integers, and here's the tea:

  • the command's standard input gets redirected to redir[0] if it is positive
  • standard output goes to redir[1] if it is not negative and different from 1
  • standard error goes to redir[2] if it is not negative and different from 2

system_execsra does not use the PATH variable β€” argv[0] must be given as a full pathname. no shortcuts bestie 🚫

system_nosh, system_execsqp, system_execsqa, system_execsqrp and system_execsqra can run whole sequences of commands separated by semicolons (;) 🎯 the moment the first command returns a non-zero exit status, the sequence breaks. done. over.

and finally: system_nosh is an almost drop-in replacement for the libc's system(3) 🌟 (system_execsqp and system_nosh are synonyms, so yes, they're the same girl.)


⭐ RETURN VALUE ⭐

these functions hand back the same return values as system(3) πŸ’« when you're running a sequence of commands, it returns the "wait status" of the first command that returns a non-zero value. and if the return value is zero? that means every single command in the sequence succeeded πŸ₯³ ate and left no crumbs.


πŸŽ€ EXAMPLE πŸŽ€

here's a whole little program showing off system_nosh πŸ“:

#include <stdio.h>
#include <unistd.h>
#include <execs.h>

#define BUFLEN 1024
int main(int argc, char *argv)
{
     char buf[BUFLEN];
     printf("type in a command and its arguments, e.g. 'ls -l'\n");
     while (fgets(buf, BUFLEN, stdin) != NULL) {
          printf("Command: '%s' \n",buf);
          system_nosh(buf);
          printf("Command done\n");
     }
}

πŸ”₯ SEE ALSO πŸ”₯


πŸ’€ BUGS πŸ’€

bug reports should be sent to <info@virtualsquare.org> β€” they're listening, fr fr 🫢


πŸ‘‘ AUTHOR πŸ‘‘

Renzo Davoli <renzo@cs.unibo.it> πŸ’œ


okay that's the whole page bestie ✨ one last thing: this masterpiece is a VirtualSquare joint, dated 2014-05-27, and you just read system_safe(3) 🌸 go forth and never spawn a shell again πŸ’…πŸ¦‹

πŸ“¦ where this page comes from