Sunday, August 17, 2014

Unix Prog: File Sharing(2)

1. fcntl

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