1.#include<sys/types.h>
#include<sys/stat.h>
int stat(const char *pathname,struct stat *buf);//根据文件名取得文件的信息
int fstat(int fd,struct stat *buf);//根据文件描述符取得文件信息
int lstat(const char *pathname,struct stat *buf);//类似stat,但当文件是一个
链接文件时,取得链接文件的信息,而非链接引用的文件
2.struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
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 ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t 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 status change */
};
3.要进入一个目录必需要有可执行权限。
4.文件类型包括:普通文件(regular file)、目录文件(directory file)、块特殊文件(block special file)(典型用于磁盘)、字符特殊文件(character special file)(用以系统中某些类型的设备)、 FIFO(用于进程间通信)、套接字(socket)(用于网络通信)、符号链接(symbolic link)。文件类型信息保存在stat类型的st_mode字段中。
确定文件类型的宏(sys/stat.h):如S_ISREG(stat.st_mode)
宏 文件类型
S_ISREG() 普通文件
S_ISDIR() 目录文件
S_ISCHR() 字符特殊文件
S_ISBLK() 块特殊文件
S_ISFIFO() 管道或FIFO
S_ISLNK() 符号链接
S_ISSOCK() 套接字
S_ISDIR的定义#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR),即文件类型与屏蔽字S_IFMT逻辑与,再与对应的宏对比。
5.有效用户和有效组
一般实际用户和有效用户是相同的,实际组和有效组是相同的。有效用户和组是用来表示对文件或者目录所拥有的权限的。
看下passwd程序,注意用户执行位的s
ls -l /usr/bin/passwd
-rwsr-xr-x 1 root shadow 79336 May 4 2007 /usr/bin/passwd
再看下passwd文件
ls -l /etc/passwd
-rw-r--r-- 1 root root 6890 Jul 3 09:25 /etc/passwd
修改passwd文件要有root权限才可以,但实际上我们任意用户都可以使用passwd程序修改passwd文件。这是因为我们在执行passwd程序时获得了root的权限,从而
passwd程序可以去修改passwd文件,我们之所以能取得root权限,就是因为passwd程序设置了有效用户位s,拥有可执行权限则为s,没有则为S。用户调用passwd程序修改passwd文件。
6.粘着位
看下tmp目录,注意红色
drwxrwxrwt 23 root root 1560 Aug 7 16:42 tmp
使用root用户在tmp目录内touch一个文件加上777权限
使用普通用户在tmp目录内删除刚才的那个文件,发现删除不了,这就是粘着位的作用。
如果对一个文件或者目录设置了粘住位,则只有对该目录具有写许可权的用户并且满足下列条件之一,才能删除或更名该目录下的文件:
st_mode屏蔽 意义
S_IRUSR 用户-读
S_IWUSR 用户-写
S_IXUSR 用户-执行
S_IRGRP 组-读
S_IWGRP 组-写
S_IXGRP 组-执行
S_IROTH 其他-读
S_IWOTH 其他-写
S_IXOTH 其他-执行
(1) 若进程的有效用户ID是0,则允许访问。
(2) 若进程的有效用户ID等于文件的所有者ID,若文件所有者相应的访问权限位被设置,则访问允许,否则拒绝。
(3) 若进程的有效组ID或进程的附件组ID之一等于文件的组ID,若组相应的访问权限位被设置,则访问允许,否则失败。
(4) 若其他用户相应的访问权限位被设置,则访问允许,否则拒绝。
1>进程的有效组ID;2>它所在目录的组ID。
int access(const char *pathname, int mode);
返回值:若成功则返回0,若出错则返回-1
mode 说明
R_OK 测试读成功
W_OK 测试写成功
X_OK 测试执行权限
F_OK 测试文件是否存在
#include <sys/stst.h>
int chmod(const char *pathname, mode_t mode);
int fchmod(int filedes, mode_t mode);
返回值:若成功则返回0,若失败则返回-1;
mode 说明
S_ISUID 执行时设置用户ID
S_ISGID 执行时设置组ID
S_ISVTX 保存正文(黏住位)
S_IRWXU 用户(所有者)读、写和执行
S_IRUSR 用户(所有者)读
S_IWUSR 用户(所有者)写
S_IXUSR 用户(所有者)执行
S_IRWXG 组读、写和执行
S_IRGRP 组读
S_IWGRP 组写
S_IXGRP 组执行
S_IRWXO 其他读、写和执行
S_IROTH 其他读
S_IWOTH 其他写
S_IXOTH 其他执行
#include <unistd.h>
int chown(const char *pathname, uid_t owner, gid_t group);
int fchown(int filedes, uid_t owner, gid_t group);
int lchown(const char *pathname, uid_t owner, gid_t group);
返回值:成功返回0,出错返回-1;
#include <unistd.h>
int truncate(const char *pathname, off_t length);
int truncate(int filedes, off_t length);
返回值:成功返回0,出错返回-1;
如果文件以前的长度大于length,则超过length以外的数据就不能再访问了;如果短于length,则效果与系统有关。
#include <unistd.h>
int link(const char *existingpath, const char *newpath);// 创建的是硬链接,不是软链接
int unlink(const char *pathname );//删除文件时,如果文件正在被当前进程打开时,当进程结束时,内核会进行删除操作,即文件引用数减1,如果为0则删除。
#include <stdio.h>
int remove(const char *pathname);
int rename(const char *oldname, const char *newname);
#include <unistd.h>
int symlink(const char *actualpath, const char *sympath);//创建符号链接时,并不要求实际路径存在。
ssize_t readlink(const char *restrict pathname, char *restrict buf, size_t bufsize);//读取符号链接本身的内容,在buf中读取的内容不包含null字符终止。
返回值:成功返回读到的字节数,出错返回-1;
字段 说明 例子 ls选项
st_atime 文件数据的最后访问时间 read -u
st_mtime 文件数据的最后修改时间 write 默认
st_ctime i节点状态的最后更改时间 chmod、chown -c
#include <utime.h>
int utime(const char *pathname, const struct utimbuf *times)
struct utimbuf{
time_t actime;
time_t modtime;
}
#include <sys/stat.h>
int mkdir(const char *pathname, mode_t mode):创建一个空目录,权限参照文件的创建。
int rmdir(const char *pathname):删除一个空目录(空目录只包含.和..这两项的目录)
21. 读目录
#include <dirent.h>
DIR *opendir(const char *pathname)
struct dirent *readdir(DIR *dp)
返回值:成功返回指针,失败返回NULL
void rewinddir(DIR *dp)//应该循环调用此函数读取目录内容
#include<unistd.h>
#include<sys/types.h>
#include<fcntl.h>
#include<dirent.h>
#include<stdio.h>
#ifndef NULL
#define NULL 0
#endif
#ifndef ERROR
#define ERROR 0
#define OK 1
#endif
typedef int Status;
Status ls(char *);
int main(int argc,char **argv)
{
if(argc==1)
ls(".");
//else
while(--argc)
{
printf("%s\n",*++argv);
ls(*argv);
}
return 0;
}
Status ls(char *dirname)
{
DIR *p_dir;//目录项指针
struct dirent *p_dirent;//
if((p_dir=opendir(dirname))==NULL)//首先打开目录
{
fprintf(stderr,"---->can\'t open %s\n",dirname);
return ERROR;
}
while((p_dirent=readdir(p_dir)))//循环读取目录
{
printf("%s\n",p_dirent->d_name);
}
closedir(p_dir);
return OK;
}
long telldir(DIR *dp)
void seekdir(DIR *dp, long loc)
struct dirent{
ino_t d_ino; /*i-node number*/
char d_name[NAME_MAX+1]; /*null-terminated filename*/
}
#include <unistd.h>
int chdir(const char *pathname);
int fchdir(int filedes);
char *getcwd(char *buf, size_t size);