fcntl can change the properties of a file that is already open.
definition:
ubuntu@ip-172-31-23-227:~$ less /usr/include/fcntl.h
......
/* Do the file control operation described by CMD on FD.
The remaining arguments are interpreted depending on CMD.
This function is a cancellation point and therefore not marked with
__THROW. */
extern int fcntl (int __fd, int __cmd, ...);
......
1) F_DUPFD:
duplicate the file descriptor, with this command, it will return the lowest numbered file descriptor who is not open yet, and is greater or equal to the 3rd argument.
fileio.c:
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
int main()
{
char buff[] = "Hello world!";
int fd1, fd2;
if((fd1 = open("test.txt", O_RDWR)) == -1) {
printf("open error!\n");
exit(1);
}
// duplicate the file descriptor, which is at least as fd1+1
if((fd2 = fcntl(fd1, F_DUPFD, fd1+1)) == -1) {
printf("fcntl error!\n");
exit(2);
}
printf("fd1: %d fd2: %d\n", fd1, fd2);
// right now fd1 and fd2 should point to the same file table entry
if(write(fd1, buff, 12) != 12) {
printf("write error!\n");
exit(3);
}
if(write(fd2, buff, 12) != 12) {
printf("write error!\n");
exit(3);
}
close(fd1);
close(fd2);
exit(0);
}
shell:
fcntl returns 4 as the new file descriptor, and following two write operations act against the same file.
ubuntu@ip-172-31-23-227:~$ cat test.txt
amazing world!
ubuntu@ip-172-31-23-227:~$ ./io.out
fd1: 3 fd2: 4
ubuntu@ip-172-31-23-227:~$ cat test.txt
Hello world!Hello world!
2) F_GETFD, F_SETFD
F_GETFD, F_SETFD commands are used to set up the file description flags.
In unix, only one flag is defined: FD_CLOEXEC, meaning the file descriptor will be closed when running the "exec".
shell:
FD_CLOEXEC is defined to be 1 at current system.
ubuntu@ip-172-31-23-227:~$ sudo find /usr/include -name *.h | xargs grep "#define FD_CLOEXEC"
/usr/include/asm-generic/fcntl.h:#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
fileio.c:
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
int main()
{
char buff[] = "Hello world!";
int fd, flag;
// open the file, return the file descriptor
if((fd = open("test.txt", O_RDWR)) == -1) {
printf("open error!\n");
exit(1);
}
// get the file description flag
if((flag = fcntl(fd, F_GETFD)) == -1) {
printf("fcntl error!\n");
exit(2);
}
printf("fd: %d, flag: %d\n", fd, flag);
// turn on the FD_CLOEXEC flag
flag |= FD_CLOEXEC;
// Setup the flag
if(fcntl(fd, F_SETFD, flag) == -1) {
printf("fcntl error!\n");
exit(3);
}
// get the file flag again to see if it is already set
flag = fcntl(fd, F_GETFD);
printf("flag: %d\n", flag);
close(fd);
exit(0);
}
shell:
1) After getting the file description flag, it is 0, after setting up the flag, it becomes 1
2) Run the program again to retrieve the description flag, but it is still 0, so file description flag always ends in memory based on this research, it never goes to disk.
ubuntu@ip-172-31-23-227:~$ ./io.out
fd: 3, flag: 0
flag: 1
ubuntu@ip-172-31-23-227:~$ ./io.out
fd: 3, flag: 0
flag: 1
No comments:
Post a Comment