Ubuntu下UnixC第五天

回忆昨天课程内容
    一、内存管理
    进程的映像  代码段  数据段 堆 栈段
    变量的空间分配在什么地方,不同的段有不同的属性
    变量的生命周期  变量的作用域
    堆      手动释放free   p=NULL;
    进程  pid PCB  进程的映像是属于PCB的一个成员
    const 定义一个只读变量
    二、使用mmap将物理地址映射到进程的虚拟地址空间
    mmap munmap
    三、文件的操作
    open(2) close(2) read(2) write(2)
    文件描述符    进程的pid PCB 可变参数  
0标准输入 STDIN_FILENO
1标准输出 STDOUT_FILENO
2标准错误输出   STDERR_FILENO
umask 权限掩码

今天内容
一、lseek(2)
     #include <sys/types.h>
       #include <unistd.h>

       off_t lseek(int fd, off_t offset, int whence);
   
    功能:
    参数:
    fd      指定了要操作的文件
    offset
    whence-     SEEK_SET    offset
                         The offset is set to offset bytes.
   
                 SEEK_CUR   locat+offset
                        The offset is set to its current location plus offset bytes.

                  SEEK_END  文件的末尾+offset
                       The offset is set to the size of the file plus offset bytes.


       
    返回值:错误 (offset_t)-1 errno被设置
        成功 返回当前位置距离文件开头的字节数
   
二、使用mmap(2)讲文件映射到进程的虚拟地址空间,对内存进行操作,直接反应到文件
    代码参见 map.c
day05$od -tx1 -tc hello
0000000  68  65  6c  6c  6f  20  62  65  69  6a  69  6e  67  0a
          h   e   l   l   o       b   e   i   j   i   n   g  \n
0000016

day05$a.out hello

day05$od -tx1 -tc hello
0000000  34  33  32  31  6f  20  62  65  69  6a  69  6e  67  0a
          4   3   2   1   o       b   e   i   j   i   n   g  \n
0000016
高位字节存放在低地址     大端
高位字节存放在高地址    小端
编写程序,测试自己的主机字节序
三、文件描述符的复制
dup(2) dup2(2)
  #include <unistd.h>

       int dup(int oldfd);
    功能:复制一个文件描述符,使用最小的
    参数:
    oldfd 源描述符
    返回值:错误-1 errno被设置
        成功:返回新的文件描述符
       int dup2(int oldfd, int newfd);
    功能:复制一个文件描述符,使用newfd指定的,如果原来的描述符是打开的,将其关闭
    参数:
    oldfd 源描述符
    newfd 目的描述符
    返回值:错误 -1 errno被设置
        成功 返回newfd
    编写代码实现文件输出重定向  代码参见direct.c
四、获取文件的原数据
    什么是文件的元数据,文件是怎么存储的?
    一个文件包含两个部分内容  元数据和内容
    元数据是对一个文件的描述信息
    每个文件有且仅有一个inode,且每个inode都有自己的编号
    链接文件
    软链接
    硬链接  文件的inode是同一个
    ln 源文件 目标文件 之后两个文件inode相同
    stat(2)
     #include <sys/types.h>
       #include <sys/stat.h>
       #include <unistd.h>

       int stat(const char *pathname, struct stat *buf);
    功能:获取文件身份信息
    参数:
    pathname 指定文件的路径,获取这个文件的元数据
   
    buf 指定地址,将文件的元数据存储到buf指定的空间里
    返回值:

    struct stat?
    值-结果参数
       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 512B blocks allocated */

               /* Since Linux 2.6, the kernel supports nanosecond
                  precision for the following timestamp fields.
                  For the details before Linux 2.6, see NOTES. */

               struct timespec st_atim;  /* time of last access */
               struct timespec st_mtim;  /* time of last modification */
               struct timespec st_ctim;  /* time of last status change */

           #define st_atime st_atim.tv_sec      /* Backward compatibility */
           #define st_mtime st_mtim.tv_sec
           #define st_ctime st_ctim.tv_sec
           };
   
    struct timespec{
        _time_t tv_sec;
        _syscall_slong_t tv_nsec;
    };
1970年1月1 0点0分0秒  unix诞生
将秒数转换为字符串
ctime(3)
 #include <time.h>
char *ctime(const time_t *timep);

功能:将秒数转换为分开的格式
参数:
timep 秒数
返回值:时间字符串,末尾为换行符

根据uid找到用户的名字
    系统中维护着用户的信息,所有用户的信息存放在/etc/passwd文件中
    tarena:x:1000:1000:ubuntu,,,:/home/tarena:/bin/bash
    nan:x:1000:1000:nan,,,:/home/nan:/bin/bash

    root:x:0:0:root:/root:/bin/bash
    getpwnam(3)
     #include <sys/types.h>
       #include <pwd.h>

       struct passwd *getpwnam(const char *name);

       struct passwd *getpwuid(uid_t uid);
      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 */
           };

     getgrnam(3)
    #include <sys/types.h>
       #include <grp.h>

       struct group *getgrnam(const char *name);
     struct group {
               char   *gr_name;        /* group name */
               char   *gr_passwd;      /* group password */
               gid_t   gr_gid;         /* group ID */
               char  **gr_mem;         /* NULL-terminated array of pointers
                                          to names of group members */
           };


根据gid找到用户组的名字

 

 

direct.c

#include<t_stdio.h>
#include<t_file.h>
#include<string.h>
int main(int argc,char*argv[]){
    char *msg="stupid jerryFeng\n";
    //打开文件,以写的方式,文件不存在则创建
    //权限为0644,文件存在则清空
    int fd=open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,0644);

    if(fd==-1) 
        E_MSG("open",-1);
//将标准输出描述符保存
    int s_fd=dup(1);
    //将标准输出重新定向到打开的文件
    dup2(fd,1);
    close(fd);
    write(1,msg,strlen(msg));
    //恢复标准输出
    dup2(s_fd,1);
    close(s_fd);
    write(1,msg,strlen(msg));
    return 0;
}
 

map.c

#include<t_file.h>
#include<t_stdio.h>
#include<sys/mman.h>
int main(int argc,char* argv[]){
    //将文件映射到进程的内存
    int prot=PROT_READ|PROT_WRITE;
    int flags=MAP_SHARED;
    int fd=open(argv[1],O_RDWR);
    if(fd==-1)
      E_MSG("open",-1);
    void *p=mmap(NULL,32,prot,flags,fd,0);
    if(p==MAP_FAILED)
      E_MSG("mmap",-1);
    *((int *)p)=0x31323334;
    //解除映射
    munmap(p,32);
    close(fd);
    return 0;
}
 

s_big.c  //看自己的虚拟机是大端还是小端

#include<t_stdio.h>
typedef union{
    
    char c;
    short s;
}u_t;
int main(void){
    u_t temp;
    temp.s=0x0001;
    printf("temp.s:%p,%d\n",&temp.s,temp.s);
    printf("temp.c:%p,%p\n",&temp.c,temp.c);
    temp.c?printf("small\n"):printf("big\n");
    return 0;
}

stat.c

#include<t_stdio.h>
#include<t_file.h>
#include<time.h>
#include<pwd.h>
#include<grp.h>
int main(int argc,char *argv[]){
    //获取文件的元数据,存储到buf
    struct stat buf;
    int s=stat(argv[1],&buf);
    if(s==-1) E_MSG("stat",-1);
    printf("hard links:%u\n",buf.st_nlink);
    printf("size:%ld\n",buf.st_size);
    printf("inode:%ld\n",buf.st_ino);
    printf("mtime:%s",ctime(&buf.st_mtime));
    printf("uid:%u\n",buf.st_uid);
    printf("username:%s\n",(getpwuid(buf.st_uid))->pw_name);
    printf("gid:%u\n",buf.st_gid);
    printf("group grname:%s\n",(getgrgid(buf.st_gid))->gr_name);
    
    return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值