目录项属性
目录读取
文件的访问许可
目录及目录项操作
其他
===============================================================================
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *file_name, struct stat *buf);
int fstat(int filedes, struct stat *buf);
int lstat(const char *file_name, struct stat *buf);
-------------------------------------------------------------------------------
struct stat
{
dev_t st_dev; /* device */
ino_t st_ino; /* inode */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device type (if inode device) */
off_t st_size; /* total size, in bytes */
unsigned long st_blksize; /* blocksize for filesystem I/O */
unsigned long st_blocks; /* number of blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last change */
};
===============================================================================
===============================================================================
S_ISLNK(m) is it a symbolic link?
S_ISREG(m) regular file?
S_ISDIR(m) directory?
S_ISCHR(m) character device?
S_ISBLK(m) block device?
S_ISFIFO(m) fifo?
S_ISSOCK(m) socket?
===============================================================================
===============================================================================
S_IFMT 0170000 bitmask for the file type bitfields
S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 fifo
S_ISUID 0004000 set UID bit
S_ISGID 0002000 set GID bit
S_ISVTX 0001000 sticky bit
S_IRWXU 00700 mask for user (file owner) permissions
S_IRUSR 00400 user has read permission
S_IWUSR 00200 user has write permission
S_IXUSR 00100 user has execute permission
S_IRWXG 00070 mask for group permissions
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 mask for permissions for others (not in group)
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permisson
S_IXOTH 00001 others have execute permission
===============================================================================
===============================================================================
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
struct dirent *readdir(DIR *dir);
int closedir(DIR *dir);
------------------------------------------------------------------------------
EXAMPLE:
/* List directory entries and do something based on file type */
static void ListDir (const char* path)
{
struct dirent* pDirEnt;
DIR* dir;
struct stat ftype;
char fullpath [MAX_PATH + 1];
dir = opendir (path);
while ((pDirEnt = readdir (dir)) != NULL) {
// Assemble full path name.
strcpy (fullpath, path);
strcat (fullpath, "/");
strcat (fullpath, pDirEnt->d_name);
if (lstat (fullpath, &ftype) < 0 ) {
continue;
}
if (S_ISDIR (ftype.st_mode))
...
else if (S_ISREG(ftype.st_mode))
...
else
...
}
closedir(dir);
}
===============================================================================
===============================================================================
#include <sys/types.h>
#include <dirent.h>
void rewinddir(DIR *dir);
void seekdir(DIR *dir, off_t offset);
off_t telldir(DIR *dir);
int scandir(const char *dir, struct dirent ***namelist,
int (*select)(const struct dirent *),
int (*compar)(const struct dirent **, const struct dirent **));
int alphasort(const struct dirent **a, const struct dirent **b);
------------------------------------------------------------------------------
EXAMPLE:
/* print files in current directory in reverse order */
#include <dirent.h>
int main ()
{
struct dirent **namelist;
int n;
n = scandir (".", &namelist, 0, alphasort);
if (n < 0)
perror ("scandir");
else
while (n--) printf("%s\n", namelist[n]->d_name);
}
===============================================================================
===============================================================================
S_IRWXU 00700 mask for user (file owner) permissions
S_IRUSR 00400 user has read permission
S_IWUSR 00200 user has write permission
S_IXUSR 00100 user has execute permission
S_IRWXG 00070 mask for group permissions
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 mask for permissions for others (not in group)
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permisson
S_IXOTH 00001 others have execute permission
===============================================================================
===============================================================================
* 要利用名称打开某个文件, 则必须在名称所涉及的所有目录上有执行许可.
* 目录的读许可允许我们获得目录中的文件清单. 可执行许可允许我们通过该目录而访问文件.
* 比如要访问 /etc/X11/XF86Config, 则必须拥有 /, /etc, /etc/X11 目录的可执行许可.
===============================================================================
===============================================================================
* 新文件的用户 ID 设置为进程的有效组 ID.
* POSIX 定义新文件的组 ID 可以是进程的有效组 ID, 也可以是新文件所在目录的组 ID.
* Linux 根据目录是否有 SGID 位确定新文件的组 ID. 若有 SGID 标志, 则新文件的
组 ID 为所在目录的组 ID, 否则为进程的有效组 ID.
===============================================================================
===============================================================================
#include <unistd.h>
int access(const char *pathname, int mode);
===============================================================================
===============================================================================
#include <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t mask);
===============================================================================
===============================================================================
#include <sys/types.h>
#include <sys/stat.h>
int chmod(const char *path, mode_t mode);
int fchmod(int fildes, mode_t mode);
===============================================================================
===============================================================================
* 保存交换后的可执行正文, 以便节省装入时间. 该标志已经没有多少实际意义.
* 对普通文件没有任何效果.
* 对目录, 作为限制删除标志, 用来限制目录项的删除和重命名.
===============================================================================
===============================================================================
#include <sys/types.h>
#include <unistd.h>
int chown(const char *path, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int lchown(const char *path, uid_t owner, gid_t group);
===============================================================================
===============================================================================
#include <unistd.h>
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
===============================================================================
===============================================================================
#include <unistd.h>
int link (const char *oldpath, const char *newpath);
int unlink (const char *pathname);
-------------------------------------------------------------------------------
unlink 成功的先决条件:
* 作用于非目录文件.
* 对包含该目录项的目录, 必须具有写和执行许可.
* 若目录具有黏着位, 则必须满足: 拥有文件, 拥有目录或具有超级用户特权
===============================================================================
===============================================================================
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
int mkdir (const char *pathname, mode_t mode);
int rmdir (const char *pathname);
-------------------------------------------------------------------------------
* rmdir 只能删除空目录.
===============================================================================
===============================================================================
#include <stdio.h>
int remove(const char *pathname);
int rename(const char *oldpath, const char *newpath);
-------------------------------------------------------------------------------
* remove 可删除文件和目录, 分别等同于 unlink 和 rmdir.
===============================================================================
===============================================================================
#include <unistd.h>
int symlink (const char *oldpath, const char *newpath);
int readlink (const char *path, char *buf, size_t bufsiz);
-------------------------------------------------------------------------------
* 建立符号链接时, 不要求 oldpath 一定存在.
* open 沿链接前行, readlink 可读取链接本身的信息.
===============================================================================
===============================================================================
#include <unistd.h>
int chdir(const char *path);
int fchdir(int fd);
char *getcwd(char *buf, size_t size);
char *get_current_dir_name(void);
char *getwd(char *buf);
-------------------------------------------------------------------------------
* 内核维护的当前目录信息是索引节点而不是完整路径名.
* get_current_dir_name 是 GNU 的扩展.
* getwd 是 BSD 扩展
===============================================================================
===============================================================================
#include <sys/types.h>
#include <utime.h>
int utime (const char *filename, struct utimbuf *buf);
#include <sys/time.h>
int utimes (char *filename, struct timeval *tvp);
-------------------------------------------------------------------------------
struct utimbuf {
time_t actime; /* access time */
time_t modtime; /* modification time */
};
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
-------------------------------------------------------------------------------
* utime 返回的时间为日历时间, 即 1970 年 1 月 1 日 0:00:00 (UTC) 开始的秒数.
* 对 utimes 必须传递一个两元素的 struct timeval 数组, 分别接受访问时间和
修改时间. 这个时间也是自 1970 年 1 月 1 日 0:00:00 (UTC) 算起的.
===============================================================================
===============================================================================
* stat 结构的 st_dev 包含了文件所在文件系统的设备号.
* stat 结构的 st_rdev 只对设备特殊文件有效.
* 对 st_dev 和 st_rdev, 用 major 和 minor 两个宏, 可得到主设备号和次设备号.
===============================================================================
===============================================================================
#include <unistd.h>
int sync (void);
int fsync (int fd);
#ifdef _POSIX_SYNCHRONIZED_IO
int fdatasync (int fd);
#endif
-------------------------------------------------------------------------------
* sync 不等待实际的磁盘 I/O 结束, 只是将所有更新的块缓冲区进行排队.
* fsync 和 fdatasync 等待实际的磁盘 I/O 结束.
* fdatasync 只更新数据, 而 fsync 还要更新 inode 中的访问时间等信息.
===============================================================================
![]()