books/apitue/sample-code/06/forkseek.c

95 lines
2.1 KiB
C

/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/* This program illustrates that after fork(2), the
* child has a copy of the file descriptors from the
* parent pointing to the same file table entries,
* meaning operations on the fd in one affect the
* other. */
#include <sys/wait.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define NUM 32
void
readData(int fd) {
int n;
char buf[NUM];
off_t offset;
if ((offset = lseek(fd, 0, SEEK_CUR)) < 0) {
err(EXIT_FAILURE, "%d lseek error", getpid());
/* NOTREACHED */
}
(void)printf("%d offset is now: %ld\n", getpid(), offset);
if ((n = read(fd, buf, NUM)) < 0) {
err(EXIT_FAILURE, "PID %d: read error", getpid());
/* NOTREACHED */
}
/* We don't do anything with the data; we just
* wanted to illustrate that reading will
* advance the offset. */
}
int
main(int argc, char **argv) {
int fd;
pid_t pid;
if (argc != 2) {
fprintf(stderr, "Usage: %s file\n", argv[0]);
exit(EXIT_FAILURE);
}
if ((fd = open(argv[1], O_RDONLY)) < 0) {
err(EXIT_FAILURE, "open error");
/* NOTREACHED */
}
(void)printf("Starting pid is: %d\n", getpid());
readData(fd);
if ((pid = fork()) < 0) {
err(EXIT_FAILURE, "fork error");
/* NOTREACHED */
} else if (pid == 0) {
if (lseek(fd, NUM, SEEK_CUR) < 0) {
err(EXIT_FAILURE, "child lseek error");
/* NOTREACHED */
}
(void)printf("child %d done seeking\n", getpid());
/* give the parent a chance to read */
sleep(2);
readData(fd);
} else {
/* give the child a chance to lseek */
sleep(1);
readData(fd);
}
(void)wait(NULL);
(void)close(fd);
return EXIT_SUCCESS;
}