- Forward


UNIX File Descriptors
An Introduction


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu

Print

Review
Back SMYC Forward
  • Files in UNIX
    • A file is a sequence of bytes
    • All I/O devices are modeled as files
  • Universal Operations:
    • Open - A statement of intent to use an I/O device
    • Read/Write - Copy bytes from/to a file to/from memory
    • Close - A statement of intent to stop using an I/O device
Opening a File
Back SMYC Forward
  • The "Statement":
    • Made using a system call
  • The "Response":
    • A nonnegative integer called a file descriptor that identifies the file
  • Information Maintained by the Kernel:
    • Process-specific file descriptor tables
    • System-wide open file table
    • System-wide i-node table (called a v-node table in System V)
Contents of the Tables
Back SMYC Forward
  • File Descriptor Table:
    • Flags controlling the operation of the file descriptor
    • A pointer/reference to the open file table
  • Open File Table:
    • The status flags specified when the file was opened
    • The file access mode
    • The current file offset (in bytes, from the start of the file)
    • A pointer/reference to the i-node table
  • i-Node Table:
    • File type
    • The locks held on the file
    • Properties of the file (e.g., size, timestamp, permissions, etc...)
Relationships Between Tables
Back SMYC Forward
file-descriptors
Relationships Between Tables (cont.)
Back SMYC Forward
  • Pointers to the Open File Table:
    • One process can have multiple file descriptors point to the same entry (e.g., as a result of a call to dup())
    • Multiple processes (e.g., a parent and child) can have file descriptors that point to the same entry
  • Pointers to the i-Node Table:
    • Multiple files can point to the same i-node table entry (e.g., open() is called multiple times for the same file)
Duplicating a File Descriptor: dup() dup
Back SMYC Forward
int dup(int oldfd);
Purpose:
Create a copy of a file descriptor using the lowest available number
Details:
oldfd The existing file descriptor
Return The new file descriptor; -1 on error
#include <unistd.h> unistd.h
Duplicating a File Descriptor: dup2() dup2
Back SMYC Forward
int dup2(int oldfd, int newfd);
Purpose:
Create a copy of a file descriptor
Details:
oldfd The existing file descriptor
newfd The new file descriptor (to silently close and re-) use
Return The new file descriptor; -1 on error
#include <unistd.h> unistd.h
Duplicating a File Descriptor: Some Values of errno
Back SMYC Forward

EBADF fd isn't a valid open file descriptor
EMFILE The per-process limit has been reached

An Example of the Relationships Between Tables
Back SMYC Forward
file-descriptors_example
"Standard" File Descriptors
Back SMYC Forward
  • An Important Note:
    • Each process created by a shell begins life with three open files: standard input (0), standard output (1) and standard error (2)
  • Portability:
    • <unistd.h> unistd.h defines STDIN_FILENO, STDOUT_FILENO and STDERR_FILENO
Closing a File
Back SMYC Forward
  • The "Announcement":
    • Made using a system call
  • The "Response":
    • The file descriptor is returned to the pool of available descriptors
Finding Open File Descriptors
Back SMYC Forward
  • /dev/fd:
    • A (virtual) directory containing file names of the form /dev/fd/n where n is one of the process's open file descriptors
  • Opening these Files:
    • Linux: Opening a file in /dev/fd is equivalent to reopening the oritinal file
    • Other Systems: Opening a file in /dev/fd is equivalent to calling dup()
  • For Convenience:
    • /dev/stdin, /dev/stdout, and /dev/stderr are symbolic links to /dev/fd/0, /dev/fd/1, and /dev/fd/2
Using <stdio> with File Descriptors
Back SMYC Forward
  • An Observation:
    • The C I/O library functions use a FILE* not a file descriptor
  • What We Need:
    • The ability to associate a FILE* (i.e., stream) with a file descriptor
Using <stdio>: fdopen() fdopen
Back SMYC Forward
FILE *fdopen(int fd, const char *mode)
Purpose:
Associate a FILE* (i.e., stream) with a valid file descriptor
Details:
fd The descriptor
mode "r", "w", "a", or "r+"/"w+" for read, write, append, read and write
Return A pointer to a stream or NULL
#include <stdio.h> stdio.h
There's Always More to Learn
Back -