一、常见的文件操作相关的系统调用
普通权限的系统调用 | 函数 | 说明 | int access(char *pathname,int mode) | 检查对某个文件的权限 | int chdir(const char *path) | * 变更目录 | int chmod(char *path,model_t mode) | * 更改某个文件的权限 | int chown(char *name,int uid,int gid) | * 更改文件的所有人 | int chroot(char *pathname); | 将(逻辑)根目录更改为路径名 | char *getcwd(char *buf , int size) | * 获取CWD的绝对路径名 | int mkdir(char *pathname,model_t mode) | * 创建目录 | int rmdir(char *pathname) | * 移除目录 | int link(char *oldpath,char *newpath); | * 将新文件名硬链接到旧文件名 | int unlink(char *pathname) | 减少文件的链接数;如果数值变成0则删除文件 | int symlink(char *oldpath,char *newpath) | 为文件创建一个符号连接 | int readlink(char *path,char *buf,int bufsize) | 读取符号链接文件的内容 | int rename(char *oldpath,char *newpath | * 重命名文件 | int utime(char *pathname,struct utimebuf *time) | * 更改文件的访问和修改时间 | int stat(char *filename,struct stat *buf) | 获取文件的状态信息 | int fstat(int filedes,struct stat *buf) | 获取文件的状态信息 | int lstat(char *filename,struct stat *buf) | * 获取文件的状态信息 | int open(char *filr,int flags,int mode) | * 打开一个文件进行读、写、追加 | int close(int fd) | * 关闭打开的 文件描述符 | int read(int fd,char buf[],int count) | * 读取打开的 文件描述符 | int write(int fd,char buf[],int count) | * 写入打开的 文件描述符 | int lseek(int fd,int offset,int whence) | 重新定位文件描述符的读/写偏移量 | int dup(int oldfd,int newfd) | 将文件描述符复制到最小可用描述符编号中 | int dup2(int oldfd,int newfd) | 先将newfd关闭,再把oldfd赋值到newfd中 | int umask(int umask); | 设置文件创建掩码;文件权限为(mask &~umask) | 需要超级用户权限的系统调用 | int mount(char *specialfile, char *mountDir) | 将文件系统添加到挂载点目录上 | int umount(char *dir); | 分离挂载的文件系统 | int mknod(char * path,int model,int device); | 创建特殊文件 |
二、st_mode 标志
宏定义? | 值(十进制) | 含义 | S_IFMT | 0170000 | 文件类型位域的位掩码 | S_IFSOCK | 0140000 | socket套接字 | S_IFLNK | 0120000 | symbolic link 符号链接 | S_IFREG | 0100000 | 常规文件 | S_IFBLK | 0060000 | 块设备 | S_IFDIR | 0040000 | 目录 | S_IFCHR | 0020000 | 字符设备 | S_IFIFO | 0010000 | fifo先进先出 | S_ISUID | 0004000 | 设置UID位 | S_ISGID | 0002000 | 设置GID位 | S_ISVTX | 0001000 | 设置粘滞位(Sticky bit) | S_IRWXU | 00700 | 当前文件的所有者所有权限 | S_IRUSR | 00400 | 当前文件的所有者读权限 | S_IWUSR | 00200 | 当前文件的所有者写权限 | S_IXUSR | 00100 | 当前文件的所有者执行权限 | S_IRWXG | 00070 | 当前文件的组所有权限 | S_IRGRP | 00040 | 当前文件的组读权限 | S_IWGRP | 00020 | 当前文件的组写权限 | S_IXGRP | 00010 | 当前文件的组执行权限 | S_IRWXO | 00007 | 当前文件的其他用户所有权限 | S_IROTH | 00004 | 当前文件的其他用户读权限 | S_IWOTH | 00002 | 当前文件的其他用户写权限 | S_IXOTH | 00001 | 当前文件的其他用户执行权限 | | | |
三、文件状态结构体? stat
struct stat {
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; //文件字节数(文件大小)
unsigned long st_blksize; //块大小(文件系统的I/O 缓冲区大小)
unsigned long st_blocks; //块数
time_t st_atime; //最后一次访问时间
time_t st_mtime; //最后一次修改时间
time_t st_ctime; //最后一次改变时间(指属性)
};
读取文件时,可以获取文件的文件属性, 可以用以下三种方法
int? stat(const char *file_name ,struct stat *buf)? ? 按文件名获得文件的stat信息,如果时链接文件获取链接文件所指向的文件信息
int? fstat(int filedes? ,struct stat *buf)? ? ? ?和stat函数效果一样,只不过传入的参数时文件描述符
int? lstat(const char *file_name ,struct stat *buf)? ? 按文件名获得文件的stat信息,如果时链接文件获取文件本身的信息??
下面展示linux 命令? ls 原理的程序:(不支持通配符)
open () 方法是打开文件,遵循符号链接,但是如果想打开文件内容本身,应调用
int readlink(char * pathname ,char buf[] , int bufsize);
/*************myls.c********************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
struct stat mystat,*sp;
char *t1 = "xwrxwrxwr-------";
char *t2 = "----------------";
int ls_file(char *fname){
struct stat fstat ,*sp;
int r,i;
char ftime[64];
sp =& fstat;
if( (r = lstat(fname,&fstat)) <0 ){
printf("can't stat %s\n",fname);
exit(1);
}
if ( (sp->st_mode &0xF000) == 0x8000 ){
// S_ISREG
printf("%c",'-');
}else if ( (sp->st_mode &0xF000) == 0x4000 ){
// S_ISDIR
printf("%c",'d');
}else if ( (sp->st_mode &0xF000) == 0xA000 ){
// S_ISLNK
printf("%c",'l');
}
for ( i =8 ; i>=0 ;i--){
if (sp->st_mode & (1 << i )){
printf("%c",t1[i]);
} else {
printf("%c",t2[i]);
}
}
printf("%4d ",sp->st_nlink);
printf("%4d ",sp->st_gid);
printf("%4d ",sp->st_uid);
printf("%8d ",sp->st_size);
//print time
strcpy(ftime ,ctime(&sp->st_ctime));
ftime[strlen(ftime) -1 ] =0;
printf ("%s " , ftime);
//print name
printf ("%s",basename(fname));
//if symbolic file , print symfile ->linkname
if( (sp->st_mode &0xF000) ==0xA000){
//uss readlink() to read linkname
char *linkname;
readlink (fname , linkname,1024);
printf(" -> %s" , linkname); //print linked name
}
printf("\n");
}
int ls_dir(char *dname){
struct dirent *ep ;
DIR *dp = opendir(dname);
if(!dp){
printf("no such dir %s\n",dname);
exit(1);
}
char newpath[1024];
while( ep = readdir(dp)){
strcpy(newpath,dname);strcat(newpath , ep ->d_name);
ls_file(newpath);
}
}
int main(int argc , char *argv[]){
struct stat mystat, *sp =&mystat;
int r ;
char *filename , path[1024] ,cwd[256];
filename = "./";
if (argc >1){
filename =argv[1];
}
if( r = lstat(filename,sp) < 0 ){
printf("no such file %s\n",filename);
}
strcpy(path , filename);
if(path[0] != '/'){
//相对路径
getcwd(cwd,256);
strcpy(path,cwd); strcat(path ,"/");strcat(path , filename);
}
if(S_ISDIR(sp -> st_mode)){
printf ("path : %s\n", path);
ls_dir(path);
}
else
ls_file(path);
}
?
|