home *** CD-ROM | disk | FTP | other *** search
- #include <fcntl.h>
- #include <stdio.h>
- #include <errno.h>
- #include <signal.h>
-
- char *progname;
-
- Usage() {
- fprintf(stderr, "Usage: %s [-rw] <filename>\n", progname);
- exit(1);
- /* NOTREACHED */
- }
-
-
- int child_pid;
- int child_status;
-
- main(int argc, char **argv) {
- int fd;
- int opt;
- int pipe_fds[2];
- static struct flock lck = {
- 0,
- 0,
- 0,
- 0,
- };
- extern int optind, opterr;
-
- progname = argv[0];
-
- opterr = 0;
- while ((opt = getopt(argc, argv, "rw")) != -1) {
- switch (opt) {
- case 'r':
- case 'w':
- if (lck.l_type != 0) {
- fprintf(stderr, "%s: Only one lock type may be specified\n", progname);
- exit(1);
- }
- lck.l_type = (opt == 'r') ? F_RDLCK : F_WRLCK;
- break;
-
- case '?':
- Usage();
- /* NOTREACHED */
- } /* switch */
- } /* while */
-
- if (lck.l_type == 0) {
- /* default is exclusive */
- lck.l_type = F_WRLCK;
- }
-
- if (argc - optind > 1) {
- Usage();
- }
-
- if (pipe(pipe_fds) == -1) {
- perror("pipe");
- exit(errno);
- }
-
- switch (child_pid = fork()) {
- case 0:
- /* The child */
- fclose(stdin);
- fclose(stdout);
- fclose(stderr);
- close(pipe_fds[0]);
- if ((fd = open(argv[optind], 2)) == -1) {
- child_status = errno;
- write(pipe_fds[1], &errno, sizeof(errno));
- exit(child_status);
- }
- if (fcntl(fd, F_SETLK, &lck) != 0) {
- child_status = errno;
- write(pipe_fds[1], &errno, sizeof(errno));
- exit(child_status);
- }
- errno = 0;
- write(pipe_fds[1], &errno, sizeof(errno));
- close(pipe_fds[1]);
- pause();
- /*
- * The only way for pause to return is on an signal, but we
- * don't do anything with signals, so it will just die.
- * The file will be closed on exit, and the lock will
- * disappear.
- */
- /* NOTREACHED */
-
- case -1:
- /* fork failed */
- perror("fork");
- exit(errno);
- /* NOTREACHED */
-
- default:
- /* The Parent */
- close(pipe_fds[1]);
- read(pipe_fds[0], &child_status, sizeof(child_status));
- if (child_status == 0)
- printf("%d\n", child_pid);
- else {
- errno = child_status;
- perror("flock");
- }
- } /* switch */
-
- exit(child_status);
- /* NOTREACHED */
- }
-