CMPSC
311,
Introduction to Systems Programming
Files, Directories and I/O
Reading
- CP:AMA
- Ch. 3
, scanf, printf
- pp. 14-15, 19-20, 22, 130-131, 134, 139-141
, scanf,
printf, getchar, putchar
- Sec. 13.3
, scanf, printf,
gets, puts
- p. 504, second Q&A,
FILE
- Ch. 21, The Standard Library
- Sec. 21.1, Using the Library,
getchar
- Sec. 21.4, The
<stddef.h> Header:
Common
Definitions
- Ch. 22, Input/Output
- CS:APP
- Ch. 10, System-Level I/O, esp. Sec. 1, 2, 3, 5
- APUE, Chapters 3, 4, 5
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:
- fully buffered
--
writes wait until the buffer is full; reads fill
the buffer completely, or up to end-of-file
- line buffered
--
writes wait until a newline character is
encountered; reads fill the buffer up to the next newline
character, or
up to end-of-file
- unbuffered --
writes and reads are done as soon as possible
- Use
fflush() to force the buffer contents to be
written.
Questions
- Does the
ungetc() function write to a
file?
If not, does it write to a buffer?
- When
read() fails, it returns -1 and errno
explains the problem. When read() encounters
end-of-file, it returns 0. When fgetc()
fails, it
returns EOF, which is a macro defined as -1, and feof()
or ferror() must be called to distinguish
end-of-file
from error (and then errno explains the
problem).
Why does fgetc() not return 0 for end-of-file?
- Why must you never use
gets()?
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:
- The
rmdir() function is used to delete a
directory.
This function should
(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
- When you are writing a program that reads a file and writes a
file, which part of the program should you write first?
Why?
Exercise
- Here is the
read_line() function from CP:AMA, p.
287. What is wrong with the design of this function?
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