Saturday, August 23, 2014

Unix Prog: Files -- Linking(1)

1. link

link command can create a new directory entry pointing to one existing entry's i-node.

definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/unistd.h  
 ......  
 /* Make a link to FROM named TO. */  
 extern int link (const char *__from, const char *__to)  
    __THROW __nonnull ((1, 2)) __wur;  
 ......  

lnfile.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
   
 int main(int argc, char* argv[])  
 {  
  if(link(argv[1], argv[2]) < 0 ) {  
   printf("link error!\n");  
   exit(1);  
  }  
   
  exit(0);  
 }  

shell:
1) List all files, including one directory testdir
2) link another path name testd2 to testdir, return error. So in current system, the current user can't make hard link to directory, which will cause infinite loop in file system.
3) Link lnfilebk.c to existing file lnfile.c, return ok. Actually it just add another directory entry(lnfilebk.c) at local directory which points to the same i-node of "lnfile.c"
4) List all files, we have another directory entry lnfilebk.c.
 ubuntu@ip-172-31-23-227:~$ ls -lrt  
 total 24  
 -rw-rw-r-- 1 ubuntu ubuntu  97 Aug 23 19:38 lnfile.c~  
 -rw-rw-r-- 1 ubuntu ubuntu 188 Aug 23 19:40 lnfile.c  
 -rwxrwxr-x 1 ubuntu ubuntu 9716 Aug 23 19:40 lntool.out  
 drwxrwxr-x 2 ubuntu ubuntu 4096 Aug 23 19:41 testdir  
 ubuntu@ip-172-31-23-227:~$ ./lntool.out testdir testd2  
 link error!  
 ubuntu@ip-172-31-23-227:~$ ./lntool.out lnfile.c lnfilebk.c  
 ubuntu@ip-172-31-23-227:~$ ls -lrt  
 total 28  
 -rw-rw-r-- 1 ubuntu ubuntu  97 Aug 23 19:38 lnfile.c~  
 -rw-rw-r-- 2 ubuntu ubuntu 188 Aug 23 19:40 lnfile.c  
 -rw-rw-r-- 2 ubuntu ubuntu 188 Aug 23 19:40 lnfilebk.c  
 -rwxrwxr-x 1 ubuntu ubuntu 9716 Aug 23 19:40 lntool.out  
 drwxrwxr-x 2 ubuntu ubuntu 4096 Aug 23 19:41 testdir  

2. unlink
unlink command remove the directory entry, and its correponding i-node link count will be decreased by 1.

definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/unistd.h  
 ......  
 /* Remove the link NAME. */  
 extern int unlink (const char *__name) __THROW __nonnull ((1));  
 ......  

ulfile.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<errno.h>  
   
 int main(int argc, char* argv[])  
 {  
  errno = 0;  
  if(unlink(argv[1]) < 0) {  
   printf("unlink error! errno: %d\n", errno);  
   exit(1);  
  }  
   
  exit(0);  
 }  

shell:
1) List all files
2) Make one hard link t2dir pointing to the i-node of testdir, but failed. In current system, current user can't make hard link of directory
3) Unlink the testdir, while trying to decrease the link count of testdir's inode, but failed. In current system, current user can't unlink directory.
4) Create file t1.
5) Make one hard link t2 pointing to the i-node of t1.
6) List files t1 and t2, they are same now, since both items pointing to the same i-node.
7) Unlink file t1, and t2.
8) List files t1, t2, but already gone.
 ubuntu@ip-172-31-23-227:~$ ls -lrt  
 total 44  
 -rw-rw-r-- 1 ubuntu ubuntu 188 Aug 23 19:40 lnfile.c~  
 drwxrwxr-x 2 ubuntu ubuntu 4096 Aug 23 19:41 testdir  
 -rw-rw-r-- 1 ubuntu ubuntu 182 Aug 23 20:06 ulfile.c~  
 -rw-rw-r-- 1 ubuntu ubuntu 230 Aug 23 20:08 ulfile.c  
 -rwxrwxr-x 1 ubuntu ubuntu 9782 Aug 23 20:09 ultool.out  
 -rw-rw-r-- 1 ubuntu ubuntu 235 Aug 23 20:18 lnfile.c  
 -rwxrwxr-x 1 ubuntu ubuntu 9780 Aug 23 20:18 lntool.out  
 ubuntu@ip-172-31-23-227:~$ ./lntool.out testdir t2dir  
 link error! errno=1  
 ubuntu@ip-172-31-23-227:~$ ./ultool.out testdir  
 unlink error! errno: 21  
 ubuntu@ip-172-31-23-227:~$ touch t1  
 ubuntu@ip-172-31-23-227:~$ ./lntool.out t1 t2  
 ubuntu@ip-172-31-23-227:~$ ls -lrt t1 t2  
 -rw-rw-r-- 2 ubuntu ubuntu 0 Aug 23 20:19 t2  
 -rw-rw-r-- 2 ubuntu ubuntu 0 Aug 23 20:19 t1  
 ubuntu@ip-172-31-23-227:~$ ./ultool.out t1  
 ubuntu@ip-172-31-23-227:~$ ./ultool.out t2  
 ubuntu@ip-172-31-23-227:~$ ls -lrt t1 t2  
 ls: cannot access t1: No such file or directory  
 ls: cannot access t2: No such file or directory  

Note:
In order to create(link) or delete(unlink) one directory entry, we need to have the write and execute permission on current directory.

If current directory's sticky bit is on, then user need to meet one of 3 requirements:
1) own the file to be created or removed
2) own the directory
3) super user.

No comments:

Post a Comment