System()

Pages: 12
Everybody says "Dont use system()" can you tell me why?
Last edited on
Good question but what other way can input be sent to the OS for a command like copy
Since it is OS dependent, for one example, to clear the screen for Windows (https://msdn.microsoft.com/en-us/library/windows/desktop/ms682022%28v=vs.85%29.aspx ), I use:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void ClearScreen(int xCoord, int yCoord) 
{
	HANDLE                     hStdOut;
	CONSOLE_SCREEN_BUFFER_INFO csbi;
	DWORD                      count;
	DWORD                      cellCount;
	COORD                      homeCoords = { xCoord, yCoord };

	hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
	if (hStdOut == INVALID_HANDLE_VALUE) return;

	/* Get the number of cells in the current buffer */
	if (!GetConsoleScreenBufferInfo(hStdOut, &csbi)) return;
	cellCount = csbi.dwSize.X *csbi.dwSize.Y;

	/* Fill the entire buffer with spaces */
	if (!FillConsoleOutputCharacter(
		hStdOut,
		(TCHAR) ' ',
		cellCount,
		homeCoords,
		&count
		)) return;

	/* Fill the entire buffer with the current colors and attributes */
	if (!FillConsoleOutputAttribute(
		hStdOut,
		csbi.wAttributes,
		cellCount,
		homeCoords,
		&count
		)) return;

	/* Move the cursor home */
	SetConsoleCursorPosition(hStdOut, homeCoords);
}


Then, I use it on something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
do
{
	displayTitle();

	while (salida == false)
	{

		if (GetAsyncKeyState(VK_RETURN))
		{
			salida = true;
			ClearScreen(0, 0); //CLEAR SCREEN
			cin.ignore();
			cin.clear();
			displayMainMenu();
		}

		else if (!GetAsyncKeyState(VK_RETURN))
		{
			// Do something else
		}

	}

	ClearScreen(0, 0); // CLEAR SCREEN.
}


For Linux, Mac and etc. will be other methods to clear the screen without using system("cls")
Good question but what other way can input be sent to the OS for a command like copy


You can use filesystem::copy if your compiler supports it.

Otherwise, boost::filesystem is good.

If you want to interact with your OS directly, look up the API; for example:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa363851(v=vs.85).aspx


or just do it yourself:
1
2
3
4
5
6
7
8
9
#include <fstream>
#include <ios>

int main() {
std::ifstream infile("input.dat", std::ios_base::binary);
std::ofstream outfile("output.dat", std::ios_base::binary);

outfile << infile.rdbuf();
}

Usually people say using system is bad is because they heard other people say it's bad, and that's pretty funny fact how majority drives the rules.

just because somebody says it's bad does not mean that it is indeed bad.

for example:

1
2
3
4
5
6
7
8
9
10
11
#include <cstdlib>

void clear_screen()
{
#ifdef _MSC_VER
    std::system("cls");
#elif defined(__GNUC__)
    std::system ("clear");
#endif
// TODO: implement functionality for other systems.
}


seriously, what's so bad here? few more lines and you have almost portable code.
Last edited on
std::system() is not bad (and certainly not evil).

Though, in a program where software security is important, it has to be used with care.

Use of the system() function can result in exploitable vulnerabilities, in the worst case allowing execution of arbitrary system commands. 
Situations in which calls to system() have high risk include the following: 

    . When passing an unsanitized or improperly sanitized command string originating from a tainted source
    . If a command is specified without a path name and the command processor path name resolution mechanism is accessible to an attacker
    . If a relative path to an executable is specified and control over the current working directory is accessible to an attacker
    . If the specified executable program can be spoofed by an attacker

https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=2130132
std::system() is not vulnerable if we use it correctly; sanitise the shell execution environment, sanitise the command string, drop elevated privileges, and make sure that the command that we are executing cannot be spoofed.

Doing all this is somewhat hard, so this is sane advice:
"In a security concious program, do not call std::system() if another good alternative is available."

For instance, to copy a text file, favour
std::ofstream(dest_file_path) << std::ifstream(srce_file_path).rdbuf() ;
over calling std::system().
As well as the massive, gaping security problem with system that JLB pointed out (surrendering control of your program to other programs over which you have no control is never going to win security awards), it's also massively expensive. Blah blah premature optimisation blah blah; don't care. It's massively expensive and not necessary; particularly for simple procedures like copying a file.

I've also coded C++ for systems that don't have a command processor. I've no idea what calling system would have done on those, but I bet it isn't good.
Last edited on
seriously, what's so bad here? few more lines and you have almost portable code.
It assumes you're using Visual Studio to compile your Windows version and GCC to compile the Terminal version. That's the typical crap I run into with much Open Source software.
@kbw
probably because much of open source software tends to be cross platform, the only thing I hate is that the code becomes too ugly for my taste.

I assume by "crap" you mean the same but how else can one achieve portability? except maybe using cross platform library which does the same thing but hides the ugly code.
I think JLBorgers made a very good point.

std::system() is not bad (and certainly not evil).
Though, in a program where software security is important, it has to be used with care.


If I have to write a program for a client I probably would not use it. However I assume that most of the people here will write programs for their own use or for school / university assignments and it should therefore not be a problem.
I assume by "crap" you mean the same but how else can one achieve portability?


There is, of course, a balance to be found. In some cases, however, one can achieve "perfect" portability by using standard C++ to achieve the same goal. For example, to copy a file, do not call the local shell's file copy command. Instead, use C++ to copy the file.
I assume by "crap" you mean ...
By crap, I mean, "doesn't work in all cases".

I've spent weeks on Ruby Version Manager, trying to get git integration to work, only to find not all features worked if you weren't on master.

There are many other instances where features work for the case that interested the developer, and it's published as a working feature. It's waste of everyone else's time; simply put, crap.

Another example, the way the time it takes for Linux to startup a new process in not linear. I think it's O**2 or something close. Things like that are really irksome, especially when you see Solaris, FreeBSD, ... being linear in this sort of thing.

Ever tried killing a really busy process on a really busy Linux box? You'll wait your turn like everyone else. Irksome.

I didn't mean to be offensive about your solutiuon, I just got a flood of bad memories that aren't your fault. But your solution is very special case and incomplete. It leads to the sort of problem I've been describing.

My apologies, but sometimes when something has a reputation for being bad, it really is.
Last edited on
@Moschops
Instead, use C++ to copy the file
.

How would copy files using just C++ code that is not OS dependent
@andrewllewop
maybe:
1
2
std::ifstream
std::ofstream


@kbw
no, no offense at all.
"not working in all cases" scenario it's nothing uncommon.
Last edited on
closed account (E0p9LyTq)
Most uses of system() are done by people coding for Windows, without realizing that MS is moving away from the C Runtime.

This API (system/_wsystem) cannot be used in applications that execute in the Windows Runtime.

https://msdn.microsoft.com/en-us/library/277bwbdz.aspx
@andrewllewop

If you read back over the thread, you'll see C++ code to copy a file has already been written in an earlier post
There are APIs that allow for easier cross-platform control over a terminal. For instance, you can use a curses implementation that works on both Windows and Linux.

For file management, you can use Boost Filesystem.

I'm not too fond of the idea that people think something is hard to abstract just because its not in the standard set of libraries.

Use of system is a bad idea. There are generally always better ways to do something. If you really need to execute a second executable, use something like Boost Process, POCO, and I think even Qt. Alternatively, it's not hard to abstract the safer method of spawning a process between platforms. It's generally less than 100 lines of code as a matter of fact.

Only time I think you should justify using system is if you plan on never distributing that piece of software.
Last edited on
Only time I think you should justify using system is if you plan on never distributing that piece of software.


And nobody else can touch your hardware. I once had the bad habit of altering programs that people might call using system.
Just as standalone executables can be spoofed, libraries too can be spoofed. For that matter, the C++ compiler can be spoofed; IDEs can be spoofed.

If anything in /bin/, /sbin/, /usr/bin, /usr/lib etc. can be spoofed, from a security standpoint, every user of that system is already dead. If std::system( "/usr/bin/clear" ) ; is an exploitable vulnerability, invoking /usr/local/bin/g++ or linking with a library in /usr/local/lib would also be an exploitable vulnerability.

The fundamental requirement for any secure coding is that the core of the system on which the program runs is not compromised.
Pages: 12