CS 321 Spring 2013  >  Lecture Notes for Monday, March 25, 2013

CS 321 Spring 2013
Lecture Notes for Monday, March 25, 2013

File Operations


Low-level file operations can be divided into three broad categories: First are those dealing with the file contents: open, close, read, write, append, seek. Second are those dealing with file existence and naming: create, delete, rename. Third are those dealing with metadata: getting and setting attributes. Some operations might cross these boundaries; for example, it is common to be able to create a file by opening it.

Some file systems allow for a file to be in multiple directories. Traditionally *ix file systems allow this. The way this is handled is that all information about a file, except for its pathname, is kept in a single location called the file’s inode. Then a directory entry for a file includes a pointer to the inode; this is called a link to the file. A file may have multiple links.

When multiple links are allowed, there is generally no primitive delete operation. Rather, we can unlink: destroy a link to the file. The inode keeps track of how many links to the file there are; when the last link is destroyed, the file is deleted.

In most *ix shells, do ls -i FILENAME to see a file’s inode number. To get the link count, do ls -l FILENAME and look at the number after the initial permissions.

System Calls

We have seen some of the *ix system calls for handling files: read, write, close.

To open a file, use open, declared in header <fcntl.h>. This takes two or three parameters: the pathname, flags, and an optional mode, giving the permissions the file should have if it needs to be created.

As usual, the flags parameter is the bitwise-OR of one or more predefined constants. O_RDONLY, O_WRONLY, and O_RDWR indicate read access, write access, and both, respectively. O_CREAT indicates that a file should be created if it does not exist. O_TRUNC indicates that a file’s contents should be cleared, if the file exists.

The mode is an integer, best specifed as a 3-digit octal number. The first digit indicates permissions for the user that owns the file, the second is permissions for users in the file’s group other than the owner, and the third is permissions for all other users. For each digit, add together 4 for reading, 2 for writing, and 1 for executing. For example, 0644 means user read & write, group read, other read.

The open call returns the file’s descriptor (a nonnegative integer) on success, and a negative number on failure.

To move within a file, use lseek, declared in the header <unistd.h>. This takes two parameters: offset and whence. “Whence” is an old word meaning “from where”. The whence parameter indicates where we start measuring the offset from. There are three possibilities for whence: SEEK_SET specifies the start of the file, SEEK_CUR specified the current location in the file, and SEEK_END specifies the end of the file.

The offset is how far to move from the start position, and in which direction. So, with SEEK_SET, the offset should not be negative. With SEEK_END it should not be positive. And with SEEK_CUR it can be any value.

The lseek call returns zero on success and nonzero on failure.

Create a new link to a file with link, remove a link with unlink, change a filename with rename, and get file metadata with stat. See documentation for details.

When trying out file operations, a useful *ix shell command to peek at file contents is od.

CS 321 Spring 2013: Lecture Notes for Monday, March 25, 2013 / Updated: 6 May 2013 / Glenn G. Chappell / ggchappell@alaska.edu