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
   443   444   445   446   447   448   449   450   451   452   453