How to Read Child Process Errno From Parent

Process management

One of the philosophies behind Unix is the motto do ane matter and practise it well. In this spirit, basic process management is done with a number of system calls, each with a single (simple) purpose. These organization calls can and so exist combined to implement more complex behaviors.

The post-obit organisation calls are used for basic process direction.

fork
A parent process uses fork to create a new child process. The child process is a copy of the parent. After fork, both parent and child executes the aforementioned program merely in separate processes.
exec
Replaces the program executed by a process. The child may apply exec after a fork to replace the process' memory space with a new programme executable making the child execute a different program than the parent.
get out
Terminates the process with an exit status.
wait
The parent may use wait to suspend execution until a child terminates. Using await the parent can obtain the go out condition of a terminated child.

Parent and child

The process invoking fork is called the parent. The new process created as the result of a fork is the child of the parent.

Subsequently a successful fork, the kid procedure is a re-create of the parent. The parent and child processes executes the same programme but in separate processes.

Fork

The fork system call is the master (and historically, only) method of procedure creation in Unix-like operating systems.

                                        #include              <unistd.h>              pid_t              fork              (              void              );                      
Render value
On success, the PID of the child procedure is returned in the parent, and 0 is returned in the child. On failure, -1 is returned in the parent, no child process is created, and errno is set up appropriately.

Fork returns twice on success

On success fork returns twice: in one case in the parent and once in the kid. Afterwards calling fork, the program tin use the fork return value to tell whether executing in the parent or kid.

  • If the return value is 0 the program executes in the new kid process.
  • If the render value is greater than naught, the programme executes in the parent process and the render value is the process ID (PID) of the created child process.
  • On failure fork returns -1.

Template program

In the file module-ii/examples/src/fork-template.c you find a template for a typical program using fork.

                                                        1                            #include              <stdio.h>  // perror()                              2                            #include              <stdlib.h> // get out(), EXIT_SUCCESS, EXIT_FAILURE                              3                            #include              <unistd.h> // fork()                              iv                                            5                            int              chief              (              void              )              {                              half-dozen                                            7                            pid_t              pid;                              viii                                            9                            switch              (pid              =              fork())              {              10                            11                            case              -              1              :              12                            // On error fork() returns -1.              13                            perror(              "fork failed"              );              14                            exit(EXIT_FAILURE);              15                            16                            case              0              :              17                            // On success fork() returns 0 in the child.              eighteen                            nineteen                            // Add lawmaking for the child process hither.                            xx                            21                            get out(EXIT_SUCCESS);              22                            23                            default              :              24                            // On success fork() returns the pid of the child to the parent.              25                            26                            // Add together code for the parent process here.                            27                            28                            go out(EXIT_SUCCESS);              29                            }              thirty                            }                      

On lines 1-3 a number of header files are included to get access to a few functions and constants from the C Standard library.

pid_t

I line seven the variable pid of blazon pid_t is declared. The pid_t data type is the data type used for process IDs.

fork

On line 9 the parent procedure calls fork and stores the return value in the variable pid.

switch

On line 9 a switch-argument is used to check the return value of fork.

Error (example -i)

On failure fork returns -1 and execution continues in the case -1 branch of the switch statement (line 11). The operating system was not able to create a new process. The parent uses perror to print an error message (line xiii) and then terminates with exit condition EXIT_FAILURE (line 14).

Kid (instance 0)

On success fork returns 0 in the new child process and execution continues in the instance 0 co-operative of the switch statement (line 16). Any code to exist executed only past the child is placed here (line nineteen). The child terminates with exit status EXIT_SUCCESS (line 21).

Parent (default)

If the value fork returned by fork was neither -1 (error) nor 0 (child), execution continues in the parent process in the default co-operative of the switch statement (line 23). In this example, the value returned past fork is the process ID (PID) of the newly created child process.

A kickoff fork case

In the file module-2/examples/fork.c you find a program with the post-obit main function.

                                        int              main              (              void              )              {              pid_t              pid;              switch              (pid              =              fork())              {              case              -              1              :              // On mistake fork() returns -1.              perror(              "fork failed"              );              get out(EXIT_FAILURE);              example              0              :              // On success fork() returns 0 in the child.              kid();              default              :              // On success fork() returns the pid of the child to the parent.              parent(pid);              }              }                      

The code for the child is in the function child and the code for the parent in the office parent.

                                        void              kid              ()              {              printf(              " CHILD <%ld> I'thousand alive! My PID is <%ld> and my parent got PID <%ld>.              \due north              "              ,              (              long              )              getpid(),              (              long              )              getpid(),              (              long              )              getppid());              printf(              " Kid <%ld> Goodbye!              \n              "              ,              (              long              )              getpid());              leave(EXIT_SUCCESS);              }              void              parent              (              pid_t              pid)              {              printf(              "PARENT <%ld> My PID is <%ld> and I spawned a child with PID <%ld>.              \northward              "              ,              (              long              )              getpid(),              (              long              )              getpid(),              (              long              )              pid);              printf(              "PARENT <%ld> Goodbye!              \north              "              ,              (              long              )              getpid());              exit(EXIT_SUCCESS);              }                      

Both parent and child prints two letters and then terminates. Navigate to the directory module-2/examples. Compile using make.

Run the program.

You should see output like to this in the final.

                          PARENT <87628> Spawned a child with PID = 87629. PARENT <87628> Goodbye.  Kid <87629> I'thou alive and my PPID = 1.  Kid <87629> Goodbye.                      

Run the program multiple times and expect specifically at the PPID value reported by the child. Sometimes the child reports PPID = 1 merely sometimes it is equal to the PID of the parent. Conspicuously the PID of the parent is non 1? Why doesn't report the "correct" PPID value all the fourth dimension?

Orphans

An orphan procedure is a process whose parent process has terminated, though it remains running itself. Whatsoever orphaned process will exist immediately adopted by the special init system process with PID one.

Processes execute concurrently

Both the parent process and the kid process competes for the CPU with all other processes in the system. The operating systems decides which process to execute when and for how long. The procedure in the organisation execute concurrently.

In our instance programme:

  • most frequently the parent terminates before the child and the kid becomes an orphan process adopted past init (PID = 1) and therefore reports PPID = 1
  • sometimes the child process terminates before its parent and and so the child is able to report PPID equal to the PID of the parent.

Await

The wait system call blocks the caller until one of its child process terminates. If the caller doesn't have any child processes, wait returns immediately without blocking the caller. Using await the parent tin can obtain the leave status of the terminated child.

                                        #include              <sys/types.h>              #include              <sys/wait.h>              pid_t              wait              (              int              *              status);                      
status
If condition is not Nada, wait store the get out status of the terminated child in the int to which status points. This integer tin exist inspected using the WIFEXITED and WEXITSTATUS macros.
Render value
On success, wait returns the PID of the terminated child. On failure (no child), wait returns -ane.

WIFEXITED

                                        #include              <sys/types.h>              #include              <sys/wait.h>              WIFEXITED(status);                      
status
The integer condition value set by the wait system call.
Return value
Returns true if the child terminated usually, that is, by calling leave or past returning from main.

WEXITSTATUS

                                        #include              <sys/types.h>              #include              <sys/wait.h>              int              WEXITSTATUS              (condition);                      
status
The integer condition value gear up by the look system call.
Render value
The exit status of the kid. This consists of the least pregnant 8 $.25 of the condition argument that the child specified in a call to exit or as the statement for a render statement in main. This macro should be employed merely if WIFEXITED returned true.

Example using await

In the module-two/examples/fork_exit_wait.c example program the parent execute the parent office.

                                                        1                            void              parent              (              pid_t              pid)              {                              ii                                            3                            printf(              "PARENT <%ld> Spawned a child with PID = %ld.              \due north              "              ,                              4                            (              long              )              getpid(),              (              long              )              pid);                              five                                            half-dozen                            wait(Zip);                              7                                            8                            printf(              "PARENT <%ld> Child with PID = %ld terminated.              \north              "              ,                              ix                            (              long              )              getpid(),              (              long              )              pid);              ten                            11                            printf(              "PARENT <%ld> Bye.              \n              "              ,              12                            (              long              )              getpid());              13                            14                            exit(EXIT_SUCCESS);              15                            }                      

On line 6 the parent calls wait(Nil) to wait for the kid process to cease.

Compile and run the program. Now the parent should always wait for the child to stop before terminating itself. As a consequence the child should:

  • newer be adopted by init
  • new report PPID = 1
  • always report PPID equal to the PID of the parent.

Example using wait to obtain the get out status of the kid

In the module-2/examples/fork_exit_wait_status.c case program the parent execute the parent function.

                                                        one                            void              parent              (              pid_t              pid)              {                              ii                            int              condition;                              three                                            four                            printf(              "PARENT <%ld> Spawned a kid with PID = %ld.              \n              "              ,                              5                            (              long              )              getpid(),              (              long              )              pid);                              6                                            7                            wait(              &              status);                              viii                                            9                            if              (WIFEXITED(status))              {              10                            printf(              "PARENT <%ld> Child with PID = %ld and get out condition = %d terminated.              \n              "              ,              xi                            (              long              )              getpid(),              (              long              )              pid,              WEXITSTATUS(status));              12                            }              13                            14                            printf(              "PARENT <%ld> Goodbye.              \n              "              ,              15                            (              long              )              getpid());              16                            17                            exit(EXIT_SUCCESS);              eighteen                            }                      

One line ii the parent creates the variable condition. On line 7 the parent calls expect(&condition) to wait for the child process to finish. The & is the address-of operator and &condition returns the address of the condition variable. When the child terminates the exit condition of the child will be stored in variable condition.

Compile using make.

Run the program.

                          $ ./bin/fork_exit_wait_status                      

In the output you should be able to see that the parent obtained the exit status of the kid.

                          PARENT <99340> Spawned a child with PID = 99341.  Child <99341> I'k alive and my PPID = 99340.  CHILD <99341> Goodbye, leave with status 42. PARENT <99340> Kid with PID = 99341 and get out condition = 42 terminated. PARENT <99340> Good day.                      

Zombies

A terminated procedure is said to exist a zombie or defunct until the parent does wait on the child.

  • When a process terminates all of the retentiveness and resource associated with it are deallocated so they can exist used past other processes.
  • However, the exit status is maintained in the PCB until the parent picks up the exit status using wait and deletes the PCB.
  • A child process e'er first becomes a zombie.
  • In virtually cases, under normal organization operation zombies are immediately waited on by their parent.
  • Processes that stay zombies for a long time are generally an mistake and cause a resource leak.

An example with a zombie process

In the module-two/examples/fork_zombie.c example plan the kid terminates before the parent does look on the child and becomes a zombie process. The parent execute the parent function.

                                                        i                            void              parent              (              pid_t              pid)              {                              2                                            three                            printf(              "PARENT <%ld> Spawned a child with PID = %ld.              \north              "              ,                              4                            (              long              )              getpid(),              (              long              )              pid);                              5                                            half-dozen                            printf(              "PARENT <%ld> Press whatever key to reap a zombie!              \n              "              ,                              7                            (              long              )              getpid());                              8                                            9                            getchar();              10                            xi                            pid              =              wait(NULL);              12                            13                            printf(              "PARENT <%ld> Zombie kid with PID = %ld"              ,              fourteen                            (              long              )              getpid(),              (              long              )              pid);              fifteen                            sixteen                            exit(EXIT_SUCCESS);              17                            }                      

On line nine the parent uses getchar to block itself until the user presses a key on the keyboard.

When the child terminates, the get out status of the kid is stored in the child process command cake (PCB). The operating system deallocates all retentivity used by the child but the PCB cannot be deallocated until the parent does look on the child.

Compile using brand.

Run the program.

In the output you should be able to see that the child terminates and that the parent blocks waiting for a keypress.

                          PARENT <4636> Spawned a child with PID = 4637. PARENT <4636> Press any key to reap a zombie!  Kid <4637> I'm alive and my PPID = 4636.  Child <4637> Cheerio.                      

The child process has terminated simply the parent has yet not read the go out status of the kid using await. The child process has now go a zombie procedure.

Monitor

Open a second concluding and navigate to the module-ii directory. The module-2/tools/monitor tool can exist used to view process condition data about process. Use the --assistance flag to come across the documentation.

This is the built in documentation for the monitor tool.

                          Usage: monitor [-s delay] [-p pid] cmd  A top-similar command that just lists USER, PID, STAT and COMM for the current user and and proceses with a control proper name with a grep match of cmd.  Options:  -s delay    Delay in seconds between refresh, default = ane.  -p pid      Include process with PID pid.                      

The cmd argument is the name of the program executed by the processes nosotros want to monitor. Use the monitor tool to view process condition information for the parent and child, both executing the fork_zombie program.

                          $ ./tools/monitor fork_zombie                      

On Linux you should see something similar to this.

                          Monitoring processes matching: fork_zombie  Press Ctrl-C to exit  USER       PID  PPID S Control abcd1234  4636  4311 S fork_zombie abcd1234  4637  4636 Z fork_zombie <defunct>                      

In the PID column yous see the PID of the listed processes. The commencement line shows information near the parent and the second line shows data about the child.

The Southward column prove the status of the process.

  • The parent got condition South (sleep) significant the procedure is waiting for an event to complete. In this case the parent is blocked waiting for the child to cease.
  • The child got status Z (zombie) significant the process terminated only not yet reaped by its parent.

Some other proper name used for a zombie process is defunct.

Reap the zombie

From the terminal used to run the fork_zombie programme, press whatsoever key to make the parent practice wait on the child.

                          PARENT <4636> Spawned a child with PID = 4637. PARENT <4636> Press any cardinal to reap a zombie!  CHILD <4637> I'1000 alive and my PPID = 4636.  Child <4637> Cheerio.  PARENT <4636> Zombie child with PID = 4637 reaped! PARENT <4636> Printing any key to finish!                      

In the terminal used to run monitor the zombie process should have disappear, leaving but the parent procedure.

                          Monitoring processes matching: fork  Printing Ctrl-C to exit  USER       PID  PPID S Control abcd1234  4636  4311 South fork_zombie                      

The parent is now blocked, waiting for user input.

Terminate the parent

From the terminal used to run the fork_zombie plan, printing any key to brand the parent terminate.

                          PARENT <4636> Spawned a child with PID = 4637. PARENT <4636> Printing any key to reap a zombie!  CHILD <4637> I'm alive and my PPID = 4636.  Kid <4637> Goodbye.  PARENT <4636> Zombie kid with PID = 4637 reaped! PARENT <4636> Press any key to terminate!  PARENT <4636> Goodbye!                      

Execute a new program in the child

If you don't want to execute the aforementioned program in both the parent and the child, you will need to use a system call of the exec family unit. The exec system calls will supersede the currently executing program with a new executable.

In module-ii/examples/src/child.c yous this pocket-size programme.

                                        #include              <stdio.h>    // puts(), printf(), perror(), getchar()              #include              <stdlib.h>   // exit(), EXIT_SUCCESS, EXIT_FAILURE              #include              <unistd.h>   // getpid(), getppid()              int              main              (              void              )              {              printf(              " Child <%ld> I'thousand alive and my PPID = %ld.              \n              "              ,              (              long              )              getpid(),              (              long              )              getppid());              printf(              " Kid <%ld> Printing any cardinal to brand me end!              \north              "              ,              (              long              )              getpid());              getchar();              printf(              " CHILD <%ld> Bye!              \northward              "              ,              (              long              )              getpid());              exit(              127              );              }                      

Compile using make.

Run the program.

First this plan simply prints two letters to the terminal and so wait for a central-press.

                                        Kid <33172> I'one thousand alive and my PPID = 81166.  Kid <33172> Press whatsoever key to make me terminate!                      

Subsequently you lot press any key in the terminal the program terminates.

                                        Child <33172> I'm live and my PPID = 81166.  Kid <33172> Printing whatsoever primal to brand me terminate!     CHILD <33172> Goodbye!                      

The module-2/examples/src/fork_exec.c program uses execv to brand the child process execute the module-2/examples/bin/child executable. After fork the kid executes the child functions.

                                                        i                            void              child              ()              {                              two                            char              *              const              argv[]              =              {              "./bin/child"              ,              Goose egg};                              iii                                            iv                            printf(              " Child <%ld> Press any key to make me call exec!              \due north              "              ,                              5                            (              long              )              getpid());                              6                                            7                            getchar();                              viii                                            9                            execv(argv[              0              ],              argv);              ten                            11                            perror(              "execv"              );              12                            exit(EXIT_FAILURE);              thirteen                            }                      

On line 2 the needed argument vector is constructed. On line 7 the child waits for a key-press. After the key-press, on line ix, the child use execv to supercede the program executed past the child process past the child executable. If execv is successful control volition never exist returned and lines eleven and 12 should not exist reached.

Compile using make.

Run the plan.

                          PARENT <33422> Spawned a kid with PID = 33423.  Child <33423> Press whatever key to brand me phone call exec!                      

Open a second final and apply the ps control with the -p option to run into data virtually the kid procedure.

                          $ ps -p 33206   PID TTY           Fourth dimension CMD   33423 ttys023    0:00.00 ./bin/fork_exec                      

Annotation that the child process currently is executing the .bin/fork_exec executable.

In the first terminal, press any primal.

                                        Kid <33423> I'thou alive and my PPID = 33422.  CHILD <33423> Press whatsoever key to brand me terminate!                      

From the other terminal and employ the ps command with the -p option to meet information about the child process.

                          $ ps -p 33206   PID TTY           TIME CMD   33423 ttys023    0:00.00 ./bin/child                      

Note that the kid procedure at present executes the ./bin/child executable.

In the first concluding, printing whatsoever key to make the kid process terminate. Now the parent performs await on the kid and reports the kid exit status.

                                        Kid <33423> Adieu!  PARENT <33422> Child with PID = 33423 and exit status = 127 terminated.  PARENT <33422> Goodbye!                      

hillantood66.blogspot.com

Source: http://www.it.uu.se/education/course/homepage/os/vt18/module-2/process-management/

0 Response to "How to Read Child Process Errno From Parent"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel