Skip to content

Reference

Opening a file: open()

#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags, ... /* mode_t mode */);
// Returns file descriptor on success, or –1 on error
  • The flags argument

Example code

  • Errors from open(): If an error occurs while trying to open the file, open() returns –1, and errno identifies the cause of the error
    EACCESThe file permissions don’t allow the calling process to open the file in the mode specified by flags. Alternatively, because of directory permissions, the file could not be accessed, or the file did not exist and could not be created.
    EISDIRThe specified file is a directory, and the caller attempted to open it for writing. This isn’t allowed.
    EMFILEThe process resource limit on the number of open file descriptors has been reached
    ENFILEThe system-wide limit on the number of open files has been reached.
    ENOENTThe specified file doesn’t exist, and O_CREAT was not specified, or O_CREAT was specified, and one of the directories in pathname doesn’t exist or is a symbolic link pointing to a nonexistent pathname (a dangling link).
    EROFSThe specified file is on a read-only file system and the caller tried to open it for writing.
    ETXTBSYThe specified file is an executable file (a program) that is currently executing. It is not permitted to modify (i.e., open for writing) the executable file associated with a running program. (We must first terminate the program in order to be able to modify the executable file.)

Reading from a file: read()

  • The read() system call reads data from the open file referred to be the descriptor fd.
#include <unistd.h>
ssize_t read(int fd, void *buffer, size_t count);
// Returns number of bytes read, 0 on EOF, or –1 on error
// typedef long ssize_t;
  • count argument: specifies the maximum number of bytes to read.
  • buffer argument: specifies the address of the memory buffer into which the input data is to be placed (must be at least count bytes long).

Closing a file: close()

  • The close() system call closes an open file descriptor, freeing it for subsequent reuse by the process. When a process terminates, all of its open file descriptors are automatically closed.
#include <unistd.h>
int close(int fd);
// Returns 0 on success, or –1 on error

Changing the file offset: lseek()

  • For each open file, the kernel records a file offset - This is the location in the file at which the next read() or write() will commence.
  • The file offset is set to point to the start of the file when the file is opened and is automatically adjusted by each subsequent call to read() or write() so that it points to the next byte of the file after the byte(s) just read or written
  • The lseek() system call adjusts the file offset of the open file referred to by the file descriptor fd, according to the values specified in offset and whence.
  • Calling lseek() simply adjusts the kernel’s record of the file offset associated with a file descriptor. It does not cause any physical device access.
  • We can’t apply lseek() to all types of files.
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
// Returns new file offset if successful, or –1 on error
// typedef long off_t

Arguments

  • offset: specifies a value in bytes
  • whence: base point from which offset is to be interpreted
    ValueUsage
    SEEK_SETThe file offset is set offset bytes from the beginning of the file.
    SEEK_CURThe file offset is adjusted by offset bytes relative to the current file offset.
    SEEK_ENDThe file offset is set to the size of the file plus offset. In other words, offset is interpreted with respect to the next byte after the last byte of the file.

Examples

lseek(fd, 0, SEEK_SET); /* Start of file */
lseek(fd, 0, SEEK_END); /* Next byte after the end of the file */
lseek(fd, -1, SEEK_END); /* Last byte of file */
lseek(fd, -10, SEEK_CUR); /* Ten bytes prior to current location */
lseek(fd, 10000, SEEK_END); /* 10001 bytes past last byte of file */

Note

  • Writing data at a position beyond the previous end of the file creates a hole in the file. Reads from a file hole return bytes containing zeros.

Atomicity and Race conditions