I can't figure out why my fcntl keeps saying "Invalid argument". Please, help. If I understand it correctly I should fill my flock (the one that I pass to fcntl) with data that points to a byte I want to check.
int byteno;
printf(ANSI_COLOR_BLUE "Insert byte number: " ANSI_COLOR_RESET);
scanf("%d\n", &byteno);
struct flock* fl = malloc(sizeof(flock));
fl -> l_type = F_GETLK;
fl -> l_whence = SEEK_SET;
fl -> l_start = byteno;
fl -> l_len = 1;
fl -> l_pid = getpid();
if(fcntl(descr, F_GETLK, fl) == -1){
perror(ANSI_COLOR_RED "Error while getting info about locks" ANSI_COLOR_RESET);
free(fl);
continue;
}
if(!(fl -> l_type == F_UNLCK)){
printf(ANSI_COLOR_YELLOW "Other proccess has a lock here. PID = %d" ANSI_COLOR_RESET, fl -> l_pid);
continue;
}
F_GETLK (struct flock *)
On input to this call, lock describes a lock we would like to place on the file. If the lock could be placed, fcntl() does not actually place it, but returns F_UNLCK in the l_type field of lock and leaves the other fields of the structure unchanged. If one or more incompatible locks would prevent this lock being placed, then fcntl() returns details about one of these locks in the l_type, l_whence, l_start, and l_len fields of lock and sets l_pid to be the PID of the process holding that lock.
F_GETLK
is not used to get information about a lock, but rather to 'test whether applying the specified lock would work'.
Try the following example. Run it twice within the 5 second window.
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
void main(void) {
int fd;
struct flock fl_info;
int ret;
fd = open("./test.txt", O_RDWR | O_CREAT, 0600);
if (fd == -1) {
perror("open()");
return;
}
memset(&fl_info, 0, sizeof(fl_info));
/* try to get a WRITE lock on the entire file (l_len == zero) */
fl_info.l_type = F_WRLCK;
fl_info.l_whence = SEEK_SET;
fl_info.l_start = 0;
fl_info.l_len = 0;
ret = fcntl(fd, F_GETLK, &fl_info);
if (ret == -1) {
perror("fcntl(F_GETLK)");
return;
}
if (fl_info.l_type != F_UNLCK) {
printf("Too bad... it's already locked... by pid=%d\n", fl_info.l_pid);
return;
}
/* try to apply a write lock */
fl_info.l_type = F_WRLCK;
ret = fcntl(fd, F_SETLK, &fl_info);
if (ret == -1) {
perror("fcntl(F_SETLK)");
return;
}
printf("Success!\n");
sleep(5);
printf("I'm done, bye!\n")
return;
}
Note also that it is not necessary to malloc()
storage for the struct flock
.