Linux programming files and I/O (6): fcntl functions and file locks

Source: Internet
Author: User
Tags flock flock lock

I. fcntl Functions

Function: manipulate the file descriptor to change the attributes of an opened file.

Int fcntl (int fd, int cmd,.../* Arg */);


The cmd value can be as follows:

Copy file descriptor
F_dupfd (long)


Set/Get file descriptor flag
F_getfd (void)
F_setfd (long)


Set/retrieve File status flag
F_getfl (void)
F_setfl (long)


GET/set file lock
F_getlk
F_setlk, f_setlkw


For details about copying file descriptors, see Linux system programming files and I/O (5): Opening file kernel structure file and redirection. The file descriptor has only one identifier, namely, fd_cloexec, set/obtain the file descriptor flag and wait until the process is learned. Next let's take a look at setting/getting the File status flag.

F_setfl:

On Linux this command can change only the o_append, o_async, o_direct, o_noatime, and o_nonblock flags.

The example program is as follows:

 

C ++ code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

  /*************************************** **********************************
> File name: file_fcntl.c
> Author: Simba
> Mail: dameng34@163.com
> Created time: sat 23 Feb 2013 02:34:02 pm CST
**************************************** ********************************/

# Include <sys/types. h>

# Include <sys/STAT. h>

# Include <unistd. h>

# Include <fcntl. h>

# Include <stdio. h>

# Include <stdlib. h>

# Include <errno. h>

# Include <string. h>

# Define err_exit (m )\


Do {\

Perror (m );\

Exit (exit_failure );\

}
While (
0)

Void set_flag (
Int,
INT );

Void clr_flag (
Int,
INT );

Int main (
Int argc,
Char * argv [])

{


Char Buf [
1024] = {
0 };


Int ret;


/*
Int flags;
Flags = fcntl (0, f_getfl, 0 );
If (flags =-1)
Err_exit ("fcntl get flag error ");
Ret = fcntl (0, setfl, flags | o_nonblock); // set to non-blocking, but do not change other statuses
If (ret =-1)
Err_exit ("fcntl set flag error ");
*/

Set_flag (
0, o_nonblock );

Ret = read (
0, Buf,
1024 );


If (ret =-
1)

Err_exit (
"Read error ");

Printf (
"Buf = % s \ n", Buf );


Return
0;

}

Void set_flag (
Int FD,
Int flags)

{


Int val;

Val = fcntl (FD, f_getfl,
0 );


If (val =-
1)

Err_exit (
"Fcntl get flag error ");

Val | = flags;


If (fcntl (FD, f_setfl, Val) <
0)

Err_exit (
"Fcntl set flag error ");

}

Void clr_flag (
Int FD,
Int flags)

{


Int val;

Val = fcntl (FD, f_getfl,
0 );


If (val =-
1)

Err_exit (
"Fcntl get flag error ");

Val & = ~ Flags;


If (fcntl (FD, f_setfl, Val) <
0)

Err_exit (
"Fcntl set flag error ");

}

Test output:

 

Simba @ Ubuntu :~ /Documents/code/linux_programming/apue/file_io $./file_fcntl
Read error: Resource temporarily unavailable

Because the status of the standard input is changed to non-blocking, the read will not block the request and an error will be returned immediately while the errno will be set to eagain, that is, you can try again.

Ii. File Lock Structure

Struct flock {
...
Short l_type;/* type of lock: f_rdlck,
F_wrlck, f_unlck */
Short l_whence;/* how to interpret l_start:
Seek_set, seek_cur, seek_end */
Off_t l_start;/* Starting offset for Lock */
Off_t l_len;/* number of bytes to lock */
Pid_t l_pid;/* PID of process blocking our lock
(F_getlk only )*/
...
};

There are only two types of File locks. One is a write lock or exclusive lock, and the other is a shared lock. Multiple processes can each hold one read lock, but only one process can hold the write lock, the corresponding lock type can be applied only when the file has the corresponding read/write permissions. The three parameters l_whence, l_start, and l_len determine the scope of the locked file. When the cmd of the fcntl function is f_getlk, The l_pid parameter of the flock struct returns the ID of the Process holding a certain type of lock. When a process exits or the file descriptor is disabled, all locks are released.


The example program is as follows:

 

C ++ code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

  /*************************************** **********************************
> File name: file_flock.c
> Author: Simba
> Mail: dameng34@163.com
> Created time: sat 23 Feb 2013 02:34:02 pm CST
**************************************** ********************************/

# Include <sys/types. h>

# Include <sys/STAT. h>

# Include <unistd. h>

# Include <fcntl. h>

# Include <stdio. h>

# Include <stdlib. h>

# Include <errno. h>

# Include <string. h>

# Define err_exit (m )\


Do {\

Perror (m );\

Exit (exit_failure );\

}
While (
0)

Int main (
Int argc,
Char * argv [])

{


Int FD;

FD = open (
"Test2.txt", o_creat | o_rdwr | o_trunc,
0664 );


If (FD =-
1)

Err_exit (
"Open error ");


/* The corresponding file lock can be applied only when the file has the corresponding read and write permissions */


Struct flock lock;

Memset (& lock,
0,
Sizeof (LOCK ));

Lock. l_type = f_wrlck;
// Exclusive lock, that is, other processes are not allowed to add any type of lock to it, but read lock (shared lock) is allowed.
Lock. l_whence = seek_set;

Lock. l_start =
0;
// Start from the beginning of the file
Lock. l_len =
0;
// Lock all file content



If (fcntl (FD, f_setlk, & lock) =
0)

{


/* If f_setlkw is used by another process, the process will be blocked until other processes release the lock */

Printf (
"Lock success \ n ");

Printf (
"Press any key to unlock \ n ");

Getchar ();

Lock. l_type = f_unlck;


If (fcntl (FD, f_setlk, & lock) =
0)

Printf (
"Unlock success \ n ");


Else

Err_exit (
"Unlock fail ");

}


Else

Err_exit (
"Lock fail ");


Return
0;
// Process exit will unlock all files
}

 

 

The test is as follows:

We first run the program on a terminal:

Simba @ Ubuntu :~ /Documents/code/linux_programming/apue/file_io $./file_flock
Lock success
Press any key to unlock


Now the file has been locked and no buttons have been pressed, so it has not been unlocked and the same program is executed again on another terminal:

Simba @ Ubuntu :~ /Documents/code/linux_programming/apue/file_io $./file_flock
Lock fail: Resource temporarily unavailable

An error will be returned immediately because we want to apply an exclusive lock, and the previous process is occupying the write lock and has not been released, so the attempt to apply the lock fails, if the cmd of the fcntl function is set to f_setlkw, that is, the version with W, the process will be blocked until the previous process releases the lock.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.