Professional Documents
Culture Documents
System Calls
1. File Descriptors All open files are referred to by file descriptors 2. File Related system calls The prototype for the creat() system call is: int creat(file_name, mode) char *file_name; int mode;
The mode is usually specified as an octal number such as 0666 manifest constants defined in the
not
exist, the UNIX system creates it with the specified mode permissions. its contents are discarded and the mode retained. However, if the file does exist,
/* write
" " */
open() Next is the open() system call. open() lets you open a file for reading, writing, or reading and writing. The prototype for the open() system call is: #include <fcntl.h> int open(file_name, option_flags [, mode]) char *file_name; int option_flags, mode; The allowable option_flags as defined in "/usr/include/fcntl.h" are: #define O_RDONLY 0 #define O_WRONLY 1 #define O_RDWR 2 #define O_APPEND 010 /* Open the file for reading only */ /* Open the file for writing only */ /* Open the file for both reading and writing*/ /* append (writes guaranteed at the end) */
#define O_CREAT 00400 /*open with file create (uses third open arg) */ #define O_TRUNC 01000 #define O_EXCL 02000 /* open with truncation */ /* exclusive open */ Note: some combinations are mutually exclusive such
Multiple values are combined using the | operator (i.e. bitwise OR). as: O_RDONLY |
O_WRONLY and will cause open() to fail. If the O_CREAT flag is used, the same manner as in the creat() system call.
Both read() and write() take three arguments. Their prototypes are: int read(file_descriptor, buffer_pointer, transfer_size) int file_descriptor; char *buffer_pointer; unsigned transfer_size; int write(file_descriptor, buffer_pointer, transfer_size) int file_descriptor; char *buffer_pointer; unsigned transfer_size; where file_descriptor identifies the I/O channel, buffer_pointer points to the area in memory where the data is stored for a read() or where transfer_size defines the maximum and the buffer. read() and write() return the number of bytes transferred. the data is taken for a write(), and
/* open.c */
#include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> /* defines options flags */ /* defines types used by sys/stat.h */ /* defines S_IREAD & S_IWRITE */
if (fd != -1) { printf("datafile.dat opened for read/write access\n"); write(fd, message, sizeof(message)); lseek(fd, 0L, 0); /* go back to the beginning of the file */
if (read(fd, buffer, sizeof(message)) == sizeof(message)) printf("\"%s\" was written to datafile.dat\n", buffer); else printf("*** error reading datafile.dat ***\n"); close (fd); } else printf("*** datafile.dat already exists ***\n"); exit (0); }
close() To close a channel, use the close() system call. The prototype for the close() system call is: int close(file_descriptor) int file_descriptor; where file_descriptor identifies a currently open channel. close() fails if file_descriptor does not identify a currently open channel.
lseek() The UNIX system file system treats an ordinary file as a sequence of bytes. Fortunately,
the UNIX system lets you read and write anywhere in the file. Known as "random access", this capability is possible with the lseek() system call. During file I/O, the UNIX system uses a long integer, also called a File Pointer, to keep track of the next byte to read or
write. This long integer represents the number of bytes from the beginning of the file to
that next character. Random pointer using access I/O is achieved by changing the value of this file
The prototype for lseek() is: long lseek(file_descriptor, offset, whence) int file_descriptor; long offset; int whence; where file_descriptor identifies the I/O channel and offset and whence work together to describe how to change the file pointer according to the following table: whence new position
-----------------------------0(SEEK_SET) 1 (SEEK_CUR) 2 (SEEK_END) offset bytes fro beginning of file current position in the file plus offset (offset can be positive or ve) current end-of-file position plus offset (offset can be positive or ve)
If successful, lseek() returns a long integer that defines the new file pointer value measured in bytes from the beginning of the file. If unsuccessful, the file position does not change.
File Sharing
The operating system (OS) has three kinds of data structures for files: ``File table entry'' -- it has one of these for each file descriptor for a user. It contains information like the current lseek pointer, and a pointer to a ``vnode'' (see below). So, when you start your program, the OS has three file table entries for you -- one each for stdin, stdout, stderr. Each time you call open(), a new file table entry is created for you in the OS.
``vnode'' -- There is one of these for each physical file that has been
opened. It contains a pointer to the file's inode, the file's size, etc.
``inode'' -- There is one of these for each file on disk. It contains all the
main()
close(fd2); }
second write() call will overwrite it with "Plank\n" Dup() Instead of calling open() to initialize fd2,we call dup(fd1). after the first write, the lseek pointer of fd2 has been updated to reflect the write to fd1 -- this is because the two file descriptors point to the same file table entry. Dup2() is a system call that dups an open file descriptor so that the result is a desired file descriptor. int dup2(int fd1, int fd2) fd2 specifies the desired value of the new descriptor. If descriptor fd2 is already in use, it is first deallocated as if it were closed by close
fd = open("file4", O_WRONLY | O_CREAT | O_TRUNC, 0666); dup2(fd, 1) ; printf("Standard output now goes to file4\n"); close(fd); printf("It goes even after we closed file descriptor %d\n", fd); }
int fcntl(int fildes, int cmd, .../*int arg*/); F_DUPFD F_GETFL F_GETFD F_SETFL F_SETFD
dev_t st_dev Device ID of device containing file. ino_t st_ino File serial number.
time_t st_atime Time of last access. time_t st_mtime Time of last data modification. time_t st_ctime Time of last status change. blksize_t st_blksize A file system-specific preferred I/O block size for this object. In some file system types, this may vary from file to file.
S_ISIFO FIFO special. S_ISREG Regular. S_ISDIR Directory. S_ISLNK Symbolic link. S_ISSOCK Socket. struct stat statbuf ; (S_ISREG(buf.st_mode)) printf(regular);
File mode bits: S_IRWXU Read, write, execute/search by owner. S_IRUSR Read permission, owner. S_IWUSR Write permission, owner. S_IXUSR Execute/search permission, owner.
S_IRGRP Read permission, group. S_IWGRP Write permission, group. S_IXGRP Execute/search permission, group.
int access(file_name, access_mode) F_OK X_OK W_OK R_OK These values may be ORed together to check for mone than one access int link(original_name, alias_name) int unlink(file_name)
execl(file_name, arg0 [, arg1, ..., argn], NULL) ; int execv(file_name, argv) char *file_name, *argv[]; int execle(file_name, arg0 [, arg1, ..., argn], NULL, envp); int execve(file_name, argv, envp) char *file_name, *argv[], *envp[]; int execlp(file_name, arg0 [, arg1, ..., argn], NULL) char *file_name, *arg0, *arg1, ..., *argn; int execvp(file_name, argv) char *file_name, *argv[];