文章目录
使用mmap将文件映射到进程的虚拟地址空间,对内存的操作,直接反应到文件中。
相关概念:
代码参考:
执行验证
代码获取文件的元数据
文件的元数据
相关使用函数
代码实现
执行
使用mmap将文件映射到进程的虚拟地址空间,对内存的操作,直接反应到文件中。
相关概念:
Linux od命令用于输出文件内容。
- od指令会读取所给予的文件的内容,并将其内容以八进制字码呈现出来。
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
- 头文件需要包含<sys/mman.h>
- 功能:映射文件或设备到内存空间
- 参数:
- addr:映射后的虚拟地址空间的地址(一般为NULL)
- length:映射的长度
- prot:
- PROT_NONE Pages may not be accessed.
- PROT_EXEC Pages may be executed.
- PROT_READ Pages may be read.
- PROT_WRITE Pages may be written.
- flags:
- MAP_SHARED:
- MAP_PRIVATE:
- MAP_ANONYMOUS: 不支持文件映射
- fd:-1
- offset:0
- 返回值:
- MAP_FAILED 错误 errno被设置
- 成功返回映射区域的地址
int munmap(void *addr, size_t length);
- 功能:解除内存映射
- 参数:
- addr:是mmap(2)的返回值
- length:同mmap(2)函数中的length
- 返回值:
- 0 成功
- -1 失败 errno被设置
代码参考:
#include <stdio.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> int main(int argc,char *argv[]){ int fd; //以读写方式打开文件 fd=open(argv[1],O_RDWR); if(fd==-1){ perror("open"); return 1; } //建立映射 void *p=mmap(NULL,6,\ PROT_READ|PROT_WRITE, MAP_SHARED,fd,0); if(p==MAP_FAILED){ perror("mmap"); return 2; } printf("success...\n"); //关闭文件 close(fd); //对内存的操作 int *q=(int *)p; q[0]=0x30313233; //解除映射 munmap(p,6); return 0; }
执行验证
代码获取文件的元数据
文件的元数据
文件的元数据就是文件的属性,使用
ls -l [文件名]#查看
相关使用函数
- 如何获取一个文件的元数据?
使用系统调用stat(2)获取文件的元数据。
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int stat(const char *path, struct stat *buf); 功能:获取文件的状态信息 参数: path:指定了文件的名字 buf:将文件的状态信息存储到buf指定的空间里。 返回值: -1 错误 errno被设置 0 成功
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 file system I/O */ blkcnt_t st_blocks; /* number of 512B 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 */ };
- 如何将uid的数字转换为用户的名字?
getpwuid(3) #include <sys/types.h> #include <pwd.h> struct passwd *getpwuid(uid_t uid); 功能:获取用户的信息 参数: uid:指定用户的uid 返回值: 返回一个指向struct passwd结构体的指针 NULL 找不到这个用户的信息或错误产生 如果是产生错误,errno被设置
/etc/passwd文件的内容
这个文件里存放的是系统的所有用户的信息。
struct passwd { char *pw_name; /* username */ char *pw_passwd; /* user password */ uid_t pw_uid; /* user ID */ gid_t pw_gid; /* group ID */ char *pw_gecos; /* user information */ char *pw_dir; /* home directory */ char *pw_shell; /* shell program */ };
- 如何通过gid获取组名?
getgrnam(3) getgrgid(3) #include <sys/types.h> #include <grp.h> struct group *getgrgid(gid_t gid); 功能:获取一条组信息 参数: gid:指定的组id 返回值: 返回一个指向struct group结构体的指针 NULL 找不到这个组的信息或错误产生 如果是产生错误,errno被设置.
struct group{ char *gr_name; /* group name */ char *gr_passwd; /* group password */ gid_t gr_gid; /* group ID */ char **gr_mem; /* group members */ };
- 组信息存放在/etc/group文件中
- 将长整型的时间转换为字符串格式的时间
ctime(3) #include <time.h> char *ctime(const time_t *timep); 功能:将长整型的时间转换为字符串格式 参数: timep:长整型的时间 返回值: NULL 错误 字符串
代码实现
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <pwd.h> #include <grp.h> #include <time.h> int main(int argc,char *argv[]){ struct stat sbuf; struct passwd *p; int s; //获取指定文件的元数据 s=stat(argv[1],&sbuf); if(s==-1){//获取文件的元数据失败 perror("stat"); return 1; } printf("size:%ld\n",sbuf.st_size); printf("hard links:%d\n",\ sbuf.st_nlink); printf("inode number:%lu\n",\ sbuf.st_ino); //printf("uid:%d\n",sbuf.st_uid); p=getpwuid(sbuf.st_uid); if(p==NULL){ return 2; } printf("username:%s\n",p->pw_name); //printf("gid:%d\n",sbuf.st_gid); struct group *q=\ getgrgid(sbuf.st_gid); printf("group name:%s\n",q->gr_name); char *st=ctime(&sbuf.st_atime); printf("time:%s\n",st); printf("mode:%o\n",sbuf.st_mode); #if 0 if(S_ISREG(sbuf.st_mode))printf("-"); if(S_ISDIR(sbuf.st_mode))printf("d"); printf("\n"); #endif switch(sbuf.st_mode&S_IFMT){ case S_IFREG: printf("-"); break; case S_IFDIR: printf("d"); break; default: break; } printf("\n"); //打印出属主的权限 if(sbuf.st_mode&S_IRUSR) printf("r"); else printf("-"); if(sbuf.st_mode&S_IWUSR) printf("w"); else printf("-"); printf("\n"); #if 0 switch(sbuf.st_mode&00700){ case S_IRUSR: printf("r"); break; case S_IWUSR: printf("w"); break; case S_IXUSR: printf("x"); break; default: break; } #endif return 0; }
执行