首页 > 代码库 > Unix/Linux文件类型及访问权限

Unix/Linux文件类型及访问权限

在Linux系统中,有7种文件类型。

  1. 普通文件 (regular file)
  2. 目录文件 (directory)
  3. 链接文件 (symbolic link)
  4. 管道文件 (FIFO)
  5. 套接字文件 (socket)
  6. 字符设备文件 (character device)
  7. 块设备文件    (block device)

在Solaris上,还有一种文件类型, 叫做door文件。

而一个文件的Unix访问权限,包括12位,通常用4个8进制位表示,

标志 八进制值 含义
S_ISUID 04000 set user ID on execution
S_ISGID 02000 set group ID on execution
S_ISVTX 01000 sticky bit
S_IWUSR 00400 owner has read permission
S_IRUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IWGRP 00040 group has read permission
S_IRGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IWOTH 00004 others have read permission
S_IGOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission

 

最后,给出一个文件类型及权限位识别的C代码实现。

  1 /*
  2  * foo.c - get Unix/Linux file type and its access,
  3  *         mostly simliar to what GNU stat does
  4  */
  5 
  6 #include <stdio.h>
  7 #include <string.h>
  8 #include <sys/types.h>
  9 #include <sys/stat.h>
 10 #include <unistd.h>
 11 #include <errno.h>
 12 
 13 int
 14 main(int argc, char *argv[])
 15 {
 16     char        *filepath = NULL;
 17     char        *filetype = NULL;
 18     char        s[] = "----------";
 19     int        rc;
 20     struct stat    sb;
 21 
 22     if (argc != 2) {
 23         (void) fprintf(stderr, "Usage %s <file>\n", argv[0]);
 24         return (-1);
 25     }
 26 
 27     filepath = argv[1];
 28 
 29     (void) memset(&sb, 0, sizeof (struct stat));
 30 
 31     errno = 0;
 32     /* NOTE: don‘t use stat() as we will get symbolic link file type */
 33     if ((rc = lstat(filepath, &sb)) != 0) {
 34         (void) fprintf(stderr, "%s: cannot stat `%s‘: %s\n",
 35             argv[0], filepath, strerror(errno));
 36         return (-1);
 37     }
 38 
 39     /* get file type */
 40     if (S_ISREG(sb.st_mode)) {
 41         s[0] = -;
 42         filetype = "regular file";
 43     }
 44     if (S_ISDIR(sb.st_mode)) {
 45         s[0] = d;
 46         filetype = "directory";
 47     }
 48     if (S_ISCHR(sb.st_mode)) {
 49         s[0] = c;
 50         filetype = "character special file";
 51     }
 52     if (S_ISBLK(sb.st_mode)) {
 53         s[0] = b;
 54         filetype = "block special file";
 55     }
 56     if (S_ISFIFO(sb.st_mode)) {
 57         s[0] = p;
 58         filetype = "fifo";
 59     }
 60     if (S_ISLNK(sb.st_mode)) {
 61         s[0] = l;
 62         filetype = "symbolic link";
 63     }
 64     if (S_ISSOCK(sb.st_mode)) {
 65         s[0] = s;
 66         filetype = "socket";
 67     }
 68 #ifdef __sunos
 69     if (S_ISDOOR(sb.st_mode)) {
 70         s[0] = D;
 71         filetype = "door";
 72     }
 73 #endif
 74 
 75     /* parse set UID, set-group-ID, sticky bit */
 76     if (sb.st_mode & S_ISUID)
 77         s[3] = S;
 78     if (sb.st_mode & S_ISGID)
 79         s[6] = S;
 80     if (sb.st_mode & S_ISVTX)
 81         s[9] = T;
 82 
 83     /* parse owner rwx bit */
 84     if (sb.st_mode & S_IRUSR)
 85         s[1] =r;
 86     if (sb.st_mode & S_IWUSR)
 87         s[2] =w;
 88     if (sb.st_mode & S_IXUSR)
 89         s[3] = (s[3] == S) ? s : x;
 90 
 91     /* parse group rwx bit */
 92     if (sb.st_mode & S_IRGRP)
 93         s[4] = r;
 94     if (sb.st_mode & S_IWGRP)
 95         s[5] = w;
 96     if (sb.st_mode & S_IXGRP)
 97         s[6] = (s[6] == S) ? s : x;
 98 
 99     /* parse others rwx bit */
100     if (sb.st_mode & S_IROTH)
101         s[7] = r;
102     if (sb.st_mode & S_IWOTH)
103         s[8] = w;
104     if (sb.st_mode & S_IXOTH)
105         s[9] = (s[9] == T) ? t : x;
106 
107     (void) printf("  File: %s\n", filepath);
108     (void) printf("Access: (%04o/%s)\n", (int)(sb.st_mode & ~S_IFMT), s);
109     (void) printf("  Type: %s\n", filetype);
110 
111     return (0);
112 }

o 在Linux上编译并测试

$ gcc -g -Wall -m32 -o foo foo.c

$ ./foo /usr/bin/passwd
  File: /usr/bin/passwd
Access: (4755/-rwsr-xr-x)
  Type: regular file

$ ./foo /var/tmp
  File: /var/tmp
Access: (1777/drwxrwxrwt)
  Type: directory

$ ./foo /bin/sh
  File: /bin/sh
Access: (0777/lrwxrwxrwx)
  Type: symbolic link

$ mkfifo /tmp/fifo
$ ./foo /tmp/fifo
  File: /tmp/fifo
Access: (0664/prw-rw-r--)
  Type: fifo

$ ./foo /dev/null
  File: /dev/null
Access: (0666/crw-rw-rw-)
  Type: character special file

$ ./foo /dev/sda
  File: /dev/sda
Access: (0660/brw-rw----)
  Type: block special file

$ ./foo /var/tmp/.sshmux 
  File: /var/tmp/.sshmux
Access: (0600/srw-------)
  Type: socket

o 在Solaris上编译并测试

 

Unix/Linux文件类型及访问权限