Page 448 - DCAP103_Principle of operating system
P. 448
Unit 14: Case Study of Linux Operating System
descriptors 0, 1, and 2 are already opened for standard input, standard output, and standard Notes
error, respectively. In this way, a filter, such as the sort program, can just read its input from
file descriptor 0 and write its output to file descriptor 1, without having to know what files they
are. This mechanism works because the shell arranges for these values to refer to the correct
(redirected) files before the program is started. The most heavily used calls are undoubtedly read
and write. Each one has three parameters: a file descriptor (telling which open file to read or
write), a buffer address (telling where to put the data or get the data from), and a count (telling
how many bytes to transfer). A typical call is
n = read(fd, buffer, nbytes);
Although nearly all programs read and write files sequentially, some programs need to be
able to access any part of a file at random. Associated with each file is a pointer that indicates
the current position in the file. When reading (writing) sequentially, it normally points to the
next byte to be read (written). If the pointer is at, say, 4096, before 1024 bytes are read, it will
automatically be moved to 5120 after a successful read system call. The lseek call changes the
value of the position pointer, so that subsequent calls to read or write can begin anywhere in the
file, or even beyond the end of it. It is called lseek to avoid conflicting with seek, a now-obsolete
call that was formerly used on 16 bit computers for seeking.
Figure 14.27: Some System Calls Relating to Files
System call Description
fd = creat(name, mode) One way to create a new file
fd = open(file, how, ...) Open a file for reading, writing or both
s = close(fd) Close an open file
n = read(fd, buffer, nbytes) Read data from a file into a buffer
n = write(fd, buffer, nbytes) Write data from a buffer into a file
position = lseek(fd, offset, whence) Move the file pointer
s = stat(name, &buf) Get a file’s status information
s = fstat(fd, &buf) Get a file’s status information
s = pipe(&fd[0]) Create a pipe
s = fcnt(fd, cms, ...) File locking and other operations
The return code s is ~1 if an error has occurred; fd is a file descriptor, and position is a file
offset. The parameters should be self-explanatory. Lseek has three parameters: the first one is
the file descriptor for the file; the second one is a file position; the third one tells whether the
file position is relative to the beginning of the file, the current position, or the end of the file.
The value returned by lseek is the absolute position in the file after the file pointer was changed.
Slightly ironically, lseek is the only file system calls that can never cause an actual disk seek
because all it does is update the current file position, which is a number in memory.
For each file, Linux keeps track of the file mode (regular, directory, special file), size, time of
last modification, and other information. Programs can ask to see this information via the stat
system call. The first parameter is the file name. The second one is a pointer to a structure where
the information requested is to be put. The fields in the structure are shown in Figure 14.28.
The fstat call is the same as stat except that it operates on an open file (whose name may not be
known) rather than on a path name.
The pipe system call is used to create shell pipelines. It creates a kind of pseudofile, which buffers the
data between the pipeline components, and returns file descriptors for both reading and writing the
buffer. In a pipeline such as sort <in | head –30 file descriptor 1 (standard output) in the process running
LOVELY PROFESSIONAL UNIVERSITY 441