I use fcntl()
for file capture and then I call execlp()
to open file by nano. I run the program here and in another session. Process from new session also open the file by nano, but it should be waiting for unlock. Effect is same for mandatory and advisory lock.
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#define editor "nano"
int main(int argc, char *argv[]) {
struct flock lock;
int fd;
if ((fd = open(argv[1], O_RDWR)) == -1) {
perror("Cannot open file");
exit(EXIT_FAILURE);
}
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
if (fcntl(fd, F_SETLKW, &lock) == -1) {
perror("fcntl failed");
exit(EXIT_FAILURE);
}
execlp(editor, editor, argv[1], NULL);
perror("exec is not working");
exit(EXIT_FAILURE);
}
Man: The new process also inherits the following attributes from the calling process: ... file-locks (see fcntl(2) and lockf(3C))
How is it possible?
Per the Solaris 10 fcntl()
man page:
All locks associated with a file for a given process are removed when a file descriptor for that file is closed by that process
Running the command truss -f -a -vall -l -d -o tout nano test.c
produces the following lines in the truss output:
Base time stamp: 1527722170.2660 [ Wed May 30 19:16:10 EDT 2018 ]
6621/1: 0.0000 execve("/usr/bin/nano", 0xFEFFEADC, 0xFEFFEAE8) argc = 2
6621/1: argv: nano test.c
...
6621/1: 0.0417 open64("/home/achenle/junk/test.c", O_RDONLY) = 3
6621/1: 0.0418 fcntl(3, F_GETFD, 0xFEFFEA98) = 0
6621/1: 0.0422 fstat64(3, 0xFEFFE6A0) = 0
6621/1: d=0x045D0009 i=418292 m=0100644 l=1 u=1000 g=100 sz=708
6621/1: at = May 30 19:09:05 EDT 2018 [ 1527721745.204432507 ]
6621/1: mt = May 30 19:04:25 EDT 2018 [ 1527721465.715445770 ]
6621/1: ct = May 30 19:04:25 EDT 2018 [ 1527721465.833365263 ]
6621/1: bsz=1024 blks=3 fs=lofs
6621/1: 0.0424 fstat64(3, 0xFEFFE5B0) = 0
6621/1: d=0x045D0009 i=418292 m=0100644 l=1 u=1000 g=100 sz=708
6621/1: at = May 30 19:09:05 EDT 2018 [ 1527721745.204432507 ]
6621/1: mt = May 30 19:04:25 EDT 2018 [ 1527721465.715445770 ]
6621/1: ct = May 30 19:04:25 EDT 2018 [ 1527721465.833365263 ]
6621/1: bsz=1024 blks=3 fs=lofs
6621/1: 0.0425 ioctl(3, TCGETA, 0xFEFFE650) Err#25 ENOTTY
6621/1: 0.0426 read(3, " # i n c l u d e < s y".., 1024) = 708
6621/1: 0.0428 read(3, 0x0814D794, 1024) = 0
6621/1: 0.0428 llseek(3, 0, SEEK_CUR) = 708
6621/1: 0.0429 close(3) = 0
That final close(3)
releases all locks on the file. And note that it happens less than 5/100 of a second after nano
starts.