Unix System Programming
Unix System Programming
Unix System Programming
Chapter 1 : Introduction
UNIX AND ANSI STANDARDS
UNIX is a computer operating system originally
developed in 1969 by a group of AT&T employees
at Bell Labs, including Ken Thompson, Dennis
Ritchie, Douglas McElroy and Joe Ossanna.
• Function prototyping
• Support of the const and volatile data type
qualifiers.
• Support wide characters and internationalization.
• Permit function pointers to be used without
dereferencing.
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.
Eg:
unsigned long f1(char * fmt, double data)
{
/*body of f1*/
}
External declaration of this function f1 is
unsigned long f1(char * fmt, double data);
ANSI C C++
Uses K&R C default function declaration Requires that all functions must be
for any functions that are referred declared / defined before they
before their declaration in the program. can be referenced.
Does not employ type safe linkage Encrypts external function names
technique and does not catch user errors. for type safe linkage. Thus reports any
user errors.
The POSIX standards
POSIX.1b
This committee proposes a set of standard APIs for a real
time OS interface; these include IPC (inter-process
communication).
This standard is formally known as IEEE standard 1003.4-
1993.
POSIX.1c
This standard specifies multi-threaded programming
interface. This is the newest POSIX standard.
These standards are proposed for a generic OS that
is not necessarily be UNIX system.
E.g.: VMS from Digital Equipment Corporation, OS/2
from IBM, & Windows NT from Microsoft Corporation
are POSIX-compliant, yet they are not UNIX systems.
To ensure a user program conforms to POSIX.1
standard, the user should either define the
manifested constant _POSIX_SOURCE at the
beginning of each source module of the program
(before inclusion of any header) as;
#define _POSIX_SOURCE
Or specify the -D_POSIX_SOURCE option to a C++
compiler (CC) in a compilation;
% CC -D _POSIX_SOURCE *.C
POSIX.1b defines different manifested constant to check
conformance of user program to that standard.
#define _POSIX_SOURCE
#define _POSIX_C_SOURCE 199309L
#include<iostream.h>
#include<unistd.h>
int main()
{
#ifdef _POSIX_VERSION
cout<<“System conforms to POSIX”<<“_POSIX_VERSION<<endl;
#else
cout<<“_POSIX_VERSION undefined\n”;
#endif
return 0;
}
The POSIX Environment
Although POSIX was developed on UNIX, a POSIX complaint system is
not necessarily a UNIX system.
A few UNIX conventions have different meanings according to the POSIX
standards.
Most C and C++ header files are stored under the /usr/include
directory in any UNIX system and each of them is referenced by
#include<header-file-name>
/* show_test_macros.C */
#define _POSIX_SOURCE
#define _POSIX_C_SOURCE 199309L
#include<iostream.h>
#include<unistd.h>
int main()
{
#ifdef _POSIX_JOB_CONTROL
cout<<“system supports job control”;
#else
cout<<“ system does not support job control\n”;
#endif
#ifdef _POSIX_SAVED_IDS
cout<<“ system supports saved set-UID and set-GID”;
#else
cout<<“ system does not support set-uid and gid\n”;
#endif
#ifdef _POSIX_CHOWN_RESTRICTED
cout<<“chown_restricted option is :”
<<_POSIX_CHOWN_RESTRICTED<<endl;
#else
cout<<”system does not support” <<” chown_restricted option\n”;
#endif
#ifdef _POSIX_NO_TRUNC
cout<<”pathname trunc option is:” << _POSIX_NO_TRUNC<<endl;
#else
cout<<” system does not support system-wide pathname” <<”trunc
option\n”;
#endif
#ifdef _POSIX_VDISABLE
cout<<“disable char. for terminal files is:” <<_POSIX_VDISABLE<<endl;
#else
cout<<“ system does not support _POSIX_VDISABLE \n”;
#endif
return 0;
}
Limits checking at Compile time and at Run time
Two functions do the same thing, the only difference is that pathconf
takes a file’s pathname as argument, whereas fconf takes a file
descriptor as argument.
Prototypes of these functions are:
#include<unistd.h>
The possible values and the corresponding data returned by the sysconf
function are:
Limit value Sysconf return data
ECHILD A process does not have any child process which it can
wait on.
UNIT 2 UNIX FILES
Files are the building blocks of any operating system.
When you execute a command in UNIX, the UNIX kernel fetches the
corresponding executable file from a file system, loads its instruction
text to memory, and creates a process to execute the command on your
behalf.
A file may be referenced by more than one path name if a user creates
one or more hard links to the file using ln command.
ln /usr/foo/path1 /usr/prog/new/n1
If the –s option is used, then it is a symbolic (soft) link .
The following files are commonly defined in most UNIX
systems
FILE Use
/etc Stores system administrative files and programs
/etc/passwd Stores all user information’s
/etc/shadow Stores user passwords
/etc/group Stores all group information
/bin Stores all the system programs like cat,
rm, cp,etc.
/dev Stores all character device and block
device files
/usr/include Stores all standard header files.
/usr/lib Stores standard libraries
/tmp Stores temporary files created by
program
The UNIX and POSIX File Attributes
The general file attributes for each file in a file system are:
File type
File inode number
File system ID
Major and minor device number
The other attributes are changed by the following UNIX commands or
system calls
Unix System Call Attributes changed
Command
chmod chmod Changes access permission, last
change time
chown chown Changes UID, last change time
chgrp chown Changes GID, ast change time
touch utime Changes last access time, modification
time
ln link Increases hard link count
rm unlink Decreases hard link count. If the hard link
count is zero, the file will be removed from
the file system.
vi, emac Changes the file size, last access time, last
modification time
Inodes in UNIX System 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 # and the physical
disk address where data of the file is stored .
Generally an OS does not keep the name of a file in its record, because
the mapping of the filenames to inode# is done via directory files i.e. a
directory file contains a list of names of their respective inode # for all
file stored in that directory.
Ex: a sample directory file content
Inode number File name
115 .
89 ..
201 xyz
346 a.out
201 xyz_ln1
To access a file, for example /usr/divya, the UNIX kernel always knows
the “/” (root) directory inode # 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 #, it accesses the contents of usr file. It then looks for the
inode # of divya 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 # to the file and add the new file name
and inode # to the directory file that contains it.
Application Program Interface to Files
The general interfaces to the files on UNIX and POSIX system
are
Files are identified by pathnames.
Files should be created before they can be used. The various
commands and system calls to create files are listed below.
File type Commands System call
Regular file vi,pico,emac open,creat
Directory file mkdir mkdir,mknod
FIFO file mkfifo mkfifo,mknod
Device file mknod mknod
Symbolic link file ln –s symlink
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.
2. The kernel will scan the file table in its kernel space to
find an unused entry that can be assigned to reference the
file.
If an unused entry is found the following events will occur:
The process file descriptor table entry will be set to point to
this file table entry.
The file table entry will be set to point to the inode table
entry, where the inode record of the file is stored.
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.
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.
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.
Symbolic link can be creates by the same command ln but with option
–s
Example: ln –s /usr/divya/old /usr/divya/new
ln –s /usr/divya/abc /usr/raj/xyz