All,
I want to develop an exit handler in my program.
I'm really new to C; is it all about managing signals in C?
How do I know if my program ended in a good way or not?
If not, how do I get the maximum information when exiting?
C (C89 and C99 standards) provides atexit() to register function to be called when the program exits. This has nothing to do with signals. Unlike signal handlers, you can register multiple exit handlers. The exit handlers are called in reverse order of how they were registered with atexit().
The convention is that when program exits cleanly it returns exit status 0. This can be done by return 0 from main() or exit(0) from anywhere in your program.
In Unix/Linux/POSIX type operating system (not sure of Windows), the parent process get exit status information about the child process using wait() system call or its variants.
Example: Here is a simple program and its output to demonstrate atexit():
#include <stdlib.h>
#include <stdio.h>
static void exit_handler1(void)
{
printf("Inside exit_handler1()!n");
}
static void exit_handler2(void)
{
printf("Inside exit_handler2()!n");
}
int main(int argc, char *argv[])
{
atexit(exit_handler1);
atexit(exit_handler2);
return 0;
}
Output generated by the program:
Inside exit_handler2()!
Inside exit_handler1()!
Look here you will find all what you want:
http://www.cplusplus.com/reference/cstdlib/exit/
I added a new link here take a look:
Exception libraries for C (not C++)
If i am not get wrong you ask about giving back results from program when exiting. You should use exit(x); function to return value from your program. You can put any integer value as parameter x. And dont forget to use #include <stdlib.h> in your program start.
Related
This question already has an answer here:
Getting output of a system command from stdout in C
(1 answer)
Closed 4 years ago.
I just learned C and fascinates with pointers. Recently I discovered C function system(). I am able to get return values from a program I executed via system ("program.exe"). Eg, program.c:
#include <stdio.h>
int main(){
printf("hello world\n");
return 123;
}
and this code calls program.exe, called call.c
#include <stdio.h>
#include <stdlib.h>
int main(){
int a;
printf("calling program.exe:\n");
a=system("program.exe");
printf("program.exe returned %d at exit\n",a);
return 0;
}
When I execute call.exe, I get this
calling program.exe:
hello world
pm returned 123 at exit
I was like, wow! This return value and system() function thing is like a new way to interprocess communication for me. But my question is, can I get a string return from the system() function?
Ii tried changing program.c "int main()" to "char * main()", and return 123 to return "bohemian rhapsody" and change "int a;" to "char *a;", printf format %d to %s in call.c, but I only get funny characters when I execute call.exe. I wonder what's wrong?
No you can't return a string from system(), and indeed a program under most modern desktop operating systems can only "return" an integer exit code when it terminates.
If you do want to get a string back from the executed program, one way would be to use popen() to invoke the program, and then have that program write the string to stdout.
The program that you call 'call.c' calls system(3), which does the following,
suspends the current process,
starts a child process,
and waits for the child process to complete
The return value from the called process, 'program.c/exe' is an integer (size is system dependent usually 16-bit), and what is happening behind the scenes is that the system(3) call uses the wait(2) call to (blocking) suspend execution until the child process returns.
Note that the string is not returned, but the child process prints to stdout. See the popen(3) call if you want to obtain the string (or binary) output from the child process.
See the manual page for wait(3) to see how to process the results returned by the called program, e.g. 'man -s2 wait',
WAIT(2) System Calls Manual WAIT(2)
NAME
wait, wait3, wait4, waitpid -- wait for process termination
SYNOPSIS
#include <sys/wait.h>
pid_t
wait(int *stat_loc);
pid_t
wait3(int *stat_loc, int options, struct rusage *rusage);
pid_t
wait4(pid_t pid, int *stat_loc, int options, struct rusage *rusage);
pid_t
waitpid(pid_t pid, int *stat_loc, int options);
Some time ago I found this exercise in C: without changing the main function, so that receiving a SIGUSR1 signal output is directed and added to a file in append mode as the first parameter. At the reception of another SIGUSR1 the output is directed to the console, and so on. How do such an exercise?
#include <stdio.h>
#include <time.h>
void redirectsetup (char *s){
}
int main (int argc, char *argv[]){
redirect setup(argv[1]);
while(1){
time_t now = time(NULL);
printf("%s",ctime(&now));
sleep(1);
}
}
I'll give you some general pointers.
You need to install a signal handler. Try typing man signal or googling "signal handler linux". As a rule your signal handler should do the minimum possible, many things are illegal in signal handlers including much of the C library. In this case, you could have it set a variable which tells you where to direct output and leave it at that.
Your main program needs to loop, sending characters to wherever the variable tells it.
One thing you might need to be careful of is a signal interrupting a system call, requiring it to be retried.
Have a go and see if you can make it work.
I am a newbie in Linux programming.I copied the code below from a book:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void ouch (int sig)
{
printf("OUCH! - I got signal %d\n", sig);
(void) signal(SIGINT, SIG_DFL);
}
int main ()
{
(void) signal(SIGINT, ouch);
while(1)
{
printf("Hello World!\n");
sleep(1);
}
}
It was expected to print something when Ctrl+C was entered.But it do nothing but print Hello World!.
EDIT:
I am so sorry that I have binded the Ctrl+C as a short-cut key for copy.
Sorry for trouble caused.
My Suggestion is don't use printf in siginal handler (ouch), it may be undefined behavior. Async-signal-safe functions: The list of safe functions that can be call in signal handler man page.
It is not safe to call all functions, such as printf, from within a signal handler.
A useful technique is to use a signal handler to set a flag and then check that flag
from the main program and print a message if required.
Reference: Beginning Linux Programming, 4th Edition,In this book exactly your code is explained, Chapter 11: Processes and Signals, page 484
An additional helpful link:
Explanation: Use reentrant functions for safer signal handling
Sorry, I can't see a question here... but I can guess what you are interested in.
printf() is a stateful function, thus not reentrant. It uses a FILE structure (variable name is 'stdin') to keep it's state. (It is like calling fprintf(stdin,format,...)).
That means, dependant on implementation and 'luck', calling printf() from a signal handler may print what you expect, but also may print nothing or may even crash or worse, smash your memory! Anything could happen.
So, just don't call functions from within a signal handler that are not explicitely marked 'signal-safe'. You will avoid lot's of headaches in the long term.
Put an fflush(stdout) in your signal handler. It was just buffered, then the second SIGINT exited the program before the buffer could be flushed.
I am working on an assignment where I am implementing the unix history command in a shell. In my program I have written a signal handler for SIGINT. When a user enters (ctrl)(c) their history is displayed.
When my program terminates I need to store the history in a file. Is there an easy way to detect when my program has exited? Or do I need to have a signal handler for every type of signal ((ctrl)(d), pausebreak, etc).
atexit() is probably what you're looking for, see the manual page: man 3 atexit
Usage is something like:
#include <stdlib.h>
static void save_the_file(void)
{
/* ... */
}
int main()
{
atexit(save_the_file);
return 0;
}
Another option is to use the destructor attribute (GCC/Clang):
static __attribute__((destructor)) void save_the_file(void)
{
/* your code */
}
atexit is that. But if you want to follow SIGKILL also, you need watcher-process that call waitpid().
What is difference between return and exit statement in C programming when called from anywhere in a C program?
return returns from the current function; it's a language keyword like for or break.
exit() terminates the whole program, wherever you call it from. (After flushing stdio buffers and so on).
The only case when both do (nearly) the same thing is in the main() function, as a return from main performs an exit().
In most C implementations, main is a real function called by some startup code that does something like int ret = main(argc, argv); exit(ret);. The C standard guarantees that something equivalent to this happens if main returns, however the implementation handles it.
Example with return:
#include <stdio.h>
void f(){
printf("Executing f\n");
return;
}
int main(){
f();
printf("Back from f\n");
}
If you execute this program it prints:
Executing f
Back from f
Another example for exit():
#include <stdio.h>
#include <stdlib.h>
void f(){
printf("Executing f\n");
exit(0);
}
int main(){
f();
printf("Back from f\n");
}
If you execute this program it prints:
Executing f
You never get "Back from f". Also notice the #include <stdlib.h> necessary to call the library function exit().
Also notice that the parameter of exit() is an integer (it's the return status of the process that the launcher process can get; the conventional usage is 0 for success or any other value for an error).
The parameter of the return statement is whatever the return type of the function is. If the function returns void, you can omit the return at the end of the function.
Last point, exit() come in two flavors _exit() and exit(). The difference between the forms is that exit() (and return from main) calls functions registered using atexit() or on_exit() before really terminating the process while _exit() (from #include <unistd.h>, or its synonymous _Exit from #include <stdlib.h>) terminates the process immediately.
Now there are also issues that are specific to C++.
C++ performs much more work than C when it is exiting from functions (return-ing). Specifically it calls destructors of local objects going out of scope. In most cases programmers won't care much of the state of a program after the processus stopped, hence it wouldn't make much difference: allocated memory will be freed, file ressource closed and so on. But it may matter if your destructor performs IOs. For instance automatic C++ OStream locally created won't be flushed on a call to exit and you may lose some unflushed data (on the other hand static OStream will be flushed).
This won't happen if you are using the good old C FILE* streams. These will be flushed on exit(). Actually, the rule is the same that for registered exit functions, FILE* will be flushed on all normal terminations, which includes exit(), but not calls to _exit() or abort().
You should also keep in mind that C++ provide a third way to get out of a function: throwing an exception. This way of going out of a function will call destructor. If it is not catched anywhere in the chain of callers, the exception can go up to the main() function and terminate the process.
Destructors of static C++ objects (globals) will be called if you call either return from main() or exit() anywhere in your program. They wont be called if the program is terminated using _exit() or abort(). abort() is mostly useful in debug mode with the purpose to immediately stop the program and get a stack trace (for post mortem analysis). It is usually hidden behind the assert() macro only active in debug mode.
When is exit() useful ?
exit() means you want to immediately stops the current process. It can be of some use for error management when we encounter some kind of irrecoverable issue that won't allow for your code to do anything useful anymore. It is often handy when the control flow is complicated and error codes has to be propagated all way up. But be aware that this is bad coding practice. Silently ending the process is in most case the worse behavior and actual error management should be preferred (or in C++ using exceptions).
Direct calls to exit() are especially bad if done in libraries as it will doom the library user and it should be a library user's choice to implement some kind of error recovery or not. If you want an example of why calling exit() from a library is bad, it leads for instance people to ask this question.
There is an undisputed legitimate use of exit() as the way to end a child process started by fork() on Operating Systems supporting it. Going back to the code before fork() is usually a bad idea. This is the rationale explaining why functions of the exec() family will never return to the caller.
I wrote two programs:
int main(){return 0;}
and
#include <stdlib.h>
int main(){exit(0)}
After executing gcc -S -O1. Here what I found watching
at assembly (only important parts):
main:
movl $0, %eax /* setting return value */
ret /* return from main */
and
main:
subq $8, %rsp /* reserving some space */
movl $0, %edi /* setting return value */
call exit /* calling exit function */
/* magic and machine specific wizardry after this call */
So my conclusion is: use return when you can, and exit() when you need.
In C, there's not much difference when used in the startup function of the program (which can be main(), wmain(), _tmain() or the default name used by your compiler).
If you return in main(), control goes back to the _start() function in the C library which originally started your program, which then calls exit() anyways. So it really doesn't matter which one you use.
For the most part, there is no difference in a C program between using return and calling exit() to terminate main().
The time when there is a difference is if you've created code that will be executed after you return from main() that relies on variables local to main(). One way that manifests itself is with setvbuf():
int main(void)
{
char buffer[BUFSIZ];
setvbuf(stdout, buffer, _IOFBF, BUFSIZ);
…code using stdout…
return 0;
}
In this example, the buffer provided via setvbuf() goes out of scope when main() returns, but the code that flushes and closes stdout will be attempting to use that buffer. This leads to undefined behaviour.
The other mechanism is to invoke atexit() with a function that accesses data from main() — via a pointer. This is harder to set up as the functions called via the atexit() mechanism are not given any arguments. So, you have to do something like this:
static void *at_exit_data = 0;
static void at_exit_handler(void)
{
char *str = at_exit_data;
printf("Exiting: %s\n", str);
}
int main(void);
{
char buffer[] = "Message to be printed via functions registered with at_exit()";
at_exit_data = buffer;
at_exit(at_exit_handler);
…processing…
return 0;
}
Again, the buffer pointed at by at_exit_data has ceased to exist when the program returned from main() and so the handler function invokes undefined behaviour.
There is a related function, at_quick_exit(), but the functions registered with it are only called if the quick_exit() function is called, which precludes the functions being called after main() returns.
the return statement exits from the current function and exit() exits from the program
they are the same when used in main() function
also return is a statement while exit() is a function which requires stdlb.h header file