Device File Apis, Fifo File Apis: Prepared by Uma.N, Asst - Profnhce 1
Device File Apis, Fifo File Apis: Prepared by Uma.N, Asst - Profnhce 1
UNIX APIs: General File APIs , File and Record locking, Directory File APIs, Device File
APIs, FIFO File APIs
Files in a UNIX and POSIX system may be any one of the following
types:
• Regular file
• Directory File
• FIFO file
• Block device file
• character device file
• Symbolic link file.
API USE
open Opens a file for data access
read Reads data from file
Write Writes data to a file
lseek Allows random access of data in a file
close Terminates the connection to a file
stat,fstat Queries attributes of a file
chmod Changes access permission of a file
chown Changes UID and/OR GID of a file
Utime Changes last modification and access time
stamps of a file
link Creates hardlink to a file
unlink Deletes hard link of a file
umask Sets default file creation mask
PREPARED BY UMA.N,ASST.PROFNHCE 1
open
There are other access modes, which are termed as access modifier
flags, and one or more of the following can be specified by
PREPARED BY UMA.N,ASST.PROFNHCE 2
bitwise-ORing them with one of the above access mode flags to
alter the access mechanism of the file.
PREPARED BY UMA.N,ASST.PROFNHCE 3
The following are the manifested constants defined in sys/stat.h
header
• for 764=>S_IRWXU|S_IRGRP|S_IWGRP|S_IROTH
• A Permission value in open system call is modified by the
calling process umask value.
• Umask value specifies the some access rights to be masked off
automatically on any files created by the process.
• Umask value can be inherited from parent and can be obtained
by calling the umask system call.
• Umask function takes a new umask value as an argument and the
function returns the old umask value.
• The following statement will assign the current umask value
to the variable old_mask,and sets the new mask value to “no
execute group” and “no write-execute” for others.
mode_t old_mask=umask(S_IXGRP|S_IWOTH|S_IXOTH);
• The open function takes its permission argument value and
bitwise ANDs it with the one’s complement of the calling
process umask value.Thus the final permission for any file
created is
• actual permission=permission& ~umask_value
• eg:if a file has t be created with 0557,and the umask value
is 0031,then the actual permission of file is
• actual permission is 0557 & ~0031=546
PREPARED BY UMA.N,ASST.PROFNHCE 4
RETURN VALUE
• -1 if API fails and errno containing error status value is
sent
• file descriptor is returned on successful(file descriptor
value should be between 0 and OPEN_MAX -1,inclusively.
2.Creat
#include <sys/types.h>
#include <unistd.h>
int creat(const char *pathname, mode_t mode);
RETURN VALUE
• -1 if API fails and errno containing error status value is
sent
• file descriptor is returned for write-only mode on success
3.read
PREPARED BY UMA.N,ASST.PROFNHCE 5
• 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);
PREPARED BY UMA.N,ASST.PROFNHCE 6
• read function may block a calling process if it is reading a
O_NONBLOCK or O_NDELAY flags on file descriptor to request
non blocking read operations on the requested file.
4.write
PREPARED BY UMA.N,ASST.PROFNHCE 7
• 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.
fcntl
The fcntl function helps a user to query or set flags and the
close-on-exec flag of any file descriptor.
The prototype of fcntl is
#include<fcntl.h>
int fcntl(int fdesc, int cmd, ...);
PREPARED BY UMA.N,ASST.PROFNHCE 8
If a return value is zero, the
flag is off; otherwise F_SETFL
F_SETFD Sets or clears the close-on-exec
flag of a fdesc. The third
argument to fcntl is an integer
value, which is 0 to clear the
flag, or 1 to set the flag
F_DUPFD Duplicates file descriptor fdesc
with another file descriptor.
The third argument to fcntl is
an integer value which specifies
that the duplicated file
descriptor must be greater than
or equal to that value. The
return value of fcntl is the
duplicated file descriptor.
int cur_flags=fcntl(fdesc,F_GETFL);
cout<<fdesc<<”close-on-exec”<<fcntl(fdesc,F_GETFD)<<end//reports
the close-on-exec flag of fdesc, sets it to on afterwards:
(void)fcntl(fdesc,F_SETFD,1); //turn on close-on-exec flag
int fdesc=open(“FOO”,O_RDONLY);//change standard input as File
Foo
close(0);////close standard input and stdin from FOO now
if(fcntl(fdesc,F_DUPFD,0)==-1)
PREPARED BY UMA.N,ASST.PROFNHCE 9
perror(“fcntl”);
char buf[256];
int rc=read(0,buf,256);//read data from FOO
The dup and dup2 functions in UNIX perform the same file
duplication function as fcntl.
They can be implemented using fcntl as:
#define dup(fdesc)
#define dup2(fdesc1,fd2)
fcntl(fdesc, F_DUPFD,0);
close(fd2);
fcntl(fdesc,F_DUPFD,fd2);
int rc=fcntl(fdesc,F_SETFL,cur_flag | O_APPEND | O_NONBLOCK);
➔ lseek
• The lseek function is also used to change the file offset to
a different value.
• Thus lseek allows a process to perform random access of data
on any opened file.
• The prototype of lseek is
• #include <sys/types.h>
• #include <unistd.h>
• off_t lseek(int fdesc, off_t pos, int whence);
• On success it returns new file offset, and –1 on error.
• The first argument fdesc, is an integer file descriptor that
refer to an opened file.
• The second argument pos, specifies a byte offset to be added
to a reference location in deriving the new file offset
value.
• The third argument whence, is the reference location.
Whence Value Reference Location
SEEK_CUR Current file pointer
address
PREPARED BY UMA.N,ASST.PROFNHCE 10
SEEK_SET The beginning of a file
SEEK_END The end of a file
➔ link
• The link function creates a new link for the existing file.
• The prototype of the link function is
#include <unistd.h>
int link(const char *cur_link, const char *new_link);
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
PREPARED BY UMA.N,ASST.PROFNHCE 11
if(argc==4)
{
if((symlink(argv[2],argv[3]))==-1)
printf("Error in softlink creation\n");
else
printf("Softlink created\n");
}
else
{
if((link(argv[1],argv[2]))==-1)
printf("Error in Hardlink Creation\n");
else
printf("Link created\n");
}
}
return 0;
}
✔ unlink
PREPARED BY UMA.N,ASST.PROFNHCE 12
• int rename(const char * old_path_name,const char *
new_path_name);
• The UNIX mv command can be implemented using the link and
unlink APIs as shown:
Emulation of mv command
#include <iostream.h>
#include <unistd.h>
#include<string.h>
int main ( int argc, char *argv[ ])
{
if (argc != 3 || strcmp(argv[1],argcv[2]))
cerr<<”usage:”<<argv[0]<<””<old_link><new_link>\n”;
else if(link(argv[1],argv[2]) == 0)
return unlink(argv[1]);
return 1;
}
✔ stat, fstat
• The stat and fstat functions retrieve the file attributes of
a given file.
• The only difference between stat and fstat is that the first
argument of a stat is a file pathname, where as the first
argument of fstat is file descriptor.
PREPARED BY UMA.N,ASST.PROFNHCE 13
{
dev_t st_dev; ///* file system ID */
0 if they succeed
-1 if they fail
PREPARED BY UMA.N,ASST.PROFNHCE 14
We can determine the file type with the macros as shown.
Macro Type of file
S_ISREG() regular file
S_ISDIR() directory file
S_ISCHR() character special file
S_ISBLK() block special file
S_ISFIFO() pipe or FIFO
S_ISLNK() symbolic link
S_ISSOCK() socket
➔ access
The access system call checks the existence and access permission
of user to a named file.
The prototype of access function is:
#include<unistd.h>
int access(const char *path_name, int flag);
On success access returns 0, on failure it returns –1.
The first argument is the pathname of a file.
The second argument flag, contains one or more of the following
bit flag .
PREPARED BY UMA.N,ASST.PROFNHCE 15
exist
R_OK Test for read permission
W_OK Test for write permission
X_OK Test for execute permission
➔ 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>
PREPARED BY UMA.N,ASST.PROFNHCE 16
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.
PREPARED BY UMA.N,ASST.PROFNHCE 17
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.
/* Program to illustrate chown function */
#include<iostream.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<pwd.h>
PREPARED BY UMA.N,ASST.PROFNHCE 18
}
The above program takes at least two command line arguments:
o The first one is the user name to be assigned to files
o The second and any subsequent arguments are file path names.
The program first converts a given user name to a user ID via
getpwuid function. If that succeeds, the program processes each
named file as follows: it calls stat to get the file group ID,
then it calls chown to change the file user ID. If either the stat
or chown fails, error is displayed.
➔ utime Function
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 */
}
• 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.
PREPARED BY UMA.N,ASST.PROFNHCE 19
• 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.
PREPARED BY UMA.N,ASST.PROFNHCE 20
• 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.
• 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.
• 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.
PREPARED BY UMA.N,ASST.PROFNHCE 21
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.
PREPARED BY UMA.N,ASST.PROFNHCE 22
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.
PREPARED BY UMA.N,ASST.PROFNHCE 23
SEEK_CUR The l_start value is added to current file pointer
address
SEEK_SET The l_start value is added to byte 0 of the file
SEEK_END The l_start value is added to the end of the file
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.
In the given example program we have performed a read lock on a
file “usp.txt” from the 50th byte to 69th byte.
Example Program
#include <unistd.h>
#include<fcntl.h>
int main ( )
{
int fd;
struct flock lock;
fd=open(“/home/Documents/usp/usp.txt”,O_RDONLY);
lock.l_type=F_RDLCK;
lock.l_whence=0;
lock.l_start=50;
lock.l_len=69;
fcntl(fd,F_SETLK,&lock);
}
PREPARED BY UMA.N,ASST.PROFNHCE 24
Directories are created with the mkdir API and deleted with the
rmdir API.
PREPARED BY UMA.N,ASST.PROFNHCE 25
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.
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
PREPARED BY UMA.N,ASST.PROFNHCE 26
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);
• 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);
PREPARED BY UMA.N,ASST.PROFNHCE 27
• On success mknod API returns 0 , else it returns -1
FIFO 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);
PREPARED BY UMA.N,ASST.PROFNHCE 28
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.
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.
The prototype of pipe is
#include <unistd.h>
int pipe(int fds[2]);
PREPARED BY UMA.N,ASST.PROFNHCE 29
Symbolic links are developed to get around the limitations of hard
links:
• Symbolic links can link files across file systems.
• Symbolic links can link directory files
• Symbolic links always reference the latest version of the
files to which they link
• There are no file system limitations on a symbolic link and
what it points to and anyone can create a
• symbolic link to a directory.
• Symbolic links are typically used to move a file or an
entire directory hierarchy to some other location on a
system.
A symbolic link is created with the symlink.
The prototype is
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
int symlink(const char *org_link, const char *sym_link);
int readlink(const char* sym_link,char* buf,int size);
int lstat(const char * sym_link, struct stat* statv);
The org_link and sym_link arguments to a sym_link call specify the
original file path name and the symbolic link path name to be
created.
PREPARED BY UMA.N,ASST.PROFNHCE 30