Difference between revisions of "Exec system call"
From Teknologisk videncenter
m (→Simple use) |
m |
||
(5 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
The '''exec()''' family executes a file as a new process. See [[fork system call]] for "cloning" a process. | The '''exec()''' family executes a file as a new process. See [[fork system call]] for "cloning" a process. | ||
− | The | + | *The '''exec()''' family replaces the current process image with a new process image. |
+ | *Never returns to caller - unless an error occur. | ||
+ | |||
=Simple use= | =Simple use= | ||
The '''execlp()''' is one of the function call in the exec family. See manpage | The '''execlp()''' is one of the function call in the exec family. See manpage | ||
Line 16: | Line 18: | ||
int main() | int main() | ||
{ | { | ||
− | execlp("ls", "ls", "-l", "/etc", NULL); | + | execlp("ls", "ls", "-l", "/etc", NULL); // See security note below!!! |
− | return 1; | + | return 1; // This line only runs if execlp() fails |
} | } | ||
</source> | </source> | ||
+ | ==Security== | ||
+ | As '''execlp()''' searches through $PATH to find the executable file - it is possible to put an executable with the same name earlier in $PATH and run a bogus and evil program. Use '''execl("/usr/bin/ls", "ls", "-l", "/etc", NULL);''' instead. | ||
+ | |||
+ | Best practice is not to use the '''p''' exec types as it uses $PATH to find the executable '''execlp()''', '''execvp()''' or '''execvpe()''' | ||
+ | =Parent and child with different code= | ||
+ | {{:fork system call#Parent and child with different code}} | ||
[[Category:Linux]][[Category:C]] | [[Category:Linux]][[Category:C]] |
Latest revision as of 11:10, 19 December 2022
The exec() family executes a file as a new process. See fork system call for "cloning" a process.
- The exec() family replaces the current process image with a new process image.
- Never returns to caller - unless an error occur.
Contents
Simple use
The execlp() is one of the function call in the exec family. See manpage
The five arguments in the execlp() below is:
- ls - the executable file must be in $PATH
- ls - argv[0] as seen from the executable file
- -l - argv[1] as seen from the executable file
- /etc - argv[2] as seen from the executable file
- NULL - argv[3] as seen from the executable file - end of argument list
#include <stdio.h>
#include <unistd.h>
int main()
{
execlp("ls", "ls", "-l", "/etc", NULL); // See security note below!!!
return 1; // This line only runs if execlp() fails
}
Security
As execlp() searches through $PATH to find the executable file - it is possible to put an executable with the same name earlier in $PATH and run a bogus and evil program. Use execl("/usr/bin/ls", "ls", "-l", "/etc", NULL); instead.
Best practice is not to use the p exec types as it uses $PATH to find the executable execlp(), execvp() or execvpe()
Parent and child with different code
If we want a parent and a child to execute different code and share a resource, for example a server that send information to a client.
Three files:
- my_system.c - forks and starts the server code as parent and the client code as child.
- server.c"' - contains the server code
- client.c - contains the client code
Typical output when starting my_system
Note:
- Server executable running with the parent PID
- Client executable running with the child PID
Starting server as parent - my PID is 2644553
Starting client as child - my PID is 2644554
Server started my PID is 2644553
Client started my PID is 2644554
Client received: hello: 1
Client received: hello: 2
Client received: hello: 3
Client received: hello: 4
Client received: hello: 5
Server signing out
Client signing out
my_system.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <sys/types.h>
4
5 int main()
6 {
7 int arr[2];
8 char argv[50];
9 pipe(arr);
10 if(fork())
11 {
12 printf("Starting server as parent - my PID is %d\n", getpid());
13 fflush(stdout);
14 close(arr[0]);
15 sprintf(argv,"%d",arr[1]);
16 execlp("./server","server",argv,NULL);
17 }
18 else
19 {
20 printf("Starting client as child - my PID is %d\n", getpid());
21 fflush(stdout);
22 close(arr[1]);
23 sprintf(argv,"%d",arr[0]);
24 execlp("./client","client",argv,NULL);
25 }
26 return 1;
27 }
server.c
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 int main(int argc,char *argv[])
8 {
9 char buf[40]="hello";
10 int fd,i;
11
12 fd = atoi(argv[1]);
13 printf("Server started my PID is %d\n", getpid());
14 for (i=1; i <= 5; i++) {
15 sprintf(buf,"hello: %d",i);
16 write(fd,buf,strlen(buf)+1);
17 sleep(1);
18 }
19 buf[0] == 0;
20 close(fd);
21 puts("Server signing out");
22
23 return 0;
24 }
client.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <sys/types.h>
4 #include <stdlib.h>
5
6 int main(int argc,char *argv[])
7 {
8 char buf[11];
9 int fd;
10
11 printf("Client started my PID is %d\n", getpid());
12 fd = atoi(argv[1]);
13 while(read(fd,buf,10) > 0)
14 {
15 printf("Client received: %s\n",buf);
16 }
17 close(fd);
18 printf("Client signing out\n");
19 return 0;
20 }