Why is system() hated so much?

Why do people say using system() is bad coding? I like using it to create "breaks" in my programs so you can press enter to continue and stuff that makes the program a little prettier. Is there an alternate I can be using?
system is not bad. System is insecure, which is 'bad' for programs that are widely distributed and could be targeted for hacking.
if you use system, a mean person can put a batch file or shell script or executable with the same name in the folder where your program executes from or in the path where it will look first and your code will run that program instead of the one you wanted to run.
for example, if you say system("cls") in windows to clear the screen, I can dump my virus into your folder named cls.exe and it will run my program.

this is done because the hacker may be able to write a new file but not execute programs (or modify existing files,etc), a fairly common permission setup on some servers.

then a user with good permissions comes along and runs your program, which then runs the hacker's program, getting around his lack of permissions...

system is just fine for school work, or personal utility programs. It is poor security and therefore poor coding to use it in professional software that is used by many people for a long lifespan and so on.

there are many alternates.
spawn, shellexecute, fork, exec, popen, createprocess (windows?) ... there are a bunch more, some specific to your OS/setup, some portable. Some of these are also just as vulnerable as the original system, so if you want security, you need to be proactive whether that means calling the correct thing via a path (eg instead say system("c:\windows\system64\cls.exe") ) or checking the target against a hash to ensure the target is the correct executable or other such ideas.
Last edited on
system() starts a new/separate process and then waits for that process to terminate. In fact, system() even starts a new shell process (e.g. cmd.exe on Windows, or bash on Linux) and then runs the specified command inside that new shell. This should always be your least favorite choice, compared to calling a "normal" function directly inside your program, or from one of the linked libraries (i.e. inside your current process).


There are a number of reasons to avoid system() whenever possible:

1. Performance: Starting a new sub-process (and especially a new shell) has a significant overhead.

2. Deployment: Using system() makes your application depend on "external" programs! You'll have to make sure that these programs will be available at runtime on the target machine, and that they behave as expected. That is quite a hassle and can easily go wrong. Better try to avoid such "external" dependencies!

3. Security: If you use a code like system("foo") in your program, but somehow a malicious foo.exe file sneaks into one of the directories listed in the user's PATH, then evil things will happen... 😨

4. Portability: According to the specs, the return value of system() "depends on the system and library implementations, but it is generally expected to be the status code returned by the called command, if supported." That is rather vague! If you really need to start a sub-process, use the exec() family of functions!
Last edited on
it does not make a new shell if you are IN one; else the constant cls and pause commands from most schools would not work. It DOES if you are in a gui program, and its terrible there. That is win behavior, not sure if linux does a new shell or not but I would think not?
Last edited on
system() does not necessarily open a new terminal. But – unlike the exec() family of functions – it runs the given command in the "command processor". This means that system("thingumabob") will not simply start a new "thingumabob[.exe]" process, but it rather starts a new shell sub-process – cmd.exe on Windows, or the default shell (e.g. bash) on Linux/Unix – and it passes the given command (e.g. "thingumabob") as a command-line argument to the shell process. In other words, the code system("thingumabob") effectively starts:

1
2
execl("cmd.exe", "cmd.exe", "/c", "thingumabob", NULL); /* <-- Windows */
execl("/bin/sh", "sh" "-c", "thingumabob", NULL);       /* <-- Linux/Unix */


That is also why shell built-in commands work with system(), but most certainly not with exec().

I think if used in a pure GUI program, then the command (shell) started by system() runs "invisibly" in the background. And, even worse, unlike with the popen() function, you won't even be able to read the child's standard output from the parent process. All output of the child process gets lost in the void...

________

For example, see the implementation of system() in the glibc (GNU C Library) used in most Linux systems:
https://github.com/bminor/glibc/blob/master/sysdeps/posix/system.c#L147

Effectively the implementation comes down to:
1
2
3
4
int system(const char *line)
{
    posix_spawn(&pid, "/bin/sh", /*...*/, { "sh, "-c", line, NULL });
} 
Last edited on
To help explain @kigar64451's comment, the black terminal screen you see on Microsoft Windows is a server called conhost.exe, to which console programs connect.
Last edited on
Topic archived. No new replies allowed.