Reputation: 135
Question: what is the signification of the 3rd argument of fcntl function WHEN is called with F_SETLK?
Well, checking the man page of fcntl I found that the third argument should be a pointer to a structure. I assume that the manual is refering to this case:
fcntl(fd, F_SETLK, *fl)
On a gogole search I found a lot of practical examples of using fcntl like this:
FCNTL(fd, F_SETLK, &fl)
I'm a bit confused about the correct answer for this.
Upvotes: 1
Views: 4973
Reputation: 229148
The man page doesn't mention fcntl(fd, F_SETLK, *fl)
, it has this to say, among other things.
The third argument, lock, is a pointer to a structure ...
F_SETLK (struct flock *) Acquire a lock (when l_type is F_RDLCK or F_WRLCK) or release a lock (when l_type is F_UNLCK) on the bytes specified by the l_whence, l_start, and l_len fields of lock. If a conflicting lock is held by another process, this call returns -1 and sets errno to EACCES or EAGAIN.
Now, the prototype for fcntl() is
int fcntl(int fd, int cmd, ... /* arg */ );
Which is a variable argument function. The command you pass in the 2. argument determines what you need to pass for the variable arguments.
This means that for the cmd
F_SETLK
you pass a pointer to a struct flock
as the 3. argument. If you have a struct flock fl
, you get a pointer to it by doing &fl
e.g.
struct flock fl;
int rc;
memset(&fl, 0, sizeof fl);
//acquire a read lock
fl.l_type = FL_RDLCK;
//for the entire file
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
rc = fcntl(my_fd, F_SETLK, &fl);
if (rc == -1) {
perror("fcntl");
//deal with error
}
Upvotes: 2
Reputation: 121397
The example you found has the correct usage:
FCNTL(fd, F_SETLK, &fl);
The flag F_SETLK
is to release an advisory lock (which was previously acquired) while the pointer fl
is a struct variable which would have declared like:
struct flock fl;
You are likely confused about what a pointer is when the manual says:
The third argument, lock, is a pointer to a structure that has at least the following [...]
If fl
was declared as: struct flock fl;
then &fl
yields a pointer and fnctl call would look like:
FCNTL(fd, F_SETLK, &fl);
If fl
was declared as:
struct flock *fl; // fl is a pointer to struct flock
fl = malloc( sizeof (struct flock) ); // allocate memory
then fl
is a pointer and fcntl call would look like:
FCNTL(fd, F_SETLK, fl);
You probably should to read more about more about pointers and understand them as that's the central issue in your question rather than fcntl.
Upvotes: 4
Reputation: 8861
According to the man page:
int fcntl(int fd, int cmd, ... /* arg */ );
...
fcntl() can take an optional third argument. Whether or not this argument is required is determined by cmd. The required argument type is indicated in parentheses after each cmd name (in most cases, the required type is int, and we identify the argument using the name arg), or void is specified if the argument is not required.
...
F_SETLK (struct flock *)
When cmd
is F_SETLK
, a third argument, which is a pointer to a flock
structure, is needed.
Upvotes: 2