system function flaws - c

We are using C in Linux. Is there any possibility that system() function can behave in an unexpected manner, especially when we handle signals?
We found that sometimes, the system() function blocks the execution or it throws SIGSEGV.
e.g:
system ( "/bin/mv a b" );
Are there any known flaws in using system() that would explain this?

The system() function does what it is supposed to do perfectly well. The behaviour is pretty reliable as long as it is invoked correctly. It has two modes of operation:
Check whether there is a command interpreter available - when the argument is a null pointer.
Run the command given, waiting for the command to complete before returning.
So, the system() statement blocks until the shell that runs the command completes. On Unix-like systems, the command invoked is effectively:
"sh", "-c", "...argument to system...", NULL
This means that the string passed is interpreted by the shell. How long that takes depends on the command that is executed. You can consider using the shell notations to run the command in background if you need to:
system("( /bin/mv a b & )");
There are few circumstances where system() will itself generate SIGSEGV. You would have to pass it an invalid pointer, a pointer to somewhere invalid in the program.

The system() call is supposed to block until execution is finished. If it takes an hour to move a to b, the process or thread calling system() will block for an hour. Knowing this, strange behavior can be explained.
If you expect system() to return immediately, it probably means that you expect code that runs after calling it to have been entered by the time you see the strange behavior. It is very likely that, due to system() taking longer than expected, some area of memory wasn't allocated or initialized. This is likely the cause of the segmentation fault when another thread or process tried to access it.
In other words, if you didn't expect system() to block, you probably assumed that code coming after it would run much sooner than it actually did.
Debunking that would be a topic for another question. The answer to this one is no, you aren't seeing flaws in the system() function, it is behaving exactly as expected.

Related

what exactly return 0 does internally in a c program?

I came to know that while writing a c program we write "return 0" to tell the os that the program is executed successfully. My question is how can we tell the os while writing the program itself without even executing the program that the program had executed successfully. Can someone tell me what exactly "return 0" does.
The return value of the main function is passed to the exit() function by the C startup code, providing the OS an exit status available to its parent process.
The OS itself does not do anything with this exit status, but shell scripts and other programs invoking multiple processes may use the exit status to determine what to do next. For example the make utility uses the exit status of the commands, eg: when invoking the C compiler, to proceed with the next command or stop the build process with an error status.
Returning 0 or EXIT_SUCCESS at the end of the main function is a convention to tell the calling process that the program completed successfully. It has become implicit in C99 so legacy programs that do not have a return statement can be considered to have completed successfully when recompiled with a C99 compiler. Nevertheless, it is considered good style to provide the exit status explicitly.
return 0 means returning the integer value 0 from a function, which is generally done inside a program.
You are referring to exit(0), which means that you stop a program successfully. Generally, when you do exit(i) with i an integer value, then that i value is the error code, explaining what happened wrongly. More information can be found here.
Once you finish writing your code and compiling it you could execute it wherever you want correct?
Once it is finished executing that piece of software you made will return a number (in your example zero).
In most cases that do absolutely nothing because there is nobody actively looking for that return code.
But you might find yourself in situations where you want to execute that software in an automated environment or something like that. let's say a script, that calls your software, and if everything goes ok, it goes on to do something else, but if it is not ok it tries again. That script or other software that is calling your first software has the power to read and interpret that return.
You can also do that manually to actually see that a certain software return code is:
Windows:
open cmd
run the software
run echo Return Code: %errorlevel%
Linux:
open terminal
run software
run echo Return Code: $?
Those pre-defined variables will give you the value your last command returned and you can do something about it.
By convention (as mentioned before) 0 means that everything was ok, and anything other than that indicates that there has been an error. If you write your code with multiple error checks, and when something goes wrong return different values. you will know straight away what went wrong with your execution.

Execute programs out of C

I´m trying to get some values displayed on an eInk-Display (via SPI). I already wrote the software to initialize the display and display the values passed as command-line arguments. The problem is, because of the eInk-technology it takes a few seconds for the display to have fully actualized, so the display-program is also running for this time.
The other ("Master"-) program collects the values and does other stuff. It has a main loop, which has to be cycled through at least 10x/second.
So I want to start the displaying program from within the main loop and immediately continue with the loop.
When using system() or execl(), the Master-program either waits till the display program is finished or exits into the new process.
Is there a way to just start other programs out of other ones without any further connection between them? It should run on Linux.
May fork() be a solution?
quick and dirty way: use system with a background suffix (&)
char cmd[200];
sprintf("%190s &","your_command");
system(cmd);
note that it's not portable because it depends on the underlying shell. For windows you would do:
sprintf("start %190s","your_command");
The main drawback of the quick & dirty solution is that it's "fire & forget". If the program fails to execute properly, you'll still have a 0 return code as long as the shell could launch the process.
A portable method (also allowing to take care of the return code of the process) is slightly more complex, involving running a system call from a thread or a forked executable. The quick & dirty solution does a fork + exec of a shell command behind the scenes.

exit() function in C — what happens if we do not write this?

I have seen many posts regarding this question. Many say that exit(EXIT_SUCCESS) should be called for successful termination, and exit(EXIT_FAILURE) for unsuccessful termination.
What I want to ask is: What if we do not call the exit() function and instead what if we write return 0 or return -1? What difference does it make?
What happens if successful termination does not happen? What are its effects?
It is told that if we call exit() functions the program becomes portable --
"portable" in the sense what? How can one function make the entire code portable?
It is told that the execution returns to the parent what happens if the execution does not return to the parent?
My questions may seem to be silly but I need answers for all of these to get rid of my ambiguity between return and exit.
Return returns a value from a function. Exit will exit your program. When called within the main function, they are essentially the same. In fact, most standard libc _start functions call main and then call exit on the result of main anyway.
Nothing, directly. The caller (usually your shell) will get the return value, and be able to know from that whether your program succeeded or not.
I don't know about this. I don't know what you mean here. exit is a standard function, and you may use it if you wish, or you can decide not to. Personally, I prefer to return from main only, and only return error status from other functions, to let the caller decide what to do with it. It's usually bad form to write an API that kills the program on anything but an unrecoverable error that the program can't manage.
If execution didn't return to the parent (which is either a shell or some other program), it would just hang forever. Your OS makes sure that this doesn't happen in most ordinary cases.

Shellcode: perform 2 execve() calls

I am trying to write shellcode in assembly. I need to perform a /usr/bin/killall command AND a /usr/bin/wget command. I have both commands running perfectly in shellcode with the execve() syscall. But now I want to combine these 2, but this is not possible because the program exits when the first execve() call is executed. (from the man pages of execve() : execve() does not return on success).
How can I perform 2 execve() calls? Or is there another way to call both /usr/bin/killall and /usr/bin/wget from the same shell code?
Greets and thanks in advance!
When you use the exec-family of functions, the program you call it with is substituted into the current process. So when the first execve-call is made, your entire process image disappears, and thus second call is never made. To get around this you must fork another process before calling execve.
First of all, it is not possible to execute two execve() one after the other. Simply because, by definition, the execve() call will override the memory of the original process with the new one and you will never be able to switch back to the original process again.
The second option that you propose (merging /usr/bin/killall and /usr/bin/wget into the shellcode) is perfectly possible if the killall command is not killing the process executing the shellcode itself. If it is the case, I really need more information about why is this behavior is needed because it seems a bit absurd to me (but I certainly miss the context in which you are running your shellcode).

What's the purpose of exit(0) ?

I understand that exit(1) indicated an error , for example :
if (something went wrong)
exit(EXIT_FAILURE);
But what's the purpose of using exit(EXIT_SUCCESS); ?
When handling with processes maybe ? e.g. for fork() ?
thanks
This gives the part of the system that invokes the program (usually the command shell) a way to check if the program terminated normally or not.
Edit - start -
By the way, it is possible to query the exit code of an interactive command as well through the use of the $? shell variable. For instance this failed ls command yields an exit code of value 2.
$ ls -3
ls: invalid option -- '3'
Try `ls --help' for more information.
$ echo $?
2
Edit - end -
Imagine a batch file (or shell script) that invokes a series of programs and depending on the outcome of each run may choose some action or the other. This action may consist of a simple message to the user, or the invocation of some other program or set of programs.
This is a way for a program to return a status of its run.
Also, note that zero denotes no problem, any non-zero value indicates a problem.
Programs will often use different non-zero values to pass more information back (other than just non-normal termination). So the non-zero exit value then serves as a more specific error code that can identify a particular problem. This of course depends on the meanings of the code being available (usually/hopefully in the documentation)
For instance, the ls man page has this bit of information at the bottom:
Exit status is 0 if OK, 1 if minor problems, 2 if serious trouble.
For Unix/Linux man pages, look for the section titled EXIT STATUS to get this information.
you can only exit your program from the main function by calling return. To exit the program from anywhere else, you can call exit(EXIT_SUCCESS). For example, when the user clicks an exit button.
It's a system call. There's always good information on system calls if you check the man pages:
http://linux.die.net/man/3/exit
On a Linux box, you can simply type man exit into a terminal and this information will come up.
There are two ways of 'normally' exiting a program: returning from main(), or calling exit(). Normally exit() is used, and thought of, for signalling a failure. However, if you are not in main(), you must still exit somehow. exit(0) is usually used to terminate the process when not in main().
main() is actually not a special function to the operating system, only to the runtime environment. The 'function' that actually gets loaded is normally defined as _start() (this is handled by the linker, and beyond the scope of this answer), written in assembly, which simply prepares the environment and calls main(). Upon return from main(), it also calls exit() with the return value from main().

Resources