C language realizes the creation of daemon process of Linux system

Hello everyone, I am the first ikun of Kungong who has been practicing programming for two and a half years. Today we will share the knowledge about the process and create a daemon process of the Linux system in c language.

Table of contents

1. Process related interface functions

1. Create a child process -- fork

(1) Function prototype

(2) Parent-child process:

2. End the process -- exit() / _exit()

3. Process recovery -- wait, waitpid

4. exec function family

Second, the daemon process

 

1. Process related interface functions

1. Create a child process -- fork

(1) Function prototype

#include <sys/types.h>
       #include <unistd.h>
​
       pid_t fork(void);

  return value:
A new child process is successfully created, the parent process returns the PID number of the child process, and the child process returns 0
If the parent process fails, the parent process returns -1, and no child process is created.

(2) Parent-child process:

A process creates a new process through the fork function. The original process is called the parent process of the new process, and the new process is called the child process of the original process.

The child process inherits almost all data from the parent process.

1. If the parent process ends in preference to the child process:

The child process is called an orphan process, which changes from a foreground process to a background process, and is uniformly adopted by the init process;

2. If the child process ends before the parent process, and the parent process does not recycle the child process resources

The child process becomes a zombie process (zombie state)

In general, if the child process ends before the parent process, the child process should be reclaimed by the parent process uniformly

The child process starts execution at the next instruction of the fork statement

2. End the process -- exit() / _exit()

  #include <stdlib.h>
​
   void exit(int status);
   parameter:
        status: Indicates the status of the process exit


   #include <unistd.h>
​
   void _exit(int status); 

Note: After the exit function is called, all buffers will be flushed, and the _exit function will not flush

3. Process recovery -- wait, waitpid

  #include <sys/types.h>
   #include <sys/wait.h>
​
   pid_t wait(int *wstatus);    
   parameter:
        wstatus:When the process ends, the first address of the status information
   
   return value:
        Successfully returns the end of the child process pid number, return on failure-1
        
        If you want to get the status information of the end of the child process, you can use the following macro to get it:
        
        WIFEXITED(wstatus) -- Determine whether a child process exits normally, the normal exit is true, the abnormal exit is false
        WEXITSTATUS(wstatus)  -- Returns the return value of the child process end
        WIFSIGNALED(wstatus) --  Determine whether it is terminated by a signal
        WTERMSIG(wstatus) -- print the number of the signal that terminates the process
----------------------------------------------------------------------------------
​
    pid_t waitpid(pid_t pid, int *wstatus, int options);
    
    parameter:
        pid: process number, -1 Indicates receiving any child process
        wstatus: When the process ends, the first address of the status information
        options: 
                0 -- Wait for the child process to end in blocking mode
                WNOHANG  -- wait for the child process to end in a non-blocking manner

4. exec function family

  
 #include <unistd.h>
   
   l: list list
   v:  argv
   p:  PATH environment variable
   
   int execl(const char *pathname, const char *arg, .../* (char  *) NULL */);
   
   parameter:
        pathname:The filename of the executable program (including the path)
        arg: Command line arguments to execute the program, the list of command line arguments starts with NULL end
   return value:
        return on failure-1;
 -----------------------------------------------------------------------------  
   int execlp(const char *file, const char *arg, .../* (char  *) NULL */);  
   parameter:
        file: program name
   
   Add environment variables:
    exist~/.bashrc Add the command to:
        export PATH=$PATH:/home/hqyj/class/220703_IO/day4
        After the configuration is complete, you need to use the following commands to make the configuration take effect:
            source ~/.bashrc
--------------------------------------------------------------------------------


   int execv(const char *pathname, char *const argv[]);
   int execvp(const char *file, char *const argv[]);

Second, the daemon process

The daemon has nothing to do with the terminal and is responsible for periodically processing certain events in the background or waiting for certain event responses

1. Process group: When a user runs a process, it is equivalent to creating a process group, and all processes that are related to the process belong to the process group ​

2. Session: When a user opens a terminal, a session is created. A session consists of one or more process groups. Once the terminal is closed, all processes in all process groups in the session end.

3. The creation process of the daemon process:

①, create a child process, the parent process exits
    fork();

②, let the child process leave the original session
   setsid();

③, modify the current working path -- not necessary
   chdir("/tmp");

④, reset the file permission mask -- not necessary
   umask(0);

⑤, delete all file descriptors in the process
   int i = 0;
   for(i = 0; i < getdtabelsize; i++)
   {
       close(i);
   }

while(1)
{
Events that need to be executed periodically;
}


4. Create a daemon process and record the current time every 1s in the time.log log file;

According to the process of creating a daemon process, we can easily create a daemon process, the code is as follows:

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>

void init_daemon();
int main(int argc, char *argv[])
{
    struct tm *t = NULL;
    time_t now;              

    init_daemon();      

    while(1)                                         
    {
        FILE *fp = fopen("/tmp/time.log", "a+");
        if(fp == NULL)
        {
            perror("fopen");
            exit(0);
        }
        time(&now);
        t = localtime(&now);
        fprintf(fp, "%d year%d moon%d day%d:%d:%d\n", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
        sleep(1);
        fflush(fp);
        fclose(fp);
    }
    return 0;
}

void init_daemon()      //Create a daemon
{
    pid_t pid = fork();      //create child process
    if(pid < 0)              
    {
        perror("fork");
        exit(0);
    }
    if(pid > 0)             //parent process exits
    {
        exit(0);
    }

    setsid();               //Let the child process leave the original session

    chdir("/tmp");          //Modify the current working path

    umask(0);               //reset file permission mask
    int i = 0;
    for(i = 0; i < getdtablesize(); i++)
    {
        close(i);
    }
    return;

} 

Running the program, the result is as follows:

 

 

 

Tags: C Linux Operation & Maintenance

Posted by tbobker on Sat, 17 Sep 2022 21:33:45 +0530