User Tools

Site Tools


os_cp:fork_exec_pipes

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
os_cp:fork_exec_pipes [2024/05/08 13:31]
jkonczak utworzono
os_cp:fork_exec_pipes [2026/05/20 20:31] (current)
jkonczak
Line 5: Line 5:
 To create a new process, POSIX defines the ''​fork''​ function: To create a new process, POSIX defines the ''​fork''​ function:
 <​html><​span style="​float:​right"><​small>​Needs header:<​code>​unistd.h</​code></​small></​span>​ <​html><​span style="​float:​right"><​small>​Needs header:<​code>​unistd.h</​code></​small></​span>​
-<a href="​https://​pubs.opengroup.org/​onlinepubs/​9699919799/​functions/​fork.html"></​html>​+<a href="​https://​pubs.opengroup.org/​onlinepubs/​9799919799/​functions/​fork.html"></​html>​
 ''​pid_t **fork**()''​ ''​pid_t **fork**()''​
 <​html></​a></​html>​ <​html></​a></​html>​
Line 14: Line 14:
 \\ \\
 **Upon success, ''​fork''​ returns the pid of the child process in the parent **Upon success, ''​fork''​ returns the pid of the child process in the parent
-process, and the value of ''​0''​ in the the child process.**+process, and the value of ''​0''​ in the child process.**
 \\ \\
 Fork may fail if the resource limits are exhausted, and in such case the Fork may fail if the resource limits are exhausted, and in such case the
Line 20: Line 20:
  
 There is a list of things that ''​fork''​ does not clone or that are reset for the There is a list of things that ''​fork''​ does not clone or that are reset for the
-child process upon ''​fork''​. See POSIX standard or Linux manual on fork for details.+child process upon ''​fork''​. 
 +\\ See POSIX standard or 
 +[[https://​man7.org/​linux/​man-pages/​man2/​fork.2.html|Linux manual on fork]] 
 +for details. 
 +\\
 Notice that: Notice that:
   * all stack and heap memory is copied   * all stack and heap memory is copied
Line 33: Line 37:
 To learn its own process identifier, the process can execute To learn its own process identifier, the process can execute
 <​html><​span style="​float:​right"><​small>​Needs header: <​code>​unistd.h</​code></​small></​span>​ <​html><​span style="​float:​right"><​small>​Needs header: <​code>​unistd.h</​code></​small></​span>​
-<a href="​https://​pubs.opengroup.org/​onlinepubs/​9699919799/​functions/​getpid.html"></​html>​+<a href="​https://​pubs.opengroup.org/​onlinepubs/​9799919799/​functions/​getpid.html"></​html>​
 ''​pid_t **getpid**()''​ ''​pid_t **getpid**()''​
 <​html></​a></​html>​ <​html></​a></​html>​
Line 39: Line 43:
 To learn the process identifier of its parent, the process can execute To learn the process identifier of its parent, the process can execute
 <​html><​span style="​float:​right"><​small>​Needs header: <​code>​unistd.h</​code></​small></​span>​ <​html><​span style="​float:​right"><​small>​Needs header: <​code>​unistd.h</​code></​small></​span>​
-<a href="​https://​pubs.opengroup.org/​onlinepubs/​9699919799/​functions/​getppid.html"></​html>​+<a href="​https://​pubs.opengroup.org/​onlinepubs/​9799919799/​functions/​getppid.html"></​html>​
 ''​pid_t **getppid**()''​ ''​pid_t **getppid**()''​
 <​html></​a></​html>​ <​html></​a></​html>​
Line 57: Line 61:
 \\ \\
 <​html><​span style="​float:​right"><​small>​Needs header:<​br><​code>​sys/​wait.h</​code></​small></​span>​ <​html><​span style="​float:​right"><​small>​Needs header:<​br><​code>​sys/​wait.h</​code></​small></​span>​
-<a href="​https://​pubs.opengroup.org/​onlinepubs/​9699919799/​functions/​wait.html"></​html>​+<a href="​https://​pubs.opengroup.org/​onlinepubs/​9799919799/​functions/​wait.html"></​html>​
 ''​pid_t **wait**(int *//​stat_loc//​)''​ \\ ''​pid_t **wait**(int *//​stat_loc//​)''​ \\
 ''​pid_t **waitpid**(pid_t //pid//, int *//​stat_loc//,​ int //​options//​)''​ ''​pid_t **waitpid**(pid_t //pid//, int *//​stat_loc//,​ int //​options//​)''​
Line 91: Line 95:
 \\ \\
 Run the program and observe it in a live process viewer. \\ Run the program and observe it in a live process viewer. \\
-<​small>​ <​html><​a href="​https://​pubs.opengroup.org/​onlinepubs/​9699919799/​functions/​sleep.html"></​html>​+<​small>​ <​html><​a href="​https://​pubs.opengroup.org/​onlinepubs/​9799919799/​functions/​sleep.html"></​html>​
 ''​sleep(int //​sec//​)''<​html></​a></​html>​ sleeps with second resolution. (The other POSIX sleep function is ''​sleep(int //​sec//​)''<​html></​a></​html>​ sleeps with second resolution. (The other POSIX sleep function is
-''​[[https://​pubs.opengroup.org/​onlinepubs/​9699919799/​functions/​nanosleep.html|nanosleep]]'';​+''​[[https://​pubs.opengroup.org/​onlinepubs/​9799919799/​functions/​nanosleep.html|nanosleep]]'';​
 C standard includes now the equivalent ''​[[https://​en.cppreference.com/​w/​c/​thread/​thrd_sleep|thrd_sleep]]''​) C standard includes now the equivalent ''​[[https://​en.cppreference.com/​w/​c/​thread/​thrd_sleep|thrd_sleep]]''​)
 \\ \\
Line 117: Line 121:
 So, typically to start a new process, one has to ''​fork''​ and then ''​exec…''​ in the child: So, typically to start a new process, one has to ''​fork''​ and then ''​exec…''​ in the child:
 <​html><​div style="​width:​ fit-content"><​pre style="​line-height:​ 1"> <​html><​div style="​width:​ fit-content"><​pre style="​line-height:​ 1">
-prog1              ,------. +prog1              ,​------. ​  <span style="​color:#​aaa">​prog1</​span>​ 
--------------------| fork |-------------------------------------- +-------------------| fork |-------------------------------------------------- 
-pid: x (ppid: y)   ​`------\ +pid: x (ppid: y)   ​`------\ ​  <span style="​color:#​aaa">​pid:​ x (ppid: y)</​span>​ 
-                           \ prog1              ,-------. prog2 +                           
-                            `-------------------| exec… |-------- +                            ​\ prog1              ,-------. prog2 
-                             ​pid: z (ppid: x)   ​`-------'​+                             ​`-------------------| exec… |------------------- 
 +                              pid: z (ppid: x)   ​`-------' ​<span style="​color:#​aaa">​pid:​ z (ppid: x)</​span>​
 </​pre></​div></​html>​ </​pre></​div></​html>​
  
 To this end, a family of functions starting with ''​exec''​ is provided: \\ To this end, a family of functions starting with ''​exec''​ is provided: \\
 <​html><​span style="​float:​right"><​small>​Needs header:<​br><​code>​unistd.h</​code></​small></​span>​ <​html><​span style="​float:​right"><​small>​Needs header:<​br><​code>​unistd.h</​code></​small></​span>​
-<a href="​https://​pubs.opengroup.org/​onlinepubs/​9699919799/​functions/​execve.html"></​html>​+<a href="​https://​pubs.opengroup.org/​onlinepubs/​9799919799/​functions/​execve.html"></​html>​
 ''​int **execlp**(const char *//file//, const char *arg0, ... /*, (char *)**0** */​)'' ​ \\ ''​int **execlp**(const char *//file//, const char *arg0, ... /*, (char *)**0** */​)'' ​ \\
 ''​int **execl **(const char *//path//, const char *arg0, ... /*, (char *)**0** */​)'' ​ \\ ''​int **execl **(const char *//path//, const char *arg0, ... /*, (char *)**0** */​)'' ​ \\
-''​int **execle**(const char *//path//, const char *arg0, ... /*, (char *)**0**,*/ char *const //​envp//​[])'' ​ \\+''​int **execle**(const char *//path//, const char *arg0, ... /*, (char *)**0**, char *const //envp//[]*/)'' ​ \\
 ''​int **execvp**(const char *//file//, char *const //​argv//​[])'' ​ \\ ''​int **execvp**(const char *//file//, char *const //​argv//​[])'' ​ \\
 ''​int **execv **(const char *//path//, char *const //​argv//​[])'' ​ \\ ''​int **execv **(const char *//path//, char *const //​argv//​[])'' ​ \\
Line 144: Line 149:
 following ''​exec…''​ do execute, then ''​exec…''​ must have failed. ​ following ''​exec…''​ do execute, then ''​exec…''​ must have failed. ​
  
-Importantly,​ upon executing ''​exec…''​ the list of open files is retained.+Importantly,​ upon executing ''​exec…''​ the list of open files is retained((With 
 +the exception of files on which the programmer explicitly set the //​close-on-exec//​ 
 +flag for the file descriptor, for instance by passing ''​O_CLOEXEC''​ among the flags 
 +upon opening the file or by issuing a ''​fcntl(…,​ F_SETFD, FD_CLOEXEC|…)''​ for the 
 +file.)).
 \\ \\
 Almost all resources are released. See the documentation for other exceptions. Almost all resources are released. See the documentation for other exceptions.
Line 155: Line 164:
 <​html><​div style="​margin-bottom:​-1.4em"></​div></​html>​ <​html><​div style="​margin-bottom:​-1.4em"></​div></​html>​
 <code c> <code c>
-char arg0[] = "​ls"; ​    char arg2[] = "​-a";​ 
-char arg1[] = "​-l"; ​    char arg3[] = "/​tmp";​ 
 # Argument list: # Argument list:
-execlp("​ls", ​   arg0arg1arg2arg3, NULL); +execlp("​ls", ​          "​ls"​"​-l"​"​-a"​"/​tmp"​, NULL); 
-# Argument vector: + 
-char *argv[] = {arg0arg1arg2arg3, NULL};+ Argument vector: 
 +char        *argv[] = {"​ls"​"​-l"​"​-a"​"/​tmp"​, NULL};
 execvp("​ls",​ argv); execvp("​ls",​ argv);
 </​code>​ </​code>​
Line 192: Line 200:
 <​small>​To access an unprocessed array of environment variables for the current process, <​small>​To access an unprocessed array of environment variables for the current process,
 one must have in the source code the following lines: one must have in the source code the following lines:
 +<​html><​div style="​margin-top:​-1.4em"></​div></​html>​
 <code c> <code c>
 #include <​unistd.h>​ #include <​unistd.h>​
Line 200: Line 209:
 (Normally, to access such variables of the running process one shall use the (Normally, to access such variables of the running process one shall use the
 ''​[[https://​en.cppreference.com/​w/​cpp/​utility/​program/​getenv|getenv]]''​ and  ''​[[https://​en.cppreference.com/​w/​cpp/​utility/​program/​getenv|getenv]]''​ and 
-''​[[https://​pubs.opengroup.org/​onlinepubs/​9699919799/​functions/​setenv.html|setenv]]''​+''​[[https://​pubs.opengroup.org/​onlinepubs/​9799919799/​functions/​setenv.html|setenv]]''​
 functions. \\ functions. \\
 <​small>​ The ''​environ''​ variable is useful when one wants to pass a slightly <​small>​ The ''​environ''​ variable is useful when one wants to pass a slightly
Line 217: Line 226:
 <​small>​ <​small>​
 To measure time, you can use the following C11 code: To measure time, you can use the following C11 code:
 +<​HTML><​div style="​margin-top:​-1.4em;​line-height:​100%"></​HTML>​
 <code c> <code c>
 #include <​time.h>​ #include <​time.h>​
Line 226: Line 236:
     double elapsedSec = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;     double elapsedSec = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
 </​code>​ </​code>​
 +<​HTML></​div><​div style="​margin-top:​-1.4em"></​HTML>​
 +Instead of the C11 function ''​[[https://​en.cppreference.com/​c/​chrono/​timespec_get|timespec_get]](&//​x//,​ TIME_UTC);'',​ you may also
 +use the POSIX function ''​[[https://​pubs.opengroup.org/​onlinepubs/​9799919799/​functions/​clock_gettime.html|clock_gettime]](CLOCK_MONOTONIC,​ &//​x//​);''​.
 +<​HTML></​div></​HTML>​
 </​small>​ </​small>​
  
Line 239: Line 253:
 POSIX defines the following functions: \\ POSIX defines the following functions: \\
 <​html><​span style="​float:​right"><​small>​Needs header:<​br><​code>​unistd.h</​code></​small></​span>​ <​html><​span style="​float:​right"><​small>​Needs header:<​br><​code>​unistd.h</​code></​small></​span>​
-<a href="​https://​pubs.opengroup.org/​onlinepubs/​9699919799/​functions/​dup.html"></​html>​+<a href="​https://​pubs.opengroup.org/​onlinepubs/​9799919799/​functions/​dup.html"></​html>​
 ''​int **dup**(int //​fildes//​)''​ \\ ''​int **dup**(int //​fildes//​)''​ \\
 ''​int **dup2**(int //fildes//, int //​target//​)''​ ''​int **dup2**(int //fildes//, int //​target//​)''​
Line 297: Line 311:
 wrote something. wrote something.
  
-When a function ​stops not because ​it is not given the CPU time but because it +When a function ​that interfaces with the operating system does not return ​because 
-waits for something to happen, then it **blocks**.+the OS waits for something to happen ​before it may respond, then one says that 
 +the function ​**blocks**.
 \\ \\
-Functions that may block are called **blocking**. (Cf. definition of +Functions that may ever block are called **blocking**. (Cf. definition of 
-[[https://​pubs.opengroup.org/​onlinepubs/​9699919799/​basedefs/​V1_chap03.html#​tag_03_77|blocking]]+[[https://​pubs.opengroup.org/​onlinepubs/​9799919799/​basedefs/​V1_chap03.html#​tag_03_48|blocking]]
 in POSIX standard.) in POSIX standard.)
  
Line 321: Line 336:
 \\ \\
 To set/clear the O_NONBLOCK flag, one shall first read the flags with  To set/clear the O_NONBLOCK flag, one shall first read the flags with 
-''​int flags = [[https://​pubs.opengroup.org/​onlinepubs/​9699919799/​functions/​fcntl.html|fcntl]](fd,​ F_GETFL);'',​+''​int flags = [[https://​pubs.opengroup.org/​onlinepubs/​9799919799/​functions/​fcntl.html|fcntl]](fd,​ F_GETFL);'',​
 then set/clear the flag (e.g., ''​flags |= O_NONBLOCK;''​) and finally set the then set/clear the flag (e.g., ''​flags |= O_NONBLOCK;''​) and finally set the
 new flags with ''​fcntl(fd,​ F_SETFL, flags);''​. new flags with ''​fcntl(fd,​ F_SETFL, flags);''​.
Line 332: Line 347:
 \\ \\
 <​html><​span style="​float:​right"><​small>​Needs header: <​code>​unistd.h</​code></​small></​span>​ <​html><​span style="​float:​right"><​small>​Needs header: <​code>​unistd.h</​code></​small></​span>​
-<a href="​https://​pubs.opengroup.org/​onlinepubs/​9699919799/​functions/​pipe.html"></​html>​+<a href="​https://​pubs.opengroup.org/​onlinepubs/​9799919799/​functions/​pipe.html"></​html>​
 ''​int **pipe**(int //​fildes//​[2])''​ ''​int **pipe**(int //​fildes//​[2])''​
 <​html></​a></​html>​ <​html></​a></​html>​
 \\ \\
 The ''//​fildes//​[0]''​ is opened for reading, and the ''//​fildes//​[1]''​ is opened The ''//​fildes//​[0]''​ is opened for reading, and the ''//​fildes//​[1]''​ is opened
-for writing.+for writing. ​<​small>​(Cf. with standard input being ''​0''​ and standard output being ''​1''​)</​small>​
 \\ \\
 Pipes can be used to send data from one process to another process, or from  Pipes can be used to send data from one process to another process, or from 
Line 366: Line 381:
 end of a pipe by providing a path to the file. A FIFO file can be created with end of a pipe by providing a path to the file. A FIFO file can be created with
 ''​mkfifo''​ shell utility or by the ''​mkfifo''​ shell utility or by the
-''​[[https://​pubs.opengroup.org/​onlinepubs/​9699919799/​functions/​mkfifo.html|mkfifo]]''​+''​[[https://​pubs.opengroup.org/​onlinepubs/​9799919799/​functions/​mkfifo.html|mkfifo]]''​
 function. function.
 \\ \\
Line 378: Line 393:
 <​small>​Pipe is unidirectional. The unix //socket// is its bidirectional <​small>​Pipe is unidirectional. The unix //socket// is its bidirectional
 equivalent. See ''​[[https://​man7.org/​linux/​man-pages/​man7/​unix.7.html|man 7 unix]]''​ equivalent. See ''​[[https://​man7.org/​linux/​man-pages/​man7/​unix.7.html|man 7 unix]]''​
-for details.</​small>​+for details. 
 +\\ 
 +POSIX standard also defines (but not mandates) 
 +[[https://​man7.org/​linux/​man-pages/​man7/​mq_overview.7.html|message queues]]. 
 +</​small>​
  
 ~~Exercise.#​~~ Write a program that: ~~Exercise.#​~~ Write a program that:
os_cp/fork_exec_pipes.1715167914.txt.gz · Last modified: 2024/05/08 13:31 by jkonczak