SlideShare a Scribd company logo
UNIX SYSTEM PROGRAMMING
BY
PROF. A. SYED MUSTAFA
HKBK COLLEGE OF ENGINEERING
1. Function prototyping
2. Support of the const and volatile data type qualifiers.
3. Support wide characters and internationalization.
4. Permit function pointers to be used without dereferencing.
The major differences between ANSI C and K&R C
[Kernighan and Ritchie] are as follows:
2PROF. SYED MUSTAFA, HKBKCE
1. Function prototyping
ANSI C adopts C++ function prototype technique where function definition and declaration include
function names, arguments’ data types, and return value data types.
This enables ANSI C compilers to check for function calls in user programs that pass invalid number of
arguments or incompatible arguments’ data type.
These fix a major weakness of K&R C compilers: invalid function calls in user programs often pass
compilation but cause programs to crash when they are executed.
Eg: unsigned long demo(char * fmt, double data)
{
/*body of demo*/
}
External declaration of this function demo is
unsigned long demo(char * fmt, double data);
eg: int printf(const char* fmt,...........); specify variable number of arguments
The major differences between ANSI C and K&R C
[Kernighan and Ritchie] are as follows:
3PROF. SYED MUSTAFA, HKBKCE
2. Support of the const and volatile data type qualifiers
The const keyword declares that some data cannot be changed.
Eg: int printf(const char* fmt,...........);
Declares a fmt argument that is of a const char * data type, meaning that the
function printf cannot modify data in any character array that is passed as an actual
argument value to fmt.
The major differences between ANSI C and K&R C
[Kernighan and Ritchie] are as follows:
4PROF. SYED MUSTAFA, HKBKCE
2. Support of the const and volatile data type qualifiers
Volatile keyword specifies that the values of some variables may change
asynchronously, giving an hint to the compiler’s optimization algorithm not to
remove any “redundant” statements that involve “volatile” objects.
eg:
char get_io()
{
volatile char* io_port = 0x7777;
char ch = *io_port; /*read first byte of data*/
ch = *io_port; /*read second byte of data*/
}
If io_port variable is not declared to be volatile when the program is compiled, the
compiler may eliminate second ch = *io_port statement, as it is considered
redundant with respect to the previous statement.
The major differences between ANSI C and K&R C
5PROF. SYED MUSTAFA, HKBKCE
3. Support wide characters and internationalization
• ANSI C supports internationalisation by allowing C-program to use wide
characters. Wide characters use more than one byte of storage per character.
• ANSI C defines the setlocale function, which allows users to specify the format of
date, monetary and real number representations.
• For eg: most countries display the date in dd/mm/yyyy format whereas US
displays it in mm/dd/yyyy format.
Function prototype of setlocale function is:
#include<locale.h>
char setlocale(int category, const char* locale);
The major differences between ANSI C and K&R C
6PROF. SYED MUSTAFA, HKBKCE
3. Support wide characters and internationalization
The major differences between ANSI C and K&R C
The setlocale function prototype and possible values of the category argument are declared in the
<locale.h> header. The category values specify what format class(es) is to be changed.
Some of the possible values of the category argument are:
Category Value Effect on standard C functions/macros
LC_CTYPE ⇒ Affects behavior of the <ctype.h> macros
LC_TIME ⇒ Affects date and time format.
LC_NUMERIC ⇒ Affects number representation format
LC_MONETARY ⇒ Affects monetary values format
LC_ALL ⇒ combines the affect of all above
Eg: setlocale(LC_ALL, “C”);
7PROF. SYED MUSTAFA, HKBKCE
4. Permit function pointers to be used without dereferencing
ANSI C specifies that a function pointer may be used like a function name. No
referencing is needed when calling a function whose address is contained in the
pointer.
For Example:
extern void foo(double xyz,const int *ptr);
void (*funptr)(double,const int *)=foo;
The function can be called directly or through function pointer as given below:
foo(12.78,”Hello world”);
funptr(12.78,”Hello world”);
K& R C requires funptr be dereferenced to call foo:
(* funptr) (13.48,”Hello usp”);
The major differences between ANSI C and K&R C
8PROF. SYED MUSTAFA, HKBKCE
#include<unistd.h>
long sysconf(const int limit_name);
long pathconf(const char *pathname, int flimit_name );
long fpathconf(const int fd, int flimit_name);
Limits checking at Run time
9PROF. SYED MUSTAFA, HKBKCE
Limits checking at Run time
The following test_config.C illustrates the
use of sysconf, pathcong and fpathconf:
#define _POSIX_SOURCE
#define _POSIX_C_SOURCE 199309L
#include<stdio.h>
#include<iostream.h>
#include<unistd.h>
int main()
{
int res;
if((res=sysconf(_SC_OPEN_MAX))==-1)
perror(“sysconf”);
else
cout<<”OPEN_MAX:”<<res<<endl;
if((res=pathconf(“/”,_PC_PATH_MAX))==-1)
perror(“pathconf”);
else
cout<<”max path name:”<<(res+1)<<endl;
if((res=fpathconf(0,_PC_CHOWN_RESTRICTED))==-1)
perror(“fpathconf”);
else
cout<<”chown_restricted for stdin:”<<res<<endl;
return 0;
}
10PROF. SYED MUSTAFA, HKBKCE
The POSIX.1 FIPS Standard
FIPS stands for Federal Information Processing Standard. The FIPS standard is a restriction of the
POSIX.1 – 1988 standard, and it requires the following features to be implemented in all FIPS-
conformingsystems:
 Job control
 Saved set-UID and saved set-GID
 Long path name is not supported
 The _POSIX_CHOWN_RESTRICTED must be defined
 The _POSIX_VDISABLE symbol must be defined
 The NGROUP_MAX symbol’s value must be at least 8
 The read and write API should return the number of bytes that have been transferred after the
APIs have been interrupted by signals
 The group ID of a newly created file must inherit the group ID of its containing directory
11PROF. SYED MUSTAFA, HKBKCE
The X/OPEN Standards
The X/Open organization was formed by a group of European companies to
propose a common operating system interface for their computer systems.
The portability guides specify a set of common facilities and C application
program interface functions to be provided on all UNIX based open systems.
In 1973, a group of computer vendors initiated a project called “common
open software environment” (COSE). The goal of the project was to define a
single UNIX programming interface specification that would be supported
by all type vendors.
The applications that conform to ANSI C and POSIX also conform to the
X/Open standards but not necessarily vice-versa.
12PROF. SYED MUSTAFA, HKBKCE
UNIX AND POSIX APIs
API - A set of application programming interface functions that can be called
by user programs to perform system specific functions.
Most UNIX systems provide a common set of API’s to perform the following
functions.
13PROF. SYED MUSTAFA, HKBKCE
API Common Characteristics
 Many APIs returns an integer value which indicates the termination
status of their execution
 API return -1 to indicate the execution has failed, and the global variable
errno is set with an error code.
 a user proces may call perror() function to print a diagnostic message of
the failure to the std o/p, or
 it may call strerror() function and gives it errno as the actual argument
value; the strerror function returns a diagnostic message string and
the user process may print that message in its preferred way
 the possible error status codes that may be assigned to errno by any API
are defined in the <errno.h> header.
14PROF. SYED MUSTAFA, HKBKCE
Commonly occur error status codes and their meanings
15PROF. SYED MUSTAFA, HKBKCE
UNIT 2 - UNIX FILES
Files are the building blocks of any operating system.
File Types
A file in a UNIX or POSIX system may be one of the following types:
•Regular file
•Directory file
•FIFO file
•Character device file
•Block device file
16PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
•Regular file
A regular file may be either a text file or a binary file
These files may be read or written to by users with the appropriate access permission
Regular files may be created, browsed through and modified by various means
such as text editors or compilers, and they can be removed by specific system
commands
17PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
•Directory file
It is like a folder that contains other files, including sub-directory files.
It provides a means for users to organise their files into some hierarchical structure
based on file relationship or uses.
Ex: /bin directory contains all system executable programs, such as cat, rm, sort
A directory may be created in UNIX by the mkdir command
Ex: mkdir /usr/foo/xyz
A directory may be removed via the rmdir command
Ex: rmdir /usr/foo/xyzThe content of directory may be displayed by the
ls command
18PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
•Device file
o For block device file, use argument ‘b’ instead of ‘c’.
19PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
•Device file
 Major device number:
 It is an index to a kernel table that contains the addresses of all device driver
functions known to the system.
 Whenever a process reads data from or writes data to a device file, the kernel uses
the device file’s major number to select and invoke a device driver function to carry
out actual data transfer with a physical device.
 Minor device number:
 It is an integer value to be passed as an argument to a device driver function when
it is called.
 It tells the device driver function what actual physical device is talking to and the
I/O buffering scheme to be used for data transfer.
20PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
 FIFO file
It is a special pipe device file which provides a temporary buffer for two or more processes to
communicate by writing data to and reading data from the buffer.
The size of the buffer is fixed to PIPE_BUF.
Data in the buffer is accessed in a first-in-first-out manner.
The buffer is allocated when the first process opens the FIFO file for read or write
The buffer is discarded when all processes close their references (stream pointers) to the FIFO file.
Data stored in a FIFO buffer is temporary.
A FIFO file may be created via the mkfifo command.
oThe following command creates a FIFO file
mkfifo /usr/d1/myfifo
mknod /usr/d1/myfifo p
FIFO files can be removed using rm command.
21PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
 Symbolic link file
BSD UNIX & SV4 defines a symbolic link file. POSIX.1 does not support symbolic link file type
A symbolic link file contains a path name which references another file in either local or a remote file
system.
A symbolic link may be created in UNIX via the ln command
Ex: ln -s /usr/d1/f1 /usr/d2/f2
It is possible to create a symbolic link to reference another symbolic link.
rm, mv and chmod commands will operate only on the symbolic link arguments directly and not on the files
that they reference.
22PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
23PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
24PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
The UNIX and POSIX File Attributes
The general file attributes for each file in a file system are:
1)File type - specifies what type of file it is.
2)Access permission - the file access permission for owner, group and others.
3)Hard link count - number of hard link of the file
4)Uid - the file owner user id.
5)Gid - the file group id.
6)File size - the file size in bytes.
7)Inode no - the system inode no of the file.
8)File system id - the file system id where the file is stored.
25PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
The UNIX and POSIX File Attributes
The general file attributes for each file in a file system are:
9) Last access time - the time, the file was last accessed.
10) Last modified time - the file, the file was last modified.
11) Last change time - the time, the file was last changed.
12) Major Number
13) Minor Number
The attributes that are constant and cannot be changed for any file are:
File type
File inode number
File system ID
Major and minor device number
26PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
27PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
In UNIX system V, a file system has an inode table, which keeps tracks of all files.
Each entry of the inode table is an inode record which contains all the attributes
of a file, including inode no. and the physical disk address where data of the file is
stored
For any operation, if a kernel needs to access information of a file with an inode
no. 15, it will scan the inode table to find an entry, which contains an inode no.
15 in order to access the necessary data.
An inode no is unique within a file system.
A file inode record is identified by a file system ID and an inode no.
Inodes in UNIX System V
28PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Generally an OS does not keep the name of a file in its record, because the
mapping of the filenames to inode no is done via directory files i.e. a directory
file contains a list of names of their respective inode no. for all file stored in that
directory.
Ex: a sample directory file content
Inodes in UNIX System V
Inode number File name
115 .
89 ..
201 xyz
346 a.out
201 xyz_lnk
29PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Inodes in UNIX System V
To access a file, for example /usr/syed, the UNIX kernel always
knows the “/” (root) directory inode number of any process.
It will scan the “/” directory file to find the inode number of the
usr file. Once it gets the usr file inode number, it accesses the
contents of usr file. It then looks for the inode number of syed
file.
Whenever a new file is created in a directory, the UNIX kernel
allocates a new entry in the inode table to store the information
of the new file
It will assign a unique inode number to the file and add the new
file name and inode number to the directory file that contains it.
30PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Application Programming Interface to Files
Files are identified by pathnames.
Files should be created before they can be used.
The various commands and system calls to create files are
File type commands System call
Regular file
Directory file
FIFO file
Device file
Symbolic link file
vi,pico,emac
mkdir
mkfifo
mknod
ln –s
open,creat
mkdir,
mknod mkfifo,
mknod
Symlink
31PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Application Programming Interface to Files
For any application to access files, first it should be opened.
Generally we use open system call to open a file, and the
returned value is an integer which is termed as file descriptor.
There are certain limits of a process to open files.
A maximum number of OPEN-MAX files can be opened.The
value is defined in <limits.h> header.
The data transfer function on any opened file is carried out by
read and write system call.
32PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Application Programming Interface to Files
File hard links can be increased by link system call, and
decreased by unlink system call.
File attributes can be changed by chown, chmod and link
system calls.
File attributes can be queried (found out or retrieved) by stat
and fstat system call.
UNIX and POSIX.1 defines a structure of data type stat i.e.
defined in <sys/stat.h> header file. This contains the user
accessible attribute of a file.
33PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
34PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILESUNIX Kernel Support for Files
In UNIX system V, the kernel maintains a file table that has an entry of
all opened files and also there is an inode table that contains a copy of
file inodes that are most recently accessed.
A process, which gets created when a command is executed will be
having its own data space (data structure) wherein it will be having file
descriptor table.
The file descriptor table will be having an maximum of OPEN_MAX file
entries.
Whenever the process calls the open function to open a file to read or
write, the kernel will resolve the pathname to the file inode number.
35PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
UNIX Kernel Support for Files
Data Structure for File Manipulation 36PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
UNIX Kernel Support for Files
The steps involved are :
1. The kernel will search the process file descriptor table and
look for the first unused entry.
2. If an entry is found, that entry will be designated to
reference the file .The index of the entry will be returned to
the process as the file descriptor of the opened file.
3. The kernel will scan the file table in its kernel space to find
an unused entry that can be assigned to reference the file.
37PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILESUNIX Kernel Support for Files
If an unused entry is found the following events will occur:
1. The process file descriptor table entry will be set to point to this file
table entry.
2. The file table entry will be set to point to the inode table entry, where
the inode record of the file is stored.
3. The file table entry will contain the current file pointer of the open file.
This is an offset from the beginning of the file where the next read or
write will occur.
4. The file table entry will contain an open mode that specifies that the
file opened is for read only, write only or read and write etc. This
should be specified in open function call.
38PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
UNIX Kernel Support for Files
If an unused entry is found the following events will occur:
5. The reference count (rc) in the file table entry is set to 1. Reference count
is used to keep track of how many file descriptors from any process are
referring the entry.
6. The reference count of the in-memory inode of the file is increased by 1.
This count specifies how many file table entries are pointing to that
inode.
If either (1) or (2) fails, the open system call returns -1 (failure/error)
39PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
UNIX Kernel Support for Files
Normally the reference count in the file table entry is 1, if we wish to increase the rc in the
file table entry, this can be done using fork,dup,dup2 system call.
When a open system call is succeeded, its return value will be an integer (file descriptor).
Whenever the process wants to read or write data from the file, it should use the file
descriptor as one of its argument.
40PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILESUNIX Kernel Support for Files
The following events will occur whenever a process calls the close function to close
the files that are opened.
1. The kernel sets the corresponding file descriptor table entry to be unused.
2. It decrements the rc in the corresponding file table entry by 1, if rc not equal to 0 go to
step 6.
3. The file table entry is marked as unused.
4. The rc in the corresponding file inode table entry is decremented by 1, if rc value not
equal to 0. go to step 6.
5. If the hard link count of the inode is not zero, it returns to the caller with a success status
otherwise it marks the inode table entry as unused and de-allocates all the physical dusk
storage of the file.
6. It returns to the process with a 0 (success) status.
41PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Relationship of C Stream Pointers and File Descriptors
The major difference between the stream pointer and the file descriptors are as
follows:
42PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Relationship of C Stream Pointers and File Descriptors
C library function UNIX system call used
fopen open
fread, fgetc, fscanf, fgets read
fwrite, fputc, fprintf, fputs write
fseek, fputc, fprintf, fputs lseek
fclose close
The file descriptor associated with a stream pointer can be extracted by fileno macro, which is
declared in the<stdio.h> header.
int fileno(FILE * stream_pointer);
To convert a file descriptor to a stream pointer, we can use fdopen C library function
FILE *fdopen(int file_descriptor, char * open_mode);
The following lists some C library functions and the underlying UNIX APIs they use to perform their
functions:
43PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Directory Files
 It is a record-oriented file.
 Each record contains the information of a file residing in that directory
 The record data type is struct dirent in UNIX System V and POSIX.1 and
struct direct in BSD UNIX.
 The record content is implementation-dependent
 They all contain 2 essential member fields:
1. File name
2. Inode number
Usage is to map file names to corresponding inode number
:
44PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Directory Files
: Directory function Purpose
opendir Opens a directory file
readdir Reads next record from the file
closedir Closes a directory file
rewinddir Sets file pointer to beginning of file
45PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Hard and Symbolic Links
:
hard link is a UNIX pathname for a file. Generally most of the UNIX files will be
having only one hard link.
In order to create a hard link, we use the command ln.
Example :
Consider a file /usr/ syed/f1, to this we can create a hard link by
ln /usr/syed/f1 /usr/ syed/f2
Symbolic link can be creates by the same command ‘ln’ but
with option –s
Example: ln –s /usr/syed/f1 /usr/syed/sf1
46PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Hard and Symbolic Links
:
ln command differs from the cp(copy) command in that cp
creates a duplicated copy of a file to another file with a different
pathname,
whereas ln command creates a new link to reference a file.
47PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Hard and Symbolic Links
:
Let’s visualize the content of a directory file after the execution of command ln.
Case 1: for hard link file
ln /usr/syed/abc /usr/mustafa/xyz
The content of the directory files /usr/syed and /usr/mustafa are:
48PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Hard and Symbolic Links
:
Let’s visualize the content of a directory file after the execution of command ln.
Case 1: for hard link file
ln /usr/syed/abc /usr/mustafa/xyz
The content of the directory files /usr/syed and /usr/mustafa are:
Both /urs/syed/abc and /usr/mustafa/xyz refer to the same inode
number 201, thus no new file is created.
49PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Hard and Symbolic Links
:
Case 2: For the same operation, if ln –s command is used then a new inode will be
created.
ln –s /usr/syed/abc /usr/mustafa/xyz
The content of the directory files syed and mustafa will be
If cp command was used then the data contents will be identical and the 2 files will
be separate objects in the file system, whereas in ln –s the data will contain only
the path name.
50PROF. SYED MUSTAFA, HKBKCE
UNIT 2 UNIX FILES
Hard and Symbolic Links
:
Limitations of hard link:
 User cannot create hard links for directories, unless he has super-user privileges.
 User cannot create hard link on a file system that references files on a different file system,
because inode number is unique to a file system.
Differences between hard link and symbolic link are listed below:
51PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
A file in a UNIX or POSIX system may be one of the following
types:
•Regular file
•Directory file
•FIFO file
•Character device file
•Block device file
•Symbolic link file
There are special API’s to create these types of files
:
52PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIsopen
This is used to establish a connection between a process and a file
i.e. it is used to open an existing file for data transfer function or else it
may be also be used to create a new file.
The returned value of the open system call is the file descriptor (row
number of the file table), which contains the inode information.
The prototype of open function is
#include<sys/types.h>
#include<sys/fcntl.h>
int open(const char *pathname, int accessmode, mode_t permission);
53PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
open
 If successful, open returns a nonnegative integer representing the open
file descriptor.If unsuccessful, open() returns –1.
 The first argument is the name of the file to be created or opened.
 This may be an absolute pathname or relative pathname.
 If the given pathname is symbolic link, the open function will resolve
the symbolic link reference to a non symbolic link file to which it refers.
 The second argument is access modes, which is an integer value that
specifies how actually the file should be accessed by the calling process.
: 54PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
open
Generally the access modes are specified in <fcntl.h>.
Various access modes are:
There are other access modes, which are termed as access modifier flags,
and one or more of the following can be specified by bitwise-ORing them
with one of the above access mode flags to alter the access mechanism of
the file.
Sl. No Flag Meaning
1 O_RDONLY open for reading file only
2 O_WRONLY open for writing file only
3 O_RDWR opens for reading and writing file
55PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
open
access modifier flags
S.No Flag Meaning
1 O_APPEND Append data to the end of file.
2 O_CREAT Create the file if it doesn’t exist
3 O_EXCL Generate an error if O_CREAT is also specified and the
file already exists.
4 O_TRUNC If file exists discard the file content and set the file
size to zero bytes.
5 O_NONBLOCK Specify subsequent read or write on the file should be
non-blocking.
6 O_NOCTTY Specify not to use terminal device file as the calling
process control terminal.
56PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
open
To illustrate the use of the above flags, the following example statement opens
a file called /usr/syed/usp for read and write in append mode:
int fd=open(“/usr/syed/usp”, O_RDWR | O_APPEND,0);
If the file is opened in read only, then no other modifier flags can be used.
If a file is opened in write only or read write, then we are allowed to use any
modifier flags along with them.
The third argument is used only when a new file is being created.
57PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
open
58PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
open
59PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
open
60PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
open
To open "sample.txt" in the current working directory for appending or create it, if it
does not exist, with read, write and execute permissions for owner only:
fd = open(“sample.txt", O_WRONLY|O_APPEND|O_CREAT, S_IRWXU);
fd = open(“sample.txt", O_WRONLY|O_APPEND|O_CREAT, 0700);
fd = open(“sample.txt", O_WRONLY|O_CREAT|O_EXCL,
S_IRWXU|S_IROTH|S_IWOTH);
fd = open(“sample.txt", O_WRONLY|O_CREAT|O_EXCL,0706);
fd = open(“sample.txt", O_WRONLY|O_CREAT|O_TRUNC,0706);
61PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
open
Tag Description
EACCES The requested access to the file is not allowed, or search
permission is denied for one of the directories in the path
prefix of pathname, or the file did not exist yet and write
access to the parent directory is not allowed.
EEXIST pathname already exists and O_CREAT and O_EXCL were
used.
EFAULT pathname points outside accessible address space.
ENOENT O_CREAT is not set and the named file does not exist. Or, a
directory component in pathname does not exist or is a
dangling symbolic link.
ENOMEM Insufficient kernel memory was available.
62PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
creat ( )
•This system call is used to create new regular files.
#include <sys/types.h>
#include<unistd.h>
int creat(const char *pathname, mode_t mode);
•Returns: file descriptor opened for write-only if OK, -1 on error.
•The first argument pathname specifies name of the file to be created.
•The second argument mode_t, specifies permission of a file to be
accessed by owner group and others.
•The creat function can be implemented using open function as:
#define creat(path_name, mode)
open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);
63PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
read ( )
The read function fetches a fixed size of block of data from a file referenced by a
given file descriptor.
The prototype of read function is:
#include<sys/types.h>
#include<unistd.h>
size_t read(int fdesc, void *buf, size_t nbyte);
 If successful, read returns the no. of bytes actually read, on error it returns –1.
 The first argument is an integer, fdesc that refers to an opened file.
 The second argument, buf is the address of a buffer holding any data read.
 The third argument specifies how many bytes of data are to be read from the
file.
 The size_t data type is defined in the <sys/types.h> header and should be the
same as unsigned int.
64PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
read ( )
There are several cases in which the number of bytes actually read is less than
the amount requested:
 When reading from a regular file, if the end of file is reached before the
requested number of bytes has been read.
 For example, if 30 bytes remain until the end of file and we try to read 100
bytes, read returns 30. The next time we call read, it will return 0 (end of file).
 When reading from a terminal device. Normally, up to one line is read at a
time.
 When reading from a network. Buffering within the network may cause less
than the requested amount to be returned.
 When reading from a pipe or FIFO. If the pipe contains fewer bytes than
requested, read will return only what is available.
65PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
read ( )- Errors
Tag Description
EAGAIN
Non-blocking I/O has been selected using O_NONBLOCK and no data
was immediately available for reading.
EBADF fd is not a valid file descriptor or is not open for reading.
EFAULT buf is outside your accessible address space.
EINTR The call was interrupted by a signal before any data was read.
EINVAL
fd is attached to an object which is unsuitable for reading; or the file
was opened with the O_DIRECT flag, and either the address specified
in buf, the value specified in count, or the current file offset is not
suitably aligned.
EIO
I/O error. This will happen for example when the process is in a
background process group, tries to read from its controlling tty, and
either it is ignoring or blocking SIGTTIN or its process group is
orphaned. It may also occur when there is a low-level I/O error while
reading from a disk or tape.
EISDIR fd refers to a directory.
66PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
read ( )
#include<fcntl.h>
int main()
{
int fd,nob;char c[256];
fd=open(“sample”,O_RDONLY);
nob= read(fd,c,sizeof(c));
if(nob!=-1)
printf("%sn",c);
else
perror(“read Error”);
close(fd);
return 0;
}
67PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
write( )
The write system call is used to write data into a file
The write function puts data to a file in the form of fixed block size referred by a
given file.
The prototype of read function is:
#include<sys/types.h>
#include<unistd.h>
ssize_t write(int fdesc, const void *buf, size_t size);
 If successful, write returns the number of bytes actually written.
 If unsuccessful, write returns –1.
 The first argument, fdesc is an integer that refers to an opened file.
 The second argument, buf is the address of a buffer that contains data to be written.
 The third argument, size specifies how many bytes of data are in the buf argument.
 The return value is usually equal to the number of bytes of data successfully written to a file.
(size value)
68PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
write( )-Errors
Error Code Description
EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and the write would block.
EBADF fd is not a valid file descriptor or is not open for writing.
EFAULT buf is outside your accessible address space.
EFBIG An attempt was made to write a file that exceeds the implementation-defined
maximum file size or the process’ file size limit, or to write at a position past the
maximum allowed offset.
EINTR The call was interrupted by a signal before any data was written.
EINVAL fd is attached to an object which is unsuitable for writing; or the file was opened with
the O_DIRECT flag, and either the address specified in buf, the value specified
in count, or the current file offset is not suitably aligned.
EIO A low-level I/O error occurred while modifying the inode.
EPIPE fd is connected to a pipe or socket whose reading end is closed. When this happens
the writing process will also receive a SIGPIPE signal. (Thus, the write return value is
seen only if the program catches, blocks or ignores this signal.)
69PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIswrite( )
#include<fcntl.h>
int main()
{
int fd,nob;char c[]=“ This is sample text”;
fd=open(“sample”,O_WRONLY,0777);
nob= write(fd,c,strlen(c));
if(nob!=-1)
printf(“Successfully written to file”);
else
perror(“write Error”);
close(fd);
return 0;
}
70PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
close( )
The close system call is used to terminate the connection to a file from a
process.
The prototype of the close() is
#include<unistd.h>
int close(int fdesc);
 If successful, close returns 0.
 If unsuccessful, close returns –1.
 The argument fdesc refers to an opened file.
 Close function frees the unused file descriptors so that they can be reused to reference other
files. This is important because a process may open up to OPEN_MAX files at any time and
the close function allows a process to reuse file descriptors to access more than OPEN_MAX
files in the course of its execution.
 The close function de-allocates system resources like file table entry and memory buffer
allocated to hold the read/write.
71PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
close( ) - Errors
Tag Description
EBADF fd isn’t a valid open file descriptor.
EINTR The close() call was interrupted by a signal.
EIO An I/O error occurred.
72PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
Emulate ‘cp’ UNIX command – cp f1 f2
#include<fcntl.h>
int main()
{
int fd1,fd2,nob;
char c;
fd1=open(“f1”,O_RDONLY);
fd2=open(“f2”,O_WRONLY|)_CREAT|O_TRUNC, 0777);
while(read(fd1,&c,1))
write(fd2,&c,1);
close(fd1);
close(fd2);
return 0;
}
73PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
Emulate ‘cp’ UNIX command – cp f1 f2
#include<fcntl.h>
int main()
{
int fd1,fd2,nob;
char c;
fd1=open(“f1”,O_RDONLY);
If(fd1!=-1)
{ fd2=open(“f2”,O_WRONLY|)_CREAT|O_TRUNC, 0777);
if(fd2!=-1)
{ while(read(fd1,&c,1))
write(fd2,&c,1);
close(fd1);
close(fd2);
}
else
{
perror(“write Error”);
close(fd1);
}
} /*if fd1 */
else
perror(“read Error”);
return 0;
}
74PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
75PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
76PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
77PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
78PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
79PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
80PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
81PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
82PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
83PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
84PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
85PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
86PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
Chown(), fchown(), lchown()
The chown functions changes the user ID and group ID of files.
The prototypes of these functions are:
#include<unistd.h>
#include<sys/types.h>
int chown(const char *path_name, uid_t uid, gid_t gid);
int fchown(int fdesc, uid_t uid, gid_t gid);
int lchown(const char *path_name, uid_t uid, gid_t gid);
The path_name argument is the path name of a file.
The uid argument specifies the new user ID to be assigned to the file.
The gid argument specifies the new group ID to be assigned to the file.
87PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
Chown(), fchown(), lchown()
/* Program to illustrate chown() */
#include<iostream.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<pwd.h>
int main(int argc, char *argv[ ])
{
if(argc>3)
{
cerr<<”usage:”<<argv[0]<<”<usr_name><
file>....n”;
return 1;
}
struct passwd *pwd = getpwuid(argv[1]) ;
uid_t UID = pwd ? pwd -> pw_uid : -1 ;
struct stat statv;
if (UID == (uid_t)-1)
cerr <<“Invalid user name”;
else
for (int i = 2; i < argc ; i++)
if (stat(argv[i], &statv)==0)
{
if (chown(argv[i], UID,statv.st_gid))
perror (“chown”);
}
return 0;
}
88PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
Chmod(), fchmod()
The chmod and fchmod functions change file access permissions for owner, group &
others as well as the set_UID, set_GID and sticky flags.
A process must have the effective UID of either the super-user/owner of the file.
The prototypes of these functions are
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
int chmod(const char *pathname, mode_t flag);
int fchmod(int fdesc, mode_t flag);
89PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
Chmod(), fchmod()
 The pathname argument of chmod is the path name of a file whereas the fdesc argument of fchmod is
the file descriptor of a file.
 The chmod function operates on the specified file, whereas the fchmod() function operates on a file
that has already been opened.
 To change the permission bits of a file, the effective user ID of the process must be equal to the owner
ID of the file, or the process must have super-user permissions. The mode is specified as the bitwise OR
of the constants shown below
90PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
91PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
92PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
93PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
94PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
95PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
96PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
97PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
File and Record Locking
 Multiple processes performs read and write operation on the
same file concurrently.
 This provides a means for data sharing among processes, but it
also renders difficulty for any process in determining when the
other process can override data in a file.
 So, in order to overcome this drawback UNIX and POSIX standard
support file locking mechanism.
 File locking is applicable for regular files.
98PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
File and Record Locking
 Only a process can impose a write lock or read lock on either a portion of a
file or on the entire file.
 The differences between the read lock and the write lock is that when write
lock is set, it prevents the other process from setting any over-lapping read
or write lock on the locked file.
 Similarly when a read lock is set, it prevents other processes from setting
any overlapping write locks on the locked region.
 The intension of the write lock is to prevent other processes from both
reading and writing the locked region while the process that sets the lock is
modifying the region, so write lock is termed as “Exclusive lock”.
99PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
File and Record Locking
 The use of read lock is to prevent other processes from writing to the
locked region while the process that sets the lock is reading data from the
region.
 Other processes are allowed to lock and read data from the locked regions.
Hence a read lock is also called as “shared lock “.
 File lock may be mandatory if they are enforced by an operating system
kernel.
 If a mandatory exclusive lock is set on a file, no process can use the read or
write system calls to access the data on the locked region.
 These mechanisms can be used to synchronize reading and writing of
shared files by multiple processes.
100PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
File and Record Locking
 If a process locks up a file, other processes that attempt to write to the
locked regions are blocked until the former process releases its lock.
 Problem with mandatory lock is – if a runaway process sets a mandatory
exclusive lock on a file and never unlocks it, then, no other process can
access the locked region of the file until the runway process is killed or the
system has to be rebooted.
 If locks are not mandatory, then it has to be advisory lock.
 A kernel at the system call level does not enforce advisory locks.
 This means that even though a lock may be set on a file, no other processes
can still use the read and write functions to access the file.
101PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
File and Record Locking
To make use of advisory locks, process that manipulate the same file must co-
operate such that they follow the given below procedure for every read or
write operation to the file.
1. Try to set a lock at the region to be accesses. If this fails, a process can
either wait for the lock request to become successful.
2. After a lock is acquired successfully, read or write the locked region.
3. Release the lock.
102PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIsFile and Record Locking
 If a process sets a read lock on a file, for example from address 0 to 256,
then sets a write lock on the file from address 0 to 512, the process will
own only one write lock on the file from 0 to 512, the previous read lock
from 0 to 256 is now covered by the write lock and the process does not
own two locks on the region from 0 to 256. This process is called “Lock
Promotion”.
 Furthermore, if a process now unblocks the file from 128 to 480, it will own
two write locks on the file:
 one from 0 to 127 and the other from 481 to 512. This process is called
“Lock Splitting”.
 UNIX systems provide fcntl function to support file locking.
 By using fcntl it is possible to impose read or write locks on either a region
or an entire file.
103PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
File and Record Locking
The prototype of fcntl is
#include<fcntl.h>
int fcntl(int fdesc, int cmd_flag, ...);
The first argument specifies the file descriptor.
The second argument cmd_flag specifies what operation has to be performed.
If fcntl is used for file locking then cmd_flag can values as:
Cmd_flag Meaning
F_SETLK sets a file lock, do not block if this cannot succeed immediately
F_SETLKW sets a file lock and blocks the process until the lock is acquired
F_GETLK queries as to which process locked a specified region of file
104PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
File and Record Locking
 For file locking purpose, the third argument to fctnl is an address of a struct
flock type variable.
 This variable specifies a region of a file where lock is to be set, unset or
queried.
struct flock
{
short l_type; /* what lock to be set or to unlock file */
short l_whence; /* Reference address for the next field */
off_t l_start ; /*offset from the l_whence reference addr*/
off_t l_len ; /*how many bytes in the locked region */
pid_t l_pid ; /*pid of a process which has locked the file */
};
105PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
File and Record Locking
 The l_type field specifies the lock type to be set or unset.
 The possible values, which are defined in the <fcntl.h>header, and
their uses are:
 The l_whence, l_start & l_len define a region of a file to be locked or
unlocked.
l_type value Use
F_RDLCK Set a read lock on a specified region
F_WRLCK Set a write lock on a specified region
F_UNLCK Unlock a specified region
106PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
File and Record Locking
 The possible values of l_whence and their uses are:
A lock set by the fcntl API is an advisory lock but we can also use fcntl for
mandatory locking purpose with the following attributes set before using fcntl
1. Turn on the set-GID flag of the file.
2. Turn off the group execute right permission of the file.
l_whence value Use
SEEK_CUR The l_start value is added to current file pointer address
SEEK_END The l_start value is added to byte 0 of the file
SEEK_SET The l_start value is added to the end of the file
107PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
File and Record Locking
In the given example program, performed a read lock on a file “sample” from the 50th byte
to 150th byte.
#include<fcntl.h>
int main ( )
{
int fd;
struct flock lock;
fd=open(“sample”,O_RDONLY);
lock.l_type=F_RDLCK;
lock.l_whence=0;
lock.l_start=50;
lock.l_len=100;
fcntl(fd,F_SETLK,&lock);
}
108PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIsutime()
The utime function modifies the access time and the modification time stamps of a file.
The prototype of utime function is
#include<sys/types.h>
#include<unistd.h>
#include<utime.h>
int utime(const char *path_name, struct utimbuf *times);
•On success it returns 0, on failure it returns –1.
•The path_name argument specifies the path name of a file.
•The times argument specifies the new access time and modification time for the file.
•The struct utimbuf is defined in the <utime.h> header as:
struct utimbuf
{
}
time_t actime; /* access time */
time_t modtime; /* modification time */
109PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
utime()
 The time_t datatype is an unsigned long and its data is the number of the seconds
elapsed since the birthday of UNIX : 12 AM , Jan 1 of 1970.
 If the times (variable) is specified as NULL, the function will set the named file access
and modification time to the current time.
 If the times (variable) is an address of the variable of the type struct utimbuf, the
function will set the file access time and modification time to the value specified by the
variable.
110PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
Directory File API’s
A Directory file is a record-oriented file, where each record stores a file name and the
inode number of a file that resides in that directory.
Directories are created with the mkdir API and deleted with the rmdir API.
The prototype of mkdir is
#include<sys/stat.h>
#include<unistd.h>
int mkdir(const char *path_name, mode_t mode);
 The first argument is the path name of a directory file to be created.
 The second argument mode, specifies the access permission for the owner, groups
and others to be assigned to the file. This function creates a new empty directory.
 The entries for “.” and “..” are automatically created.
 The specified file access permission, mode, are modified by the file mode creation mask
of the process
111PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
Directory File API’s
To allow a process to scan directories in a file system independent manner, a directory
record is defined as struct dirent in the <dirent.h> header for UNIX.
Some of the functions that are defined for directory file operations in the above header
are
#include<sys/types.h>
#if defined (BSD) && ! _POSIX_SOURCE
#include<sys/dir.h>
typedef struct direct Dirent;
#else
#include<dirent.h>
typedef struct dirent Dirent;
#endif
112PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
Directory File API’s
DIR *opendir(const char *path_name);
Dirent *readdir(DIR *dir_fdesc);
int closedir(DIR *dir_fdesc);
void rewinddir(DIR *dir_fdsec);
The uses of these functions are
Function Use
opendir Opens a directory file for read-only. Returns a file handle dir * for future reference of
the file.
readdir Reads a record from a directory file referenced by dir-fdesc and returns that record
information.
rewinddir Resets the file pointer to the beginning of the directory file referenced by dir- fdesc.
The next call to readdir will read the first record from the file.
closedir closes a directory file referenced by dir-fdesc.
113PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
Directory File API’s
An empty directory is deleted with the rmdir API.
The prototype of rmdir is
#include<unistd.h>
int rmdir (const char * path_name);
If the link count of the directory becomes 0, with the call and no other process has the
directory open then the space occupied by the directory is freed.
UNIX systems have defined additional functions for random access of directory file
records.
Function Use
telldir Returns the file pointer of a given dir_fdesc
seekdir Changes the file pointer of a given dir_fdesc to a specified address
114PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIsDirectory File API’s
The following list_dir.C program illustrates the uses of the mkdir, opendir, readdir, closedir
and rmdir APIs:
#include<iostream.h>
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>
#include<sys/stat.h>
#if defined(BSD) && !_POSIX_SOURCE
#include<sys/dir.h>
typedef struct direct Dirent;
#else
#include<dirent.h>
typedef struct dirent Dirent;
#endif
int main(int agc, char* argv[])
{
Dirent* dp; DIR* dir_fdesc;
while(--argc>0)
{
if(!(dir_fdesc=opendir(*++argv)))
{
if(mkdir(*argv,S_IRWXU | S_IRWXG | S_IRWXO)==-1)
perror("opendir");
continue;
}
115PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIsDirectory File API’s
The following list_dir.C program illustrates the uses of the mkdir, opendir, readdir, closedir
and rmdir APIs:
for(int i=0;i<2;i++)
for(int cnt=0;dp=readdir(dir_fdesc);)
{
if(i)
cout<<dp->d_name<<endl;
if(strcmp(dp->d_name,".") &&
strcmp(dp->d_name,".."))
cnt++;
}
if(!cnt)
{
rmdir(*argv);
break;
}
rewinddir(dir_fdesc);
} //end for
closedir(dir_fdesc);
} //end while
} //end main
116PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
Device file APIs
 Device files are used to interface physical device with application programs.
 A process with superuser privileges to create a device file must call the mknod API.
 The user ID and group ID attributes of a device file are assigned in the same manner as
for regular files.
 When a process reads or writes to a device file, the kernel uses the major and minor
device numbers of a file to select a device driver function to carry out the actual data
transfer.
 Device file support is implementation dependent. UNIX System defines the mknod API to
create device files.
The prototype of mknod is
#include<sys/stat.h>
#include<unistd.h>
int mknod(const char* path_name, mode_t mode, int device_id);
117PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
Device file APIs
 The first argument pathname is the pathname of a device file to be created.
 The second argument mode specifies the access permission, for the owner, group and
others, also S_IFCHR or S_IBLK flag to be assigned to the file.
 The third argument device_id contains the major and minor device number.
Example
mknod(“SCSI5”,S_IFBLK | S_IRWXU | S_IRWXG | S_IRWXO,(15<<8) | 3);
The above function creates a block device file “SCS15”, to which all the three i.e. read, write
and execute permission is granted for user, group and others with major number as 8 and
minor number 3.
On success mknod API returns 0 , else it returns -1
118PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
Device file APIs
The following test_mknod.C program illustrates the use of the mknod, open, read, write and
close APIs on a block device file.
#include<iostream.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
int main(int argc, char* argv[])
{
if(argc!=4)
{
cout<<"usage:"<<argv[0]<<"<file><major_no><minor_no>";
return 0;
}
int major=atoi(argv[2];
Int minor=atoi(argv[3]);
(void) mknod(argv[1], S_IFCHR | S_IRWXU | S_IRWXG |
S_IRWXO, (major<<8) | minor);
int rc=1,
Int fd=open(argv[1],O_RDW | O_NONBLOCK | O_NOCTTY);
char buf[256];
while(rc && fd!=-1)
if((rc=read(fd,buf,sizeof(buf)))<0)
perror("read");
else if(rc)
cout<<buf<<endl;
close(fd);
}
119PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIsFIFO file API’s
 FIFO files are sometimes called named pipes.
 Pipes can be used only between related processes when a common ancestor has created
the pipe.
 Creating a FIFO is similar to creating a file.
 Indeed the pathname for a FIFO exists in the file system.
The prototype of mkfifo is
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
int mkfifo(const char *path_name, mode_t mode);
 The first argument pathname is the pathname(filename) of a FIFO file to be created.
 The second argument mode specifies the access permission for user, group and others
and as well as the S_IFIFO flag to indicate that it is a FIFO file.
 On success it returns 0 and on failure it returns –1.
120PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIsFIFO file API’s
Example
mkfifo(“FIFO5”, S_IFIFO | S_IRWXU | S_IRGRP | S_ROTH);
 The above statement creates a FIFO file “fifo5” with read-write-execute permission for
user and only read permission for group and others.
 Once we have created a FIFO using mkfifo, we open it using open.
 Indeed, the normal file I/O functions (read, write, unlink etc) all work with FIFOs.
 When a process opens a FIFO file for reading, the kernel will block the process until there
is another process that opens the same file for writing.
 Similarly whenever a process opens a FIFO file write, the kernel will block the process
until another process opens the same FIFO for reading.
 This provides a means for synchronization in order to undergo inter-process
communication.
 If a particular process tries to write something to a FIFO file that is full, then that process
will be blocked until another process has read data from the FIFO to make space for the
process to write.
121PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
FIFO file API’s
 Similarly, if a process attempts to read data from an empty FIFO, the process will be
blocked until another process writes data to the FIFO.
 From any of the above condition if the process doesn’t want to get blocked then we
should specify O_NONBLOCK in the open call to the FIFO file.
 If the data is not ready for read/write then open returns –1 instead of process getting
blocked.
 If a process writes to a FIFO file that has no other process attached to it for read, the
kernel will send SIGPIPE signal to the process to notify that it is an illegal operation.
 Another method to create FIFO files (not exactly) for inter-process communication is to
use the pipe system call.
122PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
FIFO file API’s
The prototype of pipe is
#include <unistd.h>
int pipe(int fds[2]);
 Returns 0 on success and –1 on failure.
 If the pipe call executes successfully, the process can read from fd[0] and write to fd[1].
 A single process with a pipe is not very useful.
 Usually a parent process uses pipes to communicate with its children.
123PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
The following test_fifo.C example illustrates the use of mkfifo, open, read, write
and close APIs for a FIFO file:
#include<iostream.h>
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<string.h>
#include<errno.h>
int main(int argc,char* argv[])
{
if(argc!=2 && argc!=3)
{
cout<<"usage:"<<argv[0]<<"<file> [<arg>]";
return 0;
}
124PROF. SYED MUSTAFA, HKBKCE
UNIT 3 UNIX FILE APIs
int fd; char buf[256];
(void) mkfifo(argv[1], S_IFIFO | S_IRWXU | S_IRWXG | S_IRWXO );
if(argc==2)
{
fd=open(argv[1],O_RDONLY | O_NONBLOCK);
while(read(fd,buf,sizeof(buf))==-1 && errno==EAGAIN)
sleep(1);
while(read(fd,buf,sizeof(buf))>0)
cout<<buf<<endl;
}
else
{
fd=open(argv[1],O_WRONLY);
write(fd,argv[2],strlen(argv[2]));
}
close(fd);
}
125PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
INTRODUCTION
A Process is a program under execution in a UNIX or POSIX system.
main FUNCTION
A C program starts execution with a function called main.
The prototype for the main function is
int main(int argc, char *argv[]);
where argc is the number of command-line arguments, and argv is an array of
pointers to the arguments.
 When a C program is executed by the kernel by one of the exec functions, a
special start-up routine is called before the main function is called.
 The executable program file specifies this routine as the starting address for the
program.
 This is set up by the link editor when it is invoked by the C compiler.
 This start-up routine takes values from the kernel, the command-line arguments
and the environment and sets things up so that the main function is called.
126PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
PROCESS TERMINATION
There are eight ways for a process to terminate.
Normal termination occurs in five ways:
1. Return from main
2. Calling exit
3. Calling _exit or _Exit
4. Return of the last thread from its start routine
5. Calling pthread_exit from the last thread
Abnormal termination occurs in three ways:
1. Calling abort
2. Receipt of a signal
3. Response of the last thread to a cancellation request
127PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
Exit Functions
Three functions terminate a program normally:
_exit and _Exit, which return to the kernel immediately, and
exit, which performs certain cleanup processing and then returns to the kernel.
#include <stdlib.h>
void exit(int status);
void _Exit(int status);
#include <unistd.h>
void _exit(int status);
All three exit functions expect a single integer argument, called the exit status.
Returning an integer value from the main function is equivalent to calling exit
with the same value.
Thus exit(0) is the same as return(0) from the main function.
128PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
Exit Functions
Three functions terminate a program normally:
_exit and _Exit, which return to the kernel immediately, and
exit, which performs certain cleanup processing and then returns to the kernel.
#include <stdlib.h>
void exit(int status);
void _Exit(int status);
#include <unistd.h>
void _exit(int status);
All three exit functions expect a single integer argument, called the exit status.
Returning an integer value from the main function is equivalent to calling exit
with the same value.
Thus exit(0) is the same as return(0) from the main function.
129PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
In the following situations the exit status of the process is undefined.
1. any of these functions is called without an exit status.
2. main does a return without a return value.
3. main “falls off the end”, i.e if the exit status of the process is undefined.
int main()
{
printf(“HKBKCE”);
return(5);
}
$ cc demo.c
$ ./a.out
HKBKCE
$ echo $? //print the exit status
5
130PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
atexit Function
With ISO C, a process can register up to 32 functions that are automatically called by exit.
These are called exit handlers and are registered by calling the atexit function.
#include <stdlib.h>
int atexit(void (*func)(void));
returns: 0 if OK, nonzero on error
 This declaration says that we pass the address of a function as the argument to atexit.
 When this function is called, it is not passed any arguments and is not expected to
return a value.
 The exit function calls these functions in reverse order of their registration.
 Each function is called as many times as it was registered.
131PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
Example of exit handlers
static void my_exit1(void);
static void my_exit2(void);
int main(void)
{
if (atexit(my_exit2) != 0)
perror("can't register my_exit2");
if (atexit(my_exit1) != 0)
perror("can't register my_exit1");
printf("main is donen");
return(0);
}
static void my_exit1(void)
{
printf("first exit handlern");
}
static void my_exit2(void)
{
printf("second exit handlern");
}
Output:
$ ./a.out
main is done
first exit handler
second exit handler
132PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
How a C program is started and the various ways it can terminate
133PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
COMMAND-LINE ARGUMENTS
When a program is executed, the process that does the exec can pass command-line
arguments to the new program.
Example: Echo all command-line arguments to standard output
int main(int argc, char *argv[])
{
int i;
for (i = 0; i < argc;i++) /* echo all command-line args */
printf("argv[%d]: %sn", i, argv[i]);
exit(0);
}
Output:
$ ./echoarg arg1 TEST foo
argv[0]: ./echoarg
argv[1]: arg1
argv[2]: TEST
argv[3]: foo
134PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
ENVIRONMENT LIST
Each program is also passed an environment list.
Like the argument list, the environment list is an array of character pointers, with each
pointer containing the address of a null-terminated C string.
The address of the array of pointers is contained in the global variable environ:
extern char **environ;
Generally any environmental variable is of the form: name=value.
135PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
MEMORY LAYOUT OF A C PROGRAM
Historically, a C program has been composed of the following pieces:
Text segment:
 The machine instructions that the CPU executes.
 Usually, the text segment is sharable so that only a single copy needs to be in memory
for frequently executed programs, such as text editors, the C compiler, the shells, and
so on.
 Also, the text segment is often read-only, to prevent a program from accidentally
modifying its instructions.
Initialized data segment:
 usually called simply the data segment, containing variables that are specifically initialized
in the program.
 For example, the C declaration
 int maxcount = 99;
 appearing outside any function causes this variable to be stored in the initialized data
segment with its initial value.
136PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
MEMORY LAYOUT OF A C PROGRAM
Uninitialized data segment:
 Often called the "bss" segment, named after an ancient assembler operator that stood for
"block started by symbol."
 Data in this segment is initialized by the kernel to arithmetic 0 or null pointers before the
program starts executing.
 The C declaration
 long sum[1000];
 appearing outside any function causes this variable to be stored in the uninitialized data
segment.
137PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
MEMORY LAYOUT OF A C PROGRAM
Stack:
 where automatic variables are stored, along with information that is saved each time a
function is called.
 Each time a function is called, the address of where to return to and certain information
about the caller's environment, such as some of the machine registers, are saved on the
stack.
 The newly called function then allocates room on the stack for its automatic and
temporary variables.
 This is how recursive functions in C can work.
 Each time a recursive function calls itself, a new stack frame is used, so one set of variables
doesn't interfere with the variables from another instance of the function.
138PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
MEMORY LAYOUT OF A C PROGRAM
Heap:
 where dynamic memory allocation usually takes place.
 Historically, the heap has been located between the uninitialized data and the stack.
139PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
MEMORY ALLOCATION
ISO C specifies three functions for memory allocation:
malloc:
which allocates a specified number of bytes of memory. The initial value of the memory is
indeterminate.
calloc:
which allocates space for a specified number of objects of a specified size.
The space is initialized to all 0 bits.
realloc:
which increases or decreases the size of a previously allocated area.
When the size increases, it may involve moving the previously allocated area somewhere
else, to provide the additional room at the end. Also, when the size increases, the initial
value of the space between the old contents and the end of the new area is indeterminate.
140PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
MEMORY ALLOCATION
#include <stdlib.h>
void *malloc(size_t size);
void *calloc(size_t nobj, size_t size);
void *realloc(void *ptr, size_t newsize);
On success, it returns: non-null pointer , NULL on Error.
void free(void *ptr);
The function free causes the space pointed to by ptr to be deallocated.
This freed space is usually put into a pool of available memory and can be allocated in a later
call to one of the three alloc functions.
.
141PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
MEMORY ALLOCATION
alloca() Function
 The function alloca has the same calling sequence as malloc;
 however, instead of allocating memory from the heap, the memory is allocated from the
stack frame of the current function.
 The advantage is that we don't have to free the space;
 it goes away automatically when the function returns.
 The alloca function increases the size of the stack frame.
 The disadvantage is that some systems can't support alloca, if it's impossible to increase
the size of the stack frame after the function has been called.
.
142PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
ENVIRONMENT VARIABLES
 The environment strings are usually of the form: name=value.
 The functions that we can use to set and fetch values from the variables are setenv, putenv,
and getenv functions.
The prototype of these functions are:
#include <stdlib.h>
char *getenv(const char *name);
Returns: pointer to value associated with name, NULL if not found.
Eg:
char *res=getenv(“HOME”);
cout<<“HOME=“<<res<<endl;
output:
HOME=/home/syed
143PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
ENVIRONMENT VARIABLES
int putenv(char *str);
int setenv(const char *name, const char *value, int rewrite);
int unsetenv(const char *name);
All return: 0 if OK, nonzero on error.
 The putenv function takes a string of the form name=value and places it in the
environment list.
 If name already exists, its old definition is first removed.
144PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
ENVIRONMENT VARIABLES
int setenv(const char *name, const char *value, int rewrite);
All return: 0 if OK, nonzero on error.
The setenv function sets name to value.
 If name already exists in the environment, then
 if rewrite is nonzero, the existing definition for name is first removed;
 if rewrite is 0, an existing definition for name is not removed, name is not set to the new
value, and no error occurs.
145PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
ENVIRONMENT VARIABLES
int unsetenv(const char *name);
All return: 0 if OK, nonzero on error.
The unsetenv function removes any definition of name.
It is not an error if such a definition does not exist.
Difference between putenv() and setenv():
Whereas setenv() must allocate memory to create the name=value string from its
arguments,
putenv()is free to place the string passed to it directly into the environment.
146PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
Setjmp() & longjmp() FUNCTIONS
In C, we can't goto a label that's in another function.
Instead, we must use the setjmp and longjmp functions to perform this type of branching.
#include <setjmp.h>
int setjmp(jmp_buf env);
Returns: 0 if called directly, nonzero if returning from a call to longjmp
void longjmp(jmp_buf env, int val);
 The setjmp function records or marks a location in a program code so that later when the
longjmp function is called from some other function, the execution continues from the
location onwards.
 The env variable(the first argument) records the necessary information needed to
continue execution.
 The env is of the jmp_buf defined in <setjmp.h> file, it contains the task.
147PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
Setjmp() & longjmp() FUNCTIONS
1. The setjmp function always returns ‘0’ on its success when it is called directly in a
process (for the first time).
2. The longjmp function is called to transfer a program flow to a location that was stored in
the env argument.
3. The program code marked by the env must be in a function that is among the callers of
the current function.
4. When the process is jumping to the target function, all the stack space used in the
current function and its callers, upto the target function are discarded by the longjmp
function.
5. The process resumes execution by re-executing the setjmp statement in the target
function that is marked by env.
6. The return value of setjmp function is the value(val), as specified in the longjmp
function call.
7. The ‘val’ should be nonzero, so that it can be used to indicate where and why the
longjmp function was invoked and process can do error handling accordingly.
148PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
Setjmp() & longjmp() FUNCTIONS
#include <stdio.h>
#include <setjmp.h>
jmp_buf jb;
int main(int argc, char *argv[])
{
int a, b, c;
printf ("Give two numbers for division : ");
scanf("%d %d", &a, &b);
if(setjmp(jb) == 0)
{
c = division(a, b);
printf ("%d / %d = %d", a, b, c);
return 0;
}
else
{
handle_error();
return -1;
}
}
int division(int a, int b)
{
if(b == 0)
longjmp(jb, 1);
else
return (a/b);
}
void handle_error(void)
{
printf("Divide by zero error !");
}
149PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
getrlimit() AND setrlimit() FUNCTIONS
Every process has a set of resource limits, some of which can be queried and changed
by the getrlimit and setrlimit functions.
#include <sys/resource.h>
int getrlimit(int resource, struct rlimit *rlptr);
int setrlimit(int resource, const struct rlimit*rlptr);
Both return: 0 if OK, nonzero on error
Each call to these two functions specifies a single resource and a pointer to the following
structure:
struct rlimit
{
rlim_t rlim_cur; /* soft limit: current limit */
rlim_t rlim_max; /* hard limit: maximum value for rlim_cur */
};
150PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
getrlimit() AND setrlimit() FUNCTIONS
Three rules govern the changing of the resource limits.
1. A process can change its soft limit to a value less than or equal to its hard limit.
2. A process can lower its hard limit to a value greater than or equal to its soft limit. This
lowering of the hard limit is irreversible for normal users.
3. Only a super user process can raise a hard limit.
An infinite limit is specified by the constant RLIM_INFINITY.
RLIMIT_AS The maximum size in bytes of a process's total available memory.
RLIMIT_CORE The maximum size in bytes of a core file. A limit of 0 prevents the creation of a core file.
RLIMIT_CPU The maximum amount of CPU time in seconds. When the soft limit is exceeded, the SIGXCPU
signal is sent to the process.
RLIMIT_DATA The maximum size in bytes of the data segment: the sum of the initialized data,
uninitialized data, and heap.
RLIMIT_FSIZE The maximum size in bytes of a file that may be created. When the soft limit is exceeded,
the process is sent the SIGXFSZ signal.
RLIMIT_LOCKS The maximum number of file locks a process can hold.
RLIMIT_NOFILE The maximum number of open files per process. Changing this limit affects the value
returned by the sysconffunction for its _SC_OPEN_MAXargument
RLIMIT_NPROC The maximum number of child processes per real user ID. Changing this limit affects the
value returned for _SC_CHILD_MAX by the sysconffunction 151PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
getrlimit() AND setrlimit() FUNCTIONS
Example: Print the current resource limits
#define doit(name) p_limits(#name, name)
int main(void)
{
#ifdef RLIMIT_AS
doit(RLIMIT_AS);
#endif
doit(RLIMIT_CORE);
doit(RLIMIT_CPU);
doit(RLIMIT_DATA);
doit(RLIMIT_FSIZE);
#ifdef RLIMIT_LOCKS
doit(RLIMIT_LOCKS);
#endif
doit(RLIMIT_NOFILE);
#ifdef RLIMIT_NPROC
doit(RLIMIT_NPROC);
#endif
exit(0);
}
static void pr_limits(char *name, int resource)
{
struct rlimit limit;
if (getrlimit(resource, &limit) < 0)
printf("getrlimit error for %s", name);
printf("%-14s ", name);
if (limit.rlim_cur == RLIM_INFINITY)
printf("(infinite) ");
else
printf(FMT, limit.rlim_cur);
if (limit.rlim_max == RLIM_INFINITY)
printf("(infinite)");
else
printf(FMT, limit.rlim_max);
}
152PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
UNIX KERNEL SUPPORT FOR PROCESS
 UNIX kernel has a process table that keeps track of all active process present in the
system. Some of these processes belongs to the kernel and are called as “system
process”.
 Every entry in the process table contains pointers to the text, data and the stack
segments and also to U-area of a process.
 U-area of a process is an extension of the process table entry and contains other process
specific data such as the file descriptor table, current root and working directory inode
numbers and set of system imposed process limits.
 All processes in UNIX system expect the process that is created by the system boot code,
are created by the fork system call.
153PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
UNIX KERNEL SUPPORT FOR PROCESS
154PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
UNIX KERNEL SUPPORT FOR PROCESS
 After the fork system call, once the child process is created, both the parent and child
processes resumes execution.
 When a process is created by fork, it contains duplicated copies of the text, data and
stack segments of its parent as shown in the Figure below.
 Also it has a file descriptor table, which contains reference to the same opened files as
the parent, such that they both share the same file pointer to each opened files.
155PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
UNIX KERNEL SUPPORT FOR PROCESS
The process will be assigned with attributes, which are either inherited from its parent or
will be set by the kernel.
Attributes Meaning
real user identification number (rUID) the user ID of a user who created the parent process
real group identification number (rGID) the group ID of a user who created that parent process
effective user identification number (eUID) this allows the process to access and create files with the
same privileges as the program file owner.
effective group identification number (eGID) this allows the process to access and create files with the
same privileges as the group to which the program file
belongs.
Saved set-UID and saved set-GID these are the assigned eUID and eGID of the process
respectively
Process group identification number (PGID)
and session identification number (SID)
these identify the process group and session of which the
process is member
Supplementary group identification numbers this is a set of additional group IDs for a user who created
the process 156PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
UNIX KERNEL SUPPORT FOR PROCESS
The process will be assigned with attributes, which are either inherited from its parent or
will be set by the kernel.
Attributes Meaning
Current directory this is the reference (inode number) to a working directory file
Root directory this is the reference to a root directory
Signal handling the signal handling settings
Signal mask a signal mask that specifies which signals are to be blocked
Umask a file mode mask that is used in creation of files to specify which accession rights
should be taken out.
Nice value the process scheduling priority value
Controlling terminal the controlling terminal of the process
157PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
UNIX KERNEL SUPPORT FOR PROCESS
In addition to the above attributes, the following attributes are different between the
parent and child processes:
Attributes Meaning
Process identification number (PID) an integer identification number that is unique per process in an
entire operating system.
Parent process identification number
(PPID)
the parent process PID
Pending signals the set of signals that are pending delivery to the parent process
Alarm clock time the process alarm clock time is reset to zero in the child process
File locks the set of file locks owned by the parent process is not inherited
by the chid process
158PROF. SYED MUSTAFA, HKBKCE
UNIT 4 UNIX PROCESSES
UNIX KERNEL SUPPORT FOR PROCESS
fork and exec are commonly used together to spawn a sub-process to execute a different
program.
The advantages of this method are:
 A process can create multiple processes to execute multiple programs concurrently.
 Because each child process executes in its own virtual address space, the parent process
is not affected by the execution status of its child process.
159PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS IDENTIFIERS
#include <unistd.h>
pid_t getpid(void); Returns: process ID of calling process
pid_t getppid(void); Returns: parent process ID of calling process
uid_t getuid(void); Returns: real user ID of calling process
uid_t geteuid(void); Returns: effective user ID of calling process
gid_t getgid(void); Returns: real group ID of calling process
gid_t getegid(void); Returns: effective group ID of calling process
160PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
fork FUNCTION
An existing process can create a new one by calling the fork function.
#include <unistd.h>
pid_t fork(void);
Returns: 0 in child, process ID of child in parent, 1 on error.
 The new process created by fork is called the child process.
 This function is called once but returns twice.
 The only difference in the returns is that the return value in the child is 0, whereas the
return value in the parent is the process ID of the new child.
 The reason the child's process ID is returned to the parent is that a process can have
more than one child, and there is no function that allows a process to obtain the process
IDs of its children.
161PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
fork FUNCTION
 The reason fork returns 0 to the child is that a process can have only a single parent, and
the child can always call getppid to obtain the process ID of its parent.
 (Process ID 0 is reserved for use by the kernel, so it's not possible for 0 to be the process
ID of a child.)
 Both the child and the parent continue executing with the instruction that follows the
call to fork.
 The child is a copy of the parent.
 For example, the child gets a copy of the parent's data space, heap, and stack.
 Note that this is a copy for the child;
 the parent and the child do not share these portions of memory.
 The parent and the child share the text segment .
162PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
fork FUNCTION
Example programs:
Program 1
/* Program to demonstrate fork function Program name – fork1.c */
#include<unistd.h>
void main( )
{
fork( );
printf(“n hello USP”);
}
Output :
$ cc fork1.c
$ ./a.out
hello USP
hello USP
Note : The statement hello USP is executed twice as both the child and parent have executed that instruction.
163PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
fork FUNCTION
Example programs:
Program 2 /* Program name – fork2.c */
#include<unistd.h>
void main( )
{
printf(“n 6 sem “);
fork( );
printf(“n hello USP”);
}
Output :
$ cc fork2.c
$ ./a.out
6 sem
hello USP
hello USP
Note: The statement 6 sem is executed only once by the parent because it is called before fork and statement hello USP is
executed twice by child and parent.
164PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
fork FUNCTION
The two main reasons for fork to fail are
1. if too many processes are already in the system, which usually means that something
else is wrong, or
2. if the total number of processes for this real user ID exceeds the system's limit.
There are two uses for fork:
1. When a process wants to duplicate itself so that the parent and child can each execute
different sections of code at the same time. This is common for network servers, the
parent waits for a service request from a client. When the request arrives, the parent
calls fork and lets the child handle the request. The parent goes back to waiting for the
next service request to arrive.
2. When a process wants to execute a different program. This is common for shells. In this
case, the child does an exec right after it returns from the fork.
165PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
vfork FUNCTION
 The function vfork has the same calling sequence and same return values as fork.
 The vfork function is intended to create a new process when the purpose of the new
process is to exec a new program.
 The vfork function creates the new process, just like fork, without copying the address
space of the parent into the child, as the child won't reference that address space; the
child simply calls exec (or exit) right after the vfork.
 Instead, while the child is running and until it calls either exec or exit, the child runs in
the address space of the parent.
 This optimization provides an efficiency gain on some paged virtual-memory
implementations of the UNIX System.
 Another difference between the two functions is that vfork guarantees that the child
runs first, until the child calls exec or exit. When the child calls either of these functions,
the parent resumes.
166PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
vfork FUNCTION
Example of vfork function
int glob = 6; /* external variable in initialized data */
int main(void)
{
int var=88; /* automatic variable on the stack */
pid_t pid;
printf("before vforkn");
if ((pid = vfork()) < 0)
perror("vfork error");
else if (pid == 0) /* child */
{
glob++; /* modify parent's variables */
var++;
_exit(0); /* child terminates */
}
/* Parent continues here.*/
printf("pid = %dn", getpid());
printf("glob = %d, var = %dn", glob, var);
exit(0);
}
Output:
$ ./a.out
before vfork
pid = 29039
glob = 7, var = 89
167PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
Wait() AND waitpid() FUNCTIONS
 When a process terminates, either normally or abnormally, the kernel notifies the parent
by sending the SIGCHLD signal to the parent.
 Because the termination of a child is an asynchronous event - it can happen at any time
while the parent is running - this signal is the asynchronous notification from the kernel
to the parent.
 The parent can choose to ignore this signal, or it can provide a function that is called
when the signal occurs: a signal handler.
 A process that calls wait() or waitpid() can:
1. Block, if all of its children are still running
2. Return immediately with the termination status of a child, if a child has terminated and
is waiting for its termination status to be fetched
3. Return immediately with an error, if it doesn't have any child processes.
168PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
Wait() AND waitpid() FUNCTIONS
#include <sys/wait.h>
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int options);
1. Both return: process ID if OK, 0 (see later), or 1 on error.
2. The argument statloc is a pointer to an integer.
3. If this argument is not a null pointer, the termination status of the terminated process is
stored in the location pointed to by the argument
169PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
Wait() AND waitpid() FUNCTIONS
The differences between these two functions are as follows.
1. The wait function can block the caller until a child process terminates, whereas
waitpid() has an option that prevents it from blocking.
2. The waitpid() function doesn't wait for the child that terminates first;
3. It has a number of options that control which process it waits for.
4. If a child has already terminated and is a zombie, wait returns immediately with that
child's status. Otherwise, it blocks the caller until a child terminates.
5. If the caller blocks and has multiple children, wait returns when one terminates.
170PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
Wait() AND waitpid() FUNCTIONS
The interpretation of the pid argument for waitpid() depends on its value:
Pid Value Action
pid == 1 Waits for any child process. In this respect, waitpid is equivalent
to wait
pid > 0 Waits for the child whose process ID equals pid
pid == 0 Waits for any child whose process group ID equals that of the
calling process.
pid < 1 Waits for any child whose process group ID equals the absolute
value of pid.
171PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
Wait() AND waitpid() FUNCTIONS
Macros to examine the termination status returned by wait() and waitpid():
Macro Description
WIFEXITED(status) True if status was returned for a child that terminated normally.
In this case, we can execute
WEXITSTATUS (status)
to fetch the low-order 8 bits of the argument that the child passed to
exit, _exit,or _Exit.
WIFSIGNALED (status) True if status was returned for a child that terminated abnormally, by
receipt of a signal that it didn't catch. In this case, we can execute
WTERMSIG (status)
to fetch the signal number that caused the termination.
Additionally, some implementations (but not the Single UNIX
Specification) define the macro
WCOREDUMP (status)
that returns true if a core file of the terminated process was generated.
172PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
Wait() AND waitpid() FUNCTIONS
Macros to examine the termination status returned by wait() and waitpid():
Macro Description
WIFSTOPPED (status) True if status was returned for a child that is currently
stopped. In this case, we can execute
WSTOPSIG (status)
to fetch the signal number that caused the child to stop.
WIFCONTINUED (status) True if status was returned for a child that has been
continued after a job control stop
173PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
Wait() AND waitpid() FUNCTIONS
pid_t waitpid(pid_t pid, int *statloc, int options);
The options constants for waitpid()
Constant Description
WCONTINUED If the implementation supports job control, the status of any child specified by pid that
has been continued after being stopped, but whose status has not yet been reported,
is returned.
WNOHANG The waitpid() function will not block if a child specified by pid is not immediately
available. In this case, the return value is 0.
WUNTRACED If the implementation supports job control, the status of any child specified by pid that
has stopped, and whose status has not been reported since it has stopped, is
returned.
The WIFSTOPPED macro determines whether the return value corresponds to a
stopped child process.
174PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
Wait() AND waitpid() FUNCTIONS
pid_t waitpid(pid_t pid, int *statloc, int options);
The waitpid function provides three features that aren't provided by the wait function.
1. The waitpid() function lets us wait for one particular process, whereas the wait()
function returns the status of any terminated child.
2. The waitpid() function provides a nonblocking version of wait. There are times when
we want to fetch a child's status, but we don't want to block.
3. The waitpid() function provides support for job control with the WUNTRACED and
WCONTINUED options.
175PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
Wait() AND waitpid() FUNCTIONS
Program to Demonstrate various exit statuses
#include <sys/wait.h>
void pr_exit(int status)
{
if (WIFEXITED(status))
printf("normal termination, exit status = %dn", WEXITSTATUS(status));
else if (WIFSIGNALED(status))
printf("abnormal termination, signal number = %dn", WTERMSIG(status));
else if (WIFSTOPPED(status))
printf("child stopped, signal number = %dn", WSTOPSIG(status));
}
176PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROLWait() AND waitpid() FUNCTIONS
Program to Demonstrate various exit statuses
int main(void)
{
pid_t pid; int status;
if ((pid = fork()) < 0)
perror("fork error");
else if (pid == 0) /* child */
exit(7);
if (wait(&status) != pid) /* wait for child */
perror("wait error");
pr_exit(status); /* and print its status */
if ((pid = fork()) < 0)
perror("fork error");
else if (pid == 0) /* child */
abort(); /* generates SIGABRT */
if (wait(&status) != pid) /* wait for child */
perror("wait error");
pr_exit(status); /* and print its status */
if ((pid = fork()) < 0)
perror("fork error");
else if (pid == 0) /* child */
status /= 0;/* divide by 0 generates SIGFPE */
if (wait(&status) != pid) /* wait for child */
perror("wait error");
pr_exit(status); /* and print its status */
exit(0);
}
177PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
Wait3() AND wait4() FUNCTIONS
The only feature provided by these two functions that isn't provided by the wait, waitid,
and waitpid functions is an additional argument that allows the kernel to return a
summary of the resources used by the terminated process and all its child processes.
The prototypes of these functions are:
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
pid_t wait3(int *statloc, int options, struct rusage *rusage);
pid_t wait4(pid_t pid, int *statloc, int options, struct rusage *rusage);
Both return: process ID if OK,-1 on error.
The resource information includes such statistics as the amount of user CPU time, the
amount of system CPU time, number of page faults, number of signals received etc. the
resource information is available only for terminated child process not for the process
that were stopped due to job control.
178PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
RACE CONDITIONS
A race condition occurs when multiple processes are trying to do something with shared
data and the final outcome depends on the order in which the processes run.
Example: The program below outputs two strings: one from the child and one from the parent. The
program contains a race condition because the output depends on the order in which the processes are run
by the kernel and for how long each process runs.
static void charatatime(char *);
int main(void)
{
pid_t pid;
if ((pid = fork()) < 0)
peror("fork error");
else if (pid == 0)
charatatime("output from childn");
else
charatatime("output from parentn");
exit(0);
}
static void charatatime(char *str)
{
char *ptr;
int c;
setbuf(stdout, NULL); /* set unbuffered */
for (ptr = str; (c = *ptr++) != 0; )
putc(c, stdout);
}
Output:
$ ./a.out
ooutput from child
utput from parent
179PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
RACE CONDITIONS
How to avoid race condition?
static void charatatime(char *);
int main(void)
{
pid_t pid;
TELL_WAIT();
if ((pid = fork()) < 0)
peror("fork error");
else if (pid == 0)
{
WAIT_PARENT(); /* parent goes first */
charatatime("output from childn");
}
else
{
charatatime("output from parentn");
TELL_CHILD(pid);
}
exit(0);
}
static void charatatime(char *str)
{
char *ptr;
int c;
setbuf(stdout, NULL); /* set unbuffered */
for (ptr = str; (c = *ptr++) != 0; )
putc(c, stdout);
}
Output:
$ ./a.out
output from parent
output from child
180PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
RACE CONDITIONS
How to avoid race condition?
static void charatatime(char *);
int main(void)
{
pid_t pid;
TELL_WAIT();
if ((pid = fork()) < 0)
peror("fork error");
else if (pid == 0)
{
charatatime("output from childn");
TELL_PARENT(getppid());
}
else
{
WAIT_CHILD(); /* child goes first */
charatatime("output from parentn");
}
exit(0);
}
static void charatatime(char *str)
{
char *ptr;
int c;
setbuf(stdout, NULL); /* set unbuffered */
for (ptr = str; (c = *ptr++) != 0; )
putc(c, stdout);
}
Output:
$ ./a.out
output from child
output from parent
181PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROLexec() Functions
 When a process calls one of the exec functions, that process is completely replaced by
the new program, and the new program starts executing at its main function.
 The process ID does not change across an exec, because a new process is not created;
 exec merely replaces the current process - its text, data, heap, and stack segments -
with a brand new program from disk.
There are 6 exec functions:
182PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROLexec() Functions
 The first difference in these functions is that the first four take a pathname argument,
whereas the last two take a filename argument.
 When a filename argument is specified
 If filename contains a slash, it is taken as a pathname.
 Otherwise, the executable file is searched for in the directories specified by the PATH
environment variable.
 The next difference concerns the passing of the argument list (l stands for list and v stands for
vector). The functions execl, execlp, and execle require each of the command-line arguments
to the new program to be specified as separate arguments.
 For the other three functions (execv, execvp, and execve), we have to build an array of
pointers to the arguments, and the address of this array is the argument to these three
functions.
 The final difference is the passing of the environment list to the new program.
 The two functions whose names end in an e (execle and execve) allow us to pass a pointer to
an array of pointers to the environment strings.
 The other four functions, however, use the environ variable in the calling process to copy the
existing environment for the new program.
183PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
exec() Functions
Relationship of the six exec functions
In many UNIX system implementations, only one of these six functions,
execve, is a system call within the kernel.
The other five are just library functions that eventually invoke this system call.
184PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
exec() Functions
char *env_init[] = { "USER=syed", "PATH=/tmp",
NULL };
int main(void)
{
pid_t pid;
if ((pid = fork()) < 0)
perror("fork error");
else if (pid == 0)
{ /* specify pathname, specify environment */
if (execle("/home/sar/bin/echoall", "echoall",
"myarg1",
"MY ARG2", (char *)0, env_init) < 0)
perror("execle error");
}
if (waitpid(pid, NULL, 0) < 0)
perror("wait error")
if ((pid = fork()) < 0)
perror("fork error");
else if (pid == 0)
{ /* specify filename, inherit environment */
if (execlp("echoall", "echoall", "only 1 arg",
(char *)0) < 0)
perror("execlp error");
}
exit(0);
}
Output:
$ ./a.out
argv[0]: echoall
argv[1]: myarg1
argv[2]: MY ARG2
PATH=/tmp
$ argv[0]: echoall
argv[1]: only 1 arg
USER=syed
LOGNAME=syed
SHELL=/bin/bash
HOME=/home/sar
185PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
exec() Functions
echoall.c
int main(int argc, char *argv[])
{
int i;
char **ptr;
extern char **environ;
for (i = 0; i < argc; i++) /* echo all command-line args */
printf("argv[%d]: %sn", i, argv[i]);
for (ptr = environ; *ptr != 0; ptr++) /* and all env strings */
printf("%sn", *ptr);
exit(0);
}
186PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
CHANGING USER IDs AND GROUP IDs
 When our programs need additional privileges or need to gain access to resources that
they currently aren't allowed to access, they need to change their user or group ID to an
ID that has the appropriate privilege or access.
 Similarly, when our programs need to lower their privileges or prevent access to certain
resources, they do so by changing either their user ID or group ID to an ID without the
privilege or ability access to the resource.
We can set the real user ID and effective user ID with the setuid function. Similarly, we can
set the real group ID and the effective group ID with the setgid function.
#include <unistd.h>
int setuid(uid_t uid);
int setgid(gid_t gid);
Both return: 0 if OK, -1 on error
187PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
CHANGING USER IDs AND GROUP IDs
There are rules for who can change the IDs.
Let's consider only the user ID for now. (Everything we describe for the user ID also applies
to the group ID.)
1. If the process has superuser privileges, the setuid function sets the real user ID, effective
user ID, and saved set-user-ID to uid.
2. If the process does not have superuser privileges, but uid equals either the real user ID or
the saved setuserID, setuid sets only the effective user ID to uid. The real user ID and the
saved set-user-ID are not changed.
3. If neither of these two conditions is true, errno is set to EPERM, and –1 is returned.
188PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
CHANGING USER IDs AND GROUP IDs
setreuid() and setregid() Functions
Historically, BSD supported the swapping of the real user ID and the effective
user ID with the setreuid() function.
#include <unistd.h>
int setreuid(uid_t ruid, uid_t euid);
int setregid(gid_t rgid, gid_t egid);
Both return: 0 if OK, –1 on error
189PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
CHANGING USER IDs AND GROUP IDs
Seteuid() and setegid() Functions
POSIX.1 includes the two functions seteuid and setegid.
These functions are similar to setuid and setgid, but only the effective user ID
or effective group ID is changed.
#include <unistd.h>
int seteuid(uid_t uid);
int setegid(gid_t gid);
Both return: 0 if OK, –1 on error
190PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
Interpreter Files
All contemporary UNIX systems support interpreter files.
These files are text files that begin with a line of the form
#! pathname [ optional-argument ]
The space between the exclamation point and the pathname is optional.
The most common of these interpreter files begin with the line
#!/bin/sh
#!/usr/bin/perl
The pathname is normally an absolute pathname, since no special operations
are performed on it
191PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
Interpreter Files
Using the -f option with an interpreter file lets us write
#!/bin/awk -f
(awk program follows in the interpreter file)
Eg:
#!/bin/awk -f
BEGIN {
for (i = 0; i < ARGC; i++)
printf "ARGV[%d] = %sn", i, ARGV[i]
exit
}
192PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
system() Function
It is convenient to execute a command string from within a program.
Eg:
system("date > file");
#include <stdlib.h>
int system(const char *cmdstring);
If cmdstring is a null pointer, system returns nonzero only if a command
processor is available.
193PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
The system function, without signal handling
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
int system(const char *cmdstring) /* version without signal handling */
{
pid_t pid;
int status;
if (cmdstring == NULL)
return(1); /* always a command processor with UNIX */
if ((pid = fork()) < 0)
status = -1; /* probably out of processes */
194PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROLelse if (pid == 0)
{ /* child */
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
_exit(127); /* execl error */
}
else
while (waitpid(pid, &status, 0) < 0) /* parent */
if (errno != EINTR)
{
status = -1; /* error other than EINTR from waitpid() */
break;
}
return(status);
}
195PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS ACCOUNTING
 Most UNIX systems provide an option to do process accounting.
 When enabled, the kernel writes an accounting record each time a process
terminates.
 These accounting records are typically a small amount of binary data with
the name of the command, the amount of CPU time used, the user ID and
group ID, the starting time, and so on.
 A superuser executes action with a pathname argument to enable
accounting.
 The accounting records are written to the specified file, which is usually
/var/account/acct. Accounting is turned off by executing accton without any
arguments.
196PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS ACCOUNTING
 The data required for the accounting record, such as CPU times and number
of characters transferred, is kept by the kernel in the process table and
initialized whenever a new process is created, as in the child after a fork.
 Each accounting record is written when the process terminates.
 This means that the order of the records in the accounting file corresponds
to the termination order of the processes, not the order in which they were
started.
 The accounting records correspond to processes, not programs.
 A new record is initialized by the kernel for the child after a fork, not when a
new program is executed.
197PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS ACCOUNTING
The structure of the accounting records is defined in the header <sys/acct.h>
and looks something like
typedef u_short comp_t; /* 3-bit base 8 exponent; 13-bit fraction */
198PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
USER IDENTIFICATION
 Any process can find out its real and effective user ID and group ID.
 we want to find out the login name of the user who's running the
program.
 We could call getpwuid(getuid()), but what if a single user has multiple
login names, each with the same user ID? (A person might have multiple
entries in the password file with the same user ID to have a different login
shell for each entry.)
 The system normally keeps track of the name we log in and the getlogin
function provides a way to fetch that login name.
199PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
USER IDENTIFICATION
#include <unistd.h>
char *getlogin(void);
Returns : pointer to string giving login name if OK, NULL on error
This function can fail if the process is not attached to a terminal that a user
logged in to.
200PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS TIMES
We describe three times that we can measure: wall clock time, user CPU time,
and system CPU time.
Any process can call the times function to obtain these values for itself and
any terminated children.
#include <sys/times.h>
clock_t times(struct tms *buf);
Returns: elapsed wall clock time in clock ticks if OK, 1 on error
201PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS TIMES
This function fills in the tms structure pointed to by buf:
struct tms
{
clock_t tms_utime; /* user CPU time */
clock_t tms_stime; /* system CPU time */
clock_t tms_cutime; /* user CPU time, terminated children */
clock_t tms_cstime; /* system CPU time, terminated children */
};
 Note that the structure does not contain any measurement for the wall clock time.
 Instead, the function returns the wall clock time as the value of the function, each time
it's called.
 This value is measured from some arbitrary point in the past, so we can't use its absolute
value; instead, we use its relative value.
202PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
TERMINAL LOGINS
 The terminals were either local (directly connected) or remote (connected
through a modem).
 In either case, these logins came through a terminal device driver in the
kernel.
 The system administrator creates a file, usually /etc/ttys, that has one line
per terminal device.
 Each line specifies the name of the device and other parameters that are
passed to the getty().
203PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROLPROCESS RELATIONSHIP
TERMINAL LOGINS
 One parameter is the baud rate of the terminal, for example.
 When the system is bootstrapped, the kernel creates process ID 1, the init
process, and it is init that brings the system up multiuser.
 The init process reads the file /etc/ttys and, for every terminal device that
allows a login, does a fork followed by an exec of the program getty().
204PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
TERMINAL LOGINS
Processes invoked by init to allow terminal logins
205PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
TERMINAL LOGINS
 All the processes shown in the diagram have a real user ID of 0 and an
effective user ID of 0 (i.e., they all have superuser privileges).
 The init process also execs the getty() program with an empty environment.
 It is getty() that calls open for the terminal device.
 The terminal is opened for reading and writing.
 If the device is a modem, the open may delay inside the device driver until the
modem is dialed and the call is answered.
 Once the device is open, file descriptors 0, 1, and 2 are set to the device.
206PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
TERMINAL LOGINS
 Then getty() outputs something like login and waits for us to enter our user
name.
 When we enter our user name, getty's job is complete, and it then invokes the
login program, similar to
execle("/bin/login", "login", "-p", username, (char *)0, envp);
207PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
TERMINAL LOGINS
State of processes after login has been invoked
208PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
TERMINAL LOGINS
All the processes shown in the diagram have superuser privileges, since
the original init process has superuser privileges.
If we log in correctly, login will
 Change to our home directory (chdir)
 Change the ownership of our terminal device (chown) so we own it
 Change the access permissions for our terminal device so we have permission to
read from and write to it
 Set our group IDs by calling setgid and initgroups
209PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
TERMINAL LOGINS
 Initialize the environment with all the information that login has: our home
directory (HOME), shell (SHELL), user name (USER and LOGNAME), and a default
path (PATH)
 Change to our user ID (setuid) and invoke our login shell, as in
execl("/bin/sh", "-sh", (char *)0);
The minus sign as the first character of argv[0] is a flag to all the shells
that they are being invoked as a login shell.
The shells can look at this character and modify their start-up
accordingly.
210PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
TERMINAL LOGINS
Arrangement of processes after everything is set for a terminal login
211PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
NETWORK LOGINS
 The main (physical) difference between logging in to a system through a
serial terminal and logging in to a system through a network is that the
connection between the terminal and the computer isn't point-to-point.
 With the terminal logins, init knows which terminal devices are enabled for
logins and spawns a getty process for each device.
 In the case of network logins, however, all the logins come through the
kernel's network interface drivers (e.g., the Ethernet driver).
212PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
NETWORK LOGINS
 Let a TCP connection request arrives for the TELNET server.
 TELNET is a remote login application that uses the TCP protocol.
 A user on another host (that is connected to the server's host through a
network of some form) or on the same host initiates the login by starting
the TELNET client:
telnet hostname
 The client opens a TCP connection to hostname, and the program that's
started on hostname is called the TELNET server.
 The client and the server then exchange data across the TCP connection
using the TELNET application protocol.
213PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
NETWORK LOGINS
Figure shows the sequence of processes involved in executing the TELNET
server, called telnetd.
Sequence of processes involved in executing TELNET server
214PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
NETWORK LOGINS
 The telnetd process then opens a pseudo-terminal device and splits into
two processes using fork.
 The parent handles the communication across the network connection, and
the child does an exec of the login program.
 The parent and the child are connected through the pseudo terminal.
 Before doing the exec, the child sets up file descriptors 0, 1, and 2 to the
pseudo terminal.
 If we log in correctly, login performs the same steps as described earlier.
 It changes to our home directory and sets our group IDs, user ID, and our
initial environment.
 Then login replaces itself with our login shell by calling exec.
215PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
NETWORK LOGINS
Arrangement of processes after everything is set for a networklogin
216PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
NETWORK LOGINS
Arrangement of processes after everything is set for a networklogin
217PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
PROCESS GROUPS
 A process group is a collection of one or more processes, usually associated
with the same job, that can receive signals from the same terminal.
 Each process group has a unique process group ID.
 Process group IDs are similar to process IDs: they are positive integers and
can be stored in a pid_t data type.
 The function getpgrp() returns the process group ID of the calling process.
#include <unistd.h>
pid_t getpgrp(void);
Returns: process group ID of calling process
218PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
PROCESS GROUPS
 Each process group can have a process group leader.
 The leader is identified by its process group ID being equal to its process ID.
 It is possible for a process group leader to create a process group, create
processes in the group, and then terminate.
 The process group still exists, as long as at least one process is in the group,
regardless of whether the group leader terminates.
 This is called the process group lifetime-the period of time that begins when
the group is created and ends when the last remaining process leaves the
group.
 The last remaining process in the process group can either terminate or
enter some other process group.
219PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
PROCESS GROUPS
 A process joins an existing process group or creates a new process group by
calling setpgid().
#include <unistd.h>
int setpgid(pid_t pid, pid_t pgid);
Returns: 0 if OK, -1 on error
 This function sets the process group ID to pgid in the process whose process
ID equals pid.
 If the two arguments are equal, the process specified by pid becomes a
process group leader.
 If pid is 0, the process ID of the caller is used.
220PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
SESSIONS
A session is a collection of one or more process groups.
For example, we could have the arrangement shown in the diagram below.
Here we have three process groups in a single session.
Arrangement of processes into process groups and sessions
221PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
SESSIONS
A process establishes a new session by calling the setsid() function.
#include <unistd.h>
pid_t setsid(void);
Returns: process group ID if OK, -1 on error
If the calling process is not a process group leader, this function creates a new
session.
Three things may happen.
1. The process becomes the session leader of this new session. (A session
leader is the process that creates a session.) The process is the only process
in this new session.
2. The process becomes the process group leader of a new process group.
3. The new process group ID is the process ID of the calling process.
222PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
SESSIONS
setsid() function returns an error if the caller is already a process group leader.
The getsid function returns the process group ID of a process's session leader.
#include <unistd.h>
pid_t getsid(pid_t pid);
Returns: session leader's process group ID if OK, -1 on error
If pid is 0, getsid returns the process group ID of the calling process's session
leader.
223PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
CONTROLLING TERMINAL
Sessions and process groups have a few other characteristics.
1. A session can have a single controlling terminal. This is usually the terminal
device (in the case of a terminal login) or pseudo-terminal device (in the
case of a network login) on which we log in.
2. The session leader that establishes the connection to the controlling
terminal is called the controlling process.
3. The process groups within a session can be divided into a single foreground
process group and one or more background process groups.
4. If a session has a controlling terminal, it has a single foreground process
group, and all other process groups in the session are background process
groups.
224PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
CONTROLLING TERMINAL
5. Whenever we type the terminal's interrupt key (often DELETE or Control-C),
this causes the interrupt signal be sent to all processes in the foreground
process group.
6. Whenever we type the terminal's quit key (often Control-), this causes the
quit signal to be sent to all processes in the foreground process group.
7. If a modem (or network) disconnect is detected by the terminal interface,
the hang-up signal is sent to the controlling process (the session leader).
225PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
CONTROLLING TERMINAL
Process groups and sessions showing controlling terminal
226PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
tcgetpgrp(), tcsetpgrp() & tcgetsid()
 We need a way to tell the kernel which process group is the foreground
process group, so that the terminal device driver knows where to send the
terminal input and the terminal-generated signals.
 To retrieve the foreground process group-id and to set the foreground
process group-id we can use tcgetprgp() and tcsetpgrp() function.
The prototype of these functions are :
#include <unistd.h>
pid_t tcgetpgrp(int filedes);
Returns : process group ID of foreground process group if OK, -1 on error.
227PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
tcgetpgrp(), tcsetpgrp() & tcgetsid()
 The function tcgetpgrp() returns the process group ID of the foreground
process group associated with the terminal open on filedesc.
 If the process has a controlling terminal, the process can call tcsetpgrp to
set the foreground process group ID to pgrpid.
 The value of pgrpid must be the process group ID of a process group in the
same session, and filedes must refer to the controlling terminal of the
session.
228PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
tcgetpgrp(), tcsetpgrp() & tcgetsid()
The single UNIX specification defines an XSI extension called tcgetsid() to allow
an application to obtain the process group-ID for the session leader given a file
descriptor for the controlling terminal.
#include <termios.h>
pid_t tcgetsid(int filedesc);
Returns: session leader’s process group ID if Ok, -1 on error
229PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
JOB CONTROL
This feature allows us to start multiple jobs (groups of processes) from a single
terminal and to control which jobs can access the terminal and which jobs are
to run in the background.
Job control requires three forms of support:
1. A shell that supports job control
2. The terminal driver in the kernel must support job control
3. The kernel must support certain job-control signals
230PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
JOB CONTROL
Using job control from a shell, we can start a job in either the foreground or
the background.
A job is simply a collection of processes, often a pipeline of processes.
For example,
$vi main.c
starts a job consisting of one process in the foreground.
The commands
$pr *.c | lpr & , $make all & , $start
start two jobs in the background.
All the processes invoked by these background jobs are in the background.
231PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
JOB CONTROL
 The interaction with the terminal driver arises because a special terminal
character affects the foreground job: the suspend key (typically Control-Z).
Entering this character causes the terminal driver to send the SIGTSTP signal
to all processes in the foreground process group.
 The jobs in any background process groups aren't affected.
 The terminal driver looks for three special characters, which generate
signals to the foreground process group.
1. The interrupt character (typically DELETE or Control-C) generates SIGINT.
2. The quit character (typically Control-(back slash)) generates SIGQUIT.
3. The suspend character (typically Control-Z) generates SIGTSTP.
232PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
JOB CONTROL
This signal normally stops the background job; by using the shell, we are
notified of this and can bring the job into the foreground so that it can read
from the terminal.
The following demonstrates this:
233PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
JOB CONTROL
The shell starts the cat process in the background, but when cat tries to read
its standard input (the controlling terminal), the terminal driver, knowing that it
is a background job, sends the SIGTTIN signal to the background job.
234PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
JOB CONTROL
235PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
SHELL EXECUTION OF PROGRAMS
236PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
SHELL EXECUTION OF PROGRAMS
237PROF. SYED MUSTAFA, HKBKCE
UNIT 5 PROCESS CONTROL
PROCESS RELATIONSHIP
ORPHANED PROCESS GROUPS
A process whose parent terminates is called an orphan and is inherited by the
init process. A process that forks a child and then terminates.
238PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
 Signals are software interrupts.
 Signals provide a way of handling asynchronous events: a user at a terminal
typing the interrupt key to stop a program or the next program in a pipeline
terminating prematurely.
 When a signal is sent to a process, it is pending on the process to handle it.
The process can react to pending signals in one of three ways:
1. Accept the default action of the signal, which for most signals will terminate the
process.
2. Ignore the signal. The signal will be discarded and it has no affect whatsoever on the
recipient process.
3. Invoke a user-defined function. The function is known as a signal handler routine
and the signal is said to be caught when this function is called.
239PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
240PROF. SYED MUSTAFA, HKBKCE
Name Description Default action
SIGABRT abnormal termination (abort) terminate+core
SIGALRM timer expired (alarm) terminate
SIGCHLD change in status of child ignore
SIGCONT continue stopped process continue/ignore
SIGFPE arithmetic exception terminate+core
SIGINT terminal interrupt character terminate
SIGIO asynchronous I/O terminate/ignore
SIGKILL termination terminate
SIGPIPE write to pipe with no readers terminate
SIGQUIT terminal quit character terminate+core
SIGSEGV invalid memory reference terminate+core
SIGSTOP stop stop process
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
241PROF. SYED MUSTAFA, HKBKCE
Name Description Default action
SIGTTOU background write to control tty stop process
SIGUSR1 user-defined signal Terminate
SIGUSR2 user-defined signal Terminate
SIGTERM termination Terminate
SIGTSTP terminal stop character stop process
SIGTTIN background read from control tty stop process
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
242PROF. SYED MUSTAFA, HKBKCE
THE UNIX KERNEL SUPPORT OF SIGNALS
 When a signal is generated for a process, the kernel will set the corresponding
signal flag in the process table slot of the recipient process.
 If the recipient process is asleep, the kernel will awaken the process by scheduling it.
 When the recipient process runs, the kernel will check the process U-area that
contains an array of signal handling specifications.
 If array entry contains a zero value, the process will accept the default action of the
signal.
 If array entry contains a 1 value, the process will ignore the signal and kernel will
discard it.
 If array entry contains any other value, it is used as the function pointer for a user-
defined signal handler routine.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
243PROF. SYED MUSTAFA, HKBKCE
The function prototype of the signal API is:
#include <signal.h>
void (*signal(int sig_no, void (*handler)(int)))(int);
Returns: previous disposition of signal (see following) if OK, SIG_ERR on error
The formal argument of the API are:
sig_no is a signal identifier like SIGINT or SIGTERM.
The handler argument is the function pointer of a user-defined signal handler function.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
244PROF. SYED MUSTAFA, HKBKCE
The function prototype of the signal API is:
#include <signal.h>
void (*signal(int sig_no, void (*handler)(int)))(int);
The sig_no argument is just the name of the signal.
The value of handler is
(a) the constant SIG_IGN,
(b) the constant SIG_DFL, or
(c) the address of a function to be called when the signal occurs.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
245PROF. SYED MUSTAFA, HKBKCE
The function prototype of the signal API is:
#include <signal.h>
void (*signal(int sig_no, void (*handler)(int)))(int);
If we specify SIG_IGN, we are telling the system to ignore the signal.
(Remember that we cannot ignore the two signals SIGKILL and SIGSTOP)
When we specify SIG_DFL, we are setting the action associated with the signal to its
default value.
When we specify the address of a function to be called when the signal occurs, we are
arranging to "catch" the signal. We call the function either the signal handler or the
signal-catching function.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
246PROF. SYED MUSTAFA, HKBKCE
The function prototype of the signal API is:
#include <signal.h>
void (*signal(int sig_no, void (*handler)(int)))(int);
The prototype for the signal function states that the function requires two arguments
and returns a pointer to a function that returns nothing (void).
The signal function's first argument, sig_no, is an integer.
The second argument is a pointer to a function that takes a single integer argument and
returns nothing.
The function whose address is returned as the value of signal takes a single integer
argument (the final (int)).
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
247PROF. SYED MUSTAFA, HKBKCE
The function prototype of the signal API is:
#include <signal.h>
void (*signal(int sig_no, void (*handler)(int)))(int);
If we examine the system's header <signal.h>, we probably find declarations of the form
#define SIG_ERR (void (*)())-1
#define SIG_DFL (void (*)())0
#define SIG_IGN (void (*)())1
These constants can be used in place of the "pointer to a function that takes an integer
argument and returns nothing," the second argument to signal, and the return value
from signal.
The three values used for these constants need not be -1, 0, and 1.
They must be three values that can never be the address of any declarable function.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
248PROF. SYED MUSTAFA, HKBKCE
The following example attempts to catch the SIGTERM signal, ignores the SIGINT signal,
and accepts the default action of the SIGSEGV signal. The pause API suspends the calling
process until it is interrupted by a signal and the corresponding signal handler does a
return:
#include<iostream.h>
#include<signal.h>
/*signal handler function*/
void catch_sig(int sig_num)
{
signal (sig_num,catch_sig);
cout<<”catch_sig:”<<sig_num<<endl;
}
int main() /*main function*/
{
signal(SIGTERM,catch_sig);
signal(SIGINT,SIG_IGN);
signal(SIGSEGV,SIG_DFL);
pause( );/*wait for a signal interruption*/
}
The SIG_IGN specifies a signal is to be ignored, which means that if the signal is generated to the process,
it will be discarded without any interruption of the process.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
249PROF. SYED MUSTAFA, HKBKCE
#include<stdio.h>
#include<signal.h>
/*signal handler function*/
static void sig_usr(int signo)
/* arg is signal number */
{
if (signo == SIGUSR1)
printf("received SIGUSR1n");
else if (signo == SIGUSR2)
printf("received SIGUSR2n");
else
printf("received signal %dn", signo);
}
int main(void)
{
if (signal(SIGUSR1, sig_usr) == SIG_ERR)
perror("can't catch SIGUSR1");
if (signal(SIGUSR2, sig_usr) == SIG_ERR)
perror("can't catch SIGUSR2");
for ( ; ; )
pause();
}
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
250PROF. SYED MUSTAFA, HKBKCE
$ ./a.out & start process in background
[1] 7216 job-control shell prints job number and process ID
$ kill -USR1 7216 send it SIGUSR1
received SIGUSR1
$ kill -USR2 7216 send it SIGUSR2
received SIGUSR2
$ kill 7216 now send it SIGTERM
[1]+ Terminated ./a.out
When we send the SIGTERM signal, the process is terminated, since it doesn't catch the
signal, and the default action for the signal is termination.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
251PROF. SYED MUSTAFA, HKBKCE
kill and raise Functions
The kill function sends a signal to a process or a group of processes.
The raise function allows a process to send a signal to itself.
#include <signal.h>
int kill(pid_t pid, int signo);
int raise(int signo);
Both return: 0 if OK, –1 on error
The call
raise(signo);
is equivalent to the call
kill(getpid(), signo);
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
252PROF. SYED MUSTAFA, HKBKCE
kill and raise Functions
#include <signal.h>
int kill(pid_t pid, int signo);
There are four different conditions for the pid argument to kill.
Pid value Meaning
Pid > 0 The signal is sent to the process whose process ID is pid.
Pid==0 The signal is sent to all processes whose process group ID equals the process
group ID of the sender and for which the sender has permission to send the
signal.
Pid<0 The signal is sent to all processes whose process group ID equals the absolute
value of pid and for which the sender has permission to send the signal.
Pid==-1 The signal is sent to all processes on the system for which the sender has
permission to send the signal.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
253PROF. SYED MUSTAFA, HKBKCE
#include<iostream.h>
#include<signal.h>
/*signal handler function*/
void catch_sig(int sig_num)
{
cout<<”catch_sig:”<<sig_num<<endl;
}
int main() /*main function*/
{
signal (SIGINT,catch_sig);
cout<<“from mainn”;
kill(getpid, SIGINT);
}
#include<iostream.h>
#include<signal.h>
/*signal handler function*/
void catch_sig(int sig_num)
{
cout<<”catch_sig:”<<sig_num<<endl;
}
int main() /*main function*/
{
signal (SIGQUIT,catch_sig);
cout<<“from mainn”;
raise(SIGQUIT);
}
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
254PROF. SYED MUSTAFA, HKBKCE
alarm and pause Functions
The alarm function allows us to set a timer that will expire at a specified time in the
future.
When the timer expires, the SIGALRM signal is generated.
If we ignore or don't catch this signal, its default action is to terminate
the process.
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
Returns: 0 or number of seconds until previously set alarm.
The seconds value is the number of clock seconds in the future when the signal should
be generated.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
255PROF. SYED MUSTAFA, HKBKCE
alarm and pause Functions
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
 If, when we call alarm, a previously registered alarm clock for the process has not yet
expired, the number of seconds left for that alarm clock is returned as the value of
this function.
 That previously registered alarm clock is replaced by the new value.
 If a previously registered alarm clock for the process has not yet expired and if the
seconds value is 0, the previous alarm clock is canceled.
 The number of seconds left for that previous alarm clock is still returned as the value
of the function.
 Although the default action for SIGALRM is to terminate the process, most processes
that use an alarm clock catch this signal.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
256PROF. SYED MUSTAFA, HKBKCE
alarm and pause Functions
The pause function suspends the calling process until a signal is caught.
#include <unistd.h>
int pause(void);
Returns: –1 with errno set to EINTR
The only time pause returns is if a signal handler is executed and that handler returns.
In that case, pause returns –1 with errno set to EINTR.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
257PROF. SYED MUSTAFA, HKBKCE
alarm and pause Functions
Using alarm and pause, we can put a process to sleep for a specified amount of time.
The sleep() can be implemented using alarm() and pause().
#include <signal.h>
#include <unistd.h>
static void sig_alrm(int signo)
{
/* nothing to do, just return to
wake up the pause */
}
unsigned int sleep(unsigned int nsecs)
{
if (signal(SIGALRM, sig_alrm) == SIG_ERR)
return(nsecs);
alarm(nsecs); /* start the timer */
pause(); /* next caught signal wakes us up */
return(alarm(0));
/* turn off timer, return unslept time */
}
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
258PROF. SYED MUSTAFA, HKBKCE
SIGNAL SETS
We need a data type to represent multiple signals—a signal set
POSIX.1 defines the data type sigset_t to contain a signal set and the following five
functions to manipulate signal sets.
#include <signal.h>
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
Returns: 0 if OK, -1 on error.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
259PROF. SYED MUSTAFA, HKBKCE
SIGNAL SETS
int sigismember(const sigset_t *set, int signo);
Returns: 1 if true, 0 if false, –1 on error
 The function sigemptyset() initializes the signal set pointed to by set so that all signals
are excluded
 The function sigfillset() initializes the signal set so that all signals are included.
 All applications have to call either sigemptyset() or sigfillset() once for each signal set,
before using the signal set.
 Once we have initialized a signal set, we can add and delete specific signals in the set.
 The function sigaddset() adds a single signal to an existing set, and sigdelset()
removes a single signal from a set.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
260PROF. SYED MUSTAFA, HKBKCE
SIGNAL MASK
A process initially inherits the parent’s signal mask when it is created, but any pending
signals for the parent process are not passed on.
A process may query or set its signal mask via the sigprocmask API:
#include <signal.h>
int sigprocmask(int cmd, const sigset_t *new_mask, sigset_t *old_mask);
Returns: 0 if OK, -1 on error
.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
261PROF. SYED MUSTAFA, HKBKCE
SIGNAL MASK
The new_mask argument defines a set of signals to be set or reset in a calling process
signal mask, and the cmd argument specifies how the new_mask value is to be used by
the API.
The possible values of cmd and the corresponding use of the new_mask value are:
.
Cmd value Meaning
SIG_SETMASK
Overrides the calling process signal mask with the value specified in the new_mask
argument.
SIG_BLOCK
Adds the signals specified in the new_mask argument to the calling process signal
mask.
SIG_UNBLOCK
Removes the signals specified in the new_mask argument from the calling process
signal mask.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
262PROF. SYED MUSTAFA, HKBKCE
SIGNAL MASK
The following example checks whether the SIGINT signal is present in a process signal mask
and adds it to the mask if it is not there. Then clears the SIGSEGV signal from the process
signal mask.
#include <stdio.h>
#include <signal.h>
int main()
{
sigset_t mask;
sigemptyset(&mask);
/*initialize set*/
if (sigprocmask(0, 0, &mask) == -1)
{ /*get current signal mask*/
perror(“sigprocmask”);
exit(1);
}
else
sigaddset(&mask, SIGINT); /*set SIGINT flag*/
sigdelset(&mask, SIGSEGV);
/*clear SIGSEGV flag*/
if (sigprocmask(SIG_SETMASK, &mask, 0) == -1)
perror(“sigprocmask”);
/*set a new signal mask*/
} .
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
263PROF. SYED MUSTAFA, HKBKCE
SIGNAL MASK
The program prints the names of the signals in the signal mask of the calling process
#include <stdio.h>
#include <signal.h>
int main()
{
sigset_t sigset;
sigemptyset(&sigset);
/*initialize set*/
if (sigprocmask(0, NULL, &sigset) < 0)
perror("sigprocmask error");
if (sigismember(&sigset, SIGINT))
printf("SIGINT ");
if (sigismember(&sigset, SIGQUIT))
printf("SIGQUIT ");
if (sigismember(&sigset, SIGUSR1))
printf("SIGUSR1 ");
if (sigismember(&sigset, SIGALRM))
printf("SIGALRM ");
}
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
264PROF. SYED MUSTAFA, HKBKCE
SIGPENDING FUNCTION
The sigpending function returns the set of signals that are blocked from delivery and
currently pending for the calling process.
The set of signals is returned through the set argument
#include <signal.h>
int sigpending(sigset_t *set);
Returns: 0 if OK, –1 on error.
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
 The process blocks SIGQUIT, saving its current signal mask (to reset later),
and then goes to sleep for 5 seconds.
 Any occurrence of the quit signal during this period is blocked and won't be
delivered until the signal is unblocked.
 At the end of the 5-second sleep, we check whether the signal is pending
and unblock the signal.
265PROF. SYED MUSTAFA, HKBKCE
SIGPENDING FUNCTION
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS - SIGPENDING FUNCTION
266PROF. SYED MUSTAFA, HKBKCE
#include <signal.h>
#include <unistd.h>
static void sig_quit(int signo)
{
printf("caught SIGQUITn");
if (signal(SIGQUIT, SIG_DFL) == SIG_ERR)
perror("can't reset SIGQUIT");
}
int main(void)
{
sigset_t newmask, oldmask, pendmask;
if (signal(SIGQUIT, sig_quit) == SIG_ERR)
perror("can't catch SIGQUIT");
/* Block SIGQUIT and save current signal mask*/
sigemptyset(&newmask);
sigaddset(&newmask, SIGQUIT);
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
perror("SIG_BLOCK error");
sleep(5);
/* SIGQUIT here will remain pending */
if (sigpending(&pendmask) < 0)
perror("sigpending error");
if (sigismember(&pendmask, SIGQUIT))
printf("nSIGQUIT pendingn");
/* Reset signal mask which unblocks SIGQUIT*/
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
perror("SIG_SETMASK error");
printf("SIGQUIT unblockedn");
sleep(5);
/* SIGQUIT here will terminate with core file */
exit(0);
}
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
 The sigaction() function allows us to examine or modify (or both) the action
associated with a particular signal.
 This function supersedes the signal() function from earlier releases of the
UNIX System.
#include <signal.h>
int sigaction(int signo, const struct sigaction *restrict act,
struct sigaction *restrict oact);
Returns: 0 if OK, –1 on error
267PROF. SYED MUSTAFA, HKBKCE
Sigaction() Function
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
sigaction() Function
 The sigaction API is a replacement for the signal API in the latest UNIX and
POSIX systems.
 The sigaction API is called by a process to set up a signal handling method
for each signal it wants to deal with.
 sigaction API returns the previous signal handling method for a given signal.
268PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
sigaction() Function
The struct sigaction data type is defined in the <signal.h> header as
struct sigaction
{
void (*sa_handler)(int); /* addr of signal handler, or SIG_IGN, or SIG_DFL */
sigset_t sa_mask; /* additional signals to block */
int sa_flags; /* signal options */
void (*sa_sigaction)(int, siginfo_t *, void *); /* alternate handler */
};
269PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
sigaction() Function
 The sa_handler field can be set to SIG_IGN, SIG_DFL, or a user defined
signal handler function.
 The sa_mask field specifies additional signals that process wishes to block
when it is handling signo signal.
 The signalno argument designates which signal handling action is defined in
the action argument.
 The previous signal handling method for signalno will be returned via the
 oldaction argument if it is not a NULL pointer.
 If action argument is a NULL pointer, the calling process‘s existing signal
handling method for signalno will be unchanged.
270PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS - sigaction FUNCTION
271PROF. SYED MUSTAFA, HKBKCE
#include <signal.h>
#include <iostream.h>
void callme ( int sig_num )
{
cout <<“catch signal:”<<sig_num<< endl;
}
int main(void)
{
sigset_t sigmask;
struct sigaction action, old_action;
sigemptyset(&sigmask);
if ( sigaddset( &sigmask, SIGTERM) == -1 ||
sigprocmask( SIG_SETMASK, &sigmask, 0) == -1)
perror(“Set signal mask”);
sigemptyset( &action.sa_mask);
sigaddset( &action.sa_mask, SIGSEGV);
action.sa_handler = callme;
action.sa_flags = 0;
if (sigaction (SIGINT, &action, &old_action) == -1)
perror(“sigaction”);
pause(); /* wait for signal interruption*/
return 0;
}
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS - sigaction FUNCTION
 In the program, the process signal mask is set with SIGTERM signal.
 The process then defines a signal handler for the SIGINT signal and also
specifies that the SIGSEGV signal is to be blocked when the process is
handling the SIGINT signal.
 The process then terminates its execution via the pause API.
The output of the program would be as:
% cc sigaction.c –o sigaction
% ./sigaction &
[1] 495
% kill –INT 495
catch signal: 2
sigaction exits
[1] Done sigaction
272PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
THE SIGCHLD SIGNAL AND THE waitpid API
When a child process terminates or stops, the kernel will generate a SIGCHLD signal to its
parent process. Depending on how the parent sets up the handling of the SIGCHLD signal,
different events may occur:
1. Parent accepts the default action of the SIGCHLD signal:
 SIGCHLD does not terminate the parent process.
 Parent process will be awakened.
 API will return the child’s exit status and process ID to the parent.
 Kernel will clear up the Process Table slot allocated for the child process.
 Parent process can call the waitpid API repeatedly to wait for each child it created.
273PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
THE SIGCHLD SIGNAL AND THE waitpid API
2. Parent ignores the SIGCHLD signal:
 SIGCHLD signal will be discarded.
 Parent will not be disturbed even if it is executing the waitpid system call.
 If the parent calls the waitpid API, the API will suspend the parent until all its child
processes have terminated.
 Child process table slots will be cleared up by the kernel.
 API will return a -1 value to the parent process.
3. Process catches the SIGCHLD signal:
 The signal handler function will be called in the parent process whenever a child process
terminates.
 If the SIGCHLD arrives while the parent process is executing the waitpid system call, the
waitpid API may be restarted to collect the child exit status and clear its process table
slots.
 Depending on parent setup, the API may be aborted and child process table slot not
freed.
274PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
abort() Function
abort function causes abnormal program termination
#include <stdlib.h>
void abort(void);
This function never returns.
This function sends the SIGABRT signal to the caller.
Processes should not ignore this signal.
ISO C states that calling abort will deliver an unsuccessful termination notification to the
host environment by calling raise(SIGABRT).
275PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
system() Function
#include <stdlib.h>
int system(const char *command);
This function returns is -1 on error.
If the value of command is NULL, system() returns nonzero if the shell is available, and zero
if not.
system() executes a command specified in command by calling /bin/sh -c command, and
returns after the command has been completed. During execution of the
command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored
Eg: system(“ls –l”);
276PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
sleep() Function
sleep - sleep for the specified number of seconds
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
Returns: 0 or number of unslept seconds.
This function causes the calling process to be suspended until either
1. The amount of wall clock time specified by seconds has elapsed.
2. A signal is caught by the process and the signal handler returns.
Eg:
sleep(60); // suspend the process for one minute.
277PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
Job-Control Signals
POSIX.1 considers six signals as job-control signals:
278PROF. SYED MUSTAFA, HKBKCE
Signal Meaning
SIGCHLD Child process has stopped or terminated.
SIGCONT Continue process, if stopped.
SIGSTOP Stop signal (can't be caught or ignored).
SIGTSTP Interactive stop signal.
SIGTTIN Read from controlling terminal by member of a background process
group
SIGTTOU Write to controlling terminal by member of a background process group
UNIT 6 SIGNALS AND DAEMON PROCESSES
SIGNALS
Job-Control Signals
 When we type the suspend character (usually Control-Z), SIGTSTP is sent to all processes
in the foreground process group.
 When we tell the shell to resume a job in the foreground or background, the shell sends
all the processes in the job the SIGCONT signal.
 Similarly, if SIGTTIN or SIGTTOU is delivered to a process, the process is stopped by
default, and the job-control shell recognizes this and notifies us.
 When any of the four stop signals (SIGTSTP, SIGSTOP, SIGTTIN, or SIGTTOU) is generated
for a process, any pending SIGCONT signal for that process is discarded.
 Similarly, when the SIGCONT signal is generated for a process, any pending stop signals
for that same process are discarded.
 The default action for SIGCONT is to continue the process, if it is stopped; otherwise, the
signal is ignored.
279PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
DAEMON PROCESSES
 Daemons are processes that live for a long time.
 They are often started when the system is bootstrapped and terminate only when the
system is shut down.
 Because they don't have a controlling terminal, we say that they run in the background.
 UNIX systems have numerous daemons that perform day-to-day activities.
280PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
DAEMON PROCESSES
Deamon Characteristics
 $ps -axj
281PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
DAEMON PROCESSES
Deamon Characteristics
 Daemons run in background.
 Daemons have super-user privilege.
 Daemons don’t have controlling terminal.
 Daemons are session and group leaders.
282PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
DAEMON PROCESSES
Deamon Characteristics
 Anything with a parent process ID of 0 is usually a kernel process started as part of the
system bootstrap procedure.
 Kernel processes are special and generally exist for the entire lifetime of the system.
 They run with superuser privileges and have no controlling terminal and no command
line.
 Process ID of 1 is usually init.
 It is a system daemon responsible for, among other things, starting system services
specific to various run levels.
283PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
DAEMON PROCESSES
Deamon Characteristics
 keventd daemon provides process context for running scheduled functions in the kernel.
 The kapmd daemon provides support for the advanced power management features
available with various computer systems.
 The kswapd daemon is also known as the pageout daemon.
 It supports the virtual memory subsystem by writing dirty pages to disk slowly over time,
so the pages can be reclaimed.
 The inetd daemon (xinetd) listens on the system's network interfaces for incoming
requests for various network servers.
 The nfsd, lockd, and rpciod daemons provide support for the
 Network File System (NFS).
 The cron daemon (crond) executes commands at specified dates and times. Numerous
system administration tasks are handled by having programs executed regularly by cron.
 The cupsd daemon is a print spooler; it handles print requests on the system.
284PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
DAEMON PROCESSES
CODING RULES
1. Call umask to set the file mode creation mask to 0. The file mode creation
mask that's inherited could be set to deny certain permissions. If the
daemon process is going to create files, it may want to set specific
permissions.
2. Call fork and have the parent exit. This does several things. First, if the
daemon was started as a simple shell command, having the parent
terminate makes the shell think that the command is done. Second, the
child inherits the process group ID of the parent but gets a new process ID,
so we're guaranteed that the child is not a process group leader.
285PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSESDAEMON PROCESSES
CODING RULES
3. Call setsid to create a new session. The process (a) becomes a session
leader of a new session, (b) becomes the process group leader of a new
process group, and (c) has no controlling terminal.
4. Change the current working directory to the root directory. The current
working directory inherited from the parent could be on a mounted file
system. Since daemons normally exist until the system is rebooted, if the
daemon stays on a mounted file system, that file system cannot be
unmounted.
5. Unneeded file descriptors should be closed. This prevents the daemon
from holding open any descriptors that it may have inherited from its
parent.
286PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
DAEMON PROCESSES
CODING RULES
6. Some daemons open file descriptors 0, 1, and 2 to /dev/null so that any
library routines that try to read from standard input or write to standard
output or standard error will have no effect. Since the daemon is not
associated with a terminal device, there is nowhere for output to be
displayed; nor is there anywhere to receive input from an interactive user.
Even if the daemon was started from an interactive session, the daemon
runs in the background, and the login session can terminate without
affecting the daemon. If other users log in on the same terminal device, we
wouldn't want output from the daemon showing up on the terminal, and
the users wouldn't expect their input to be read by the daemon.
287PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
DAEMON PROCESSES
CODING RULES
Example Program:
288PROF. SYED MUSTAFA, HKBKCE
#include <unistd,h>
#include <sys/types.h>
#include <fcntl.h>
int daemon_initialise( )
{
pid_t pid;
if (( pid = fork() ) < 0)
return –1;
else if ( pid != 0)
exit(0); /* parent exits */
/* child continues */
setsid( );
chdir(“/”);
umask(0);
return 0;
}
UNIT 6 SIGNALS AND DAEMON PROCESSES
DAEMON PROCESSES
Error Logging
 One problem a daemon has is how to handle error messages.
 It can't simply write to standard error, since it shouldn't have a controlling
terminal.
 We don't want all the daemons writing to the console device, since on
 many workstations, the console device runs a windowing system.
 We also don't want each daemon writing its own error messages into a
separate file.
 A central daemon errorlogging facility is required.
289PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
DAEMON PROCESSES
Error Logging
290PROF. SYED MUSTAFA, HKBKCE
UNIT 6 SIGNALS AND DAEMON PROCESSES
DAEMON PROCESSES
Error Logging
There are three ways to generate log messages:
1. Kernel routines can call the log function.
These messages can be read by any user process that opens and reads the
/dev/klog device.
2. Most user processes (daemons) call the syslog(3) function to generate log
messages. This causes the message to be sent to the UNIX domain datagram
socket /dev/log.
3. A user process on this host, or on some other host that is connected to this
host by a TCP/IP network, can send log messages to UDP port 514.
The syslogd daemon reads all three forms of log messages.
On start-up, this daemon reads a configuration file, usually /etc/syslog.conf,
which determines where different classes of messages are to be sent.
291PROF. SYED MUSTAFA, HKBKCE
Ad

Recommended

Case study operating systems
Case study operating systems
Akhil Bevara
 
OS UNIT – 2 - Process Management
OS UNIT – 2 - Process Management
Gyanmanjari Institute Of Technology
 
Introduction to Simplified instruction computer or SIC/XE
Introduction to Simplified instruction computer or SIC/XE
Temesgen Molla
 
Cryptography & Network Security
Cryptography & Network Security
Fahad Shaikh
 
Object Oriented Programming Lab Manual
Object Oriented Programming Lab Manual
Abdul Hannan
 
Distributed and Cloud Computing 1st Edition Hwang Solutions Manual
Distributed and Cloud Computing 1st Edition Hwang Solutions Manual
kyxeminut
 
Google App Engine
Google App Engine
Urmi510
 
OIT552 Cloud Computing - Question Bank
OIT552 Cloud Computing - Question Bank
pkaviya
 
Code optimization in compiler design
Code optimization in compiler design
Kuppusamy P
 
Linux process management
Linux process management
Raghu nath
 
Phases of Compiler
Phases of Compiler
Tanzeela_Hussain
 
Linux basic commands with examples
Linux basic commands with examples
abclearnn
 
Disk scheduling
Disk scheduling
NEERAJ BAGHEL
 
Inter Process Communication
Inter Process Communication
Adeel Rasheed
 
Operating system structures
Operating system structures
Mohd Arif
 
Multithreading models.ppt
Multithreading models.ppt
Luis Goldster
 
OS - Process Concepts
OS - Process Concepts
Mukesh Chinta
 
Analysis of the source program
Analysis of the source program
Huawei Technologies
 
Ipc in linux
Ipc in linux
Dr. C.V. Suresh Babu
 
File system
File system
Mohd Arif
 
File handling in Python
File handling in Python
Megha V
 
Code Optimization
Code Optimization
guest9f8315
 
Code Optimization
Code Optimization
Akhil Kaushik
 
process creation OS
process creation OS
Kiran Kumar Thota
 
Principle source of optimazation
Principle source of optimazation
Siva Sathya
 
Os Swapping, Paging, Segmentation and Virtual Memory
Os Swapping, Paging, Segmentation and Virtual Memory
sgpraju
 
System calls
System calls
AfshanKhan51
 
The linux networking architecture
The linux networking architecture
hugo lu
 
Unit 2
Unit 2
siddr
 
Usp notes unit6-8
Usp notes unit6-8
Syed Mustafa
 

More Related Content

What's hot (20)

Code optimization in compiler design
Code optimization in compiler design
Kuppusamy P
 
Linux process management
Linux process management
Raghu nath
 
Phases of Compiler
Phases of Compiler
Tanzeela_Hussain
 
Linux basic commands with examples
Linux basic commands with examples
abclearnn
 
Disk scheduling
Disk scheduling
NEERAJ BAGHEL
 
Inter Process Communication
Inter Process Communication
Adeel Rasheed
 
Operating system structures
Operating system structures
Mohd Arif
 
Multithreading models.ppt
Multithreading models.ppt
Luis Goldster
 
OS - Process Concepts
OS - Process Concepts
Mukesh Chinta
 
Analysis of the source program
Analysis of the source program
Huawei Technologies
 
Ipc in linux
Ipc in linux
Dr. C.V. Suresh Babu
 
File system
File system
Mohd Arif
 
File handling in Python
File handling in Python
Megha V
 
Code Optimization
Code Optimization
guest9f8315
 
Code Optimization
Code Optimization
Akhil Kaushik
 
process creation OS
process creation OS
Kiran Kumar Thota
 
Principle source of optimazation
Principle source of optimazation
Siva Sathya
 
Os Swapping, Paging, Segmentation and Virtual Memory
Os Swapping, Paging, Segmentation and Virtual Memory
sgpraju
 
System calls
System calls
AfshanKhan51
 
The linux networking architecture
The linux networking architecture
hugo lu
 
Code optimization in compiler design
Code optimization in compiler design
Kuppusamy P
 
Linux process management
Linux process management
Raghu nath
 
Linux basic commands with examples
Linux basic commands with examples
abclearnn
 
Inter Process Communication
Inter Process Communication
Adeel Rasheed
 
Operating system structures
Operating system structures
Mohd Arif
 
Multithreading models.ppt
Multithreading models.ppt
Luis Goldster
 
OS - Process Concepts
OS - Process Concepts
Mukesh Chinta
 
File handling in Python
File handling in Python
Megha V
 
Code Optimization
Code Optimization
guest9f8315
 
Principle source of optimazation
Principle source of optimazation
Siva Sathya
 
Os Swapping, Paging, Segmentation and Virtual Memory
Os Swapping, Paging, Segmentation and Virtual Memory
sgpraju
 
The linux networking architecture
The linux networking architecture
hugo lu
 

Viewers also liked (20)

Unit 2
Unit 2
siddr
 
Usp notes unit6-8
Usp notes unit6-8
Syed Mustafa
 
Unix operating system
Unix operating system
ABhay Panchal
 
Unit 3
Unit 3
siddr
 
Li-Fi Technology
Li-Fi Technology
Anjeet Kumar
 
Prog ii
Prog ii
Sanchit Patil
 
Unit 6
Unit 6
siddr
 
6th Semester (June; July-2014) Computer Science and Information Science Engin...
6th Semester (June; July-2014) Computer Science and Information Science Engin...
BGS Institute of Technology, Adichunchanagiri University (ACU)
 
UNIX introduction
UNIX introduction
MUFIX Community
 
Unit 5
Unit 5
siddr
 
Unit 7
Unit 7
siddr
 
unix interprocess communication
unix interprocess communication
guest4c9430
 
6th Semester (June; July-2015) Computer Science and Information Science Engin...
6th Semester (June; July-2015) Computer Science and Information Science Engin...
BGS Institute of Technology, Adichunchanagiri University (ACU)
 
Unix Introduction
Unix Introduction
Ananthi
 
C LANGUAGE - BESTECH SOLUTIONS
C LANGUAGE - BESTECH SOLUTIONS
BESTECH SOLUTIONS
 
Linking in MS-Dos System
Linking in MS-Dos System
Satyamevjayte Haxor
 
Unit 1
Unit 1
siddr
 
Introduction to C programming
Introduction to C programming
Rutvik Pensionwar
 
Unit 4
Unit 4
siddr
 
Structure of c_program_to_input_output
Structure of c_program_to_input_output
Anil Dutt
 
Ad

Similar to Unix system programming (20)

Usp notes
Usp notes
subash prakash
 
MODULE 3.1 updated-18cs56.pptx
MODULE 3.1 updated-18cs56.pptx
ManasaPJ1
 
computer networksssssssssssssssssssssssssssss.pptx
computer networksssssssssssssssssssssssssssss.pptx
bmit1
 
Linux 系統程式--第一章 i/o 函式
Linux 系統程式--第一章 i/o 函式
艾鍗科技
 
18CS56-UP-Module 3.pptx
18CS56-UP-Module 3.pptx
ChenamPawan
 
Introduction to C Unit 1
Introduction to C Unit 1
Dr. SURBHI SAROHA
 
2ab. UNIX files.ppt JSS science and technology university
2ab. UNIX files.ppt JSS science and technology university
tempemailtemp19
 
cs262_intro_slides.pptx
cs262_intro_slides.pptx
AnaLoreto13
 
C LANGUAGE UNIT-1 PREPARED BY MVB REDDY
C LANGUAGE UNIT-1 PREPARED BY MVB REDDY
Rajeshkumar Reddy
 
Linux System Programming - File I/O
Linux System Programming - File I/O
YourHelper1
 
C for Java programmers (part 1)
C for Java programmers (part 1)
Dmitry Zinoviev
 
Prog i
Prog i
Sanchit Patil
 
C Programming Tutorial - www.infomtec.com
C Programming Tutorial - www.infomtec.com
M-TEC Computer Education
 
Ch2 C Fundamentals
Ch2 C Fundamentals
SzeChingChen
 
Unix files
Unix files
Sunil Rm
 
All C ppt.ppt
All C ppt.ppt
JeelBhanderi4
 
Lecture 01 Programming C for Beginners 001
Lecture 01 Programming C for Beginners 001
MahmoudElsamanty
 
Introduction of c language
Introduction of c language
farishah
 
510Lec01-Overview.pptx
510Lec01-Overview.pptx
KrosumLabs1
 
Report on c and c++
Report on c and c++
oggyrao
 
MODULE 3.1 updated-18cs56.pptx
MODULE 3.1 updated-18cs56.pptx
ManasaPJ1
 
computer networksssssssssssssssssssssssssssss.pptx
computer networksssssssssssssssssssssssssssss.pptx
bmit1
 
Linux 系統程式--第一章 i/o 函式
Linux 系統程式--第一章 i/o 函式
艾鍗科技
 
18CS56-UP-Module 3.pptx
18CS56-UP-Module 3.pptx
ChenamPawan
 
2ab. UNIX files.ppt JSS science and technology university
2ab. UNIX files.ppt JSS science and technology university
tempemailtemp19
 
cs262_intro_slides.pptx
cs262_intro_slides.pptx
AnaLoreto13
 
C LANGUAGE UNIT-1 PREPARED BY MVB REDDY
C LANGUAGE UNIT-1 PREPARED BY MVB REDDY
Rajeshkumar Reddy
 
Linux System Programming - File I/O
Linux System Programming - File I/O
YourHelper1
 
C for Java programmers (part 1)
C for Java programmers (part 1)
Dmitry Zinoviev
 
Ch2 C Fundamentals
Ch2 C Fundamentals
SzeChingChen
 
Unix files
Unix files
Sunil Rm
 
Lecture 01 Programming C for Beginners 001
Lecture 01 Programming C for Beginners 001
MahmoudElsamanty
 
Introduction of c language
Introduction of c language
farishah
 
510Lec01-Overview.pptx
510Lec01-Overview.pptx
KrosumLabs1
 
Report on c and c++
Report on c and c++
oggyrao
 
Ad

More from Syed Mustafa (20)

BPOPS203 PRINCIPLES OF PROGRAMMING USING C LAB Manual.pdf
BPOPS203 PRINCIPLES OF PROGRAMMING USING C LAB Manual.pdf
Syed Mustafa
 
18CSL58 DBMS LAB Manual.pdf
18CSL58 DBMS LAB Manual.pdf
Syed Mustafa
 
Syed IoT - module 5
Syed IoT - module 5
Syed Mustafa
 
IoT - module 4
IoT - module 4
Syed Mustafa
 
15CS81- IoT- VTU- module 3
15CS81- IoT- VTU- module 3
Syed Mustafa
 
15CS81- IoT Module-2
15CS81- IoT Module-2
Syed Mustafa
 
Internet of Things - module 1
Internet of Things - module 1
Syed Mustafa
 
15CS664- Python Application Programming- Question bank 1
15CS664- Python Application Programming- Question bank 1
Syed Mustafa
 
15CS664- Python Application Programming VTU syllabus
15CS664- Python Application Programming VTU syllabus
Syed Mustafa
 
15CS664- Python Application Programming - Module 3
15CS664- Python Application Programming - Module 3
Syed Mustafa
 
15CS664-Python Application Programming - Module 3 and 4
15CS664-Python Application Programming - Module 3 and 4
Syed Mustafa
 
15CS664 Python Question Bank-3
15CS664 Python Question Bank-3
Syed Mustafa
 
Data structures lab manual
Data structures lab manual
Syed Mustafa
 
Grid computing notes
Grid computing notes
Syed Mustafa
 
answer-model-qp-15-pcd13pcd
answer-model-qp-15-pcd13pcd
Syed Mustafa
 
VTU PCD Model Question Paper - Programming in C
VTU PCD Model Question Paper - Programming in C
Syed Mustafa
 
Pointers and call by value, reference, address in C
Pointers and call by value, reference, address in C
Syed Mustafa
 
Data structures lab c programs
Data structures lab c programs
Syed Mustafa
 
Infix prefix postfix expression -conversion
Infix prefix postfix expression -conversion
Syed Mustafa
 
Service Oriented Architecture
Service Oriented Architecture
Syed Mustafa
 
BPOPS203 PRINCIPLES OF PROGRAMMING USING C LAB Manual.pdf
BPOPS203 PRINCIPLES OF PROGRAMMING USING C LAB Manual.pdf
Syed Mustafa
 
18CSL58 DBMS LAB Manual.pdf
18CSL58 DBMS LAB Manual.pdf
Syed Mustafa
 
Syed IoT - module 5
Syed IoT - module 5
Syed Mustafa
 
15CS81- IoT- VTU- module 3
15CS81- IoT- VTU- module 3
Syed Mustafa
 
15CS81- IoT Module-2
15CS81- IoT Module-2
Syed Mustafa
 
Internet of Things - module 1
Internet of Things - module 1
Syed Mustafa
 
15CS664- Python Application Programming- Question bank 1
15CS664- Python Application Programming- Question bank 1
Syed Mustafa
 
15CS664- Python Application Programming VTU syllabus
15CS664- Python Application Programming VTU syllabus
Syed Mustafa
 
15CS664- Python Application Programming - Module 3
15CS664- Python Application Programming - Module 3
Syed Mustafa
 
15CS664-Python Application Programming - Module 3 and 4
15CS664-Python Application Programming - Module 3 and 4
Syed Mustafa
 
15CS664 Python Question Bank-3
15CS664 Python Question Bank-3
Syed Mustafa
 
Data structures lab manual
Data structures lab manual
Syed Mustafa
 
Grid computing notes
Grid computing notes
Syed Mustafa
 
answer-model-qp-15-pcd13pcd
answer-model-qp-15-pcd13pcd
Syed Mustafa
 
VTU PCD Model Question Paper - Programming in C
VTU PCD Model Question Paper - Programming in C
Syed Mustafa
 
Pointers and call by value, reference, address in C
Pointers and call by value, reference, address in C
Syed Mustafa
 
Data structures lab c programs
Data structures lab c programs
Syed Mustafa
 
Infix prefix postfix expression -conversion
Infix prefix postfix expression -conversion
Syed Mustafa
 
Service Oriented Architecture
Service Oriented Architecture
Syed Mustafa
 

Recently uploaded (20)

grade 9 science q1 quiz.pptx science quiz
grade 9 science q1 quiz.pptx science quiz
norfapangolima
 
Deep Learning for Natural Language Processing_FDP on 16 June 2025 MITS.pptx
Deep Learning for Natural Language Processing_FDP on 16 June 2025 MITS.pptx
resming1
 
Understanding Amplitude Modulation : A Guide
Understanding Amplitude Modulation : A Guide
CircuitDigest
 
Water demand - Types , variations and WDS
Water demand - Types , variations and WDS
dhanashree78
 
4th International Conference on Computer Science and Information Technology (...
4th International Conference on Computer Science and Information Technology (...
ijait
 
chemistry investigatory project for class 12
chemistry investigatory project for class 12
Susis10
 
362 Alec Data Center Solutions-Slysium Data Center-AUH-ABB Furse.pdf
362 Alec Data Center Solutions-Slysium Data Center-AUH-ABB Furse.pdf
djiceramil
 
Structural Design for Residential-to-Restaurant Conversion
Structural Design for Residential-to-Restaurant Conversion
DanielRoman285499
 
Fundamentals of Digital Design_Class_12th April.pptx
Fundamentals of Digital Design_Class_12th April.pptx
drdebarshi1993
 
362 Alec Data Center Solutions-Slysium Data Center-AUH-ABB Furse.pdf
362 Alec Data Center Solutions-Slysium Data Center-AUH-ABB Furse.pdf
djiceramil
 
COMPOSITE COLUMN IN STEEL CONCRETE COMPOSITES.ppt
COMPOSITE COLUMN IN STEEL CONCRETE COMPOSITES.ppt
ravicivil
 
How Binning Affects LED Performance & Consistency.pdf
How Binning Affects LED Performance & Consistency.pdf
Mina Anis
 
Microwatt: Open Tiny Core, Big Possibilities
Microwatt: Open Tiny Core, Big Possibilities
IBM
 
IntroSlides-June-GDG-Cloud-Munich community [email protected]
IntroSlides-June-GDG-Cloud-Munich community [email protected]
Luiz Carneiro
 
VARICELLA VACCINATION: A POTENTIAL STRATEGY FOR PREVENTING MULTIPLE SCLEROSIS
VARICELLA VACCINATION: A POTENTIAL STRATEGY FOR PREVENTING MULTIPLE SCLEROSIS
ijab2
 
362 Alec Data Center Solutions-Slysium Data Center-AUH-Adaptaflex.pdf
362 Alec Data Center Solutions-Slysium Data Center-AUH-Adaptaflex.pdf
djiceramil
 
OCS Group SG - HPHT Well Design and Operation - SN.pdf
OCS Group SG - HPHT Well Design and Operation - SN.pdf
Muanisa Waras
 
Decoding Kotlin - Your Guide to Solving the Mysterious in Kotlin - Devoxx PL ...
Decoding Kotlin - Your Guide to Solving the Mysterious in Kotlin - Devoxx PL ...
João Esperancinha
 
Pavement and its types, Application of rigid and Flexible Pavements
Pavement and its types, Application of rigid and Flexible Pavements
Sakthivel M
 
362 Alec Data Center Solutions-Slysium Data Center-AUH-Glands & Lugs, Simplex...
362 Alec Data Center Solutions-Slysium Data Center-AUH-Glands & Lugs, Simplex...
djiceramil
 
grade 9 science q1 quiz.pptx science quiz
grade 9 science q1 quiz.pptx science quiz
norfapangolima
 
Deep Learning for Natural Language Processing_FDP on 16 June 2025 MITS.pptx
Deep Learning for Natural Language Processing_FDP on 16 June 2025 MITS.pptx
resming1
 
Understanding Amplitude Modulation : A Guide
Understanding Amplitude Modulation : A Guide
CircuitDigest
 
Water demand - Types , variations and WDS
Water demand - Types , variations and WDS
dhanashree78
 
4th International Conference on Computer Science and Information Technology (...
4th International Conference on Computer Science and Information Technology (...
ijait
 
chemistry investigatory project for class 12
chemistry investigatory project for class 12
Susis10
 
362 Alec Data Center Solutions-Slysium Data Center-AUH-ABB Furse.pdf
362 Alec Data Center Solutions-Slysium Data Center-AUH-ABB Furse.pdf
djiceramil
 
Structural Design for Residential-to-Restaurant Conversion
Structural Design for Residential-to-Restaurant Conversion
DanielRoman285499
 
Fundamentals of Digital Design_Class_12th April.pptx
Fundamentals of Digital Design_Class_12th April.pptx
drdebarshi1993
 
362 Alec Data Center Solutions-Slysium Data Center-AUH-ABB Furse.pdf
362 Alec Data Center Solutions-Slysium Data Center-AUH-ABB Furse.pdf
djiceramil
 
COMPOSITE COLUMN IN STEEL CONCRETE COMPOSITES.ppt
COMPOSITE COLUMN IN STEEL CONCRETE COMPOSITES.ppt
ravicivil
 
How Binning Affects LED Performance & Consistency.pdf
How Binning Affects LED Performance & Consistency.pdf
Mina Anis
 
Microwatt: Open Tiny Core, Big Possibilities
Microwatt: Open Tiny Core, Big Possibilities
IBM
 
VARICELLA VACCINATION: A POTENTIAL STRATEGY FOR PREVENTING MULTIPLE SCLEROSIS
VARICELLA VACCINATION: A POTENTIAL STRATEGY FOR PREVENTING MULTIPLE SCLEROSIS
ijab2
 
362 Alec Data Center Solutions-Slysium Data Center-AUH-Adaptaflex.pdf
362 Alec Data Center Solutions-Slysium Data Center-AUH-Adaptaflex.pdf
djiceramil
 
OCS Group SG - HPHT Well Design and Operation - SN.pdf
OCS Group SG - HPHT Well Design and Operation - SN.pdf
Muanisa Waras
 
Decoding Kotlin - Your Guide to Solving the Mysterious in Kotlin - Devoxx PL ...
Decoding Kotlin - Your Guide to Solving the Mysterious in Kotlin - Devoxx PL ...
João Esperancinha
 
Pavement and its types, Application of rigid and Flexible Pavements
Pavement and its types, Application of rigid and Flexible Pavements
Sakthivel M
 
362 Alec Data Center Solutions-Slysium Data Center-AUH-Glands & Lugs, Simplex...
362 Alec Data Center Solutions-Slysium Data Center-AUH-Glands & Lugs, Simplex...
djiceramil
 

Unix system programming

  • 1. UNIX SYSTEM PROGRAMMING BY PROF. A. SYED MUSTAFA HKBK COLLEGE OF ENGINEERING
  • 2. 1. Function prototyping 2. Support of the const and volatile data type qualifiers. 3. Support wide characters and internationalization. 4. Permit function pointers to be used without dereferencing. The major differences between ANSI C and K&R C [Kernighan and Ritchie] are as follows: 2PROF. SYED MUSTAFA, HKBKCE
  • 3. 1. Function prototyping ANSI C adopts C++ function prototype technique where function definition and declaration include function names, arguments’ data types, and return value data types. This enables ANSI C compilers to check for function calls in user programs that pass invalid number of arguments or incompatible arguments’ data type. These fix a major weakness of K&R C compilers: invalid function calls in user programs often pass compilation but cause programs to crash when they are executed. Eg: unsigned long demo(char * fmt, double data) { /*body of demo*/ } External declaration of this function demo is unsigned long demo(char * fmt, double data); eg: int printf(const char* fmt,...........); specify variable number of arguments The major differences between ANSI C and K&R C [Kernighan and Ritchie] are as follows: 3PROF. SYED MUSTAFA, HKBKCE
  • 4. 2. Support of the const and volatile data type qualifiers The const keyword declares that some data cannot be changed. Eg: int printf(const char* fmt,...........); Declares a fmt argument that is of a const char * data type, meaning that the function printf cannot modify data in any character array that is passed as an actual argument value to fmt. The major differences between ANSI C and K&R C [Kernighan and Ritchie] are as follows: 4PROF. SYED MUSTAFA, HKBKCE
  • 5. 2. Support of the const and volatile data type qualifiers Volatile keyword specifies that the values of some variables may change asynchronously, giving an hint to the compiler’s optimization algorithm not to remove any “redundant” statements that involve “volatile” objects. eg: char get_io() { volatile char* io_port = 0x7777; char ch = *io_port; /*read first byte of data*/ ch = *io_port; /*read second byte of data*/ } If io_port variable is not declared to be volatile when the program is compiled, the compiler may eliminate second ch = *io_port statement, as it is considered redundant with respect to the previous statement. The major differences between ANSI C and K&R C 5PROF. SYED MUSTAFA, HKBKCE
  • 6. 3. Support wide characters and internationalization • ANSI C supports internationalisation by allowing C-program to use wide characters. Wide characters use more than one byte of storage per character. • ANSI C defines the setlocale function, which allows users to specify the format of date, monetary and real number representations. • For eg: most countries display the date in dd/mm/yyyy format whereas US displays it in mm/dd/yyyy format. Function prototype of setlocale function is: #include<locale.h> char setlocale(int category, const char* locale); The major differences between ANSI C and K&R C 6PROF. SYED MUSTAFA, HKBKCE
  • 7. 3. Support wide characters and internationalization The major differences between ANSI C and K&R C The setlocale function prototype and possible values of the category argument are declared in the <locale.h> header. The category values specify what format class(es) is to be changed. Some of the possible values of the category argument are: Category Value Effect on standard C functions/macros LC_CTYPE ⇒ Affects behavior of the <ctype.h> macros LC_TIME ⇒ Affects date and time format. LC_NUMERIC ⇒ Affects number representation format LC_MONETARY ⇒ Affects monetary values format LC_ALL ⇒ combines the affect of all above Eg: setlocale(LC_ALL, “C”); 7PROF. SYED MUSTAFA, HKBKCE
  • 8. 4. Permit function pointers to be used without dereferencing ANSI C specifies that a function pointer may be used like a function name. No referencing is needed when calling a function whose address is contained in the pointer. For Example: extern void foo(double xyz,const int *ptr); void (*funptr)(double,const int *)=foo; The function can be called directly or through function pointer as given below: foo(12.78,”Hello world”); funptr(12.78,”Hello world”); K& R C requires funptr be dereferenced to call foo: (* funptr) (13.48,”Hello usp”); The major differences between ANSI C and K&R C 8PROF. SYED MUSTAFA, HKBKCE
  • 9. #include<unistd.h> long sysconf(const int limit_name); long pathconf(const char *pathname, int flimit_name ); long fpathconf(const int fd, int flimit_name); Limits checking at Run time 9PROF. SYED MUSTAFA, HKBKCE
  • 10. Limits checking at Run time The following test_config.C illustrates the use of sysconf, pathcong and fpathconf: #define _POSIX_SOURCE #define _POSIX_C_SOURCE 199309L #include<stdio.h> #include<iostream.h> #include<unistd.h> int main() { int res; if((res=sysconf(_SC_OPEN_MAX))==-1) perror(“sysconf”); else cout<<”OPEN_MAX:”<<res<<endl; if((res=pathconf(“/”,_PC_PATH_MAX))==-1) perror(“pathconf”); else cout<<”max path name:”<<(res+1)<<endl; if((res=fpathconf(0,_PC_CHOWN_RESTRICTED))==-1) perror(“fpathconf”); else cout<<”chown_restricted for stdin:”<<res<<endl; return 0; } 10PROF. SYED MUSTAFA, HKBKCE
  • 11. The POSIX.1 FIPS Standard FIPS stands for Federal Information Processing Standard. The FIPS standard is a restriction of the POSIX.1 – 1988 standard, and it requires the following features to be implemented in all FIPS- conformingsystems:  Job control  Saved set-UID and saved set-GID  Long path name is not supported  The _POSIX_CHOWN_RESTRICTED must be defined  The _POSIX_VDISABLE symbol must be defined  The NGROUP_MAX symbol’s value must be at least 8  The read and write API should return the number of bytes that have been transferred after the APIs have been interrupted by signals  The group ID of a newly created file must inherit the group ID of its containing directory 11PROF. SYED MUSTAFA, HKBKCE
  • 12. The X/OPEN Standards The X/Open organization was formed by a group of European companies to propose a common operating system interface for their computer systems. The portability guides specify a set of common facilities and C application program interface functions to be provided on all UNIX based open systems. In 1973, a group of computer vendors initiated a project called “common open software environment” (COSE). The goal of the project was to define a single UNIX programming interface specification that would be supported by all type vendors. The applications that conform to ANSI C and POSIX also conform to the X/Open standards but not necessarily vice-versa. 12PROF. SYED MUSTAFA, HKBKCE
  • 13. UNIX AND POSIX APIs API - A set of application programming interface functions that can be called by user programs to perform system specific functions. Most UNIX systems provide a common set of API’s to perform the following functions. 13PROF. SYED MUSTAFA, HKBKCE
  • 14. API Common Characteristics  Many APIs returns an integer value which indicates the termination status of their execution  API return -1 to indicate the execution has failed, and the global variable errno is set with an error code.  a user proces may call perror() function to print a diagnostic message of the failure to the std o/p, or  it may call strerror() function and gives it errno as the actual argument value; the strerror function returns a diagnostic message string and the user process may print that message in its preferred way  the possible error status codes that may be assigned to errno by any API are defined in the <errno.h> header. 14PROF. SYED MUSTAFA, HKBKCE
  • 15. Commonly occur error status codes and their meanings 15PROF. SYED MUSTAFA, HKBKCE
  • 16. UNIT 2 - UNIX FILES Files are the building blocks of any operating system. File Types A file in a UNIX or POSIX system may be one of the following types: •Regular file •Directory file •FIFO file •Character device file •Block device file 16PROF. SYED MUSTAFA, HKBKCE
  • 17. UNIT 2 UNIX FILES •Regular file A regular file may be either a text file or a binary file These files may be read or written to by users with the appropriate access permission Regular files may be created, browsed through and modified by various means such as text editors or compilers, and they can be removed by specific system commands 17PROF. SYED MUSTAFA, HKBKCE
  • 18. UNIT 2 UNIX FILES •Directory file It is like a folder that contains other files, including sub-directory files. It provides a means for users to organise their files into some hierarchical structure based on file relationship or uses. Ex: /bin directory contains all system executable programs, such as cat, rm, sort A directory may be created in UNIX by the mkdir command Ex: mkdir /usr/foo/xyz A directory may be removed via the rmdir command Ex: rmdir /usr/foo/xyzThe content of directory may be displayed by the ls command 18PROF. SYED MUSTAFA, HKBKCE
  • 19. UNIT 2 UNIX FILES •Device file o For block device file, use argument ‘b’ instead of ‘c’. 19PROF. SYED MUSTAFA, HKBKCE
  • 20. UNIT 2 UNIX FILES •Device file  Major device number:  It is an index to a kernel table that contains the addresses of all device driver functions known to the system.  Whenever a process reads data from or writes data to a device file, the kernel uses the device file’s major number to select and invoke a device driver function to carry out actual data transfer with a physical device.  Minor device number:  It is an integer value to be passed as an argument to a device driver function when it is called.  It tells the device driver function what actual physical device is talking to and the I/O buffering scheme to be used for data transfer. 20PROF. SYED MUSTAFA, HKBKCE
  • 21. UNIT 2 UNIX FILES  FIFO file It is a special pipe device file which provides a temporary buffer for two or more processes to communicate by writing data to and reading data from the buffer. The size of the buffer is fixed to PIPE_BUF. Data in the buffer is accessed in a first-in-first-out manner. The buffer is allocated when the first process opens the FIFO file for read or write The buffer is discarded when all processes close their references (stream pointers) to the FIFO file. Data stored in a FIFO buffer is temporary. A FIFO file may be created via the mkfifo command. oThe following command creates a FIFO file mkfifo /usr/d1/myfifo mknod /usr/d1/myfifo p FIFO files can be removed using rm command. 21PROF. SYED MUSTAFA, HKBKCE
  • 22. UNIT 2 UNIX FILES  Symbolic link file BSD UNIX & SV4 defines a symbolic link file. POSIX.1 does not support symbolic link file type A symbolic link file contains a path name which references another file in either local or a remote file system. A symbolic link may be created in UNIX via the ln command Ex: ln -s /usr/d1/f1 /usr/d2/f2 It is possible to create a symbolic link to reference another symbolic link. rm, mv and chmod commands will operate only on the symbolic link arguments directly and not on the files that they reference. 22PROF. SYED MUSTAFA, HKBKCE
  • 23. UNIT 2 UNIX FILES 23PROF. SYED MUSTAFA, HKBKCE
  • 24. UNIT 2 UNIX FILES 24PROF. SYED MUSTAFA, HKBKCE
  • 25. UNIT 2 UNIX FILES The UNIX and POSIX File Attributes The general file attributes for each file in a file system are: 1)File type - specifies what type of file it is. 2)Access permission - the file access permission for owner, group and others. 3)Hard link count - number of hard link of the file 4)Uid - the file owner user id. 5)Gid - the file group id. 6)File size - the file size in bytes. 7)Inode no - the system inode no of the file. 8)File system id - the file system id where the file is stored. 25PROF. SYED MUSTAFA, HKBKCE
  • 26. UNIT 2 UNIX FILES The UNIX and POSIX File Attributes The general file attributes for each file in a file system are: 9) Last access time - the time, the file was last accessed. 10) Last modified time - the file, the file was last modified. 11) Last change time - the time, the file was last changed. 12) Major Number 13) Minor Number The attributes that are constant and cannot be changed for any file are: File type File inode number File system ID Major and minor device number 26PROF. SYED MUSTAFA, HKBKCE
  • 27. UNIT 2 UNIX FILES 27PROF. SYED MUSTAFA, HKBKCE
  • 28. UNIT 2 UNIX FILES In UNIX system V, a file system has an inode table, which keeps tracks of all files. Each entry of the inode table is an inode record which contains all the attributes of a file, including inode no. and the physical disk address where data of the file is stored For any operation, if a kernel needs to access information of a file with an inode no. 15, it will scan the inode table to find an entry, which contains an inode no. 15 in order to access the necessary data. An inode no is unique within a file system. A file inode record is identified by a file system ID and an inode no. Inodes in UNIX System V 28PROF. SYED MUSTAFA, HKBKCE
  • 29. UNIT 2 UNIX FILES Generally an OS does not keep the name of a file in its record, because the mapping of the filenames to inode no is done via directory files i.e. a directory file contains a list of names of their respective inode no. for all file stored in that directory. Ex: a sample directory file content Inodes in UNIX System V Inode number File name 115 . 89 .. 201 xyz 346 a.out 201 xyz_lnk 29PROF. SYED MUSTAFA, HKBKCE
  • 30. UNIT 2 UNIX FILES Inodes in UNIX System V To access a file, for example /usr/syed, the UNIX kernel always knows the “/” (root) directory inode number of any process. It will scan the “/” directory file to find the inode number of the usr file. Once it gets the usr file inode number, it accesses the contents of usr file. It then looks for the inode number of syed file. Whenever a new file is created in a directory, the UNIX kernel allocates a new entry in the inode table to store the information of the new file It will assign a unique inode number to the file and add the new file name and inode number to the directory file that contains it. 30PROF. SYED MUSTAFA, HKBKCE
  • 31. UNIT 2 UNIX FILES Application Programming Interface to Files Files are identified by pathnames. Files should be created before they can be used. The various commands and system calls to create files are File type commands System call Regular file Directory file FIFO file Device file Symbolic link file vi,pico,emac mkdir mkfifo mknod ln –s open,creat mkdir, mknod mkfifo, mknod Symlink 31PROF. SYED MUSTAFA, HKBKCE
  • 32. UNIT 2 UNIX FILES Application Programming Interface to Files For any application to access files, first it should be opened. Generally we use open system call to open a file, and the returned value is an integer which is termed as file descriptor. There are certain limits of a process to open files. A maximum number of OPEN-MAX files can be opened.The value is defined in <limits.h> header. The data transfer function on any opened file is carried out by read and write system call. 32PROF. SYED MUSTAFA, HKBKCE
  • 33. UNIT 2 UNIX FILES Application Programming Interface to Files File hard links can be increased by link system call, and decreased by unlink system call. File attributes can be changed by chown, chmod and link system calls. File attributes can be queried (found out or retrieved) by stat and fstat system call. UNIX and POSIX.1 defines a structure of data type stat i.e. defined in <sys/stat.h> header file. This contains the user accessible attribute of a file. 33PROF. SYED MUSTAFA, HKBKCE
  • 34. UNIT 2 UNIX FILES 34PROF. SYED MUSTAFA, HKBKCE
  • 35. UNIT 2 UNIX FILESUNIX Kernel Support for Files In UNIX system V, the kernel maintains a file table that has an entry of all opened files and also there is an inode table that contains a copy of file inodes that are most recently accessed. A process, which gets created when a command is executed will be having its own data space (data structure) wherein it will be having file descriptor table. The file descriptor table will be having an maximum of OPEN_MAX file entries. Whenever the process calls the open function to open a file to read or write, the kernel will resolve the pathname to the file inode number. 35PROF. SYED MUSTAFA, HKBKCE
  • 36. UNIT 2 UNIX FILES UNIX Kernel Support for Files Data Structure for File Manipulation 36PROF. SYED MUSTAFA, HKBKCE
  • 37. UNIT 2 UNIX FILES UNIX Kernel Support for Files The steps involved are : 1. The kernel will search the process file descriptor table and look for the first unused entry. 2. If an entry is found, that entry will be designated to reference the file .The index of the entry will be returned to the process as the file descriptor of the opened file. 3. The kernel will scan the file table in its kernel space to find an unused entry that can be assigned to reference the file. 37PROF. SYED MUSTAFA, HKBKCE
  • 38. UNIT 2 UNIX FILESUNIX Kernel Support for Files If an unused entry is found the following events will occur: 1. The process file descriptor table entry will be set to point to this file table entry. 2. The file table entry will be set to point to the inode table entry, where the inode record of the file is stored. 3. The file table entry will contain the current file pointer of the open file. This is an offset from the beginning of the file where the next read or write will occur. 4. The file table entry will contain an open mode that specifies that the file opened is for read only, write only or read and write etc. This should be specified in open function call. 38PROF. SYED MUSTAFA, HKBKCE
  • 39. UNIT 2 UNIX FILES UNIX Kernel Support for Files If an unused entry is found the following events will occur: 5. The reference count (rc) in the file table entry is set to 1. Reference count is used to keep track of how many file descriptors from any process are referring the entry. 6. The reference count of the in-memory inode of the file is increased by 1. This count specifies how many file table entries are pointing to that inode. If either (1) or (2) fails, the open system call returns -1 (failure/error) 39PROF. SYED MUSTAFA, HKBKCE
  • 40. UNIT 2 UNIX FILES UNIX Kernel Support for Files Normally the reference count in the file table entry is 1, if we wish to increase the rc in the file table entry, this can be done using fork,dup,dup2 system call. When a open system call is succeeded, its return value will be an integer (file descriptor). Whenever the process wants to read or write data from the file, it should use the file descriptor as one of its argument. 40PROF. SYED MUSTAFA, HKBKCE
  • 41. UNIT 2 UNIX FILESUNIX Kernel Support for Files The following events will occur whenever a process calls the close function to close the files that are opened. 1. The kernel sets the corresponding file descriptor table entry to be unused. 2. It decrements the rc in the corresponding file table entry by 1, if rc not equal to 0 go to step 6. 3. The file table entry is marked as unused. 4. The rc in the corresponding file inode table entry is decremented by 1, if rc value not equal to 0. go to step 6. 5. If the hard link count of the inode is not zero, it returns to the caller with a success status otherwise it marks the inode table entry as unused and de-allocates all the physical dusk storage of the file. 6. It returns to the process with a 0 (success) status. 41PROF. SYED MUSTAFA, HKBKCE
  • 42. UNIT 2 UNIX FILES Relationship of C Stream Pointers and File Descriptors The major difference between the stream pointer and the file descriptors are as follows: 42PROF. SYED MUSTAFA, HKBKCE
  • 43. UNIT 2 UNIX FILES Relationship of C Stream Pointers and File Descriptors C library function UNIX system call used fopen open fread, fgetc, fscanf, fgets read fwrite, fputc, fprintf, fputs write fseek, fputc, fprintf, fputs lseek fclose close The file descriptor associated with a stream pointer can be extracted by fileno macro, which is declared in the<stdio.h> header. int fileno(FILE * stream_pointer); To convert a file descriptor to a stream pointer, we can use fdopen C library function FILE *fdopen(int file_descriptor, char * open_mode); The following lists some C library functions and the underlying UNIX APIs they use to perform their functions: 43PROF. SYED MUSTAFA, HKBKCE
  • 44. UNIT 2 UNIX FILES Directory Files  It is a record-oriented file.  Each record contains the information of a file residing in that directory  The record data type is struct dirent in UNIX System V and POSIX.1 and struct direct in BSD UNIX.  The record content is implementation-dependent  They all contain 2 essential member fields: 1. File name 2. Inode number Usage is to map file names to corresponding inode number : 44PROF. SYED MUSTAFA, HKBKCE
  • 45. UNIT 2 UNIX FILES Directory Files : Directory function Purpose opendir Opens a directory file readdir Reads next record from the file closedir Closes a directory file rewinddir Sets file pointer to beginning of file 45PROF. SYED MUSTAFA, HKBKCE
  • 46. UNIT 2 UNIX FILES Hard and Symbolic Links : hard link is a UNIX pathname for a file. Generally most of the UNIX files will be having only one hard link. In order to create a hard link, we use the command ln. Example : Consider a file /usr/ syed/f1, to this we can create a hard link by ln /usr/syed/f1 /usr/ syed/f2 Symbolic link can be creates by the same command ‘ln’ but with option –s Example: ln –s /usr/syed/f1 /usr/syed/sf1 46PROF. SYED MUSTAFA, HKBKCE
  • 47. UNIT 2 UNIX FILES Hard and Symbolic Links : ln command differs from the cp(copy) command in that cp creates a duplicated copy of a file to another file with a different pathname, whereas ln command creates a new link to reference a file. 47PROF. SYED MUSTAFA, HKBKCE
  • 48. UNIT 2 UNIX FILES Hard and Symbolic Links : Let’s visualize the content of a directory file after the execution of command ln. Case 1: for hard link file ln /usr/syed/abc /usr/mustafa/xyz The content of the directory files /usr/syed and /usr/mustafa are: 48PROF. SYED MUSTAFA, HKBKCE
  • 49. UNIT 2 UNIX FILES Hard and Symbolic Links : Let’s visualize the content of a directory file after the execution of command ln. Case 1: for hard link file ln /usr/syed/abc /usr/mustafa/xyz The content of the directory files /usr/syed and /usr/mustafa are: Both /urs/syed/abc and /usr/mustafa/xyz refer to the same inode number 201, thus no new file is created. 49PROF. SYED MUSTAFA, HKBKCE
  • 50. UNIT 2 UNIX FILES Hard and Symbolic Links : Case 2: For the same operation, if ln –s command is used then a new inode will be created. ln –s /usr/syed/abc /usr/mustafa/xyz The content of the directory files syed and mustafa will be If cp command was used then the data contents will be identical and the 2 files will be separate objects in the file system, whereas in ln –s the data will contain only the path name. 50PROF. SYED MUSTAFA, HKBKCE
  • 51. UNIT 2 UNIX FILES Hard and Symbolic Links : Limitations of hard link:  User cannot create hard links for directories, unless he has super-user privileges.  User cannot create hard link on a file system that references files on a different file system, because inode number is unique to a file system. Differences between hard link and symbolic link are listed below: 51PROF. SYED MUSTAFA, HKBKCE
  • 52. UNIT 3 UNIX FILE APIs A file in a UNIX or POSIX system may be one of the following types: •Regular file •Directory file •FIFO file •Character device file •Block device file •Symbolic link file There are special API’s to create these types of files : 52PROF. SYED MUSTAFA, HKBKCE
  • 53. UNIT 3 UNIX FILE APIsopen This is used to establish a connection between a process and a file i.e. it is used to open an existing file for data transfer function or else it may be also be used to create a new file. The returned value of the open system call is the file descriptor (row number of the file table), which contains the inode information. The prototype of open function is #include<sys/types.h> #include<sys/fcntl.h> int open(const char *pathname, int accessmode, mode_t permission); 53PROF. SYED MUSTAFA, HKBKCE
  • 54. UNIT 3 UNIX FILE APIs open  If successful, open returns a nonnegative integer representing the open file descriptor.If unsuccessful, open() returns –1.  The first argument is the name of the file to be created or opened.  This may be an absolute pathname or relative pathname.  If the given pathname is symbolic link, the open function will resolve the symbolic link reference to a non symbolic link file to which it refers.  The second argument is access modes, which is an integer value that specifies how actually the file should be accessed by the calling process. : 54PROF. SYED MUSTAFA, HKBKCE
  • 55. UNIT 3 UNIX FILE APIs open Generally the access modes are specified in <fcntl.h>. Various access modes are: There are other access modes, which are termed as access modifier flags, and one or more of the following can be specified by bitwise-ORing them with one of the above access mode flags to alter the access mechanism of the file. Sl. No Flag Meaning 1 O_RDONLY open for reading file only 2 O_WRONLY open for writing file only 3 O_RDWR opens for reading and writing file 55PROF. SYED MUSTAFA, HKBKCE
  • 56. UNIT 3 UNIX FILE APIs open access modifier flags S.No Flag Meaning 1 O_APPEND Append data to the end of file. 2 O_CREAT Create the file if it doesn’t exist 3 O_EXCL Generate an error if O_CREAT is also specified and the file already exists. 4 O_TRUNC If file exists discard the file content and set the file size to zero bytes. 5 O_NONBLOCK Specify subsequent read or write on the file should be non-blocking. 6 O_NOCTTY Specify not to use terminal device file as the calling process control terminal. 56PROF. SYED MUSTAFA, HKBKCE
  • 57. UNIT 3 UNIX FILE APIs open To illustrate the use of the above flags, the following example statement opens a file called /usr/syed/usp for read and write in append mode: int fd=open(“/usr/syed/usp”, O_RDWR | O_APPEND,0); If the file is opened in read only, then no other modifier flags can be used. If a file is opened in write only or read write, then we are allowed to use any modifier flags along with them. The third argument is used only when a new file is being created. 57PROF. SYED MUSTAFA, HKBKCE
  • 58. UNIT 3 UNIX FILE APIs open 58PROF. SYED MUSTAFA, HKBKCE
  • 59. UNIT 3 UNIX FILE APIs open 59PROF. SYED MUSTAFA, HKBKCE
  • 60. UNIT 3 UNIX FILE APIs open 60PROF. SYED MUSTAFA, HKBKCE
  • 61. UNIT 3 UNIX FILE APIs open To open "sample.txt" in the current working directory for appending or create it, if it does not exist, with read, write and execute permissions for owner only: fd = open(“sample.txt", O_WRONLY|O_APPEND|O_CREAT, S_IRWXU); fd = open(“sample.txt", O_WRONLY|O_APPEND|O_CREAT, 0700); fd = open(“sample.txt", O_WRONLY|O_CREAT|O_EXCL, S_IRWXU|S_IROTH|S_IWOTH); fd = open(“sample.txt", O_WRONLY|O_CREAT|O_EXCL,0706); fd = open(“sample.txt", O_WRONLY|O_CREAT|O_TRUNC,0706); 61PROF. SYED MUSTAFA, HKBKCE
  • 62. UNIT 3 UNIX FILE APIs open Tag Description EACCES The requested access to the file is not allowed, or search permission is denied for one of the directories in the path prefix of pathname, or the file did not exist yet and write access to the parent directory is not allowed. EEXIST pathname already exists and O_CREAT and O_EXCL were used. EFAULT pathname points outside accessible address space. ENOENT O_CREAT is not set and the named file does not exist. Or, a directory component in pathname does not exist or is a dangling symbolic link. ENOMEM Insufficient kernel memory was available. 62PROF. SYED MUSTAFA, HKBKCE
  • 63. UNIT 3 UNIX FILE APIs creat ( ) •This system call is used to create new regular files. #include <sys/types.h> #include<unistd.h> int creat(const char *pathname, mode_t mode); •Returns: file descriptor opened for write-only if OK, -1 on error. •The first argument pathname specifies name of the file to be created. •The second argument mode_t, specifies permission of a file to be accessed by owner group and others. •The creat function can be implemented using open function as: #define creat(path_name, mode) open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode); 63PROF. SYED MUSTAFA, HKBKCE
  • 64. UNIT 3 UNIX FILE APIs read ( ) The read function fetches a fixed size of block of data from a file referenced by a given file descriptor. The prototype of read function is: #include<sys/types.h> #include<unistd.h> size_t read(int fdesc, void *buf, size_t nbyte);  If successful, read returns the no. of bytes actually read, on error it returns –1.  The first argument is an integer, fdesc that refers to an opened file.  The second argument, buf is the address of a buffer holding any data read.  The third argument specifies how many bytes of data are to be read from the file.  The size_t data type is defined in the <sys/types.h> header and should be the same as unsigned int. 64PROF. SYED MUSTAFA, HKBKCE
  • 65. UNIT 3 UNIX FILE APIs read ( ) There are several cases in which the number of bytes actually read is less than the amount requested:  When reading from a regular file, if the end of file is reached before the requested number of bytes has been read.  For example, if 30 bytes remain until the end of file and we try to read 100 bytes, read returns 30. The next time we call read, it will return 0 (end of file).  When reading from a terminal device. Normally, up to one line is read at a time.  When reading from a network. Buffering within the network may cause less than the requested amount to be returned.  When reading from a pipe or FIFO. If the pipe contains fewer bytes than requested, read will return only what is available. 65PROF. SYED MUSTAFA, HKBKCE
  • 66. UNIT 3 UNIX FILE APIs read ( )- Errors Tag Description EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and no data was immediately available for reading. EBADF fd is not a valid file descriptor or is not open for reading. EFAULT buf is outside your accessible address space. EINTR The call was interrupted by a signal before any data was read. EINVAL fd is attached to an object which is unsuitable for reading; or the file was opened with the O_DIRECT flag, and either the address specified in buf, the value specified in count, or the current file offset is not suitably aligned. EIO I/O error. This will happen for example when the process is in a background process group, tries to read from its controlling tty, and either it is ignoring or blocking SIGTTIN or its process group is orphaned. It may also occur when there is a low-level I/O error while reading from a disk or tape. EISDIR fd refers to a directory. 66PROF. SYED MUSTAFA, HKBKCE
  • 67. UNIT 3 UNIX FILE APIs read ( ) #include<fcntl.h> int main() { int fd,nob;char c[256]; fd=open(“sample”,O_RDONLY); nob= read(fd,c,sizeof(c)); if(nob!=-1) printf("%sn",c); else perror(“read Error”); close(fd); return 0; } 67PROF. SYED MUSTAFA, HKBKCE
  • 68. UNIT 3 UNIX FILE APIs write( ) The write system call is used to write data into a file The write function puts data to a file in the form of fixed block size referred by a given file. The prototype of read function is: #include<sys/types.h> #include<unistd.h> ssize_t write(int fdesc, const void *buf, size_t size);  If successful, write returns the number of bytes actually written.  If unsuccessful, write returns –1.  The first argument, fdesc is an integer that refers to an opened file.  The second argument, buf is the address of a buffer that contains data to be written.  The third argument, size specifies how many bytes of data are in the buf argument.  The return value is usually equal to the number of bytes of data successfully written to a file. (size value) 68PROF. SYED MUSTAFA, HKBKCE
  • 69. UNIT 3 UNIX FILE APIs write( )-Errors Error Code Description EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and the write would block. EBADF fd is not a valid file descriptor or is not open for writing. EFAULT buf is outside your accessible address space. EFBIG An attempt was made to write a file that exceeds the implementation-defined maximum file size or the process’ file size limit, or to write at a position past the maximum allowed offset. EINTR The call was interrupted by a signal before any data was written. EINVAL fd is attached to an object which is unsuitable for writing; or the file was opened with the O_DIRECT flag, and either the address specified in buf, the value specified in count, or the current file offset is not suitably aligned. EIO A low-level I/O error occurred while modifying the inode. EPIPE fd is connected to a pipe or socket whose reading end is closed. When this happens the writing process will also receive a SIGPIPE signal. (Thus, the write return value is seen only if the program catches, blocks or ignores this signal.) 69PROF. SYED MUSTAFA, HKBKCE
  • 70. UNIT 3 UNIX FILE APIswrite( ) #include<fcntl.h> int main() { int fd,nob;char c[]=“ This is sample text”; fd=open(“sample”,O_WRONLY,0777); nob= write(fd,c,strlen(c)); if(nob!=-1) printf(“Successfully written to file”); else perror(“write Error”); close(fd); return 0; } 70PROF. SYED MUSTAFA, HKBKCE
  • 71. UNIT 3 UNIX FILE APIs close( ) The close system call is used to terminate the connection to a file from a process. The prototype of the close() is #include<unistd.h> int close(int fdesc);  If successful, close returns 0.  If unsuccessful, close returns –1.  The argument fdesc refers to an opened file.  Close function frees the unused file descriptors so that they can be reused to reference other files. This is important because a process may open up to OPEN_MAX files at any time and the close function allows a process to reuse file descriptors to access more than OPEN_MAX files in the course of its execution.  The close function de-allocates system resources like file table entry and memory buffer allocated to hold the read/write. 71PROF. SYED MUSTAFA, HKBKCE
  • 72. UNIT 3 UNIX FILE APIs close( ) - Errors Tag Description EBADF fd isn’t a valid open file descriptor. EINTR The close() call was interrupted by a signal. EIO An I/O error occurred. 72PROF. SYED MUSTAFA, HKBKCE
  • 73. UNIT 3 UNIX FILE APIs Emulate ‘cp’ UNIX command – cp f1 f2 #include<fcntl.h> int main() { int fd1,fd2,nob; char c; fd1=open(“f1”,O_RDONLY); fd2=open(“f2”,O_WRONLY|)_CREAT|O_TRUNC, 0777); while(read(fd1,&c,1)) write(fd2,&c,1); close(fd1); close(fd2); return 0; } 73PROF. SYED MUSTAFA, HKBKCE
  • 74. UNIT 3 UNIX FILE APIs Emulate ‘cp’ UNIX command – cp f1 f2 #include<fcntl.h> int main() { int fd1,fd2,nob; char c; fd1=open(“f1”,O_RDONLY); If(fd1!=-1) { fd2=open(“f2”,O_WRONLY|)_CREAT|O_TRUNC, 0777); if(fd2!=-1) { while(read(fd1,&c,1)) write(fd2,&c,1); close(fd1); close(fd2); } else { perror(“write Error”); close(fd1); } } /*if fd1 */ else perror(“read Error”); return 0; } 74PROF. SYED MUSTAFA, HKBKCE
  • 75. UNIT 3 UNIX FILE APIs 75PROF. SYED MUSTAFA, HKBKCE
  • 76. UNIT 3 UNIX FILE APIs 76PROF. SYED MUSTAFA, HKBKCE
  • 77. UNIT 3 UNIX FILE APIs 77PROF. SYED MUSTAFA, HKBKCE
  • 78. UNIT 3 UNIX FILE APIs 78PROF. SYED MUSTAFA, HKBKCE
  • 79. UNIT 3 UNIX FILE APIs 79PROF. SYED MUSTAFA, HKBKCE
  • 80. UNIT 3 UNIX FILE APIs 80PROF. SYED MUSTAFA, HKBKCE
  • 81. UNIT 3 UNIX FILE APIs 81PROF. SYED MUSTAFA, HKBKCE
  • 82. UNIT 3 UNIX FILE APIs 82PROF. SYED MUSTAFA, HKBKCE
  • 83. UNIT 3 UNIX FILE APIs 83PROF. SYED MUSTAFA, HKBKCE
  • 84. UNIT 3 UNIX FILE APIs 84PROF. SYED MUSTAFA, HKBKCE
  • 85. UNIT 3 UNIX FILE APIs 85PROF. SYED MUSTAFA, HKBKCE
  • 86. UNIT 3 UNIX FILE APIs 86PROF. SYED MUSTAFA, HKBKCE
  • 87. UNIT 3 UNIX FILE APIs Chown(), fchown(), lchown() The chown functions changes the user ID and group ID of files. The prototypes of these functions are: #include<unistd.h> #include<sys/types.h> int chown(const char *path_name, uid_t uid, gid_t gid); int fchown(int fdesc, uid_t uid, gid_t gid); int lchown(const char *path_name, uid_t uid, gid_t gid); The path_name argument is the path name of a file. The uid argument specifies the new user ID to be assigned to the file. The gid argument specifies the new group ID to be assigned to the file. 87PROF. SYED MUSTAFA, HKBKCE
  • 88. UNIT 3 UNIX FILE APIs Chown(), fchown(), lchown() /* Program to illustrate chown() */ #include<iostream.h> #include<sys/types.h> #include<sys/stat.h> #include<unistd.h> #include<pwd.h> int main(int argc, char *argv[ ]) { if(argc>3) { cerr<<”usage:”<<argv[0]<<”<usr_name>< file>....n”; return 1; } struct passwd *pwd = getpwuid(argv[1]) ; uid_t UID = pwd ? pwd -> pw_uid : -1 ; struct stat statv; if (UID == (uid_t)-1) cerr <<“Invalid user name”; else for (int i = 2; i < argc ; i++) if (stat(argv[i], &statv)==0) { if (chown(argv[i], UID,statv.st_gid)) perror (“chown”); } return 0; } 88PROF. SYED MUSTAFA, HKBKCE
  • 89. UNIT 3 UNIX FILE APIs Chmod(), fchmod() The chmod and fchmod functions change file access permissions for owner, group & others as well as the set_UID, set_GID and sticky flags. A process must have the effective UID of either the super-user/owner of the file. The prototypes of these functions are #include<sys/types.h> #include<sys/stat.h> #include<unistd.h> int chmod(const char *pathname, mode_t flag); int fchmod(int fdesc, mode_t flag); 89PROF. SYED MUSTAFA, HKBKCE
  • 90. UNIT 3 UNIX FILE APIs Chmod(), fchmod()  The pathname argument of chmod is the path name of a file whereas the fdesc argument of fchmod is the file descriptor of a file.  The chmod function operates on the specified file, whereas the fchmod() function operates on a file that has already been opened.  To change the permission bits of a file, the effective user ID of the process must be equal to the owner ID of the file, or the process must have super-user permissions. The mode is specified as the bitwise OR of the constants shown below 90PROF. SYED MUSTAFA, HKBKCE
  • 91. UNIT 3 UNIX FILE APIs 91PROF. SYED MUSTAFA, HKBKCE
  • 92. UNIT 3 UNIX FILE APIs 92PROF. SYED MUSTAFA, HKBKCE
  • 93. UNIT 3 UNIX FILE APIs 93PROF. SYED MUSTAFA, HKBKCE
  • 94. UNIT 3 UNIX FILE APIs 94PROF. SYED MUSTAFA, HKBKCE
  • 95. UNIT 3 UNIX FILE APIs 95PROF. SYED MUSTAFA, HKBKCE
  • 96. UNIT 3 UNIX FILE APIs 96PROF. SYED MUSTAFA, HKBKCE
  • 97. UNIT 3 UNIX FILE APIs 97PROF. SYED MUSTAFA, HKBKCE
  • 98. UNIT 3 UNIX FILE APIs File and Record Locking  Multiple processes performs read and write operation on the same file concurrently.  This provides a means for data sharing among processes, but it also renders difficulty for any process in determining when the other process can override data in a file.  So, in order to overcome this drawback UNIX and POSIX standard support file locking mechanism.  File locking is applicable for regular files. 98PROF. SYED MUSTAFA, HKBKCE
  • 99. UNIT 3 UNIX FILE APIs File and Record Locking  Only a process can impose a write lock or read lock on either a portion of a file or on the entire file.  The differences between the read lock and the write lock is that when write lock is set, it prevents the other process from setting any over-lapping read or write lock on the locked file.  Similarly when a read lock is set, it prevents other processes from setting any overlapping write locks on the locked region.  The intension of the write lock is to prevent other processes from both reading and writing the locked region while the process that sets the lock is modifying the region, so write lock is termed as “Exclusive lock”. 99PROF. SYED MUSTAFA, HKBKCE
  • 100. UNIT 3 UNIX FILE APIs File and Record Locking  The use of read lock is to prevent other processes from writing to the locked region while the process that sets the lock is reading data from the region.  Other processes are allowed to lock and read data from the locked regions. Hence a read lock is also called as “shared lock “.  File lock may be mandatory if they are enforced by an operating system kernel.  If a mandatory exclusive lock is set on a file, no process can use the read or write system calls to access the data on the locked region.  These mechanisms can be used to synchronize reading and writing of shared files by multiple processes. 100PROF. SYED MUSTAFA, HKBKCE
  • 101. UNIT 3 UNIX FILE APIs File and Record Locking  If a process locks up a file, other processes that attempt to write to the locked regions are blocked until the former process releases its lock.  Problem with mandatory lock is – if a runaway process sets a mandatory exclusive lock on a file and never unlocks it, then, no other process can access the locked region of the file until the runway process is killed or the system has to be rebooted.  If locks are not mandatory, then it has to be advisory lock.  A kernel at the system call level does not enforce advisory locks.  This means that even though a lock may be set on a file, no other processes can still use the read and write functions to access the file. 101PROF. SYED MUSTAFA, HKBKCE
  • 102. UNIT 3 UNIX FILE APIs File and Record Locking To make use of advisory locks, process that manipulate the same file must co- operate such that they follow the given below procedure for every read or write operation to the file. 1. Try to set a lock at the region to be accesses. If this fails, a process can either wait for the lock request to become successful. 2. After a lock is acquired successfully, read or write the locked region. 3. Release the lock. 102PROF. SYED MUSTAFA, HKBKCE
  • 103. UNIT 3 UNIX FILE APIsFile and Record Locking  If a process sets a read lock on a file, for example from address 0 to 256, then sets a write lock on the file from address 0 to 512, the process will own only one write lock on the file from 0 to 512, the previous read lock from 0 to 256 is now covered by the write lock and the process does not own two locks on the region from 0 to 256. This process is called “Lock Promotion”.  Furthermore, if a process now unblocks the file from 128 to 480, it will own two write locks on the file:  one from 0 to 127 and the other from 481 to 512. This process is called “Lock Splitting”.  UNIX systems provide fcntl function to support file locking.  By using fcntl it is possible to impose read or write locks on either a region or an entire file. 103PROF. SYED MUSTAFA, HKBKCE
  • 104. UNIT 3 UNIX FILE APIs File and Record Locking The prototype of fcntl is #include<fcntl.h> int fcntl(int fdesc, int cmd_flag, ...); The first argument specifies the file descriptor. The second argument cmd_flag specifies what operation has to be performed. If fcntl is used for file locking then cmd_flag can values as: Cmd_flag Meaning F_SETLK sets a file lock, do not block if this cannot succeed immediately F_SETLKW sets a file lock and blocks the process until the lock is acquired F_GETLK queries as to which process locked a specified region of file 104PROF. SYED MUSTAFA, HKBKCE
  • 105. UNIT 3 UNIX FILE APIs File and Record Locking  For file locking purpose, the third argument to fctnl is an address of a struct flock type variable.  This variable specifies a region of a file where lock is to be set, unset or queried. struct flock { short l_type; /* what lock to be set or to unlock file */ short l_whence; /* Reference address for the next field */ off_t l_start ; /*offset from the l_whence reference addr*/ off_t l_len ; /*how many bytes in the locked region */ pid_t l_pid ; /*pid of a process which has locked the file */ }; 105PROF. SYED MUSTAFA, HKBKCE
  • 106. UNIT 3 UNIX FILE APIs File and Record Locking  The l_type field specifies the lock type to be set or unset.  The possible values, which are defined in the <fcntl.h>header, and their uses are:  The l_whence, l_start & l_len define a region of a file to be locked or unlocked. l_type value Use F_RDLCK Set a read lock on a specified region F_WRLCK Set a write lock on a specified region F_UNLCK Unlock a specified region 106PROF. SYED MUSTAFA, HKBKCE
  • 107. UNIT 3 UNIX FILE APIs File and Record Locking  The possible values of l_whence and their uses are: A lock set by the fcntl API is an advisory lock but we can also use fcntl for mandatory locking purpose with the following attributes set before using fcntl 1. Turn on the set-GID flag of the file. 2. Turn off the group execute right permission of the file. l_whence value Use SEEK_CUR The l_start value is added to current file pointer address SEEK_END The l_start value is added to byte 0 of the file SEEK_SET The l_start value is added to the end of the file 107PROF. SYED MUSTAFA, HKBKCE
  • 108. UNIT 3 UNIX FILE APIs File and Record Locking In the given example program, performed a read lock on a file “sample” from the 50th byte to 150th byte. #include<fcntl.h> int main ( ) { int fd; struct flock lock; fd=open(“sample”,O_RDONLY); lock.l_type=F_RDLCK; lock.l_whence=0; lock.l_start=50; lock.l_len=100; fcntl(fd,F_SETLK,&lock); } 108PROF. SYED MUSTAFA, HKBKCE
  • 109. UNIT 3 UNIX FILE APIsutime() The utime function modifies the access time and the modification time stamps of a file. The prototype of utime function is #include<sys/types.h> #include<unistd.h> #include<utime.h> int utime(const char *path_name, struct utimbuf *times); •On success it returns 0, on failure it returns –1. •The path_name argument specifies the path name of a file. •The times argument specifies the new access time and modification time for the file. •The struct utimbuf is defined in the <utime.h> header as: struct utimbuf { } time_t actime; /* access time */ time_t modtime; /* modification time */ 109PROF. SYED MUSTAFA, HKBKCE
  • 110. UNIT 3 UNIX FILE APIs utime()  The time_t datatype is an unsigned long and its data is the number of the seconds elapsed since the birthday of UNIX : 12 AM , Jan 1 of 1970.  If the times (variable) is specified as NULL, the function will set the named file access and modification time to the current time.  If the times (variable) is an address of the variable of the type struct utimbuf, the function will set the file access time and modification time to the value specified by the variable. 110PROF. SYED MUSTAFA, HKBKCE
  • 111. UNIT 3 UNIX FILE APIs Directory File API’s A Directory file is a record-oriented file, where each record stores a file name and the inode number of a file that resides in that directory. Directories are created with the mkdir API and deleted with the rmdir API. The prototype of mkdir is #include<sys/stat.h> #include<unistd.h> int mkdir(const char *path_name, mode_t mode);  The first argument is the path name of a directory file to be created.  The second argument mode, specifies the access permission for the owner, groups and others to be assigned to the file. This function creates a new empty directory.  The entries for “.” and “..” are automatically created.  The specified file access permission, mode, are modified by the file mode creation mask of the process 111PROF. SYED MUSTAFA, HKBKCE
  • 112. UNIT 3 UNIX FILE APIs Directory File API’s To allow a process to scan directories in a file system independent manner, a directory record is defined as struct dirent in the <dirent.h> header for UNIX. Some of the functions that are defined for directory file operations in the above header are #include<sys/types.h> #if defined (BSD) && ! _POSIX_SOURCE #include<sys/dir.h> typedef struct direct Dirent; #else #include<dirent.h> typedef struct dirent Dirent; #endif 112PROF. SYED MUSTAFA, HKBKCE
  • 113. UNIT 3 UNIX FILE APIs Directory File API’s DIR *opendir(const char *path_name); Dirent *readdir(DIR *dir_fdesc); int closedir(DIR *dir_fdesc); void rewinddir(DIR *dir_fdsec); The uses of these functions are Function Use opendir Opens a directory file for read-only. Returns a file handle dir * for future reference of the file. readdir Reads a record from a directory file referenced by dir-fdesc and returns that record information. rewinddir Resets the file pointer to the beginning of the directory file referenced by dir- fdesc. The next call to readdir will read the first record from the file. closedir closes a directory file referenced by dir-fdesc. 113PROF. SYED MUSTAFA, HKBKCE
  • 114. UNIT 3 UNIX FILE APIs Directory File API’s An empty directory is deleted with the rmdir API. The prototype of rmdir is #include<unistd.h> int rmdir (const char * path_name); If the link count of the directory becomes 0, with the call and no other process has the directory open then the space occupied by the directory is freed. UNIX systems have defined additional functions for random access of directory file records. Function Use telldir Returns the file pointer of a given dir_fdesc seekdir Changes the file pointer of a given dir_fdesc to a specified address 114PROF. SYED MUSTAFA, HKBKCE
  • 115. UNIT 3 UNIX FILE APIsDirectory File API’s The following list_dir.C program illustrates the uses of the mkdir, opendir, readdir, closedir and rmdir APIs: #include<iostream.h> #include<stdio.h> #include<sys/types.h> #include<unistd.h> #include<string.h> #include<sys/stat.h> #if defined(BSD) && !_POSIX_SOURCE #include<sys/dir.h> typedef struct direct Dirent; #else #include<dirent.h> typedef struct dirent Dirent; #endif int main(int agc, char* argv[]) { Dirent* dp; DIR* dir_fdesc; while(--argc>0) { if(!(dir_fdesc=opendir(*++argv))) { if(mkdir(*argv,S_IRWXU | S_IRWXG | S_IRWXO)==-1) perror("opendir"); continue; } 115PROF. SYED MUSTAFA, HKBKCE
  • 116. UNIT 3 UNIX FILE APIsDirectory File API’s The following list_dir.C program illustrates the uses of the mkdir, opendir, readdir, closedir and rmdir APIs: for(int i=0;i<2;i++) for(int cnt=0;dp=readdir(dir_fdesc);) { if(i) cout<<dp->d_name<<endl; if(strcmp(dp->d_name,".") && strcmp(dp->d_name,"..")) cnt++; } if(!cnt) { rmdir(*argv); break; } rewinddir(dir_fdesc); } //end for closedir(dir_fdesc); } //end while } //end main 116PROF. SYED MUSTAFA, HKBKCE
  • 117. UNIT 3 UNIX FILE APIs Device file APIs  Device files are used to interface physical device with application programs.  A process with superuser privileges to create a device file must call the mknod API.  The user ID and group ID attributes of a device file are assigned in the same manner as for regular files.  When a process reads or writes to a device file, the kernel uses the major and minor device numbers of a file to select a device driver function to carry out the actual data transfer.  Device file support is implementation dependent. UNIX System defines the mknod API to create device files. The prototype of mknod is #include<sys/stat.h> #include<unistd.h> int mknod(const char* path_name, mode_t mode, int device_id); 117PROF. SYED MUSTAFA, HKBKCE
  • 118. UNIT 3 UNIX FILE APIs Device file APIs  The first argument pathname is the pathname of a device file to be created.  The second argument mode specifies the access permission, for the owner, group and others, also S_IFCHR or S_IBLK flag to be assigned to the file.  The third argument device_id contains the major and minor device number. Example mknod(“SCSI5”,S_IFBLK | S_IRWXU | S_IRWXG | S_IRWXO,(15<<8) | 3); The above function creates a block device file “SCS15”, to which all the three i.e. read, write and execute permission is granted for user, group and others with major number as 8 and minor number 3. On success mknod API returns 0 , else it returns -1 118PROF. SYED MUSTAFA, HKBKCE
  • 119. UNIT 3 UNIX FILE APIs Device file APIs The following test_mknod.C program illustrates the use of the mknod, open, read, write and close APIs on a block device file. #include<iostream.h> #include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<unistd.h> #include<fcntl.h> #include<sys/stat.h> int main(int argc, char* argv[]) { if(argc!=4) { cout<<"usage:"<<argv[0]<<"<file><major_no><minor_no>"; return 0; } int major=atoi(argv[2]; Int minor=atoi(argv[3]); (void) mknod(argv[1], S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, (major<<8) | minor); int rc=1, Int fd=open(argv[1],O_RDW | O_NONBLOCK | O_NOCTTY); char buf[256]; while(rc && fd!=-1) if((rc=read(fd,buf,sizeof(buf)))<0) perror("read"); else if(rc) cout<<buf<<endl; close(fd); } 119PROF. SYED MUSTAFA, HKBKCE
  • 120. UNIT 3 UNIX FILE APIsFIFO file API’s  FIFO files are sometimes called named pipes.  Pipes can be used only between related processes when a common ancestor has created the pipe.  Creating a FIFO is similar to creating a file.  Indeed the pathname for a FIFO exists in the file system. The prototype of mkfifo is #include<sys/types.h> #include<sys/stat.h> #include<unistd.h> int mkfifo(const char *path_name, mode_t mode);  The first argument pathname is the pathname(filename) of a FIFO file to be created.  The second argument mode specifies the access permission for user, group and others and as well as the S_IFIFO flag to indicate that it is a FIFO file.  On success it returns 0 and on failure it returns –1. 120PROF. SYED MUSTAFA, HKBKCE
  • 121. UNIT 3 UNIX FILE APIsFIFO file API’s Example mkfifo(“FIFO5”, S_IFIFO | S_IRWXU | S_IRGRP | S_ROTH);  The above statement creates a FIFO file “fifo5” with read-write-execute permission for user and only read permission for group and others.  Once we have created a FIFO using mkfifo, we open it using open.  Indeed, the normal file I/O functions (read, write, unlink etc) all work with FIFOs.  When a process opens a FIFO file for reading, the kernel will block the process until there is another process that opens the same file for writing.  Similarly whenever a process opens a FIFO file write, the kernel will block the process until another process opens the same FIFO for reading.  This provides a means for synchronization in order to undergo inter-process communication.  If a particular process tries to write something to a FIFO file that is full, then that process will be blocked until another process has read data from the FIFO to make space for the process to write. 121PROF. SYED MUSTAFA, HKBKCE
  • 122. UNIT 3 UNIX FILE APIs FIFO file API’s  Similarly, if a process attempts to read data from an empty FIFO, the process will be blocked until another process writes data to the FIFO.  From any of the above condition if the process doesn’t want to get blocked then we should specify O_NONBLOCK in the open call to the FIFO file.  If the data is not ready for read/write then open returns –1 instead of process getting blocked.  If a process writes to a FIFO file that has no other process attached to it for read, the kernel will send SIGPIPE signal to the process to notify that it is an illegal operation.  Another method to create FIFO files (not exactly) for inter-process communication is to use the pipe system call. 122PROF. SYED MUSTAFA, HKBKCE
  • 123. UNIT 3 UNIX FILE APIs FIFO file API’s The prototype of pipe is #include <unistd.h> int pipe(int fds[2]);  Returns 0 on success and –1 on failure.  If the pipe call executes successfully, the process can read from fd[0] and write to fd[1].  A single process with a pipe is not very useful.  Usually a parent process uses pipes to communicate with its children. 123PROF. SYED MUSTAFA, HKBKCE
  • 124. UNIT 3 UNIX FILE APIs The following test_fifo.C example illustrates the use of mkfifo, open, read, write and close APIs for a FIFO file: #include<iostream.h> #include<stdio.h> #include<sys/types.h> #include<unistd.h> #include<fcntl.h> #include<sys/stat.h> #include<string.h> #include<errno.h> int main(int argc,char* argv[]) { if(argc!=2 && argc!=3) { cout<<"usage:"<<argv[0]<<"<file> [<arg>]"; return 0; } 124PROF. SYED MUSTAFA, HKBKCE
  • 125. UNIT 3 UNIX FILE APIs int fd; char buf[256]; (void) mkfifo(argv[1], S_IFIFO | S_IRWXU | S_IRWXG | S_IRWXO ); if(argc==2) { fd=open(argv[1],O_RDONLY | O_NONBLOCK); while(read(fd,buf,sizeof(buf))==-1 && errno==EAGAIN) sleep(1); while(read(fd,buf,sizeof(buf))>0) cout<<buf<<endl; } else { fd=open(argv[1],O_WRONLY); write(fd,argv[2],strlen(argv[2])); } close(fd); } 125PROF. SYED MUSTAFA, HKBKCE
  • 126. UNIT 4 UNIX PROCESSES INTRODUCTION A Process is a program under execution in a UNIX or POSIX system. main FUNCTION A C program starts execution with a function called main. The prototype for the main function is int main(int argc, char *argv[]); where argc is the number of command-line arguments, and argv is an array of pointers to the arguments.  When a C program is executed by the kernel by one of the exec functions, a special start-up routine is called before the main function is called.  The executable program file specifies this routine as the starting address for the program.  This is set up by the link editor when it is invoked by the C compiler.  This start-up routine takes values from the kernel, the command-line arguments and the environment and sets things up so that the main function is called. 126PROF. SYED MUSTAFA, HKBKCE
  • 127. UNIT 4 UNIX PROCESSES PROCESS TERMINATION There are eight ways for a process to terminate. Normal termination occurs in five ways: 1. Return from main 2. Calling exit 3. Calling _exit or _Exit 4. Return of the last thread from its start routine 5. Calling pthread_exit from the last thread Abnormal termination occurs in three ways: 1. Calling abort 2. Receipt of a signal 3. Response of the last thread to a cancellation request 127PROF. SYED MUSTAFA, HKBKCE
  • 128. UNIT 4 UNIX PROCESSES Exit Functions Three functions terminate a program normally: _exit and _Exit, which return to the kernel immediately, and exit, which performs certain cleanup processing and then returns to the kernel. #include <stdlib.h> void exit(int status); void _Exit(int status); #include <unistd.h> void _exit(int status); All three exit functions expect a single integer argument, called the exit status. Returning an integer value from the main function is equivalent to calling exit with the same value. Thus exit(0) is the same as return(0) from the main function. 128PROF. SYED MUSTAFA, HKBKCE
  • 129. UNIT 4 UNIX PROCESSES Exit Functions Three functions terminate a program normally: _exit and _Exit, which return to the kernel immediately, and exit, which performs certain cleanup processing and then returns to the kernel. #include <stdlib.h> void exit(int status); void _Exit(int status); #include <unistd.h> void _exit(int status); All three exit functions expect a single integer argument, called the exit status. Returning an integer value from the main function is equivalent to calling exit with the same value. Thus exit(0) is the same as return(0) from the main function. 129PROF. SYED MUSTAFA, HKBKCE
  • 130. UNIT 4 UNIX PROCESSES In the following situations the exit status of the process is undefined. 1. any of these functions is called without an exit status. 2. main does a return without a return value. 3. main “falls off the end”, i.e if the exit status of the process is undefined. int main() { printf(“HKBKCE”); return(5); } $ cc demo.c $ ./a.out HKBKCE $ echo $? //print the exit status 5 130PROF. SYED MUSTAFA, HKBKCE
  • 131. UNIT 4 UNIX PROCESSES atexit Function With ISO C, a process can register up to 32 functions that are automatically called by exit. These are called exit handlers and are registered by calling the atexit function. #include <stdlib.h> int atexit(void (*func)(void)); returns: 0 if OK, nonzero on error  This declaration says that we pass the address of a function as the argument to atexit.  When this function is called, it is not passed any arguments and is not expected to return a value.  The exit function calls these functions in reverse order of their registration.  Each function is called as many times as it was registered. 131PROF. SYED MUSTAFA, HKBKCE
  • 132. UNIT 4 UNIX PROCESSES Example of exit handlers static void my_exit1(void); static void my_exit2(void); int main(void) { if (atexit(my_exit2) != 0) perror("can't register my_exit2"); if (atexit(my_exit1) != 0) perror("can't register my_exit1"); printf("main is donen"); return(0); } static void my_exit1(void) { printf("first exit handlern"); } static void my_exit2(void) { printf("second exit handlern"); } Output: $ ./a.out main is done first exit handler second exit handler 132PROF. SYED MUSTAFA, HKBKCE
  • 133. UNIT 4 UNIX PROCESSES How a C program is started and the various ways it can terminate 133PROF. SYED MUSTAFA, HKBKCE
  • 134. UNIT 4 UNIX PROCESSES COMMAND-LINE ARGUMENTS When a program is executed, the process that does the exec can pass command-line arguments to the new program. Example: Echo all command-line arguments to standard output int main(int argc, char *argv[]) { int i; for (i = 0; i < argc;i++) /* echo all command-line args */ printf("argv[%d]: %sn", i, argv[i]); exit(0); } Output: $ ./echoarg arg1 TEST foo argv[0]: ./echoarg argv[1]: arg1 argv[2]: TEST argv[3]: foo 134PROF. SYED MUSTAFA, HKBKCE
  • 135. UNIT 4 UNIX PROCESSES ENVIRONMENT LIST Each program is also passed an environment list. Like the argument list, the environment list is an array of character pointers, with each pointer containing the address of a null-terminated C string. The address of the array of pointers is contained in the global variable environ: extern char **environ; Generally any environmental variable is of the form: name=value. 135PROF. SYED MUSTAFA, HKBKCE
  • 136. UNIT 4 UNIX PROCESSES MEMORY LAYOUT OF A C PROGRAM Historically, a C program has been composed of the following pieces: Text segment:  The machine instructions that the CPU executes.  Usually, the text segment is sharable so that only a single copy needs to be in memory for frequently executed programs, such as text editors, the C compiler, the shells, and so on.  Also, the text segment is often read-only, to prevent a program from accidentally modifying its instructions. Initialized data segment:  usually called simply the data segment, containing variables that are specifically initialized in the program.  For example, the C declaration  int maxcount = 99;  appearing outside any function causes this variable to be stored in the initialized data segment with its initial value. 136PROF. SYED MUSTAFA, HKBKCE
  • 137. UNIT 4 UNIX PROCESSES MEMORY LAYOUT OF A C PROGRAM Uninitialized data segment:  Often called the "bss" segment, named after an ancient assembler operator that stood for "block started by symbol."  Data in this segment is initialized by the kernel to arithmetic 0 or null pointers before the program starts executing.  The C declaration  long sum[1000];  appearing outside any function causes this variable to be stored in the uninitialized data segment. 137PROF. SYED MUSTAFA, HKBKCE
  • 138. UNIT 4 UNIX PROCESSES MEMORY LAYOUT OF A C PROGRAM Stack:  where automatic variables are stored, along with information that is saved each time a function is called.  Each time a function is called, the address of where to return to and certain information about the caller's environment, such as some of the machine registers, are saved on the stack.  The newly called function then allocates room on the stack for its automatic and temporary variables.  This is how recursive functions in C can work.  Each time a recursive function calls itself, a new stack frame is used, so one set of variables doesn't interfere with the variables from another instance of the function. 138PROF. SYED MUSTAFA, HKBKCE
  • 139. UNIT 4 UNIX PROCESSES MEMORY LAYOUT OF A C PROGRAM Heap:  where dynamic memory allocation usually takes place.  Historically, the heap has been located between the uninitialized data and the stack. 139PROF. SYED MUSTAFA, HKBKCE
  • 140. UNIT 4 UNIX PROCESSES MEMORY ALLOCATION ISO C specifies three functions for memory allocation: malloc: which allocates a specified number of bytes of memory. The initial value of the memory is indeterminate. calloc: which allocates space for a specified number of objects of a specified size. The space is initialized to all 0 bits. realloc: which increases or decreases the size of a previously allocated area. When the size increases, it may involve moving the previously allocated area somewhere else, to provide the additional room at the end. Also, when the size increases, the initial value of the space between the old contents and the end of the new area is indeterminate. 140PROF. SYED MUSTAFA, HKBKCE
  • 141. UNIT 4 UNIX PROCESSES MEMORY ALLOCATION #include <stdlib.h> void *malloc(size_t size); void *calloc(size_t nobj, size_t size); void *realloc(void *ptr, size_t newsize); On success, it returns: non-null pointer , NULL on Error. void free(void *ptr); The function free causes the space pointed to by ptr to be deallocated. This freed space is usually put into a pool of available memory and can be allocated in a later call to one of the three alloc functions. . 141PROF. SYED MUSTAFA, HKBKCE
  • 142. UNIT 4 UNIX PROCESSES MEMORY ALLOCATION alloca() Function  The function alloca has the same calling sequence as malloc;  however, instead of allocating memory from the heap, the memory is allocated from the stack frame of the current function.  The advantage is that we don't have to free the space;  it goes away automatically when the function returns.  The alloca function increases the size of the stack frame.  The disadvantage is that some systems can't support alloca, if it's impossible to increase the size of the stack frame after the function has been called. . 142PROF. SYED MUSTAFA, HKBKCE
  • 143. UNIT 4 UNIX PROCESSES ENVIRONMENT VARIABLES  The environment strings are usually of the form: name=value.  The functions that we can use to set and fetch values from the variables are setenv, putenv, and getenv functions. The prototype of these functions are: #include <stdlib.h> char *getenv(const char *name); Returns: pointer to value associated with name, NULL if not found. Eg: char *res=getenv(“HOME”); cout<<“HOME=“<<res<<endl; output: HOME=/home/syed 143PROF. SYED MUSTAFA, HKBKCE
  • 144. UNIT 4 UNIX PROCESSES ENVIRONMENT VARIABLES int putenv(char *str); int setenv(const char *name, const char *value, int rewrite); int unsetenv(const char *name); All return: 0 if OK, nonzero on error.  The putenv function takes a string of the form name=value and places it in the environment list.  If name already exists, its old definition is first removed. 144PROF. SYED MUSTAFA, HKBKCE
  • 145. UNIT 4 UNIX PROCESSES ENVIRONMENT VARIABLES int setenv(const char *name, const char *value, int rewrite); All return: 0 if OK, nonzero on error. The setenv function sets name to value.  If name already exists in the environment, then  if rewrite is nonzero, the existing definition for name is first removed;  if rewrite is 0, an existing definition for name is not removed, name is not set to the new value, and no error occurs. 145PROF. SYED MUSTAFA, HKBKCE
  • 146. UNIT 4 UNIX PROCESSES ENVIRONMENT VARIABLES int unsetenv(const char *name); All return: 0 if OK, nonzero on error. The unsetenv function removes any definition of name. It is not an error if such a definition does not exist. Difference between putenv() and setenv(): Whereas setenv() must allocate memory to create the name=value string from its arguments, putenv()is free to place the string passed to it directly into the environment. 146PROF. SYED MUSTAFA, HKBKCE
  • 147. UNIT 4 UNIX PROCESSES Setjmp() & longjmp() FUNCTIONS In C, we can't goto a label that's in another function. Instead, we must use the setjmp and longjmp functions to perform this type of branching. #include <setjmp.h> int setjmp(jmp_buf env); Returns: 0 if called directly, nonzero if returning from a call to longjmp void longjmp(jmp_buf env, int val);  The setjmp function records or marks a location in a program code so that later when the longjmp function is called from some other function, the execution continues from the location onwards.  The env variable(the first argument) records the necessary information needed to continue execution.  The env is of the jmp_buf defined in <setjmp.h> file, it contains the task. 147PROF. SYED MUSTAFA, HKBKCE
  • 148. UNIT 4 UNIX PROCESSES Setjmp() & longjmp() FUNCTIONS 1. The setjmp function always returns ‘0’ on its success when it is called directly in a process (for the first time). 2. The longjmp function is called to transfer a program flow to a location that was stored in the env argument. 3. The program code marked by the env must be in a function that is among the callers of the current function. 4. When the process is jumping to the target function, all the stack space used in the current function and its callers, upto the target function are discarded by the longjmp function. 5. The process resumes execution by re-executing the setjmp statement in the target function that is marked by env. 6. The return value of setjmp function is the value(val), as specified in the longjmp function call. 7. The ‘val’ should be nonzero, so that it can be used to indicate where and why the longjmp function was invoked and process can do error handling accordingly. 148PROF. SYED MUSTAFA, HKBKCE
  • 149. UNIT 4 UNIX PROCESSES Setjmp() & longjmp() FUNCTIONS #include <stdio.h> #include <setjmp.h> jmp_buf jb; int main(int argc, char *argv[]) { int a, b, c; printf ("Give two numbers for division : "); scanf("%d %d", &a, &b); if(setjmp(jb) == 0) { c = division(a, b); printf ("%d / %d = %d", a, b, c); return 0; } else { handle_error(); return -1; } } int division(int a, int b) { if(b == 0) longjmp(jb, 1); else return (a/b); } void handle_error(void) { printf("Divide by zero error !"); } 149PROF. SYED MUSTAFA, HKBKCE
  • 150. UNIT 4 UNIX PROCESSES getrlimit() AND setrlimit() FUNCTIONS Every process has a set of resource limits, some of which can be queried and changed by the getrlimit and setrlimit functions. #include <sys/resource.h> int getrlimit(int resource, struct rlimit *rlptr); int setrlimit(int resource, const struct rlimit*rlptr); Both return: 0 if OK, nonzero on error Each call to these two functions specifies a single resource and a pointer to the following structure: struct rlimit { rlim_t rlim_cur; /* soft limit: current limit */ rlim_t rlim_max; /* hard limit: maximum value for rlim_cur */ }; 150PROF. SYED MUSTAFA, HKBKCE
  • 151. UNIT 4 UNIX PROCESSES getrlimit() AND setrlimit() FUNCTIONS Three rules govern the changing of the resource limits. 1. A process can change its soft limit to a value less than or equal to its hard limit. 2. A process can lower its hard limit to a value greater than or equal to its soft limit. This lowering of the hard limit is irreversible for normal users. 3. Only a super user process can raise a hard limit. An infinite limit is specified by the constant RLIM_INFINITY. RLIMIT_AS The maximum size in bytes of a process's total available memory. RLIMIT_CORE The maximum size in bytes of a core file. A limit of 0 prevents the creation of a core file. RLIMIT_CPU The maximum amount of CPU time in seconds. When the soft limit is exceeded, the SIGXCPU signal is sent to the process. RLIMIT_DATA The maximum size in bytes of the data segment: the sum of the initialized data, uninitialized data, and heap. RLIMIT_FSIZE The maximum size in bytes of a file that may be created. When the soft limit is exceeded, the process is sent the SIGXFSZ signal. RLIMIT_LOCKS The maximum number of file locks a process can hold. RLIMIT_NOFILE The maximum number of open files per process. Changing this limit affects the value returned by the sysconffunction for its _SC_OPEN_MAXargument RLIMIT_NPROC The maximum number of child processes per real user ID. Changing this limit affects the value returned for _SC_CHILD_MAX by the sysconffunction 151PROF. SYED MUSTAFA, HKBKCE
  • 152. UNIT 4 UNIX PROCESSES getrlimit() AND setrlimit() FUNCTIONS Example: Print the current resource limits #define doit(name) p_limits(#name, name) int main(void) { #ifdef RLIMIT_AS doit(RLIMIT_AS); #endif doit(RLIMIT_CORE); doit(RLIMIT_CPU); doit(RLIMIT_DATA); doit(RLIMIT_FSIZE); #ifdef RLIMIT_LOCKS doit(RLIMIT_LOCKS); #endif doit(RLIMIT_NOFILE); #ifdef RLIMIT_NPROC doit(RLIMIT_NPROC); #endif exit(0); } static void pr_limits(char *name, int resource) { struct rlimit limit; if (getrlimit(resource, &limit) < 0) printf("getrlimit error for %s", name); printf("%-14s ", name); if (limit.rlim_cur == RLIM_INFINITY) printf("(infinite) "); else printf(FMT, limit.rlim_cur); if (limit.rlim_max == RLIM_INFINITY) printf("(infinite)"); else printf(FMT, limit.rlim_max); } 152PROF. SYED MUSTAFA, HKBKCE
  • 153. UNIT 4 UNIX PROCESSES UNIX KERNEL SUPPORT FOR PROCESS  UNIX kernel has a process table that keeps track of all active process present in the system. Some of these processes belongs to the kernel and are called as “system process”.  Every entry in the process table contains pointers to the text, data and the stack segments and also to U-area of a process.  U-area of a process is an extension of the process table entry and contains other process specific data such as the file descriptor table, current root and working directory inode numbers and set of system imposed process limits.  All processes in UNIX system expect the process that is created by the system boot code, are created by the fork system call. 153PROF. SYED MUSTAFA, HKBKCE
  • 154. UNIT 4 UNIX PROCESSES UNIX KERNEL SUPPORT FOR PROCESS 154PROF. SYED MUSTAFA, HKBKCE
  • 155. UNIT 4 UNIX PROCESSES UNIX KERNEL SUPPORT FOR PROCESS  After the fork system call, once the child process is created, both the parent and child processes resumes execution.  When a process is created by fork, it contains duplicated copies of the text, data and stack segments of its parent as shown in the Figure below.  Also it has a file descriptor table, which contains reference to the same opened files as the parent, such that they both share the same file pointer to each opened files. 155PROF. SYED MUSTAFA, HKBKCE
  • 156. UNIT 4 UNIX PROCESSES UNIX KERNEL SUPPORT FOR PROCESS The process will be assigned with attributes, which are either inherited from its parent or will be set by the kernel. Attributes Meaning real user identification number (rUID) the user ID of a user who created the parent process real group identification number (rGID) the group ID of a user who created that parent process effective user identification number (eUID) this allows the process to access and create files with the same privileges as the program file owner. effective group identification number (eGID) this allows the process to access and create files with the same privileges as the group to which the program file belongs. Saved set-UID and saved set-GID these are the assigned eUID and eGID of the process respectively Process group identification number (PGID) and session identification number (SID) these identify the process group and session of which the process is member Supplementary group identification numbers this is a set of additional group IDs for a user who created the process 156PROF. SYED MUSTAFA, HKBKCE
  • 157. UNIT 4 UNIX PROCESSES UNIX KERNEL SUPPORT FOR PROCESS The process will be assigned with attributes, which are either inherited from its parent or will be set by the kernel. Attributes Meaning Current directory this is the reference (inode number) to a working directory file Root directory this is the reference to a root directory Signal handling the signal handling settings Signal mask a signal mask that specifies which signals are to be blocked Umask a file mode mask that is used in creation of files to specify which accession rights should be taken out. Nice value the process scheduling priority value Controlling terminal the controlling terminal of the process 157PROF. SYED MUSTAFA, HKBKCE
  • 158. UNIT 4 UNIX PROCESSES UNIX KERNEL SUPPORT FOR PROCESS In addition to the above attributes, the following attributes are different between the parent and child processes: Attributes Meaning Process identification number (PID) an integer identification number that is unique per process in an entire operating system. Parent process identification number (PPID) the parent process PID Pending signals the set of signals that are pending delivery to the parent process Alarm clock time the process alarm clock time is reset to zero in the child process File locks the set of file locks owned by the parent process is not inherited by the chid process 158PROF. SYED MUSTAFA, HKBKCE
  • 159. UNIT 4 UNIX PROCESSES UNIX KERNEL SUPPORT FOR PROCESS fork and exec are commonly used together to spawn a sub-process to execute a different program. The advantages of this method are:  A process can create multiple processes to execute multiple programs concurrently.  Because each child process executes in its own virtual address space, the parent process is not affected by the execution status of its child process. 159PROF. SYED MUSTAFA, HKBKCE
  • 160. UNIT 5 PROCESS CONTROL PROCESS IDENTIFIERS #include <unistd.h> pid_t getpid(void); Returns: process ID of calling process pid_t getppid(void); Returns: parent process ID of calling process uid_t getuid(void); Returns: real user ID of calling process uid_t geteuid(void); Returns: effective user ID of calling process gid_t getgid(void); Returns: real group ID of calling process gid_t getegid(void); Returns: effective group ID of calling process 160PROF. SYED MUSTAFA, HKBKCE
  • 161. UNIT 5 PROCESS CONTROL fork FUNCTION An existing process can create a new one by calling the fork function. #include <unistd.h> pid_t fork(void); Returns: 0 in child, process ID of child in parent, 1 on error.  The new process created by fork is called the child process.  This function is called once but returns twice.  The only difference in the returns is that the return value in the child is 0, whereas the return value in the parent is the process ID of the new child.  The reason the child's process ID is returned to the parent is that a process can have more than one child, and there is no function that allows a process to obtain the process IDs of its children. 161PROF. SYED MUSTAFA, HKBKCE
  • 162. UNIT 5 PROCESS CONTROL fork FUNCTION  The reason fork returns 0 to the child is that a process can have only a single parent, and the child can always call getppid to obtain the process ID of its parent.  (Process ID 0 is reserved for use by the kernel, so it's not possible for 0 to be the process ID of a child.)  Both the child and the parent continue executing with the instruction that follows the call to fork.  The child is a copy of the parent.  For example, the child gets a copy of the parent's data space, heap, and stack.  Note that this is a copy for the child;  the parent and the child do not share these portions of memory.  The parent and the child share the text segment . 162PROF. SYED MUSTAFA, HKBKCE
  • 163. UNIT 5 PROCESS CONTROL fork FUNCTION Example programs: Program 1 /* Program to demonstrate fork function Program name – fork1.c */ #include<unistd.h> void main( ) { fork( ); printf(“n hello USP”); } Output : $ cc fork1.c $ ./a.out hello USP hello USP Note : The statement hello USP is executed twice as both the child and parent have executed that instruction. 163PROF. SYED MUSTAFA, HKBKCE
  • 164. UNIT 5 PROCESS CONTROL fork FUNCTION Example programs: Program 2 /* Program name – fork2.c */ #include<unistd.h> void main( ) { printf(“n 6 sem “); fork( ); printf(“n hello USP”); } Output : $ cc fork2.c $ ./a.out 6 sem hello USP hello USP Note: The statement 6 sem is executed only once by the parent because it is called before fork and statement hello USP is executed twice by child and parent. 164PROF. SYED MUSTAFA, HKBKCE
  • 165. UNIT 5 PROCESS CONTROL fork FUNCTION The two main reasons for fork to fail are 1. if too many processes are already in the system, which usually means that something else is wrong, or 2. if the total number of processes for this real user ID exceeds the system's limit. There are two uses for fork: 1. When a process wants to duplicate itself so that the parent and child can each execute different sections of code at the same time. This is common for network servers, the parent waits for a service request from a client. When the request arrives, the parent calls fork and lets the child handle the request. The parent goes back to waiting for the next service request to arrive. 2. When a process wants to execute a different program. This is common for shells. In this case, the child does an exec right after it returns from the fork. 165PROF. SYED MUSTAFA, HKBKCE
  • 166. UNIT 5 PROCESS CONTROL vfork FUNCTION  The function vfork has the same calling sequence and same return values as fork.  The vfork function is intended to create a new process when the purpose of the new process is to exec a new program.  The vfork function creates the new process, just like fork, without copying the address space of the parent into the child, as the child won't reference that address space; the child simply calls exec (or exit) right after the vfork.  Instead, while the child is running and until it calls either exec or exit, the child runs in the address space of the parent.  This optimization provides an efficiency gain on some paged virtual-memory implementations of the UNIX System.  Another difference between the two functions is that vfork guarantees that the child runs first, until the child calls exec or exit. When the child calls either of these functions, the parent resumes. 166PROF. SYED MUSTAFA, HKBKCE
  • 167. UNIT 5 PROCESS CONTROL vfork FUNCTION Example of vfork function int glob = 6; /* external variable in initialized data */ int main(void) { int var=88; /* automatic variable on the stack */ pid_t pid; printf("before vforkn"); if ((pid = vfork()) < 0) perror("vfork error"); else if (pid == 0) /* child */ { glob++; /* modify parent's variables */ var++; _exit(0); /* child terminates */ } /* Parent continues here.*/ printf("pid = %dn", getpid()); printf("glob = %d, var = %dn", glob, var); exit(0); } Output: $ ./a.out before vfork pid = 29039 glob = 7, var = 89 167PROF. SYED MUSTAFA, HKBKCE
  • 168. UNIT 5 PROCESS CONTROL Wait() AND waitpid() FUNCTIONS  When a process terminates, either normally or abnormally, the kernel notifies the parent by sending the SIGCHLD signal to the parent.  Because the termination of a child is an asynchronous event - it can happen at any time while the parent is running - this signal is the asynchronous notification from the kernel to the parent.  The parent can choose to ignore this signal, or it can provide a function that is called when the signal occurs: a signal handler.  A process that calls wait() or waitpid() can: 1. Block, if all of its children are still running 2. Return immediately with the termination status of a child, if a child has terminated and is waiting for its termination status to be fetched 3. Return immediately with an error, if it doesn't have any child processes. 168PROF. SYED MUSTAFA, HKBKCE
  • 169. UNIT 5 PROCESS CONTROL Wait() AND waitpid() FUNCTIONS #include <sys/wait.h> pid_t wait(int *statloc); pid_t waitpid(pid_t pid, int *statloc, int options); 1. Both return: process ID if OK, 0 (see later), or 1 on error. 2. The argument statloc is a pointer to an integer. 3. If this argument is not a null pointer, the termination status of the terminated process is stored in the location pointed to by the argument 169PROF. SYED MUSTAFA, HKBKCE
  • 170. UNIT 5 PROCESS CONTROL Wait() AND waitpid() FUNCTIONS The differences between these two functions are as follows. 1. The wait function can block the caller until a child process terminates, whereas waitpid() has an option that prevents it from blocking. 2. The waitpid() function doesn't wait for the child that terminates first; 3. It has a number of options that control which process it waits for. 4. If a child has already terminated and is a zombie, wait returns immediately with that child's status. Otherwise, it blocks the caller until a child terminates. 5. If the caller blocks and has multiple children, wait returns when one terminates. 170PROF. SYED MUSTAFA, HKBKCE
  • 171. UNIT 5 PROCESS CONTROL Wait() AND waitpid() FUNCTIONS The interpretation of the pid argument for waitpid() depends on its value: Pid Value Action pid == 1 Waits for any child process. In this respect, waitpid is equivalent to wait pid > 0 Waits for the child whose process ID equals pid pid == 0 Waits for any child whose process group ID equals that of the calling process. pid < 1 Waits for any child whose process group ID equals the absolute value of pid. 171PROF. SYED MUSTAFA, HKBKCE
  • 172. UNIT 5 PROCESS CONTROL Wait() AND waitpid() FUNCTIONS Macros to examine the termination status returned by wait() and waitpid(): Macro Description WIFEXITED(status) True if status was returned for a child that terminated normally. In this case, we can execute WEXITSTATUS (status) to fetch the low-order 8 bits of the argument that the child passed to exit, _exit,or _Exit. WIFSIGNALED (status) True if status was returned for a child that terminated abnormally, by receipt of a signal that it didn't catch. In this case, we can execute WTERMSIG (status) to fetch the signal number that caused the termination. Additionally, some implementations (but not the Single UNIX Specification) define the macro WCOREDUMP (status) that returns true if a core file of the terminated process was generated. 172PROF. SYED MUSTAFA, HKBKCE
  • 173. UNIT 5 PROCESS CONTROL Wait() AND waitpid() FUNCTIONS Macros to examine the termination status returned by wait() and waitpid(): Macro Description WIFSTOPPED (status) True if status was returned for a child that is currently stopped. In this case, we can execute WSTOPSIG (status) to fetch the signal number that caused the child to stop. WIFCONTINUED (status) True if status was returned for a child that has been continued after a job control stop 173PROF. SYED MUSTAFA, HKBKCE
  • 174. UNIT 5 PROCESS CONTROL Wait() AND waitpid() FUNCTIONS pid_t waitpid(pid_t pid, int *statloc, int options); The options constants for waitpid() Constant Description WCONTINUED If the implementation supports job control, the status of any child specified by pid that has been continued after being stopped, but whose status has not yet been reported, is returned. WNOHANG The waitpid() function will not block if a child specified by pid is not immediately available. In this case, the return value is 0. WUNTRACED If the implementation supports job control, the status of any child specified by pid that has stopped, and whose status has not been reported since it has stopped, is returned. The WIFSTOPPED macro determines whether the return value corresponds to a stopped child process. 174PROF. SYED MUSTAFA, HKBKCE
  • 175. UNIT 5 PROCESS CONTROL Wait() AND waitpid() FUNCTIONS pid_t waitpid(pid_t pid, int *statloc, int options); The waitpid function provides three features that aren't provided by the wait function. 1. The waitpid() function lets us wait for one particular process, whereas the wait() function returns the status of any terminated child. 2. The waitpid() function provides a nonblocking version of wait. There are times when we want to fetch a child's status, but we don't want to block. 3. The waitpid() function provides support for job control with the WUNTRACED and WCONTINUED options. 175PROF. SYED MUSTAFA, HKBKCE
  • 176. UNIT 5 PROCESS CONTROL Wait() AND waitpid() FUNCTIONS Program to Demonstrate various exit statuses #include <sys/wait.h> void pr_exit(int status) { if (WIFEXITED(status)) printf("normal termination, exit status = %dn", WEXITSTATUS(status)); else if (WIFSIGNALED(status)) printf("abnormal termination, signal number = %dn", WTERMSIG(status)); else if (WIFSTOPPED(status)) printf("child stopped, signal number = %dn", WSTOPSIG(status)); } 176PROF. SYED MUSTAFA, HKBKCE
  • 177. UNIT 5 PROCESS CONTROLWait() AND waitpid() FUNCTIONS Program to Demonstrate various exit statuses int main(void) { pid_t pid; int status; if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) /* child */ exit(7); if (wait(&status) != pid) /* wait for child */ perror("wait error"); pr_exit(status); /* and print its status */ if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) /* child */ abort(); /* generates SIGABRT */ if (wait(&status) != pid) /* wait for child */ perror("wait error"); pr_exit(status); /* and print its status */ if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) /* child */ status /= 0;/* divide by 0 generates SIGFPE */ if (wait(&status) != pid) /* wait for child */ perror("wait error"); pr_exit(status); /* and print its status */ exit(0); } 177PROF. SYED MUSTAFA, HKBKCE
  • 178. UNIT 5 PROCESS CONTROL Wait3() AND wait4() FUNCTIONS The only feature provided by these two functions that isn't provided by the wait, waitid, and waitpid functions is an additional argument that allows the kernel to return a summary of the resources used by the terminated process and all its child processes. The prototypes of these functions are: #include <sys/types.h> #include <sys/wait.h> #include <sys/time.h> #include <sys/resource.h> pid_t wait3(int *statloc, int options, struct rusage *rusage); pid_t wait4(pid_t pid, int *statloc, int options, struct rusage *rusage); Both return: process ID if OK,-1 on error. The resource information includes such statistics as the amount of user CPU time, the amount of system CPU time, number of page faults, number of signals received etc. the resource information is available only for terminated child process not for the process that were stopped due to job control. 178PROF. SYED MUSTAFA, HKBKCE
  • 179. UNIT 5 PROCESS CONTROL RACE CONDITIONS A race condition occurs when multiple processes are trying to do something with shared data and the final outcome depends on the order in which the processes run. Example: The program below outputs two strings: one from the child and one from the parent. The program contains a race condition because the output depends on the order in which the processes are run by the kernel and for how long each process runs. static void charatatime(char *); int main(void) { pid_t pid; if ((pid = fork()) < 0) peror("fork error"); else if (pid == 0) charatatime("output from childn"); else charatatime("output from parentn"); exit(0); } static void charatatime(char *str) { char *ptr; int c; setbuf(stdout, NULL); /* set unbuffered */ for (ptr = str; (c = *ptr++) != 0; ) putc(c, stdout); } Output: $ ./a.out ooutput from child utput from parent 179PROF. SYED MUSTAFA, HKBKCE
  • 180. UNIT 5 PROCESS CONTROL RACE CONDITIONS How to avoid race condition? static void charatatime(char *); int main(void) { pid_t pid; TELL_WAIT(); if ((pid = fork()) < 0) peror("fork error"); else if (pid == 0) { WAIT_PARENT(); /* parent goes first */ charatatime("output from childn"); } else { charatatime("output from parentn"); TELL_CHILD(pid); } exit(0); } static void charatatime(char *str) { char *ptr; int c; setbuf(stdout, NULL); /* set unbuffered */ for (ptr = str; (c = *ptr++) != 0; ) putc(c, stdout); } Output: $ ./a.out output from parent output from child 180PROF. SYED MUSTAFA, HKBKCE
  • 181. UNIT 5 PROCESS CONTROL RACE CONDITIONS How to avoid race condition? static void charatatime(char *); int main(void) { pid_t pid; TELL_WAIT(); if ((pid = fork()) < 0) peror("fork error"); else if (pid == 0) { charatatime("output from childn"); TELL_PARENT(getppid()); } else { WAIT_CHILD(); /* child goes first */ charatatime("output from parentn"); } exit(0); } static void charatatime(char *str) { char *ptr; int c; setbuf(stdout, NULL); /* set unbuffered */ for (ptr = str; (c = *ptr++) != 0; ) putc(c, stdout); } Output: $ ./a.out output from child output from parent 181PROF. SYED MUSTAFA, HKBKCE
  • 182. UNIT 5 PROCESS CONTROLexec() Functions  When a process calls one of the exec functions, that process is completely replaced by the new program, and the new program starts executing at its main function.  The process ID does not change across an exec, because a new process is not created;  exec merely replaces the current process - its text, data, heap, and stack segments - with a brand new program from disk. There are 6 exec functions: 182PROF. SYED MUSTAFA, HKBKCE
  • 183. UNIT 5 PROCESS CONTROLexec() Functions  The first difference in these functions is that the first four take a pathname argument, whereas the last two take a filename argument.  When a filename argument is specified  If filename contains a slash, it is taken as a pathname.  Otherwise, the executable file is searched for in the directories specified by the PATH environment variable.  The next difference concerns the passing of the argument list (l stands for list and v stands for vector). The functions execl, execlp, and execle require each of the command-line arguments to the new program to be specified as separate arguments.  For the other three functions (execv, execvp, and execve), we have to build an array of pointers to the arguments, and the address of this array is the argument to these three functions.  The final difference is the passing of the environment list to the new program.  The two functions whose names end in an e (execle and execve) allow us to pass a pointer to an array of pointers to the environment strings.  The other four functions, however, use the environ variable in the calling process to copy the existing environment for the new program. 183PROF. SYED MUSTAFA, HKBKCE
  • 184. UNIT 5 PROCESS CONTROL exec() Functions Relationship of the six exec functions In many UNIX system implementations, only one of these six functions, execve, is a system call within the kernel. The other five are just library functions that eventually invoke this system call. 184PROF. SYED MUSTAFA, HKBKCE
  • 185. UNIT 5 PROCESS CONTROL exec() Functions char *env_init[] = { "USER=syed", "PATH=/tmp", NULL }; int main(void) { pid_t pid; if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) { /* specify pathname, specify environment */ if (execle("/home/sar/bin/echoall", "echoall", "myarg1", "MY ARG2", (char *)0, env_init) < 0) perror("execle error"); } if (waitpid(pid, NULL, 0) < 0) perror("wait error") if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) { /* specify filename, inherit environment */ if (execlp("echoall", "echoall", "only 1 arg", (char *)0) < 0) perror("execlp error"); } exit(0); } Output: $ ./a.out argv[0]: echoall argv[1]: myarg1 argv[2]: MY ARG2 PATH=/tmp $ argv[0]: echoall argv[1]: only 1 arg USER=syed LOGNAME=syed SHELL=/bin/bash HOME=/home/sar 185PROF. SYED MUSTAFA, HKBKCE
  • 186. UNIT 5 PROCESS CONTROL exec() Functions echoall.c int main(int argc, char *argv[]) { int i; char **ptr; extern char **environ; for (i = 0; i < argc; i++) /* echo all command-line args */ printf("argv[%d]: %sn", i, argv[i]); for (ptr = environ; *ptr != 0; ptr++) /* and all env strings */ printf("%sn", *ptr); exit(0); } 186PROF. SYED MUSTAFA, HKBKCE
  • 187. UNIT 5 PROCESS CONTROL CHANGING USER IDs AND GROUP IDs  When our programs need additional privileges or need to gain access to resources that they currently aren't allowed to access, they need to change their user or group ID to an ID that has the appropriate privilege or access.  Similarly, when our programs need to lower their privileges or prevent access to certain resources, they do so by changing either their user ID or group ID to an ID without the privilege or ability access to the resource. We can set the real user ID and effective user ID with the setuid function. Similarly, we can set the real group ID and the effective group ID with the setgid function. #include <unistd.h> int setuid(uid_t uid); int setgid(gid_t gid); Both return: 0 if OK, -1 on error 187PROF. SYED MUSTAFA, HKBKCE
  • 188. UNIT 5 PROCESS CONTROL CHANGING USER IDs AND GROUP IDs There are rules for who can change the IDs. Let's consider only the user ID for now. (Everything we describe for the user ID also applies to the group ID.) 1. If the process has superuser privileges, the setuid function sets the real user ID, effective user ID, and saved set-user-ID to uid. 2. If the process does not have superuser privileges, but uid equals either the real user ID or the saved setuserID, setuid sets only the effective user ID to uid. The real user ID and the saved set-user-ID are not changed. 3. If neither of these two conditions is true, errno is set to EPERM, and –1 is returned. 188PROF. SYED MUSTAFA, HKBKCE
  • 189. UNIT 5 PROCESS CONTROL CHANGING USER IDs AND GROUP IDs setreuid() and setregid() Functions Historically, BSD supported the swapping of the real user ID and the effective user ID with the setreuid() function. #include <unistd.h> int setreuid(uid_t ruid, uid_t euid); int setregid(gid_t rgid, gid_t egid); Both return: 0 if OK, –1 on error 189PROF. SYED MUSTAFA, HKBKCE
  • 190. UNIT 5 PROCESS CONTROL CHANGING USER IDs AND GROUP IDs Seteuid() and setegid() Functions POSIX.1 includes the two functions seteuid and setegid. These functions are similar to setuid and setgid, but only the effective user ID or effective group ID is changed. #include <unistd.h> int seteuid(uid_t uid); int setegid(gid_t gid); Both return: 0 if OK, –1 on error 190PROF. SYED MUSTAFA, HKBKCE
  • 191. UNIT 5 PROCESS CONTROL Interpreter Files All contemporary UNIX systems support interpreter files. These files are text files that begin with a line of the form #! pathname [ optional-argument ] The space between the exclamation point and the pathname is optional. The most common of these interpreter files begin with the line #!/bin/sh #!/usr/bin/perl The pathname is normally an absolute pathname, since no special operations are performed on it 191PROF. SYED MUSTAFA, HKBKCE
  • 192. UNIT 5 PROCESS CONTROL Interpreter Files Using the -f option with an interpreter file lets us write #!/bin/awk -f (awk program follows in the interpreter file) Eg: #!/bin/awk -f BEGIN { for (i = 0; i < ARGC; i++) printf "ARGV[%d] = %sn", i, ARGV[i] exit } 192PROF. SYED MUSTAFA, HKBKCE
  • 193. UNIT 5 PROCESS CONTROL system() Function It is convenient to execute a command string from within a program. Eg: system("date > file"); #include <stdlib.h> int system(const char *cmdstring); If cmdstring is a null pointer, system returns nonzero only if a command processor is available. 193PROF. SYED MUSTAFA, HKBKCE
  • 194. UNIT 5 PROCESS CONTROL The system function, without signal handling #include <sys/wait.h> #include <errno.h> #include <unistd.h> int system(const char *cmdstring) /* version without signal handling */ { pid_t pid; int status; if (cmdstring == NULL) return(1); /* always a command processor with UNIX */ if ((pid = fork()) < 0) status = -1; /* probably out of processes */ 194PROF. SYED MUSTAFA, HKBKCE
  • 195. UNIT 5 PROCESS CONTROLelse if (pid == 0) { /* child */ execl("/bin/sh", "sh", "-c", cmdstring, (char *)0); _exit(127); /* execl error */ } else while (waitpid(pid, &status, 0) < 0) /* parent */ if (errno != EINTR) { status = -1; /* error other than EINTR from waitpid() */ break; } return(status); } 195PROF. SYED MUSTAFA, HKBKCE
  • 196. UNIT 5 PROCESS CONTROL PROCESS ACCOUNTING  Most UNIX systems provide an option to do process accounting.  When enabled, the kernel writes an accounting record each time a process terminates.  These accounting records are typically a small amount of binary data with the name of the command, the amount of CPU time used, the user ID and group ID, the starting time, and so on.  A superuser executes action with a pathname argument to enable accounting.  The accounting records are written to the specified file, which is usually /var/account/acct. Accounting is turned off by executing accton without any arguments. 196PROF. SYED MUSTAFA, HKBKCE
  • 197. UNIT 5 PROCESS CONTROL PROCESS ACCOUNTING  The data required for the accounting record, such as CPU times and number of characters transferred, is kept by the kernel in the process table and initialized whenever a new process is created, as in the child after a fork.  Each accounting record is written when the process terminates.  This means that the order of the records in the accounting file corresponds to the termination order of the processes, not the order in which they were started.  The accounting records correspond to processes, not programs.  A new record is initialized by the kernel for the child after a fork, not when a new program is executed. 197PROF. SYED MUSTAFA, HKBKCE
  • 198. UNIT 5 PROCESS CONTROL PROCESS ACCOUNTING The structure of the accounting records is defined in the header <sys/acct.h> and looks something like typedef u_short comp_t; /* 3-bit base 8 exponent; 13-bit fraction */ 198PROF. SYED MUSTAFA, HKBKCE
  • 199. UNIT 5 PROCESS CONTROL USER IDENTIFICATION  Any process can find out its real and effective user ID and group ID.  we want to find out the login name of the user who's running the program.  We could call getpwuid(getuid()), but what if a single user has multiple login names, each with the same user ID? (A person might have multiple entries in the password file with the same user ID to have a different login shell for each entry.)  The system normally keeps track of the name we log in and the getlogin function provides a way to fetch that login name. 199PROF. SYED MUSTAFA, HKBKCE
  • 200. UNIT 5 PROCESS CONTROL USER IDENTIFICATION #include <unistd.h> char *getlogin(void); Returns : pointer to string giving login name if OK, NULL on error This function can fail if the process is not attached to a terminal that a user logged in to. 200PROF. SYED MUSTAFA, HKBKCE
  • 201. UNIT 5 PROCESS CONTROL PROCESS TIMES We describe three times that we can measure: wall clock time, user CPU time, and system CPU time. Any process can call the times function to obtain these values for itself and any terminated children. #include <sys/times.h> clock_t times(struct tms *buf); Returns: elapsed wall clock time in clock ticks if OK, 1 on error 201PROF. SYED MUSTAFA, HKBKCE
  • 202. UNIT 5 PROCESS CONTROL PROCESS TIMES This function fills in the tms structure pointed to by buf: struct tms { clock_t tms_utime; /* user CPU time */ clock_t tms_stime; /* system CPU time */ clock_t tms_cutime; /* user CPU time, terminated children */ clock_t tms_cstime; /* system CPU time, terminated children */ };  Note that the structure does not contain any measurement for the wall clock time.  Instead, the function returns the wall clock time as the value of the function, each time it's called.  This value is measured from some arbitrary point in the past, so we can't use its absolute value; instead, we use its relative value. 202PROF. SYED MUSTAFA, HKBKCE
  • 203. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP TERMINAL LOGINS  The terminals were either local (directly connected) or remote (connected through a modem).  In either case, these logins came through a terminal device driver in the kernel.  The system administrator creates a file, usually /etc/ttys, that has one line per terminal device.  Each line specifies the name of the device and other parameters that are passed to the getty(). 203PROF. SYED MUSTAFA, HKBKCE
  • 204. UNIT 5 PROCESS CONTROLPROCESS RELATIONSHIP TERMINAL LOGINS  One parameter is the baud rate of the terminal, for example.  When the system is bootstrapped, the kernel creates process ID 1, the init process, and it is init that brings the system up multiuser.  The init process reads the file /etc/ttys and, for every terminal device that allows a login, does a fork followed by an exec of the program getty(). 204PROF. SYED MUSTAFA, HKBKCE
  • 205. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP TERMINAL LOGINS Processes invoked by init to allow terminal logins 205PROF. SYED MUSTAFA, HKBKCE
  • 206. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP TERMINAL LOGINS  All the processes shown in the diagram have a real user ID of 0 and an effective user ID of 0 (i.e., they all have superuser privileges).  The init process also execs the getty() program with an empty environment.  It is getty() that calls open for the terminal device.  The terminal is opened for reading and writing.  If the device is a modem, the open may delay inside the device driver until the modem is dialed and the call is answered.  Once the device is open, file descriptors 0, 1, and 2 are set to the device. 206PROF. SYED MUSTAFA, HKBKCE
  • 207. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP TERMINAL LOGINS  Then getty() outputs something like login and waits for us to enter our user name.  When we enter our user name, getty's job is complete, and it then invokes the login program, similar to execle("/bin/login", "login", "-p", username, (char *)0, envp); 207PROF. SYED MUSTAFA, HKBKCE
  • 208. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP TERMINAL LOGINS State of processes after login has been invoked 208PROF. SYED MUSTAFA, HKBKCE
  • 209. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP TERMINAL LOGINS All the processes shown in the diagram have superuser privileges, since the original init process has superuser privileges. If we log in correctly, login will  Change to our home directory (chdir)  Change the ownership of our terminal device (chown) so we own it  Change the access permissions for our terminal device so we have permission to read from and write to it  Set our group IDs by calling setgid and initgroups 209PROF. SYED MUSTAFA, HKBKCE
  • 210. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP TERMINAL LOGINS  Initialize the environment with all the information that login has: our home directory (HOME), shell (SHELL), user name (USER and LOGNAME), and a default path (PATH)  Change to our user ID (setuid) and invoke our login shell, as in execl("/bin/sh", "-sh", (char *)0); The minus sign as the first character of argv[0] is a flag to all the shells that they are being invoked as a login shell. The shells can look at this character and modify their start-up accordingly. 210PROF. SYED MUSTAFA, HKBKCE
  • 211. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP TERMINAL LOGINS Arrangement of processes after everything is set for a terminal login 211PROF. SYED MUSTAFA, HKBKCE
  • 212. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP NETWORK LOGINS  The main (physical) difference between logging in to a system through a serial terminal and logging in to a system through a network is that the connection between the terminal and the computer isn't point-to-point.  With the terminal logins, init knows which terminal devices are enabled for logins and spawns a getty process for each device.  In the case of network logins, however, all the logins come through the kernel's network interface drivers (e.g., the Ethernet driver). 212PROF. SYED MUSTAFA, HKBKCE
  • 213. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP NETWORK LOGINS  Let a TCP connection request arrives for the TELNET server.  TELNET is a remote login application that uses the TCP protocol.  A user on another host (that is connected to the server's host through a network of some form) or on the same host initiates the login by starting the TELNET client: telnet hostname  The client opens a TCP connection to hostname, and the program that's started on hostname is called the TELNET server.  The client and the server then exchange data across the TCP connection using the TELNET application protocol. 213PROF. SYED MUSTAFA, HKBKCE
  • 214. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP NETWORK LOGINS Figure shows the sequence of processes involved in executing the TELNET server, called telnetd. Sequence of processes involved in executing TELNET server 214PROF. SYED MUSTAFA, HKBKCE
  • 215. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP NETWORK LOGINS  The telnetd process then opens a pseudo-terminal device and splits into two processes using fork.  The parent handles the communication across the network connection, and the child does an exec of the login program.  The parent and the child are connected through the pseudo terminal.  Before doing the exec, the child sets up file descriptors 0, 1, and 2 to the pseudo terminal.  If we log in correctly, login performs the same steps as described earlier.  It changes to our home directory and sets our group IDs, user ID, and our initial environment.  Then login replaces itself with our login shell by calling exec. 215PROF. SYED MUSTAFA, HKBKCE
  • 216. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP NETWORK LOGINS Arrangement of processes after everything is set for a networklogin 216PROF. SYED MUSTAFA, HKBKCE
  • 217. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP NETWORK LOGINS Arrangement of processes after everything is set for a networklogin 217PROF. SYED MUSTAFA, HKBKCE
  • 218. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP PROCESS GROUPS  A process group is a collection of one or more processes, usually associated with the same job, that can receive signals from the same terminal.  Each process group has a unique process group ID.  Process group IDs are similar to process IDs: they are positive integers and can be stored in a pid_t data type.  The function getpgrp() returns the process group ID of the calling process. #include <unistd.h> pid_t getpgrp(void); Returns: process group ID of calling process 218PROF. SYED MUSTAFA, HKBKCE
  • 219. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP PROCESS GROUPS  Each process group can have a process group leader.  The leader is identified by its process group ID being equal to its process ID.  It is possible for a process group leader to create a process group, create processes in the group, and then terminate.  The process group still exists, as long as at least one process is in the group, regardless of whether the group leader terminates.  This is called the process group lifetime-the period of time that begins when the group is created and ends when the last remaining process leaves the group.  The last remaining process in the process group can either terminate or enter some other process group. 219PROF. SYED MUSTAFA, HKBKCE
  • 220. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP PROCESS GROUPS  A process joins an existing process group or creates a new process group by calling setpgid(). #include <unistd.h> int setpgid(pid_t pid, pid_t pgid); Returns: 0 if OK, -1 on error  This function sets the process group ID to pgid in the process whose process ID equals pid.  If the two arguments are equal, the process specified by pid becomes a process group leader.  If pid is 0, the process ID of the caller is used. 220PROF. SYED MUSTAFA, HKBKCE
  • 221. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP SESSIONS A session is a collection of one or more process groups. For example, we could have the arrangement shown in the diagram below. Here we have three process groups in a single session. Arrangement of processes into process groups and sessions 221PROF. SYED MUSTAFA, HKBKCE
  • 222. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP SESSIONS A process establishes a new session by calling the setsid() function. #include <unistd.h> pid_t setsid(void); Returns: process group ID if OK, -1 on error If the calling process is not a process group leader, this function creates a new session. Three things may happen. 1. The process becomes the session leader of this new session. (A session leader is the process that creates a session.) The process is the only process in this new session. 2. The process becomes the process group leader of a new process group. 3. The new process group ID is the process ID of the calling process. 222PROF. SYED MUSTAFA, HKBKCE
  • 223. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP SESSIONS setsid() function returns an error if the caller is already a process group leader. The getsid function returns the process group ID of a process's session leader. #include <unistd.h> pid_t getsid(pid_t pid); Returns: session leader's process group ID if OK, -1 on error If pid is 0, getsid returns the process group ID of the calling process's session leader. 223PROF. SYED MUSTAFA, HKBKCE
  • 224. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP CONTROLLING TERMINAL Sessions and process groups have a few other characteristics. 1. A session can have a single controlling terminal. This is usually the terminal device (in the case of a terminal login) or pseudo-terminal device (in the case of a network login) on which we log in. 2. The session leader that establishes the connection to the controlling terminal is called the controlling process. 3. The process groups within a session can be divided into a single foreground process group and one or more background process groups. 4. If a session has a controlling terminal, it has a single foreground process group, and all other process groups in the session are background process groups. 224PROF. SYED MUSTAFA, HKBKCE
  • 225. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP CONTROLLING TERMINAL 5. Whenever we type the terminal's interrupt key (often DELETE or Control-C), this causes the interrupt signal be sent to all processes in the foreground process group. 6. Whenever we type the terminal's quit key (often Control-), this causes the quit signal to be sent to all processes in the foreground process group. 7. If a modem (or network) disconnect is detected by the terminal interface, the hang-up signal is sent to the controlling process (the session leader). 225PROF. SYED MUSTAFA, HKBKCE
  • 226. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP CONTROLLING TERMINAL Process groups and sessions showing controlling terminal 226PROF. SYED MUSTAFA, HKBKCE
  • 227. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP tcgetpgrp(), tcsetpgrp() & tcgetsid()  We need a way to tell the kernel which process group is the foreground process group, so that the terminal device driver knows where to send the terminal input and the terminal-generated signals.  To retrieve the foreground process group-id and to set the foreground process group-id we can use tcgetprgp() and tcsetpgrp() function. The prototype of these functions are : #include <unistd.h> pid_t tcgetpgrp(int filedes); Returns : process group ID of foreground process group if OK, -1 on error. 227PROF. SYED MUSTAFA, HKBKCE
  • 228. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP tcgetpgrp(), tcsetpgrp() & tcgetsid()  The function tcgetpgrp() returns the process group ID of the foreground process group associated with the terminal open on filedesc.  If the process has a controlling terminal, the process can call tcsetpgrp to set the foreground process group ID to pgrpid.  The value of pgrpid must be the process group ID of a process group in the same session, and filedes must refer to the controlling terminal of the session. 228PROF. SYED MUSTAFA, HKBKCE
  • 229. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP tcgetpgrp(), tcsetpgrp() & tcgetsid() The single UNIX specification defines an XSI extension called tcgetsid() to allow an application to obtain the process group-ID for the session leader given a file descriptor for the controlling terminal. #include <termios.h> pid_t tcgetsid(int filedesc); Returns: session leader’s process group ID if Ok, -1 on error 229PROF. SYED MUSTAFA, HKBKCE
  • 230. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP JOB CONTROL This feature allows us to start multiple jobs (groups of processes) from a single terminal and to control which jobs can access the terminal and which jobs are to run in the background. Job control requires three forms of support: 1. A shell that supports job control 2. The terminal driver in the kernel must support job control 3. The kernel must support certain job-control signals 230PROF. SYED MUSTAFA, HKBKCE
  • 231. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP JOB CONTROL Using job control from a shell, we can start a job in either the foreground or the background. A job is simply a collection of processes, often a pipeline of processes. For example, $vi main.c starts a job consisting of one process in the foreground. The commands $pr *.c | lpr & , $make all & , $start start two jobs in the background. All the processes invoked by these background jobs are in the background. 231PROF. SYED MUSTAFA, HKBKCE
  • 232. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP JOB CONTROL  The interaction with the terminal driver arises because a special terminal character affects the foreground job: the suspend key (typically Control-Z). Entering this character causes the terminal driver to send the SIGTSTP signal to all processes in the foreground process group.  The jobs in any background process groups aren't affected.  The terminal driver looks for three special characters, which generate signals to the foreground process group. 1. The interrupt character (typically DELETE or Control-C) generates SIGINT. 2. The quit character (typically Control-(back slash)) generates SIGQUIT. 3. The suspend character (typically Control-Z) generates SIGTSTP. 232PROF. SYED MUSTAFA, HKBKCE
  • 233. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP JOB CONTROL This signal normally stops the background job; by using the shell, we are notified of this and can bring the job into the foreground so that it can read from the terminal. The following demonstrates this: 233PROF. SYED MUSTAFA, HKBKCE
  • 234. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP JOB CONTROL The shell starts the cat process in the background, but when cat tries to read its standard input (the controlling terminal), the terminal driver, knowing that it is a background job, sends the SIGTTIN signal to the background job. 234PROF. SYED MUSTAFA, HKBKCE
  • 235. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP JOB CONTROL 235PROF. SYED MUSTAFA, HKBKCE
  • 236. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP SHELL EXECUTION OF PROGRAMS 236PROF. SYED MUSTAFA, HKBKCE
  • 237. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP SHELL EXECUTION OF PROGRAMS 237PROF. SYED MUSTAFA, HKBKCE
  • 238. UNIT 5 PROCESS CONTROL PROCESS RELATIONSHIP ORPHANED PROCESS GROUPS A process whose parent terminates is called an orphan and is inherited by the init process. A process that forks a child and then terminates. 238PROF. SYED MUSTAFA, HKBKCE
  • 239. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS  Signals are software interrupts.  Signals provide a way of handling asynchronous events: a user at a terminal typing the interrupt key to stop a program or the next program in a pipeline terminating prematurely.  When a signal is sent to a process, it is pending on the process to handle it. The process can react to pending signals in one of three ways: 1. Accept the default action of the signal, which for most signals will terminate the process. 2. Ignore the signal. The signal will be discarded and it has no affect whatsoever on the recipient process. 3. Invoke a user-defined function. The function is known as a signal handler routine and the signal is said to be caught when this function is called. 239PROF. SYED MUSTAFA, HKBKCE
  • 240. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 240PROF. SYED MUSTAFA, HKBKCE Name Description Default action SIGABRT abnormal termination (abort) terminate+core SIGALRM timer expired (alarm) terminate SIGCHLD change in status of child ignore SIGCONT continue stopped process continue/ignore SIGFPE arithmetic exception terminate+core SIGINT terminal interrupt character terminate SIGIO asynchronous I/O terminate/ignore SIGKILL termination terminate SIGPIPE write to pipe with no readers terminate SIGQUIT terminal quit character terminate+core SIGSEGV invalid memory reference terminate+core SIGSTOP stop stop process
  • 241. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 241PROF. SYED MUSTAFA, HKBKCE Name Description Default action SIGTTOU background write to control tty stop process SIGUSR1 user-defined signal Terminate SIGUSR2 user-defined signal Terminate SIGTERM termination Terminate SIGTSTP terminal stop character stop process SIGTTIN background read from control tty stop process
  • 242. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 242PROF. SYED MUSTAFA, HKBKCE THE UNIX KERNEL SUPPORT OF SIGNALS  When a signal is generated for a process, the kernel will set the corresponding signal flag in the process table slot of the recipient process.  If the recipient process is asleep, the kernel will awaken the process by scheduling it.  When the recipient process runs, the kernel will check the process U-area that contains an array of signal handling specifications.  If array entry contains a zero value, the process will accept the default action of the signal.  If array entry contains a 1 value, the process will ignore the signal and kernel will discard it.  If array entry contains any other value, it is used as the function pointer for a user- defined signal handler routine.
  • 243. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 243PROF. SYED MUSTAFA, HKBKCE The function prototype of the signal API is: #include <signal.h> void (*signal(int sig_no, void (*handler)(int)))(int); Returns: previous disposition of signal (see following) if OK, SIG_ERR on error The formal argument of the API are: sig_no is a signal identifier like SIGINT or SIGTERM. The handler argument is the function pointer of a user-defined signal handler function.
  • 244. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 244PROF. SYED MUSTAFA, HKBKCE The function prototype of the signal API is: #include <signal.h> void (*signal(int sig_no, void (*handler)(int)))(int); The sig_no argument is just the name of the signal. The value of handler is (a) the constant SIG_IGN, (b) the constant SIG_DFL, or (c) the address of a function to be called when the signal occurs.
  • 245. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 245PROF. SYED MUSTAFA, HKBKCE The function prototype of the signal API is: #include <signal.h> void (*signal(int sig_no, void (*handler)(int)))(int); If we specify SIG_IGN, we are telling the system to ignore the signal. (Remember that we cannot ignore the two signals SIGKILL and SIGSTOP) When we specify SIG_DFL, we are setting the action associated with the signal to its default value. When we specify the address of a function to be called when the signal occurs, we are arranging to "catch" the signal. We call the function either the signal handler or the signal-catching function.
  • 246. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 246PROF. SYED MUSTAFA, HKBKCE The function prototype of the signal API is: #include <signal.h> void (*signal(int sig_no, void (*handler)(int)))(int); The prototype for the signal function states that the function requires two arguments and returns a pointer to a function that returns nothing (void). The signal function's first argument, sig_no, is an integer. The second argument is a pointer to a function that takes a single integer argument and returns nothing. The function whose address is returned as the value of signal takes a single integer argument (the final (int)).
  • 247. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 247PROF. SYED MUSTAFA, HKBKCE The function prototype of the signal API is: #include <signal.h> void (*signal(int sig_no, void (*handler)(int)))(int); If we examine the system's header <signal.h>, we probably find declarations of the form #define SIG_ERR (void (*)())-1 #define SIG_DFL (void (*)())0 #define SIG_IGN (void (*)())1 These constants can be used in place of the "pointer to a function that takes an integer argument and returns nothing," the second argument to signal, and the return value from signal. The three values used for these constants need not be -1, 0, and 1. They must be three values that can never be the address of any declarable function.
  • 248. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 248PROF. SYED MUSTAFA, HKBKCE The following example attempts to catch the SIGTERM signal, ignores the SIGINT signal, and accepts the default action of the SIGSEGV signal. The pause API suspends the calling process until it is interrupted by a signal and the corresponding signal handler does a return: #include<iostream.h> #include<signal.h> /*signal handler function*/ void catch_sig(int sig_num) { signal (sig_num,catch_sig); cout<<”catch_sig:”<<sig_num<<endl; } int main() /*main function*/ { signal(SIGTERM,catch_sig); signal(SIGINT,SIG_IGN); signal(SIGSEGV,SIG_DFL); pause( );/*wait for a signal interruption*/ } The SIG_IGN specifies a signal is to be ignored, which means that if the signal is generated to the process, it will be discarded without any interruption of the process.
  • 249. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 249PROF. SYED MUSTAFA, HKBKCE #include<stdio.h> #include<signal.h> /*signal handler function*/ static void sig_usr(int signo) /* arg is signal number */ { if (signo == SIGUSR1) printf("received SIGUSR1n"); else if (signo == SIGUSR2) printf("received SIGUSR2n"); else printf("received signal %dn", signo); } int main(void) { if (signal(SIGUSR1, sig_usr) == SIG_ERR) perror("can't catch SIGUSR1"); if (signal(SIGUSR2, sig_usr) == SIG_ERR) perror("can't catch SIGUSR2"); for ( ; ; ) pause(); }
  • 250. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 250PROF. SYED MUSTAFA, HKBKCE $ ./a.out & start process in background [1] 7216 job-control shell prints job number and process ID $ kill -USR1 7216 send it SIGUSR1 received SIGUSR1 $ kill -USR2 7216 send it SIGUSR2 received SIGUSR2 $ kill 7216 now send it SIGTERM [1]+ Terminated ./a.out When we send the SIGTERM signal, the process is terminated, since it doesn't catch the signal, and the default action for the signal is termination.
  • 251. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 251PROF. SYED MUSTAFA, HKBKCE kill and raise Functions The kill function sends a signal to a process or a group of processes. The raise function allows a process to send a signal to itself. #include <signal.h> int kill(pid_t pid, int signo); int raise(int signo); Both return: 0 if OK, –1 on error The call raise(signo); is equivalent to the call kill(getpid(), signo);
  • 252. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 252PROF. SYED MUSTAFA, HKBKCE kill and raise Functions #include <signal.h> int kill(pid_t pid, int signo); There are four different conditions for the pid argument to kill. Pid value Meaning Pid > 0 The signal is sent to the process whose process ID is pid. Pid==0 The signal is sent to all processes whose process group ID equals the process group ID of the sender and for which the sender has permission to send the signal. Pid<0 The signal is sent to all processes whose process group ID equals the absolute value of pid and for which the sender has permission to send the signal. Pid==-1 The signal is sent to all processes on the system for which the sender has permission to send the signal.
  • 253. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 253PROF. SYED MUSTAFA, HKBKCE #include<iostream.h> #include<signal.h> /*signal handler function*/ void catch_sig(int sig_num) { cout<<”catch_sig:”<<sig_num<<endl; } int main() /*main function*/ { signal (SIGINT,catch_sig); cout<<“from mainn”; kill(getpid, SIGINT); } #include<iostream.h> #include<signal.h> /*signal handler function*/ void catch_sig(int sig_num) { cout<<”catch_sig:”<<sig_num<<endl; } int main() /*main function*/ { signal (SIGQUIT,catch_sig); cout<<“from mainn”; raise(SIGQUIT); }
  • 254. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 254PROF. SYED MUSTAFA, HKBKCE alarm and pause Functions The alarm function allows us to set a timer that will expire at a specified time in the future. When the timer expires, the SIGALRM signal is generated. If we ignore or don't catch this signal, its default action is to terminate the process. #include <unistd.h> unsigned int alarm(unsigned int seconds); Returns: 0 or number of seconds until previously set alarm. The seconds value is the number of clock seconds in the future when the signal should be generated.
  • 255. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 255PROF. SYED MUSTAFA, HKBKCE alarm and pause Functions #include <unistd.h> unsigned int alarm(unsigned int seconds);  If, when we call alarm, a previously registered alarm clock for the process has not yet expired, the number of seconds left for that alarm clock is returned as the value of this function.  That previously registered alarm clock is replaced by the new value.  If a previously registered alarm clock for the process has not yet expired and if the seconds value is 0, the previous alarm clock is canceled.  The number of seconds left for that previous alarm clock is still returned as the value of the function.  Although the default action for SIGALRM is to terminate the process, most processes that use an alarm clock catch this signal.
  • 256. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 256PROF. SYED MUSTAFA, HKBKCE alarm and pause Functions The pause function suspends the calling process until a signal is caught. #include <unistd.h> int pause(void); Returns: –1 with errno set to EINTR The only time pause returns is if a signal handler is executed and that handler returns. In that case, pause returns –1 with errno set to EINTR.
  • 257. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 257PROF. SYED MUSTAFA, HKBKCE alarm and pause Functions Using alarm and pause, we can put a process to sleep for a specified amount of time. The sleep() can be implemented using alarm() and pause(). #include <signal.h> #include <unistd.h> static void sig_alrm(int signo) { /* nothing to do, just return to wake up the pause */ } unsigned int sleep(unsigned int nsecs) { if (signal(SIGALRM, sig_alrm) == SIG_ERR) return(nsecs); alarm(nsecs); /* start the timer */ pause(); /* next caught signal wakes us up */ return(alarm(0)); /* turn off timer, return unslept time */ }
  • 258. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 258PROF. SYED MUSTAFA, HKBKCE SIGNAL SETS We need a data type to represent multiple signals—a signal set POSIX.1 defines the data type sigset_t to contain a signal set and the following five functions to manipulate signal sets. #include <signal.h> int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigaddset(sigset_t *set, int signo); int sigdelset(sigset_t *set, int signo); Returns: 0 if OK, -1 on error.
  • 259. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 259PROF. SYED MUSTAFA, HKBKCE SIGNAL SETS int sigismember(const sigset_t *set, int signo); Returns: 1 if true, 0 if false, –1 on error  The function sigemptyset() initializes the signal set pointed to by set so that all signals are excluded  The function sigfillset() initializes the signal set so that all signals are included.  All applications have to call either sigemptyset() or sigfillset() once for each signal set, before using the signal set.  Once we have initialized a signal set, we can add and delete specific signals in the set.  The function sigaddset() adds a single signal to an existing set, and sigdelset() removes a single signal from a set.
  • 260. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 260PROF. SYED MUSTAFA, HKBKCE SIGNAL MASK A process initially inherits the parent’s signal mask when it is created, but any pending signals for the parent process are not passed on. A process may query or set its signal mask via the sigprocmask API: #include <signal.h> int sigprocmask(int cmd, const sigset_t *new_mask, sigset_t *old_mask); Returns: 0 if OK, -1 on error .
  • 261. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 261PROF. SYED MUSTAFA, HKBKCE SIGNAL MASK The new_mask argument defines a set of signals to be set or reset in a calling process signal mask, and the cmd argument specifies how the new_mask value is to be used by the API. The possible values of cmd and the corresponding use of the new_mask value are: . Cmd value Meaning SIG_SETMASK Overrides the calling process signal mask with the value specified in the new_mask argument. SIG_BLOCK Adds the signals specified in the new_mask argument to the calling process signal mask. SIG_UNBLOCK Removes the signals specified in the new_mask argument from the calling process signal mask.
  • 262. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 262PROF. SYED MUSTAFA, HKBKCE SIGNAL MASK The following example checks whether the SIGINT signal is present in a process signal mask and adds it to the mask if it is not there. Then clears the SIGSEGV signal from the process signal mask. #include <stdio.h> #include <signal.h> int main() { sigset_t mask; sigemptyset(&mask); /*initialize set*/ if (sigprocmask(0, 0, &mask) == -1) { /*get current signal mask*/ perror(“sigprocmask”); exit(1); } else sigaddset(&mask, SIGINT); /*set SIGINT flag*/ sigdelset(&mask, SIGSEGV); /*clear SIGSEGV flag*/ if (sigprocmask(SIG_SETMASK, &mask, 0) == -1) perror(“sigprocmask”); /*set a new signal mask*/ } .
  • 263. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 263PROF. SYED MUSTAFA, HKBKCE SIGNAL MASK The program prints the names of the signals in the signal mask of the calling process #include <stdio.h> #include <signal.h> int main() { sigset_t sigset; sigemptyset(&sigset); /*initialize set*/ if (sigprocmask(0, NULL, &sigset) < 0) perror("sigprocmask error"); if (sigismember(&sigset, SIGINT)) printf("SIGINT "); if (sigismember(&sigset, SIGQUIT)) printf("SIGQUIT "); if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 "); if (sigismember(&sigset, SIGALRM)) printf("SIGALRM "); }
  • 264. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS 264PROF. SYED MUSTAFA, HKBKCE SIGPENDING FUNCTION The sigpending function returns the set of signals that are blocked from delivery and currently pending for the calling process. The set of signals is returned through the set argument #include <signal.h> int sigpending(sigset_t *set); Returns: 0 if OK, –1 on error.
  • 265. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS  The process blocks SIGQUIT, saving its current signal mask (to reset later), and then goes to sleep for 5 seconds.  Any occurrence of the quit signal during this period is blocked and won't be delivered until the signal is unblocked.  At the end of the 5-second sleep, we check whether the signal is pending and unblock the signal. 265PROF. SYED MUSTAFA, HKBKCE SIGPENDING FUNCTION
  • 266. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS - SIGPENDING FUNCTION 266PROF. SYED MUSTAFA, HKBKCE #include <signal.h> #include <unistd.h> static void sig_quit(int signo) { printf("caught SIGQUITn"); if (signal(SIGQUIT, SIG_DFL) == SIG_ERR) perror("can't reset SIGQUIT"); } int main(void) { sigset_t newmask, oldmask, pendmask; if (signal(SIGQUIT, sig_quit) == SIG_ERR) perror("can't catch SIGQUIT"); /* Block SIGQUIT and save current signal mask*/ sigemptyset(&newmask); sigaddset(&newmask, SIGQUIT); if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) perror("SIG_BLOCK error"); sleep(5); /* SIGQUIT here will remain pending */ if (sigpending(&pendmask) < 0) perror("sigpending error"); if (sigismember(&pendmask, SIGQUIT)) printf("nSIGQUIT pendingn"); /* Reset signal mask which unblocks SIGQUIT*/ if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) perror("SIG_SETMASK error"); printf("SIGQUIT unblockedn"); sleep(5); /* SIGQUIT here will terminate with core file */ exit(0); }
  • 267. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS  The sigaction() function allows us to examine or modify (or both) the action associated with a particular signal.  This function supersedes the signal() function from earlier releases of the UNIX System. #include <signal.h> int sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oact); Returns: 0 if OK, –1 on error 267PROF. SYED MUSTAFA, HKBKCE Sigaction() Function
  • 268. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS sigaction() Function  The sigaction API is a replacement for the signal API in the latest UNIX and POSIX systems.  The sigaction API is called by a process to set up a signal handling method for each signal it wants to deal with.  sigaction API returns the previous signal handling method for a given signal. 268PROF. SYED MUSTAFA, HKBKCE
  • 269. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS sigaction() Function The struct sigaction data type is defined in the <signal.h> header as struct sigaction { void (*sa_handler)(int); /* addr of signal handler, or SIG_IGN, or SIG_DFL */ sigset_t sa_mask; /* additional signals to block */ int sa_flags; /* signal options */ void (*sa_sigaction)(int, siginfo_t *, void *); /* alternate handler */ }; 269PROF. SYED MUSTAFA, HKBKCE
  • 270. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS sigaction() Function  The sa_handler field can be set to SIG_IGN, SIG_DFL, or a user defined signal handler function.  The sa_mask field specifies additional signals that process wishes to block when it is handling signo signal.  The signalno argument designates which signal handling action is defined in the action argument.  The previous signal handling method for signalno will be returned via the  oldaction argument if it is not a NULL pointer.  If action argument is a NULL pointer, the calling process‘s existing signal handling method for signalno will be unchanged. 270PROF. SYED MUSTAFA, HKBKCE
  • 271. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS - sigaction FUNCTION 271PROF. SYED MUSTAFA, HKBKCE #include <signal.h> #include <iostream.h> void callme ( int sig_num ) { cout <<“catch signal:”<<sig_num<< endl; } int main(void) { sigset_t sigmask; struct sigaction action, old_action; sigemptyset(&sigmask); if ( sigaddset( &sigmask, SIGTERM) == -1 || sigprocmask( SIG_SETMASK, &sigmask, 0) == -1) perror(“Set signal mask”); sigemptyset( &action.sa_mask); sigaddset( &action.sa_mask, SIGSEGV); action.sa_handler = callme; action.sa_flags = 0; if (sigaction (SIGINT, &action, &old_action) == -1) perror(“sigaction”); pause(); /* wait for signal interruption*/ return 0; }
  • 272. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS - sigaction FUNCTION  In the program, the process signal mask is set with SIGTERM signal.  The process then defines a signal handler for the SIGINT signal and also specifies that the SIGSEGV signal is to be blocked when the process is handling the SIGINT signal.  The process then terminates its execution via the pause API. The output of the program would be as: % cc sigaction.c –o sigaction % ./sigaction & [1] 495 % kill –INT 495 catch signal: 2 sigaction exits [1] Done sigaction 272PROF. SYED MUSTAFA, HKBKCE
  • 273. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS THE SIGCHLD SIGNAL AND THE waitpid API When a child process terminates or stops, the kernel will generate a SIGCHLD signal to its parent process. Depending on how the parent sets up the handling of the SIGCHLD signal, different events may occur: 1. Parent accepts the default action of the SIGCHLD signal:  SIGCHLD does not terminate the parent process.  Parent process will be awakened.  API will return the child’s exit status and process ID to the parent.  Kernel will clear up the Process Table slot allocated for the child process.  Parent process can call the waitpid API repeatedly to wait for each child it created. 273PROF. SYED MUSTAFA, HKBKCE
  • 274. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS THE SIGCHLD SIGNAL AND THE waitpid API 2. Parent ignores the SIGCHLD signal:  SIGCHLD signal will be discarded.  Parent will not be disturbed even if it is executing the waitpid system call.  If the parent calls the waitpid API, the API will suspend the parent until all its child processes have terminated.  Child process table slots will be cleared up by the kernel.  API will return a -1 value to the parent process. 3. Process catches the SIGCHLD signal:  The signal handler function will be called in the parent process whenever a child process terminates.  If the SIGCHLD arrives while the parent process is executing the waitpid system call, the waitpid API may be restarted to collect the child exit status and clear its process table slots.  Depending on parent setup, the API may be aborted and child process table slot not freed. 274PROF. SYED MUSTAFA, HKBKCE
  • 275. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS abort() Function abort function causes abnormal program termination #include <stdlib.h> void abort(void); This function never returns. This function sends the SIGABRT signal to the caller. Processes should not ignore this signal. ISO C states that calling abort will deliver an unsuccessful termination notification to the host environment by calling raise(SIGABRT). 275PROF. SYED MUSTAFA, HKBKCE
  • 276. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS system() Function #include <stdlib.h> int system(const char *command); This function returns is -1 on error. If the value of command is NULL, system() returns nonzero if the shell is available, and zero if not. system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed. During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored Eg: system(“ls –l”); 276PROF. SYED MUSTAFA, HKBKCE
  • 277. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS sleep() Function sleep - sleep for the specified number of seconds #include <unistd.h> unsigned int sleep(unsigned int seconds); Returns: 0 or number of unslept seconds. This function causes the calling process to be suspended until either 1. The amount of wall clock time specified by seconds has elapsed. 2. A signal is caught by the process and the signal handler returns. Eg: sleep(60); // suspend the process for one minute. 277PROF. SYED MUSTAFA, HKBKCE
  • 278. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS Job-Control Signals POSIX.1 considers six signals as job-control signals: 278PROF. SYED MUSTAFA, HKBKCE Signal Meaning SIGCHLD Child process has stopped or terminated. SIGCONT Continue process, if stopped. SIGSTOP Stop signal (can't be caught or ignored). SIGTSTP Interactive stop signal. SIGTTIN Read from controlling terminal by member of a background process group SIGTTOU Write to controlling terminal by member of a background process group
  • 279. UNIT 6 SIGNALS AND DAEMON PROCESSES SIGNALS Job-Control Signals  When we type the suspend character (usually Control-Z), SIGTSTP is sent to all processes in the foreground process group.  When we tell the shell to resume a job in the foreground or background, the shell sends all the processes in the job the SIGCONT signal.  Similarly, if SIGTTIN or SIGTTOU is delivered to a process, the process is stopped by default, and the job-control shell recognizes this and notifies us.  When any of the four stop signals (SIGTSTP, SIGSTOP, SIGTTIN, or SIGTTOU) is generated for a process, any pending SIGCONT signal for that process is discarded.  Similarly, when the SIGCONT signal is generated for a process, any pending stop signals for that same process are discarded.  The default action for SIGCONT is to continue the process, if it is stopped; otherwise, the signal is ignored. 279PROF. SYED MUSTAFA, HKBKCE
  • 280. UNIT 6 SIGNALS AND DAEMON PROCESSES DAEMON PROCESSES  Daemons are processes that live for a long time.  They are often started when the system is bootstrapped and terminate only when the system is shut down.  Because they don't have a controlling terminal, we say that they run in the background.  UNIX systems have numerous daemons that perform day-to-day activities. 280PROF. SYED MUSTAFA, HKBKCE
  • 281. UNIT 6 SIGNALS AND DAEMON PROCESSES DAEMON PROCESSES Deamon Characteristics  $ps -axj 281PROF. SYED MUSTAFA, HKBKCE
  • 282. UNIT 6 SIGNALS AND DAEMON PROCESSES DAEMON PROCESSES Deamon Characteristics  Daemons run in background.  Daemons have super-user privilege.  Daemons don’t have controlling terminal.  Daemons are session and group leaders. 282PROF. SYED MUSTAFA, HKBKCE
  • 283. UNIT 6 SIGNALS AND DAEMON PROCESSES DAEMON PROCESSES Deamon Characteristics  Anything with a parent process ID of 0 is usually a kernel process started as part of the system bootstrap procedure.  Kernel processes are special and generally exist for the entire lifetime of the system.  They run with superuser privileges and have no controlling terminal and no command line.  Process ID of 1 is usually init.  It is a system daemon responsible for, among other things, starting system services specific to various run levels. 283PROF. SYED MUSTAFA, HKBKCE
  • 284. UNIT 6 SIGNALS AND DAEMON PROCESSES DAEMON PROCESSES Deamon Characteristics  keventd daemon provides process context for running scheduled functions in the kernel.  The kapmd daemon provides support for the advanced power management features available with various computer systems.  The kswapd daemon is also known as the pageout daemon.  It supports the virtual memory subsystem by writing dirty pages to disk slowly over time, so the pages can be reclaimed.  The inetd daemon (xinetd) listens on the system's network interfaces for incoming requests for various network servers.  The nfsd, lockd, and rpciod daemons provide support for the  Network File System (NFS).  The cron daemon (crond) executes commands at specified dates and times. Numerous system administration tasks are handled by having programs executed regularly by cron.  The cupsd daemon is a print spooler; it handles print requests on the system. 284PROF. SYED MUSTAFA, HKBKCE
  • 285. UNIT 6 SIGNALS AND DAEMON PROCESSES DAEMON PROCESSES CODING RULES 1. Call umask to set the file mode creation mask to 0. The file mode creation mask that's inherited could be set to deny certain permissions. If the daemon process is going to create files, it may want to set specific permissions. 2. Call fork and have the parent exit. This does several things. First, if the daemon was started as a simple shell command, having the parent terminate makes the shell think that the command is done. Second, the child inherits the process group ID of the parent but gets a new process ID, so we're guaranteed that the child is not a process group leader. 285PROF. SYED MUSTAFA, HKBKCE
  • 286. UNIT 6 SIGNALS AND DAEMON PROCESSESDAEMON PROCESSES CODING RULES 3. Call setsid to create a new session. The process (a) becomes a session leader of a new session, (b) becomes the process group leader of a new process group, and (c) has no controlling terminal. 4. Change the current working directory to the root directory. The current working directory inherited from the parent could be on a mounted file system. Since daemons normally exist until the system is rebooted, if the daemon stays on a mounted file system, that file system cannot be unmounted. 5. Unneeded file descriptors should be closed. This prevents the daemon from holding open any descriptors that it may have inherited from its parent. 286PROF. SYED MUSTAFA, HKBKCE
  • 287. UNIT 6 SIGNALS AND DAEMON PROCESSES DAEMON PROCESSES CODING RULES 6. Some daemons open file descriptors 0, 1, and 2 to /dev/null so that any library routines that try to read from standard input or write to standard output or standard error will have no effect. Since the daemon is not associated with a terminal device, there is nowhere for output to be displayed; nor is there anywhere to receive input from an interactive user. Even if the daemon was started from an interactive session, the daemon runs in the background, and the login session can terminate without affecting the daemon. If other users log in on the same terminal device, we wouldn't want output from the daemon showing up on the terminal, and the users wouldn't expect their input to be read by the daemon. 287PROF. SYED MUSTAFA, HKBKCE
  • 288. UNIT 6 SIGNALS AND DAEMON PROCESSES DAEMON PROCESSES CODING RULES Example Program: 288PROF. SYED MUSTAFA, HKBKCE #include <unistd,h> #include <sys/types.h> #include <fcntl.h> int daemon_initialise( ) { pid_t pid; if (( pid = fork() ) < 0) return –1; else if ( pid != 0) exit(0); /* parent exits */ /* child continues */ setsid( ); chdir(“/”); umask(0); return 0; }
  • 289. UNIT 6 SIGNALS AND DAEMON PROCESSES DAEMON PROCESSES Error Logging  One problem a daemon has is how to handle error messages.  It can't simply write to standard error, since it shouldn't have a controlling terminal.  We don't want all the daemons writing to the console device, since on  many workstations, the console device runs a windowing system.  We also don't want each daemon writing its own error messages into a separate file.  A central daemon errorlogging facility is required. 289PROF. SYED MUSTAFA, HKBKCE
  • 290. UNIT 6 SIGNALS AND DAEMON PROCESSES DAEMON PROCESSES Error Logging 290PROF. SYED MUSTAFA, HKBKCE
  • 291. UNIT 6 SIGNALS AND DAEMON PROCESSES DAEMON PROCESSES Error Logging There are three ways to generate log messages: 1. Kernel routines can call the log function. These messages can be read by any user process that opens and reads the /dev/klog device. 2. Most user processes (daemons) call the syslog(3) function to generate log messages. This causes the message to be sent to the UNIX domain datagram socket /dev/log. 3. A user process on this host, or on some other host that is connected to this host by a TCP/IP network, can send log messages to UDP port 514. The syslogd daemon reads all three forms of log messages. On start-up, this daemon reads a configuration file, usually /etc/syslog.conf, which determines where different classes of messages are to be sent. 291PROF. SYED MUSTAFA, HKBKCE