exit(), abort() and assert()

exit()

filter_none

edit
close

play_arrow

link
brightness_4
code

void exit ( int status ); 

chevron_right


exit() terminates the process normally.
status: Status value returned to the parent process. Generally, a status value of 0 or EXIT_SUCCESS indicates success, and any other value or the constant EXIT_FAILURE is used to indicate an error. exit() performs following operations.
* Flushes unwritten buffered data.
* Closes all open files.
* Removes temporary files.
* Returns an integer exit status to the operating system.

The C standard atexit() function can be used to customize exit() to perform additional actions at program termination.



Example use of exit.

filter_none

edit
close

play_arrow

link
brightness_4
code

/* exit example */
#include <stdio.h>
#include <stdlib.h>
   
int main ()
{
  FILE * pFile;
  pFile = fopen ("myfile.txt", "r");
  if (pFile == NULL)
  {
    printf ("Error opening file");
    exit (1);
  }
  else
  {
    /* file operations here */
  }
  return 0;
}

chevron_right



When exit() is called, any open file descriptors belonging to the process are closed and any children of the process are inherited by process 1, init, and the process parent is sent a SIGCHLD signal.

The mystery behind exit() is that it takes only integer args in the range 0 – 255 . Out of range exit values can result in unexpected exit codes. An exit value greater than 255 returns an exit code modulo 256.
For example, exit 9999 gives an exit code of 15 i.e. (9999 % 256 = 15).

Below is the C implementation to illustrate the above fact:

filter_none

edit
close

play_arrow

link
brightness_4
code

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
  
int main(void)
{
    pid_t pid = fork();
      
    if ( pid == 0 )
    {
       exit(9999); //passing value more than 255
    }
  
    int status;
    waitpid(pid, &status, 0);
  
    if ( WIFEXITED(status) )
    {
        int exit_status = WEXITSTATUS(status);
          
        printf("Exit code: %d\n", exit_status);
    }
  
return 0;
}

chevron_right


Output:

Exit code: 15

Note that the above code may not work with online compiler as fork() is disabled.

Explanation: It is effect of 8-bit integer overflow. After 255 (all 8 bits set) comes 0.
So the output is “exit code modulo 256”. The output above is actually the modulo of the value 9999 and 256 i.e. 15.



abort()

filter_none

edit
close

play_arrow

link
brightness_4
code

void abort ( void );

chevron_right


Unlike exit() function, abort() may not close files that are open. It may also not delete temporary files and may not flush stream buffer. Also, it does not call functions registered with atexit().


This function actually terminates the process by raising a SIGABRT signal, and your program can include a handler to intercept this signal (see this).

So programs like below might not write “Geeks for Geeks” to “tempfile.txt”

filter_none

edit
close

play_arrow

link
brightness_4
code

#include<stdio.h>
#include<stdlib.h>
int main()
{
  FILE *fp = fopen("C:\\myfile.txt", "w");
    
  if(fp == NULL)
  {
    printf("\n could not open file ");
    getchar();
    exit(1);
  }  
    
  fprintf(fp, "%s", "Geeks for Geeks");
    
  /* ....... */
  /* ....... */
  /* Something went wrong so terminate here */  
  abort();
    
  getchar();
  return 0;  
}    

chevron_right


If we want to make sure that data is written to files and/or buffers are flushed then we should either use exit() or include a signal handler for SIGABRT.



assert()

filter_none

edit
close

play_arrow

link
brightness_4
code

void assert( int expression );

chevron_right


If expression evaluates to 0 (false), then the expression, sourcecode filename, and line number are sent to the standard error, and then abort() function is called. If the identifier NDEBUG (“no debug”) is defined with #define NDEBUG then the macro assert does nothing.

Common error outputting is in the form:

Assertion failed: expression, file filename, line line-number

filter_none

edit
close

play_arrow

link
brightness_4
code

#include<assert.h>
  
void open_record(char *record_name)
{
    assert(record_name != NULL);
    /* Rest of code */
}
  
int main(void)
{
   open_record(NULL);
}

chevron_right


Related Article :
exit() vs _Exit() in C and C++

This article is contributed by Rahul Gupta. Please write comments if you find anything incorrect in the above article or you want to share more information about the topic discussed above.

References:
exit codes
http://www.cplusplus.com/reference/clibrary/cstdlib/abort/
http://www.cplusplus.com/reference/clibrary/cassert/assert/
http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.1.html
https://www.securecoding.cert.org/confluence/display/seccode/ERR06-C.+Understand+the+termination+behavior+of+assert%28%29+and+abort%28%29
https://www.securecoding.cert.org/confluence/display/seccode/ERR04-C.+Choose+an+appropriate+termination+strategy



My Personal Notes arrow_drop_up

Improved By : MAZHAR IMAM KHAN



Article Tags :
Practice Tags :


4


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.