Return value of system() function - c

#include<stdio.h>
#include<stdlib.h>
main()
{
printf("Hello World..\n");
system("ls");
}
Here...ON SUCCESSFUL execution system function returns the statys of "ls" command..and ON FAILURE it returns -1..
so can anyone help me to get this FAILURE condition for system function that gives return value as "-1"

The system function returns -1 if system itself fails, not if the command it invokes fails. For example, system returns -1 if the fork call fails. This can happen if your system is very short on resources, such as memory, or if your system imposes a limit on the number of processes you can run.
If the command fails (for example if you call system("false")), the value returned by system isn't simply the return value of the command; it's the value returned by the wait system call; man 2 wait for more information. (This assumes a Unix-like system; the behavior of system() on other operating systems differs.)
Of course if you want to see the value returned by a call to system, you'll need to store that value in a variable:
int result = system("ls");
You should read the documentation for the system function.
If you're trying to cause system to fail and return -1, one way to do it is to use it to invoke your program recursively. This can consume a lot of memory, and may interfere with your system. Do this only if you're the only person using the system, and you don't mind possibly interfering with its operation.
(Incidentally, the definition for main should be int main(void), not just main(), though that's not directly relevant. Prior 1999, omitting the return type would default to int; that's no longer permitted, but many compiler still support the old form. Empty parentheses do not specify the number of parameters; (void) explicitly says that there are no parameters, and is the preferred form.)

Related

How does the function pthread_yield work?

I am implementing a threads library in C and I am stuck on the meaning of pthread_yield(). I have looked it up on the man page in the terminal but I did not really understand the explanation. Could someone explain it to me?
Note well that its name notwithstanding, pthread_yield is not standardized. Its Linux manual page says this, for example:
This call is nonstandard, but present on several other systems. Use the standardized sched_yield(2) instead.
The specifications for sched_yield() are written in much the same terms as those of pthread_yield(), however:
The sched_yield() function shall force the running thread to relinquish the processor until it again becomes the head of its thread list. It takes no arguments.
This just means that the thread that calls the function allows other threads and processes a chance to run, waiting to resume until its turn comes again. It is not necessary to do this in a preemptive multitasking system such as pthreads is designed around -- the kernel manages assigning CPU time to threads and processes without any such help -- but there may occasionally be special cases where it smooths out thread scheduling issues.
In the GLIBC, pthread_yield merely invokes sched_yield() system call (cf. nptl/pthread_yield.c in the source tree of the library):
/* With the 1-on-1 model we implement this function is equivalent to
the 'sched_yield' function. */
int
pthread_yield (void)
{
return sched_yield ();
}
As you are implementing a thread library, note that the above GLIBC source code (2.31 version) of pthread_yield() results in an unusual pthread API behavior which may be an implementation bug as it returns directly the result of sched_yield(). Like most of the Linux system calls, the latter returns -1 and sets errno if it fails (even if the manual specifies that it actually never returns in error). So, theoretically, this makes pthread_yield() return -1 and set errno in case of error although the pthread API usually returns 0 if successful and the error number in case of error (errno is not supposed to be set). So, the manual is wrong or at least does not comply with the GLIBC's implementation when it describes the returned value as:
RETURN VALUE
On success, pthread_yield() returns 0; on error, it returns an error number.
The expected source code could be something like:
int
pthread_yield (void)
{
return sched_yield() == -1 ? errno : 0;
}
For example, pthread_sigmask() is coded as:
int
pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask)
{
[...]
return sigprocmask (how, newmask, oldmask) == -1 ? errno : 0;
[...]
}
which complies with what is stated in the manual:
RETURN VALUE
On success, pthread_sigmask() returns 0; on error, it returns an
error number.

How to tell if a call to system() has exited?

In C I wrote a code using system() to start another application , say abc.exe .Now how do I find if abc.exe has exited and when it has done so , I want to run another application, say xyz.exe .
system() is synchronous i.e. when it is done you simply get to the next instruction of your code, so basically it should be :
system("abc");
system("xyz");
also system returns the exit status of executed program, so if there is a dependency between programs and xyz can't be executed without successful execution of abc, you should check ret status of abc
if(system("abc") != -1 )
system("xyz");
Call the application after the first system(). System() is synchronous.
system("abc");
system("xyz");
Like anthropomorphic notice,
synchronous means that a call to system("abc") will only return after
"abc" is done.
You are able to verify the execution with the return value. Generally a non zero value is returned, if the program was not execute currently.
In many systems, 0 is used to indicate that the command was
successfully executed and other values to indicate some sort of error.
If command is a null pointer, the function returns a non-zero value in
case a command processor is available and a zero value if it is not.
If command is not a null pointer, the value returned depends on the
system and library implementations, but it is generally expected to be
the status code returned by the called command, if supported.
You can check whether system executed correctly by looking what it has returned to you. If it executed successfully, the return value will be zero (null pointer).
From C++ Reference:
If command is a null pointer, the function returns a non-zero value in case a command processor is available and a zero value if it is not.
If command is not a null pointer, the value returned depends on the system and library implementations, but it is generally expected to be the status code returned by the called command, if supported.

How do I explain 'main()'?

I'm creating a presentation on how to program in C, and since I'm fairly new to C, I want to check whether my assumptions are correct, and what am I missing.
Every C program has to have an entry point for the OS to know where to begin execution. This is defined by the main() function. This function always has a return value, whether it be user defined or an implicit return 0;.
Since this function is returning something, we must define the type of the thing it returns.
This is where my understand starts to get hazy...
Why does the entry point needs to have a return value?
Why does it have to be an int?
What does the OS do with the address of int main() after the program executes?
What happens in that address when say a segfault or some other error halts the program without reaching a return statement?
Every program terminates with an exit code. This exit code is determined by the return of main().
Programs typically return 0 for success or 1 for failure, but you can choose to use exit codes for other purposes.
1 and 2 are because the language says so.
For 3: Most operating systems have some sort of process management, and a process exits by invoking a suitable operating system service to do so, which takes a status value as an argument. For example, both DOS and Linux have "exit" system calls which accept one numeric argument.
For 4: Following from the above, operating systems typically also allow processes to die in response to receiving a signal which is not ignored or handled. In a decent OS you should be able to distinguish whether a process has exited normally (and retrieve its exit status) or been killed because of a signal (and retrieve the signal number). For instance, in Linux the wait system call provides this service.
Exit statuses and signals provide a simple mechanism for processes to communicate with one another in a generic way without the need for a custom communications infrastructure. It would be significantly more tedious and cumbersome to use an OS which didn't have such facilities or something equivalent.

In C, what is the limit for program return values? Or, what is causing this? [duplicate]

What does standard say about main return values range?
Say only up to 255?
Because
int main(void){
return 256;
}
echo $? ; # out 0
The standard doesn't say. 0, EXIT_SUCCESS and EXIT_FAILURE have (sort of) specified meanings. Anything else depends on the implementation.
At the present time, most Unix-based systems only support 8-bit return values. Windows supports (at least) a 32-bit return value. I haven't checked whether 64-bit Windows supports a 64-bit return value, but I rather doubt it, since even 64-bit Windows normally still uses a 32-bit int.
As others have stated, the C & C++ Standards don't constrain return values at all other than to state that
main() returns an int (which is of an implementation defined size), and
zero (or EXIT_SUCCESS) is a successful return and EXIT_FAILURE is a non-successful return.
It does specify that a main() that does explicitly not return a value is treated as if it had returned zero.
In this case, the interpretation of the return value is up to the process that waits on the process to complete (by calling wait(), waitpid(), or waitid()). wait() and waitpid() are the older POSIX functions and they specify that only the least significant eight bits of the return value shall be available to a waiting parent process. The POSIX:2008 standard added waitid() as a generalized wait method that has access to the full exit status of a child process.
After forking off a subprocess, the parent process calls one of the wait*() functions to sleep until the forked process is completed (e.g., returns from main(), calls exit() or abort() or something). The wait() and waitpid() functions return the status by way of a pointer to an integer. The caller extracts the actual exit status using the WIFEXITED(status_val) and WEXITSTATUS(status_val) macros. The latter is defined by POSIX and required to return the low-order 8 bits of the status argument. The waitid() function uses a pointer to a siginfo_t structure to return the process's status information. The si_status member contains the full status value as described in Status Information.
Basically, the values of the exit status are in the eye of the beholder. The ANSI/ISO specifications are open-ended. The POSIX suite has multiple ways to wait on a process to finish and fetch it's exit status. POSIX also defines spawn() as a lighter-weight version of exec() which has its own set of constraints on exit status values. Shells have a habit of further restricting result values -- GNU's bash limits the return status to 7 bits and a POSIX-compliant shell limits exit status values to 8 bits. FWIW, most people agree that restricting your return values to be lower than 64 seems to be safe.
Exit codes are a number between 0 and 255 inclusive on Unix like system. You can return anything but in Linux it's modded 256. Take a peek here for a good explanation on Linux return codes. There is also a Wikipedia article on the topic which talks breifly about exit codes for Windows.
The C standard do not impose particular limitation on exit codes, the paragraph about the return value of main delegates to the documentation about the exit() function, which in turn says:
If the value of status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned. If the value of status is EXIT_FAILURE, an implementation-defined form of the status unsuccessful termination is returned. Otherwise the status returned is implementation-defined.
which, apart from the EXIT_SUCCESS/EXIT_FAILURE guidelines, basically means "do whatever you want". :)
As said in one comment, the fact that on POSIX systems only the lower 8 bits of the exit code are actually considered is just a UNIXism, deriving from how the wait syscall is designed (the exit status has to be packed in the lower 8 bits of the wait return value), and has nothing to do with the C standard.
A counterexample is Windows, where the whole value passed to exit/return is considered (as long as it's not bigger than a DWORD1, but I don't think they'll ever make int be bigger than a DWORD, it would break a lot of code).
1. Because the GetExitCodeProcess parameter reserved for returning this value is a DWORD *.
On Unix, the wait system call sets a
status value of type int packed as a
bitfield with various types of child
termination information. If the child
terminated by exiting (as determined
by the WIFEXITED macro; the usual
alternative being that it died from an
uncaught signal), SUS specifies that
the lower 8 bits of the status value
contain the exit status; this can
be retrieved using the WEXITSTATUS
macro in wait.h. As such, on Unix
exit statuses are restricted to values
0-255, the range of an unsigned 8-bit
integer.
Unix like systems typically use a
convention of zero for success and non
zero for error. Some conventions
have developed as to the relative
meanings of various error codes; for
example GNU recommend that codes with
the high bit set be reserved for
serious errors, and FreeBSD have
documented an extensive set of
preferred interpretations.
C99 standard defines only 0 and 1. However, allows other values to be used.
See Exit Status wiki for more.
You return type int. You should be able to return any value that can be stored in an int. The exact size of an int is implementation-dependent, so I can't give you an exact range.
5.1.2.2.3 Program termination 1 If the return type of the main function is a
type compatible with int, a return
from the initial call to the main
function is equivalent to calling the
exit function with the value returned
by the main function as its argument;
10) reaching the } that terminates the
main function returns a value of 0. If
the return type is not compatible with
int, the termination status returned
to the host environment is unspeciļ¬ed
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
ie, there is no requirement for it to return anything. However it strongly states just up from that what the usual definitions are. Almost implying they are they standard, but has a get out of jail free card which means it can be anything.

What Happens when main() function does not return zero

Please consider the following Code:
#include <stdio.h>
int main()
{
int x;
printf ("\nEnter x: ");
scanf ("%d", &x);
return x;
}
Output:
$Enter x: -2
$echo $?
254
My Question is:
The OS knows that return value of main() by executing a process P (The above code under execution) is NON-ZERO.
Does the OS does any kind of Handling in such cases?
It has to be made clear what you are understanding by the "operating system" here.
If you look from the shell's point of view (which usually is just another userspace program anyway, and not a part of the kernel itself), the exit value of a process is used to evaluate the value of an expression and is important when doing shell programming as it is the most natural check one does after the termination of a process.
From the point of view of the kernel, the exit value of a process is largely dismissed. The kernel has to clean after the process regardless of the exit code it has returned.
The return value actually indicates the status of program completion. A non-zero value indicates the program has been terminated abnormally. The status may be used by used by other programs, so it is always a good practice to return the actual status.
Normally, when the program executes "expectedly" we return 0. If it does something it should not, we return non-zero depending upon the type of error (For this you can refer to errno manual). Now this return value is received by the "shell" under which the program was running. This return value can be accessed using "$?" in BASH. So it is purely for user's accessibility for a program ( that it ran correctly, and if not what is the error). This return value then can be used in shell scripts, etc., to make decisions whether to rerun or whatever the admin wants to do.
The kernel just cleans the user-land program.

Resources