Usp Slides
Usp Slides
1. Function prototyping
2. Support of the const and volatiledata type qualifiers.
3. Support wide characters and internationalization.
4. Permit function pointers to be used without dereferencing.
The major differences between ANSICand K&R C
[Kernighan and Ritchie] are as follows:
1. Function prototyping
ANSI Cadopts C++function prototype technique where function definition and declaration include
function names, arguments’ data types, and return value datatypes.
This enables ANSI Ccompilers to check for function calls in user programs that pass invalid number of
arguments or incompatible arguments’ datatype.
These fix a major weakness of K&R Ccompilers: invalid function calls in user programs often pass
compilation but cause programs tocrash when they are executed.
Eg: unsigned long demo(char * fmt, doubledata)
{
/*body of demo*/
}
External declaration of this function demois
unsigned long demo(char * fmt, doubledata);
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 ANSICand K&R C
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 ANSICand K&R C
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 Cdefines 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/yyyyformat.
Function prototype of setlocale functionis:
#include<locale.h>
char setlocale(int category, const char* locale);
The major differences between ANSICand K&R C
3. Support wide characters and internationalization
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:
The function can be called directly or through function pointeras given below:
foo(12.78,”Hello world”);
funptr(12.78,”Hello world”);
#include<unistd.h>
Job control
Saved set-UID and saved set-GID
Long path name is not supported
The _POSIX_CHOWN_RESTRICTED must bedefined
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
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.
Most UNIX systems provide a common set of API’s to perform the following
functions.
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 tothe 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 preferredway
the possible error status codes that may be assigned to errno by any API
are defined in the <errno.h> header.
Commonly occur error status codes and their meanings
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
UNIT 2 UNIX FILES
•Regular 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
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
BSDUNIX & SV4 defines a symbolic link file. POSIX.1 does not support symbolic link filetype
A symbolic link file contains a path name which references another file in either local or a remotefile
system.
rm, mv and chmod commands will operate only on the symbolic link arguments directly and not on the files
that they reference.
UNIT 2 UNIX FILES
UNIT 2 UNIX FILES
UNIT 2 UNIX FILES
The UNIXand POSIXFile Attributes
The general file attributes for each file in a file systemare:
1) File type - specifies what type of file it is.
2) Access permission - the file access permission forowner, group and others.
Hard link count
3) - number of hard link of the file
Uid
4) - the file owner userid.
Gid
5) - the file groupid.
File size
6) - the file size in bytes.
Inode no
7) - the system inode no of the file.
File system id
8) - the file system id where the file is stored.
UNIT 2 UNIX FILES
The UNIXand POSIXFile Attributes
The general file attributes for each file in a file systemare:
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 devicenumber
UNIT 2 UNIX FILES
UNIT 2 UNIX FILES
Inodes in UNIXSystem V
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 thenecessary data.
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.
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 recentlyaccessed.
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.
UNIT 2 UNIX FILES
UNIX Kernel Support for Files
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.
If either (1) or (2) fails, the open system call returns -1 (failure/error)
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,dup2system call.
When a open system call is succeeded, its return value will bean 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.
UNIX Kernel Support for Files UNIT 2 UNIX 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 asunused.
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.
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:
UNIT 2 UNIX FILES
Relationship of C Stream Pointers and File Descriptors
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:
Clibrary function UNIX system call used
fopen open
fread, fgetc, fscanf, fgets read
fwrite, fputc, fprintf, fputs write
fseek, fputc, fprintf, fputs lseek
fclose close
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.1and
struct direct in BSDUNIX.
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
:
UNIT 2 UNIX FILES
Directory Files
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.
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 filesystem.
Differences between hard link and symbolic link are listedbelow:
UNIT 3 UNIX FILEAPIs
:
open UNIT 3 UNIX FILEAPIs
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 elseit
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.
: PROF.SYEDMUSTAFA, HKBKCE 54
UNIT 3 UNIX FILEAPIs
open
Generally the access modes are specified in <fcntl.h>.
Various access modes are:
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
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.
UNIT 3 UNIX FILEAPIs
open
access modifier flags
S.No Flag Meaning
1 O_APPEND Append data to the end offile.
2 O_CREAT Create the file if it doesn’t exist
3 O_EXCL Generate an error if O_CREATis 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 fileas the calling
process control terminal.
UNIT 3 UNIX FILEAPIs
open
To illustrate the use of the above flags, the following example statementopens
a file called /usr/syed/usp for read and write inappend mode:
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.
UNIT 3 UNIX FILEAPIs
open
58
UNIT 3 UNIX FILEAPIs
open
UNIT 3 UNIX FILEAPIs
open
UNIT 3 UNIX FILEAPIs
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_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);
UNIT 3 UNIX FILEAPIs
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.
UNIT 3 UNIX FILEAPIs
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);
UNIT 3 UNIX FILEAPIs
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.
UNIT 3 UNIX FILEAPIs
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.
UNIT 3 UNIX FILEAPIs
read ( )- Errors
Tag Description
Non-blocking I/O has been selected using O_NONBLOCK and no data
EAGAIN
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.
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
EINVAL
in buf, the value specified in count, or the current file offset is not
suitably aligned.
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
EIO 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.
UNIT 3 UNIX FILEAPIs
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("%s\ n",c);
else
perror(“read Error”);
close(fd);
return 0;
}
UNIT 3 UNIX FILEAPIs
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)
UNIT 3 UNIX FILEAPIs
write( )-Errors
Error Code Description
EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and the write would block.
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.)
write( ) UNIT 3 UNIX FILEAPIs
#include<fcntl.h>
int main()
{
int fd,nob;char c[]=“ This is sampletext”;
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;
}
UNIT 3 UNIX FILEAPIs
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.
UNIT 3 UNIX FILEAPIs
close( ) - Errors
Tag Description
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
PROF.YEDMUSTAFA HKBKCE 90
UNIT 3 UNIX FILEAPIs
UNIT 3 UNIX FILEAPIs
UNIT 3 UNIX FILEAPIs
UNIT 3 UNIX FILEAPIs
UNIT 3 UNIX FILEAPIs
UNIT 3 UNIX FILEAPIs
UNIT 3 UNIX FILEAPIs
UNIT 3 UNIX FILEAPIs
A lock set by the fcntl API is an advisory lock but we can also use fcntl for
mandatory locking purpose with the following attributesset before using fcntl
1. Turn on the set-GID flag of the file.
2. Turn off the group execute right permission of the file.
UNIT 3 UNIX FILEAPIs
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);
}
utime() UNIT 3 UNIX FILEAPIs
The utime function modifies the access time and the modification time stamps ofa 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);
struct utimbuf
{
time_t actime; /* access time */
time_t modtime; /* modification time */
}
UNIT 3 UNIX FILEAPIs
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 , Jan1 of1970.
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.
110
UNIT 3 UNIX FILEAPIs
iDrectory File API’s
A Directory file is a record-oriented file, where each record stores a file name andthe
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
UNIT 3 UNIX FILEAPIs
iDrectory File API’s
Toallow 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
UNIT 3 UNIX FILEAPIs
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 thatrecord
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 bydir-fdesc.
UNIT 3 UNIX FILEAPIs
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 ofa given dir_fdesc
seekdir Changes the file pointer of a given dir_fdesc toa specified address
Directory FileAPI’s UNIT 3 UNIX FILEAPIs
The following list_dir.C program illustrates the uses of the mkdir, opendir, readdir, closedir
and rmdir APIs:
#include<iostream.h> int main(int agc, char* argv[])
#include<stdio.h> {
#include<sys/types Dirent* dp; DIR* dir_fdesc;
.h> while(--argc>0)
#include<unistd.h> {
#include<string.h> if(!(dir_fdesc=opendir(*++argv)))
#include<sys/stat.h> {
#if defined(BSD) && !_POSIX_SOURCE if(mkdir(*argv,S_IRWXU | S_IRWXG| S_IRWXO)==-1)
#include<sys/dir.h> perror("opendir");
typedef struct direct Dirent; continue;
#else }
#include<dirent.h>
typedef struct dirent Dirent;
#endif
Directory FileAPI’s UNIT 3 UNIX FILEAPIs
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++) if(!cnt)
for(int cnt=0;dp=readdir(dir_fdesc);) {
{ rmdir(*argv);
if(i) break;
cout<<dp->d_name<<endl; }
if(strcmp(dp->d_name,".") && rewinddir(dir_fdesc);
strcmp(dp->d_name,"..")) } //end for
cnt++; closedir(dir_fdesc);
} } //end while
} //end main
UNIT 3 UNIX FILEAPIs
Device file APIs
Device files are used to interface physical device withapplication programs.
Aprocess 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, intdevice_id);
UNIT 3 UNIX FILEAPIs
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 thirdargument 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.
#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 tobe created.
The second argument mode specifies the access permission for user, group andothers
and as well as the S_IFIFO flag to indicate that it is aFIFO file.
On success it returns 0 and on failure it returns –1.
120
FIFO file API’s UNIT 3 UNIX FILEAPIs
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 andothers.
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 FIFOfile for reading, the kernel will block the process until there
is another process that opens the same file forwriting.
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.
UNIT 3 UNIX FILEAPIs
#include <unistd.h>
int pipe(intfds[2]);
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 itschildren.
UNIT 3 UNIX FILEAPIs
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;
}
UNIT 3 UNIX FILEAPIs
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);
}
UNIT 4 UNIX PROCESSES
INTRODUCTION
A Process is a program under execution in a UNIX or POSIXsystem.
main FUNCTION
A Cprogram starts execution with a function called main.
The prototype for the main functionis
int main(int argc, char *argv[]);
where argc is the number of command-line arguments, and argv is an arrayof
pointers to the arguments.
When a Cprogram 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 Ccompiler.
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.
UNIT 4 UNIX PROCESSES
PROCESSTERMINATION
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 lastthread
#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 samevalue.
Thus exit(0) is the same asreturn(0) from the main function.
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 samevalue.
Thus exit(0) is the same asreturn(0) from the main function.
UNIT 4 UNIX PROCESSES
In the following situations the exit status of the process is undefined.
1. any of these functions is called withoutan 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
130
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 atexitfunction.
#include <stdlib.h>
int atexit(void (*func)(void));
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 avalue.
The exit function calls these functions in reverse order of their registration.
Each function is called as many times as it wasregistered.
UNIT 4 UNIX PROCESSES
Example of exit handlers
static void my_exit1(void); static void my_exit1(void)
static void my_exit2(void); {
int main(void) printf("first exit handler\n");
{ }
if (atexit(my_exit2) != 0)
perror("can't register my_exit2"); static void my_exit2(void)
{
if (atexit(my_exit1) != 0) printf("second exit handler\n");
perror("can't register my_exit1"); }
Output:
printf("main is done\n"); $ ./a.out
return(0); main isdone
} first exit handler
second exit handler
UNIT 4 UNIX PROCESSES
How a Cprogram is started and the various ways it canterminate
UNIT 4 UNIX PROCESSES
COMMAND-LINEARGUMENTS
When a program is executed, the process that does the exec can pass command-line
arguments to the newprogram.
Example: Echo all command-line arguments to standardoutput
int main(int argc, char *argv[])
{
int i;
for (i = 0; i < argc;i++) / * echo all command-lineargs * /
printf("argv[%d]: %s\n", i, argv[i]);
exit(0);
}
Output:
$ ./echoarg arg1 TESTfoo
argv[0]: ./echoarg
argv[1]: arg1
argv[2]: TEST
argv[3]: foo
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 Cstring.
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.
135
UNIT 4 UNIX PROCESSES
MEMORY LAYOUTOFACPROGRAM
Historically, a Cprogram has been composed of the followingpieces:
Text segment:
The machine instructions that the CPUexecutes.
Usually, the text segment is sharable so that only a single copy needs to be in memory for
frequently executed programs, such astext editors, the Ccompiler, 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 Cdeclaration
int maxcount =99;
appearing outside any function causes this variable to be stored in the initialized data
segment with its initial value.
UNIT 4 UNIX PROCESSES
MEMORY LAYOUTOFACPROGRAM
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 Cdeclaration
long sum[1000];
appearing outside any function causes this variable to be stored in the uninitialized data
segment.
UNIT 4 UNIX PROCESSES
MEMORY LAYOUTOFACPROGRAM
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 Ccanwork.
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.
UNIT 4 UNIX PROCESSES
MEMORY LAYOUTOFACPROGRAM
Heap:
where dynamic memory allocation usually takesplace.
Historically, the heap has been located between the uninitialized data and the stack.
UNIT 4 UNIX PROCESSES
MEMORYALLOCATION
ISO Cspecifies three functions for memoryallocation:
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 specifiedsize.
The space is initialized to all 0bits.
realloc:
which increases or decreases the size of a previously allocatedarea.
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.
140
UNIT 4 UNIX PROCESSES
MEMORYALLOCATION
#include <stdlib.h>
void *malloc(size_t size);
void *calloc(size_t nobj, size_t size);
void *realloc(void *ptr, size_t newsize);
.
UNIT 4 UNIX PROCESSES
MEMORYALLOCATION
alloca() Function
The function alloca has the same calling sequence asmalloc;
however, instead of allocating memory from the heap, the memory is allocated from the
stack frame of the currentfunction.
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 stackframe.
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.
.
UNIT 4 UNIX PROCESSES
ENVIRONMENT VARIABLES
The environment strings are usually of the form:name=value.
The functions that we can use toset 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, NULLif not found.
Eg:
char *res=getenv(“HOME”);
cout<<“HOME=“<<res<<endl;
output:
HOME=/home/syed
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);
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.
UNIT 4 UNIX PROCESSES
ENVIRONMENT VARIABLES
#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.
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 toa 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 byenv.
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 handlingaccordingly.
UNIT 4 UNIX PROCESSES
Setjmp() & longjmp() FUNCTIONS
#include <stdio.h> int division(int a, int b)
#include<setjmp.h> {
jmp_buf jb; if(b == 0)
int main(int argc, char *argv[]) longjmp(jb, 1);
{ else
int a, b, c; return (a/b);
printf ("Give two numbers for division : "); }
scanf("%d %d", &a, &b);
if(setjmp(jb) == 0) void handle_error(void)
{ {
c= division(a, b); printf("Divide by zero error !");
printf ("%d / %d = %d", a, b,c); }
return 0;
}
else
{
handle_error();
return -1;
}
}
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 onerror
Each call tothese 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* /
};
150
UNIT 4 UNIX PROCESSES
getrlimit() AND setrlimit() FUNCTIONS
Three rules govern the changing of the resourcelimits.
1. Aprocess can change its soft limit to a value less than or equal to its hard limit.
2. Aprocess 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 constantRLIM_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 corefile.
RLIMIT_CPU The maximum amount of CPUtime 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_CHILPRDOF_.SMYEDAMUXSTAbFAy,HtKhBKeCEsysconffunction 151
UNIT 4 UNIX PROCESSES
getrlimit() AND setrlimit() FUNCTIONS
Example: Print the current resource limits
#define doit(name) p_limits(#name,name)
int main(void)
{ static void pr_limits(char *name, int resource)
#ifdef RLIMIT_AS {
doit(RLIMIT_A struct rlimit limit;
S); #endif if (getrlimit(resource, &limit) < 0)
doit(RLIMIT_CO printf("getrlimit error for %s",name);
RE); printf("%-14s ", name);
doit(RLIMIT_CPU); if (limit.rlim_cur ==RLIM_INFINITY)
doit(RLIMIT_DATA); printf("(infinite) ");
doit(RLIMIT_FSIZE); else
#ifdef RLIMIT_LOCKS printf(FMT, limit.rlim_cur);
doit(RLIMIT_LOC if (limit.rlim_max == RLIM_INFINITY)
KS); printf("(infinite)");
#endif else
doit(RLIMIT_NOFILE); printf(FMT, limit.rlim_max);
#ifdef RLIMIT_NPROC }
doit(RLIMIT_NPRO
C);
#endif
UNIT 4 UNIX PROCESSES
UNIX KERNELSUPPORTFORPROCESS
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 aprocess.
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 processlimits.
All processes in UNIX system expect the process that is created by the system boot code,
are created by the fork systemcall.
UNIT 4 UNIX PROCESSES
UNIX KERNELSUPPORTFORPROCESS
UNIT 4 UNIX PROCESSES
UNIX KERNELSUPPORTFORPROCESS
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 theFigure 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.
UNIT 4 UNIX PROCESSES
UNIX KERNELSUPPORTFORPROCESS
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 theparent process
real group identification number (rGID) the group ID of a user who created thatparent 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) these identify the process group and session of which the
and session identification number (SID) process is member
Supplementary group identification numbers this is a set of additional group IDs for a user who created
the process
PROF. SYEDMUSTAFA, HKBKCE 156
UNIT 4 UNIX PROCESSES
UNIX KERNELSUPPORTFORPROCESS
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 rootdirectory
Signal handling the signal handling settings
Signal mask a signal mask that specifies which signals are to beblocked
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
Attributes Meaning
Process identification number (PID) an integer identification number that is unique per process in an
entire operating system.
Parent process identification number the parent processPID
(PPID)
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
UNIT 4 UNIX PROCESSES
UNIX KERNELSUPPORTFORPROCESS
fork and exec are commonly used together to spawn a sub-process to execute a different
program.
Because each child process executes in its own virtual address space, the parentprocess
is not affected by the execution status of its child process.
UNIT 5 PROCESS CONTROL
PROCESSIDENTIFIERS
#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
160
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.
For example, the child gets a copy of theparent's data space, heap, and stack.
The function vfork has the same calling sequence and same return values asfork.
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 UNIXSystem.
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.
UNIT 5 PROCESS CONTROL
vfork FUNCTION
Example of vfork function
int glob = 6; / * external variable in initialized data * / / * Parent continues here.*/
int main(void) printf("pid = %d\n", getpid());
{ printf("glob = %d, var = %d\n", glob, var);
int var=88; / * automatic variable on thestack * /
pid_t pid; exit(0);
printf("before vfork\n"); }
if ((pid = vfork()) < 0) Output:
perror("vfork error"); $ ./a.out
else if (pid == 0) / * child * /
{ before vfork
glob++; / * modify parent's variables * / pid = 29039
var++; glob = 7, var = 89
_exit(0); / * child terminates * /
}
UNIT 5 PROCESS CONTROL
Wait() AND waitpid() FUNCTIONS
When a process terminates, either normally or abnormally, the kernel notifies the parent
by sending the SIGCHLDsignal 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.
#include <sys/wait.h>
170
UNIT 5 PROCESS CONTROL
The interpretation of the pid argument for waitpid() depends on its value:
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.
UNIT 5 PROCESS CONTROL
Wait() AND waitpid() FUNCTIONS
Program to Demonstrate various exitstatuses
#include <sys/wait.h>
void pr_exit(int status)
{
if (WIFEXITED(status))
printf("normal termination, exit status = %d\n", WEXITSTATUS(status));
else if (WIFSIGNALED(status))
printf("abnormal termination, signal number = %d\n", WTERMSIG(status));
else if (WIFSTOPPED(status))
printf("child stopped, signal number = %d\n", WSTOPSIG(status));
}
Wait() AND waitpid() FUNCTIONS
UNIT 5 PROCESS CONTROL
Program to Demonstrate various exitstatuses
int main(void) if (wait(&status) != pid) / * wait for child * /
{ perror("wait error");
pid_t pid; int status; pr_exit(status); / * and print its status * /
if ((pid = fork()) < 0)
if ((pid = fork()) < 0)
perror("fork error");
perror("fork error");
else if (pid == 0) / * child * /
else if (pid == 0) / * child * /
exit(7);
status /= 0;/* divide by 0 generates SIGFPE* /
if (wait(&status) != pid) / * wait for child * /
perror("wait error"); if (wait(&status) != pid) / * wait for child * /
pr_exit(status); / * and printits status * / perror("wait error");
pr_exit(status); / * and printits status * /
if ((pid = fork()) < 0)
perror("fork error"); exit(0);
else if (pid == 0) / * child * / }
abort(); / * generates SIGABRT* /
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);
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: 0if OK, -1 on error
UNIT 5 PROCESS CONTROL
CHANGING USERIDs 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 groupID.)
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.
#include <unistd.h>
int setreuid(uid_t ruid, uid_t euid);
int setregid(gid_t rgid, gid_t egid);
#include <unistd.h>
int seteuid(uid_t uid);
int setegid(gid_t gid);
190
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
#!/bin/awk -f
(awk program follows in the interpreter file)
Eg:
#!/bin/awk -f
BEGIN {
for (i = 0; i < ARGC;i++)
printf "ARGV[%d] = %s\n", i, ARGV[i]
exit
}
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);
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.
UNIT 5 PROCESS CONTROL
PROCESSACCOUNTING
The data required for the accounting record, such as CPUtimes 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 afork.
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.
Anew record is initialized by the kernel for the child after a fork, not when a
new program is executed.
UNIT 5 PROCESS CONTROL
PROCESSACCOUNTING
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* /
198
UNIT 5 PROCESS CONTROL
USERIDENTIFICATION
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.
The system normally keeps track of the name we log in and the getlogin
function provides a way to fetch that login name.
UNIT 5 PROCESS CONTROL
USERIDENTIFICATION
#include <unistd.h>
char *getlogin(void);
This function can fail if the process is not attached to a terminal that a user
logged in to.
UNIT 5 PROCESS CONTROL
PROCESSTIMES
We describe three times that we can measure: wall clock time, user CPUtime,
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>
When the system is bootstrapped, the kernel creates process ID 1, the init
process, and it is init that brings thesystem up multiuser.
The init process reads the file /etc/ttysand, for every terminal device that
allows a login, does a fork followed by an exec of the program getty().
UNIT 5 PROCESS CONTROL
PROCESSRELATIONSHIP
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 superuserprivileges).
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.
Ifthe 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 thedevice.
UNIT 5 PROCESS CONTROL
PROCESSRELATIONSHIP
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 itthen invokes the
login program, similar to
All the processes shown in the diagram have superuser privileges, since
the original init process has superuser privileges.
If we log in correctly, loginwill
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 toit
Set our group IDs by calling setgid and initgroups
UNIT 5 PROCESS CONTROL
PROCESSRELATIONSHIP
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.
210
UNIT 5 PROCESS CONTROL
PROCESSRELATIONSHIP
TERMINAL LOGINS
220
UNIT 5 PROCESS CONTROL
PROCESSRELATIONSHIP
SESSIONS
A session is a collection of one or more process groups.
For example, we could have the arrangement shown in the diagrambelow.
Here we have three process groups in a single session.
#include <unistd.h>
pid_t getsid(pid_t pid);
PROCESSRELATIONSHIP
CONTROLLING TERMINAL
#include <unistd.h>
pid_t tcgetpgrp(int filedes);
Returns : process group ID of foreground process group if OK, -1 on error.
UNIT 5 PROCESS CONTROL
PROCESSRELATIONSHIP
tcgetpgrp(), tcsetpgrp() & tcgetsid()
PROCESSRELATIONSHIP
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);
PROCESSRELATIONSHIP
JOBCONTROL
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 thebackground.
Job control requires three forms of support:
230
UNIT 5 PROCESS CONTROL
PROCESSRELATIONSHIP
JOBCONTROL
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 thebackground.
All the processes invoked by these background jobs are in the background.
UNIT 5 PROCESS CONTROL
PROCESSRELATIONSHIP
JOBCONTROL
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 SIGTSTPsignal
to all processes in the foreground processgroup.
The jobs in any background process groups aren't affected.
The terminal driver looks for three special characters, which
generate signals to the foreground processgroup.
1. The interrupt character (typically DELETEor Control-C) generatesSIGINT.
2. The quit character (typically Control-\(back slash)) generates SIGQUIT.
3. The suspend character (typically Control-Z) generates SIGTSTP.
UNIT 5 PROCESS CONTROL
PROCESSRELATIONSHIP
JOBCONTROL
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:
UNIT 5 PROCESS CONTROL
PROCESSRELATIONSHIP
JOBCONTROL
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.
UNIT 5 PROCESS CONTROL
PROCESSRELATIONSHIP
JOBCONTROL
UNIT 5 PROCESS CONTROL
PROCESSRELATIONSHIP
SHELLEXECUTION OFPROGRAMS
UNIT 5 PROCESS CONTROL
PROCESSRELATIONSHIP
SHELLEXECUTION OFPROGRAMS
UNIT 5 PROCESS CONTROL
PROCESSRELATIONSHIP
ORPHANED PROCESSGROUPS
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.
UNIT 6 SIGNALSAND 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 handleit.
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 iscalled.
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS
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
240
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS
#include <signal.h>
void (*signal(int sig_no, void (*handler)(int)))(int);
#include <signal.h>
void (*signal(int sig_no, void (*handler)(int)))(int);
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 SIGNALSAND DAEMON PROCESSES
SIGNALS
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 aninteger.
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 SIGNALSAND DAEMON PROCESSES
SIGNALS
The function prototype of the signalAPI 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
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, and1.
They must be three values that can never be the address of any declarablefunction.
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS
The following example attempts to catch the SIGTERMsignal, ignores the SIGINT signal,
and accepts the default action of the SIGSEGVsignal. 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> int main() /*main function*/
#include<signal.h> {
/*signal handler function*/ signal(SIGTERM,catch_
void catch_sig(int sig_num) sig);
{ signal(SIGINT,SIG_IGN);
signal (sig_num,catch_sig); signal(SIGSEGV,SIG_DFL);
cout<<”catch_sig:”<<sig_num<<endl; 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 theprocess,
it will be discarded without any interruption of the process.
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS
#include<stdio.h> int main(void)
#include<signal {
.h> if (signal(SIGUSR1, sig_usr) == SIG_ERR)
/*signal handler function*/ perror("can't catch SIGUSR1");
static void sig_usr(int signo) if (signal(SIGUSR2, sig_usr) == SIG_ERR)
/ * arg is signal number* / perror("can't catch SIGUSR2");
{ for ( ; ; )
if (signo == SIGUSR1) pause();
printf("received SIGUSR1\n"); }
else if (signo == SIGUSR2)
printf("received SIGUSR2\n");
else
printf("received signal %d\n", signo);
}
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS
When we send the SIGTERM signal, the process is terminated, since it doesn'tcatch the
signal, and the default action for the signal is termination.
250
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS
kill and raise 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 isgenerated.
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);
The seconds value is the number of clock seconds in the future when the signal should
be generated.
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS
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 newvalue.
If a previously registered alarm clock for the process has not yet expired and if the
seconds value is 0, the previous alarm clock iscanceled.
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 SIGNALSAND DAEMON PROCESSES
SIGNALS
alarm and pause Functions
The pause function suspends the calling process until a signal is caught.
#include <unistd.h>
int pause(void);
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 SIGNALSAND DAEMON PROCESSES
SIGNALS
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().
POSIX.1 defines the data type sigset_t tocontain a signal set and the following five
functions to manipulate signalsets.
#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);
A process may query or set its signal mask via the sigprocmaskAPI:
#include <signal.h>
int sigprocmask(int cmd, const sigset_t *new_mask, sigset_t *old_mask);
260
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS
SIGNALMASK
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 valueare:
Cmd value Meaning
Overrides the calling process signal mask with the value specified in the new_mask
. SIG_SETMASK
argument.
Adds the signals specified in the new_mask argument tothe calling process signal
SIG_BLOCK
mask.
Removes the signals specified in the new_mask argument from thecalling process
SIG_UNBLOCK
signal mask.
261
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS
SIGNALMASK
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 SIGSEGVsignal from the process
signal mask.
#include <stdio.h> else
#include <signal.h> sigaddset(&mask, SIGINT); /*set SIGINT flag*/
int main() sigdelset(&mask, SIGSEGV);
{ /*clear SIGSEGVflag*/
sigset_t mask; if (sigprocmask(SIG_SETMASK, &mask, 0) == -1)
sigemptyset(&mask); perror(“sigprocmask”);
/*initialize set*/ /*set a new signalmask*/
if (sigprocmask(0, 0, &mask) == -1) }.
{ /*get current signalmask*/
perror(“sigprocmask”);
exit(1);
} PROF. SYED MUSTAFA, HKBKCE 262
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS
SIGNALMASK
The program prints the names of the signals in the signal mask of the calling process
The sigpending function returns the set of signals that are blocked from delivery and
currently pending for the callingprocess.
#include <signal.h>
int sigpending(sigset_t * set);
SIGPENDING FUNCTION
The process blocks SIGQUIT, saving its current signal mask (to reset later),
and then goes to sleep for 5seconds.
Any occurrence of the quit signal during this period is blocked and won't be
delivered until the signal isunblocked.
At the end of the 5-second sleep, we check whether the signal is pending
and unblock the signal.
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS- SIGPENDINGFUNCTION
#include <signal.h> if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) <0)
#include <unistd.h> perror("SIG_BLOCK error");
static void sig_quit(int signo) sleep(5);
{ / * SIGQUIT here willremain pending * /
printf("caught SIGQUIT\n"); if (sigpending(&pendmask) < 0)
if (signal(SIGQUIT, SIG_DFL) ==SIG_ERR) perror("sigpending error");
perror("can't reset SIGQUIT"); if (sigismember(&pendmask, SIGQUIT))
} printf("\nSIGQUIT pending\n");
int main(void) / * Reset signal mask which unblocksSIGQUIT*/
{ if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
sigset_t newmask, oldmask, pendmask; perror("SIG_SETMASK error");
if (signal(SIGQUIT, sig_quit) == SIG_ERR) printf("SIGQUIT unblocked\n");
perror("can't catch SIGQUIT"); sleep(5);
/ * Block SIGQUIT and save current signalmask*/ / * SIGQUIT here will terminate with core file * /
sigemptyset(&newmask); exit(0);
sigaddset(&newmask, SIGQUIT); }
PROF. SYED MUSTAFA, HKBKCE 266
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS
Sigaction() Function
The sigaction() function allows us toexamine 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);
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 todeal with.
sigaction API returns the previous signal handling method for a given signal.
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS
sigaction() Function
struct sigaction
{
void (*sa_handler)(int); / * addr of signal handler, or SIG_IGN, orSIG_DFL* /
sigset_t sa_mask; / * additional signals to block * /
int sa_flags; / * signal options* /
void (*sa_sigaction)(int, siginfo_t *, void *); / * alternate handler * /
};
UNIT 6 SIGNALSAND 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 signosignal.
The signalno argument designates which signal handling action is defined in
the action argument.
The previous signal handling method for signalno will be returned viathe
oldaction argument if it is not a NULLpointer.
If action argument is a NULLpointer, the calling process‘s existing signal
handling method for signalno will beunchanged.
270
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS- sigactionFUNCTION
#include <signal.h> if ( sigaddset( &sigmask, SIGTERM) == -1 | |
#include <iostream.h> sigprocmask( SIG_SETMASK, &sigmask, 0) == -1)
void callme ( int sig_num )
perror(“Set signal mask”);
{
sigemptyset( &action.sa_mask);
cout <<“catch signal:”<<sig_num<< endl;
sigaddset( &action.sa_mask, SIGSEGV);
}
action.sa_handler = callme;
int main(void)
action.sa_flags = 0;
{
if (sigaction (SIGINT, &action, &old_action) == -1)
sigset_t sigmask;
perror(“sigaction”);
struct sigaction action, old_action;
pause(); / * waitfor signal interruption*/
sigemptyset(&sigmask);
return 0;
}
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS- sigactionFUNCTION
In the program, the process signal mask is set with SIGTERMsignal.
The process then defines a signal handler for the SIGINT signal and also
specifies that the SIGSEGVsignal is to be blocked when the process is
handling the SIGINTsignal.
The process then terminates its execution via the pauseAPI.
The output of the program wouldbe as:
% cc sigaction.c –o sigaction
%./sigaction &
[1] 495
%kill –INT 495
catch signal: 2
sigaction exits
[1] Done sigaction
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS
THESIGCHLDSIGNALAND THEwaitpidAPI
When a child process terminates or stops, the kernel will generate a SIGCHLDsignal to its
parent process. Depending on how the parent sets up the handling of the SIGCHLDsignal,
different events may occur:
SIGNALS
abort() Function
abort function causes abnormal program termination
#include <stdlib.h>
void abort(void);
#include <stdlib.h>
int system(const char *command);
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
Eg:
sleep(60); / / suspend the process for one minute.
UNIT 6 SIGNALSAND DAEMON PROCESSES
SIGNALS
Job-Control Signals
POSIX.1 considers six signals as job-control signals:
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 SIGNALSAND DAEMON PROCESSES
SIGNALS
Job-Control Signals
When we type the suspend character (usually Control-Z), SIGTSTPis sent to all processes
in the foreground processgroup.
When we tell the shell to resume a job in the foreground or background, the shell sends
all the processes in the job the SIGCONTsignal.
Similarly, if SIGTTIN or SIGTTOU is delivered to a process, the process is stopped by
default, and the job-control shell recognizes this and notifiesus.
When any of the four stop signals (SIGTSTP,SIGSTOP,SIGTTIN, or SIGTTOU) is generated
for a process, any pending SIGCONTsignal for that process is discarded.
Similarly, when the SIGCONTsignal is generated for a process, any pending stop signals
for that same process arediscarded.
The default action for SIGCONTis to continue the process, if it is stopped; otherwise, the
signal is ignored.
UNIT 6 SIGNALSAND 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.
280
UNIT 6 SIGNALSAND DAEMON PROCESSES
DAEMON PROCESSES
Deamon Characteristics
$ps -axj
UNIT 6 SIGNALSAND 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.
UNIT 6 SIGNALSAND 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.
UNIT 6 SIGNALSAND 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 computersystems.
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 bycron.
The cupsd daemon is a print spooler; ithandles print requests on the system.
UNIT 6 SIGNALSAND 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 groupleader.
DAEMON PROCESSES UNIT 6 SIGNALSAND DAEMON 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.
UNIT 6 SIGNALSAND 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.
UNIT 6 SIGNALSAND DAEMON PROCESSES
DAEMON PROCESSES
CODING RULES
Example Program:
#include <unistd,h> else if ( pid != 0)
#include <sys/types.h> exit(0); / * parent exits * /
#include <fcntl.h> / * child continues * /
int daemon_initialise( ) setsid( );
{ chdir(“/”
pid_t pid; );
if (( pid = fork() ) <0) umask(0);
return –1; return 0;
}
UNIT 6 SIGNALSAND 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.
UNIT 6 SIGNALSAND DAEMON PROCESSES
DAEMON PROCESSES
Error Logging
290
UNIT 6 SIGNALSAND 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 besent.
291