使用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被设置
成功返回映射区域的地址
- 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;
}