COP4610: Operating Systems & Concurrent Programming up ↑

Unix File Concepts

 

File Descriptors, Open File Descriptions, Streams

What are the differences between the following, and how do they relate to one another?

Diagram of File Descriptors, Open File Descriptions, Streams

*

This diagram shows the relationships of file descriptors, streams, buffers, open file descriptions, and files.

Pay special attention to the many-one relationships.

Stream

Streams provide buffered I/O support. They are built on top of the lower-level abstractions of open file descriptor and open file description.

The fdopen operation takes a file descriptor and access mode information, creates a stream, and returns a pointer to the stream object. The fclose operation deallocates the stream object.

Stream Example

abstracted from simple_fork.c

FILE *outstream;
...
if (!(outstream = fdopen (outfildes, "w"))) {
  perror ("could not open stream for writing");  exit (-1);
}
  ...
fprintf (outstream, "some text\n");

Read the entire example program.

File Descriptor

File Descriptor Example

abstracted from hw1.c

int fd;
fd = open ("my_file", O_RDONLY, 0);
if (fd == -1) {
  perror ("open failed\n"); exit (-1);
}       
close (0);
if (dup2 (fd, 0) < 0) {
  perror ("dup2 failed"); exit(-1);
}
close (fd);

The dup2() call acts like an assignment statement for file descriptors. It make file descriptor 0 (stdin) refer to the same open file description as fd. We can then close fd, so that only 0 refers to the open file.

Read the entire example program.

Open File Description

The above are just summaries. See the Unix man-pages for complete descriptions of the effects of open, close, fdopen, and fclose.

The reference from the open file description to the actual file data is also indirect, through operating system data structures we will study later.

Directories, Filenames, Pathnames, Files

*

The diagram shows the relationships of directories, filenames, pathnames, and files.

Again pay attention to which relationships are one-one and which are many-one.

Regular Unix File

Unix Directory

Unix files do not have names. Only links (in directories) have names.

Shell command ln makes direct and indirect links. The form "ln -s" is used to create symbolic links.

Shell command rm removes links.

The corresponcding system calls (C API) are link() and unlink().

See the Unix man pages for more detail on each of these system calls.

Pipe

Read the entire example program.

Pipe Example

abstracted from hmwk1.c

int pipefd[2];
...
if (pipe (pipefd) == -1) {perror ("could not create pipe"); exit (-1);}
child = fork();
if (child != 0) {
  close (pipefd[0]);  /* the reading end of the pipe */
  if (write (pipefd[1], &outbuf, sizeof(outbuf)) == -1)
    perror ("write to pipe failed"); exit -1;
  }
  ...
  close (pipefd[1]);
} else {
  close (pipefd[1]);
  if ((nread = read (pipefd[0], &buffer, count)) == -1) {
    perror ("read failed"); exit (-1);
  }
  ...
  close (pipefd[0]);
}

The parent process creates the pipe, and then forks. The parent closes one end of the pipe. The child closes the other. The parent writes to the pipe, and the child reads from it.

This example uses of the unbuffered I/O operations, read() and write(), just for variety. A stream could be associated with either or both of the file descriptors, allowing use of the stream input and output functions. In program hmk1.c, the child process used dup2() to map the input side of the pipe to stdin, before executing a new program.

Read the entire example program.

Unix Special Files

T. P. Baker. ($Id)