Tom Kelliher, CS43
Mar. 26, 1996
We will finish up the material from last time, then move into this.
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *path, int flags, mode_t mode);
Used to open a file for reading, writing, appending, etc.
Returns a file descriptor (small positive integer). Returns -1 on error.
path: Path to file to open.
flags: What is to be done by the open. Multiple flags are
specified by bit or'ing (|):
O_RDONLY --- Open for reading only.
O_WRONLY --- Open for writing only.
O_CREAT --- Create file if it does not exist.
O_TRUNC --- Truncate size to 0.
mode: Permissions with which to create a file. Used only when creating a file on an open for write. Multiple modes are specified by bit or'ing:
S_IRUSR --- Read for owner.
S_IWUSR --- Write for owner.
S_IRGRP --- Read for group.
S_IROTH --- Read for other.
Typical read call:
int rfd;
if ((rfd = open(argv[1], O_RDONLY, 0)) < 0)
pdie("Open failed");
Typical write call:
int wfd;
if ((wfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0)
pdie("Open failed");
/**********************************************************************
* fileio.c
* Tom Kelliher
*
* This program demonstrates how to do low-level file I/O in C. This
* program implements a simple version of Unix's cp command. Two
* filename are expected on the command line. The first file is the
* name of the file to be copied, the second is the file to be created.
**********************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/* Prototypes. */
void pdie(const char *);
void die(const char *);
#define BUFFER_SIZE 1024 /* Size of the read/write buffer. */
/**********************************************************************
* main
**********************************************************************/
int main(int argc, char* argv[])
{
int rfd; /* Read file descriptor. */
int wfd; /* Write file descriptor. */
char buffer[BUFFER_SIZE]; /* Read/Write buffer. */
char *bp; /* Pointer into write buffer. */
int bufferChars; /* Number of bytes remaining to be written. */
int writtenChars; /* Number of bytes written on last write. */
if (argc != 3)
{
printf("Two filenames expected.\n");
exit(1);
}
/* Open file to be copied. */
if ((rfd = open(argv[1], O_RDONLY, 0)) < 0)
pdie("Open failed");
/* Open file to be created. */
if ((wfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0)
pdie("Open failed");
while (1)
{
/* Normal case --- some number of bytes read. */
if ((bufferChars = read(rfd, buffer, BUFFER_SIZE)) > 0)
{
bp = buffer; /* Pointer to next byte to write. */
/*
Since we can't guarantee that all the bytes will be written
in a single write(), this code must be written such that
several write()'s can possibly be called.
*/
while (bufferChars > 0)
{
if ((writtenChars = write(wfd, bp, bufferChars)) < 0)
pdie("Write failed");
bufferChars -= writtenChars; /* Update. */
bp += writtenChars;
}
}
else if (bufferChars == 0) /* EOF reached. */
break;
else /* bufferChars < 0 --- read failure. */
pdie("Read failed");
}
close(rfd);
close(wfd);
return 0;
}
/**********************************************************************
* pdie --- Print error message, call perror, and die.
**********************************************************************/
void pdie(const char *mesg) {
perror(mesg);
exit(1);
}
/**********************************************************************
* die --- Print error message and die.
**********************************************************************/
void die(const char *mesg) {
fputs(mesg, stderr);
fputc('\n', stderr);
exit(1);
}