EXIT_SUCCESS & EXIT_FAILURE constants / _exit
authorgumartinm <gu.martinm@gmail.com>
Sun, 23 Dec 2012 19:15:17 +0000 (20:15 +0100)
committergumartinm <gu.martinm@gmail.com>
Sun, 23 Dec 2012 19:15:17 +0000 (20:15 +0100)
About _exit: I do not think I really need to use _exit but anyway it seems to me like it does not hurt me so... Let's do it in the right way!!!

From: http://www.unixguide.net/unix/programming/1.1.3.shtml / http://stupefydeveloper.blogspot.com.es/2009/01/c-to-exit-or-to-exit.html

There are a few differences between exit() and _exit()
that become significant when fork(), and especially
vfork(), is used.

The basic difference between exit() and _exit() is that
the former performs clean-up related to user-mode constructs in the
library, and calls user-supplied cleanup functions, whereas the latter
performs only the kernel cleanup for the process.

In the child branch of a fork(), it is normally incorrect to use
exit(), because that can lead to stdio buffers being flushed
twice, and temporary files being unexpectedly removed. In C++ code the
situation is worse, because destructors for static objects may be run
incorrectly. (There are some unusual cases, like daemons, where the
parent should call _exit() rather than the child; the
basic rule, applicable in the overwhelming majority of cases, is that
exit() should be called only once for each entry into
main.)

In the child branch of a vfork(), the use of exit() is
even more dangerous, since it will affect the state of the parent
process.

Daemon/javafork.c

index 7b0602d..7d0a42b 100644 (file)
@@ -585,25 +585,25 @@ int fork_system(int socket, unsigned char *command, int *returnstatus)
         if (sigemptyset(&unBlockMask) < 0) {
             syslog (LOG_ERR, "Unblock SIGCHLD empty mask: %m");
             /*Going to zombie state, hopefully waitpid will catch it*/
-            exit(-1);
+            _exit(EXIT_FAILURE);
         }
         if (sigaddset(&unBlockMask, SIGCHLD) <0) {
             syslog (LOG_ERR, "Unblock SIGCHLD sigaddset mask: %m");
             /*Going to zombie state, hopefully waitpid will catch it*/
-            exit(-1);
+            _exit(EXIT_FAILURE);
         }
         /*Should I use pthread_sigmask?*/
         if (sigprocmask(SIG_UNBLOCK, &unBlockMask, NULL) == -1) {
             syslog (LOG_ERR, "Unblock sigprocmask failed: %m");
             /*Going to zombie state, hopefully waitpid will catch it*/
-            exit(-1);
+            _exit(EXIT_FAILURE);
         }
 
         /*Attach stderr and stdout streams to my pipes (their write end)*/
         if ((TEMP_FAILURE_RETRY(dup2(out[1], 1)) < 0) || (TEMP_FAILURE_RETRY(dup2(err[1], 2)) < 0)) {  
             syslog (LOG_ERR, "child dup2 failed: %m");
             /*Going to zombie state, hopefully waitpid will catch it*/ 
-            exit(-1);
+            _exit(EXIT_FAILURE);
         }
 
 
@@ -611,13 +611,14 @@ int fork_system(int socket, unsigned char *command, int *returnstatus)
         /*During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT*/
         /* will be ignored. From man system(3)*/
         /*Attention: warning about signedness. I guess it does not hurt me.*/
+        /*TODO: usar para el retorno de system una variable local mejor que la variable compartida????*/
         *returnstatus=system(command);
         if (WIFEXITED(returnstatus) == 1)
             (*returnstatus) = WEXITSTATUS(*returnstatus);
         else
             (*returnstatus) = -1;
         /*Going to zombie state, hopefully waitpid will catch it*/
-        exit(0);
+        _exit(EXIT_SUCCESS);
     }
     else {
         /*Parent process*/
@@ -745,7 +746,7 @@ void sigint_handler(int sig)
      */
     if (sigaction(SIGINT, &sigintAction, NULL) < 0) {
         syslog (LOG_ERR, "SIGINT restore signal handler failed: %m");
-        exit (1);
+        exit (EXIT_FAILURE);
     }
     kill(getpid(), SIGINT);
 }