Processes in UNIX System calls
Document Sample


Processes in UNIX
System calls
What is a process?
Definition
A temporal succession of actions – produced by the
execution of a sequence of instructions
A program in execution
Process hierarchy
Treelike (similar to the UNIX filesystem)
INIT process is the root (pid=1) – started during
booting the system
all further processes are sucessors of INIT
For each terminal, getty is started for the interaction
with the system.
After the successful login a shell program is started.
What are system calls?
Interface between processes and the Operating
System
Direct access to the the kernel
A System Call writes the parameters in a certain
address and triggers a TRAP. The OS takes over
the control.
Produces, destroys, and uses resources managed
by the OS.
System calls, #2
Examples of resources :
Processes
Files
Memory
Semaphores
Function call vs. system call?
function is part of the program of a user (user
space)
system call executes kernel code (kernel space)
System calls, #3
System call fork()
creates a new process
After the exection of fork(), two identical processes
exist, but run completely independently.
Syntax
#include <unistd.h>
pid_t fork(); /* pid_t is mapped to an integer */
Return values:
the parent: the PID of the child process
the child: 0
error: 1
fork(), #2
System call wait()
wait for the end of a child (used in the parent
process)
Syntax
#include <sys/wait.h>
pid_t wait(int *status);
return values:
the pid of the child process which terminated
error: 1 (errno is set)
the exit status of the child process can be read
using macros
System call exec()
loads a program code into the current process
overloads a process with new code
several „flavours“ of exec() routines:
execl, execle, execv, execlp and execvp.
Syntax
int execvp( const char *file, char *const argv[])
file program to be executed
argv the arguments for the program
exec() examples
#include <unistd.h>
int ret;
...
ret=execlp(“ls“,“ls“,“-l“,NULL);
char *env[]={“HOME=/usr/home“,NULL);
...
ret=execle(“/bin/ls“,“ls“,“-l“,NULL,env);
char *cmd[]={ “ls“, “-l“, NULL};
...
ret=execvp(“ls“, cmd);
System call fgets()
reads from stream until “\n“ or EOF
produces a nullterminated string
Example:
#include<stdio.h>
char buf[255];
printf ("type something: ");
if ( fgets(buf, sizeof(buffer), stdin)!=NULL) {
printf ("you typed:%s\n",buf);
}
alternative: scanf()
System call strtok()
divides a string on the basis of a separator into
several parts (tokens).
returns: the part of the string until the next separator
Syntax
#include <string.h>
char *strtok( char *str1, const char *delimiter );
The string to be divided must be given only for the
first call, all the subsequent calls need only the
separator (see example)
strtok(), #2
Example:
char str[] = ” now # is time for # good men";
char delims[] = "#";
char *result = NULL;
result = strtok( str, delims );
while( result != NULL ) {
printf( "result is \"%s\"\n", result );
result = strtok( NULL, delims ); }
Output:
result is "now "
result is " is time for "
result is " good men”
System call getpid()
returns the process ID of the current
process
to get the pid of the parent process:
getppid()
Example:
#include<stdio.h>
int main(int argc, char **argv)
{
int pid=getpid();
printf ("my pid:%d\n",pid)
}
PIPES
(Full & Half Duplex)
Pipes – pipe()
What is a pipe?
communication channel between related processes
often used in the interactive shell
“ ls – l | grep foo | wc – l“
serves as control flow between processes
supports only a certain amount of data (normally
4KByte)
pipes(), #2
Two types of pipes
Bidirectional – Fullduplex Pipe (not
available under Linux)
Unidirectional – Halfduplex Pipe
A pipe has two ends:
fd[0] is the filedescriptor for READING
fd[1] is the filedescriptor for WRITTING
Pipes – pipe()
Two types of Pipes
Bidirectional – Fullduplex Pipe
fd[1] fd[0]
Father process Child process
fd[0] fd[1]
Unidirectional – Halfduplex Pipe
Pipes and system calls
pipe()
creates a pipe, returns two descriptors
read()
blocks, until the data is written in the pipe
returns EOF and/or 0, if the writing process closed the
pipe
write()
blocks, if the pipe buffer is full and no read access
a SIGPIPE signal is generated if the read descriptor is
closed
Pipes and system calls, #2
fdopen()
assigns a descriptor to a file pointer
pipe can be treated as normal file (fprintf(), fscanf(),
…)
Do not mix descriptors and file pointers!
dup(), dup2()
Produces a copy (duplicates) of a file descriptor
The old and the new file descriptors can be used
interchangeably
Allows to manipulate stdin, stdout, stderr
popen(), pclose()
popen()
Produces a child process and supplies descriptor on
standard channels
The following steps are done:
pipe();
fork();
dup();
close();
exec();
pclose()
Closes child process created by popen()
Has the same meaning as wait() for fork()
Stdin, Stdout and Stderr
fd table
0 stdin
1 stdout
2 stderr
out ...
in
P
err
fd table has “file descriptors” for normal files, but also entries for
special files like pipes or network sockets, etc...
Redirecting stdout... (cat > my.file)
In C:
fd = open(“my.file”...); out my.file
in
dup2(fd, STDOUT_FILENO);
cat
close(fd);
err
write(STDOUT_FILENO, “OK”,...);
fd table fd table fd table
0 stdin 0 stdin 0 stdin
1 stdout 1 stdout 1 write to my.file
2 stderr 2 stderr 2 stderr
3 write to my.file 3 write to my.file 3 write to my.file
(after open) (after dup2) (after close)
Using pipes for communication
exec (“ls –l | sort –n); // DOESN’T WORK
int ret,pid,fd[2]; // pipe’ s read end (fd[0]) write end (fd[1])
pipe(fd); // create a pipe!
pid = fork(); // duplicate the current process
if (pid==0) { // son: inherits the file descriptors!
dup2(fd[1], STDOUT_FILENO); // copies write pipe on stdout
close(fd[0]); // do not need read pipe
close(fd[1]); // do not need pipe write
ret=execlp ("ls", "ls", "-l", NULL);
} else { // father:
dup2(fd[0], STDIN_FILENO);
close(fd[0]); close(fd[1]);
ret=execlp("sort", "sort", "-n", NULL);
}
Error handling
What is error handling?
System calls under Unix have a uniform convention
for the return of values:
Return values are of type integer (int)
In case of error 1 is returned, and (usually) the external
variable errno is set)
strerror() converts the error code from errno into a
string, which describes the error cause
Error handling with errno.h
defines the global variable errno, which is set by
different functions when an error happens.
Further it defines all possible values of errno.
Error handling with perror()
produces a message on the stdout, describing the
last error encountered during a system call or a
library function
The error message refers to the variable errno
Syntax
#include <stdio.h>
void perror( const char *s )
the string „s“ will be printed first, followed by a colon
and a blank, and then the error message.
If the parameter „s“ is NULL, only the error message is
displayed
Related docs
Get documents about "