check_mandatory_lock.c
unknown
c_cpp
3 years ago
1.8 kB
7
Indexable
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/wait.h> int write_lock(int fd, int offset, short offset_type, int len) { struct flock fl; fl.l_type = F_WRLCK; fl.l_len = len; fl.l_start = offset; fl.l_whence = offset_type; return fcntl(fd, F_SETLK, &fl); } int main(int argc, char *argv[]) { int fd; pid_t pid; char buf[6]; struct stat statbuf; if (argc != 2) { fprintf(stderr, "usage: %s filename\n", argv[0]); exit(1); } if ((fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC)) < 0) perror("open error"); if (write(fd, "abcdef", 6) != 6) perror("write error"); /* turn on set-group-ID and turn off group-execute */ if (fstat(fd, &statbuf) < 0) perror("fstat error"); if (fchmod(fd, (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < 0) perror("fchmod error"); if ((pid = fork()) < 0) { perror("fork error"); } else if (pid > 0) { /* parent */ /* write lock entire file */ if (write_lock(fd, 0, SEEK_SET, 0) < 0) perror("write_lock error"); if (waitpid(pid, NULL, 0) < 0) perror("waitpid error"); } else { /* child */ int flg; fcntl(fd, F_GETFL, &flg); fcntl(fd, F_SETFL, flg | O_NONBLOCK); // to show EAGAIN error /* now try to read the mandatory locked file */ if (lseek(fd, 0, SEEK_SET) == -1) perror("lseek error"); if (read(fd, buf, 6) < 0) perror("read failed (mandatory locking works)"); else printf("read OK (no mandatory locking), buf = %2.2s\n", buf); sleep(5); // you can lslocks here. } }
Editor is loading...