CMPSC 311, Introduction to Systems Programming

Files, Directories and I/O



Reading





File I/O
unbuffered
buffered
Which standard defines these functions? Posix C, Posix
Which include files do you need?
<fcntl.h>
<unistd.h>
<stdio.h>
How do you refer to an open file? file descriptor
type int
file pointer
type FILE *
How do you open a file?
open
fopen, freopen
How do you close a file?
close
fclose
How do you read from an open file?
read
fgetc, getc, getchar
fgets, gets
fread
fscanf, scanf
How do you write to an open file?
write
fputc, putc, putchar
fputs, puts
fwrite
fprintf, printf
Where do read and write operations start?
at the current file offset
at the current stream position
How do you move to another position in an open file (without changing the file)?
lseek
fseek, ftell
fgetpos, fsetpos
rewind
Additional types, values, functions
size_t
fpos_t
NULL, EOF
ungetc
feof, ferror
clearerr
fflush
tmpfile, tmpnam
setbuf, setvbuf
remove, rename

Note that the C Standard I/O library refers to "streams", not "open files", since a stream need not be connected to an actual file.

A file opened with open() can be associated with a stream by calling fdopen(), and the net effect is as if fopen() had been used.  A file opened with fopen() can obtain its file descriptor using fileno().

The Standard I/O library uses three types of buffering:
Questions
Excerpts from the Mac OS X man page,

#include <stdio.h>

char *fgets(char *restrict s, int n, FILE *restrict stream);
char *gets(char *s);

The gets() function is equivalent to fgets() with an infinite n and a stream of stdin, except that the newline character (if any) is not stored in the string.  It is the caller's responsibility to ensure that the input line, if any, is sufficiently short to fit in the string.

SECURITY CONSIDERATIONS
The gets() function cannot be used securely.  Because of its lack of bounds checking, and the inability for the calling program to reliably determine the length of the next incoming line, the use of this function enables malicious users to arbitrarily change a running program's functionality through a buffer overflow attack.  It is strongly suggested that the fgets() function be used in all cases.


Directory I/O

Which standard defines these functions? Posix
Which include files do you need? <dirent.h>
How do you refer to an open directory?
DIR *
What data structure describes a directory entry?
struct dirent
How do you open a directory?
opendir
How do you close an open directory?
closedir
How do you read from an open directory?
readdir
How do you write to an open directory?
see below
How do you create a new directory?
mkdir
<sys/stat.h>
How do you delete a directory?
rmdir
<unistd.h>

Writing to a directory is a side effect of creating a new file.

Note that the C standard does not define any operations on directories.

See APUE Fig. 1.3 for a simple example.  (Intro to Unix notes)


File information

Which standard defines these functions? Posix
Which include files do you need? <sys/stat.h>
<unistd.h>
<utime.h>
What data structure describes properties of a file system entry? struct stat
How do you discover properties of a file system entry?
stat
If the file could be a symbolic link, and if you would then want information about the link and not what it points to,
lstat
How do you discover properties of an open file?
fstat
How can you tell if a file exists, and what permissions are associated with it?
access
How can you change the permissions associated with a file?
chmod, fchmod
To limit the default permissions for new files,
umask
How can you change the owner of a file?
chown
fchown
lchown
How can you change the times associated with a file?
utime

The header <sys/stat.h> defines some macros to determine file types from the struct stat entries.  See CS:APP, p. 874, for some examples.

Multiple choice:
(1)  fail if the directory does not exist.
(2)  fail if the directory is not empty.
(3)  fail if the directory is not empty (except for the . and .. entries).
(4)  always succeed.

Exercise
Exercise
int read_line(char str[], int n)
{
  int ch, i = 0;

  while ((ch = getchar()) != '\n')
    if (i < n)
      str[i++] = ch;
 
  str[i] = '\0';  // terminate the string
  return i;       // number of characters stored
}



Last revised, 18 Feb. 2013