zoukankan      html  css  js  c++  java
  • 信息安全系统设计基础第十周学习总结

    上周已完成第十章 系统I/O的学习笔记,这周对主要对附录A 错误处理进行学习,并对第十章进行进一步理解。

    附录A 错误处理

    基于错误处理包装函数

    思想:给定的基本级系统函数foo,我们有相同参数的、函数名大写的包装函数Foo;包装函数调用基本函数并检查错误。如果发现了错误,包装函数就终止进程并返回一条信息;当基本函数无误的时候,包装函数就返回调用者。(包装函数被封装在源文件csapp.c中)

    A.1 Unix系统中的错误处理

    系统基函数调用时用三种不同风格的返回错误:Unix风格和Posix风格和DNS风格。

    1. unix风格

      例如fork函数和外套函数,返回值既包括错误代码,又包括有用的结果。

       if((pid = wait(NULL))<0)
       {
          fprintf(stderr,"wait error:%s
      ",strerror(errno));   //将errno设置为指向错误原因的代码
          exit(0);
       }
      
    2. Posix风格

      例如pthread,函数只返回调用成功(0)或者失败(非0),任何有用的信息都返回在通过调用引用进来的参数中。

    3. DNS风格

      gethostbyname和gethostbyaddr检索NDS(域名系统)库;它们在错误的时候会返回NULL,并设置全局变量h_errno。

    A.2 错误处理包装函数

    1. unix风格

        pid_t Wait(int *status)
        {
           pid_t pid;
           if(pid = wait(status)<0)
           unix_error("wait error");
           return pid;
        }
      
    2. Posix风格

        void Pthread_detach(pthread_t tid)
        {
           int rc;
           if(rc=pthread_detach(tid) != 0)
           posix_error(rc,"Pthread_detach error");
         }
      
    3. DNS风格

        struct hostent *Gethostbyname(const char *name)
        {
           struct hostname *p;
           if((p = gethostbyname(name)) == NULL)
           dns_error("Gethostbyname error");
           return p;
        }
      

    重要命令:

    man -k key1 | grep key2| grep 2   : 根据关键字检索系统调用
    grep -nr XXX /usr/include  :查找宏定义,类型定义
    

    系统调用:文件I/O 如何用Linux学习系统编程

    who

    多用户系统如何知道谁在使用系统?who

    1. who能做什么,查阅一下:

    2. who命令的工作流程是:

      打开utmp文件,针对文件,读取一条记录,显示记录,关闭文件。

    3. 如何实现who?

      代码思想:从UTMP_FILE文件中读取想要的信息到存储器中,然后再用标准输出函数打印到屏幕上,最后关闭文件。

       #include	<stdio.h>
       #include	<stdlib.h>
       #include	<utmp.h>
       #include	<fcntl.h>
       #include	<unistd.h>
      
       #define	SHOWHOST	
      
       int show_info( struct utmp *utbufp )
       {
            printf("%-8.8s", utbufp->ut_name);	
            printf(" ");				
            printf("%-8.8s", utbufp->ut_line);	
            printf(" ");				
            printf("%10ld", utbufp->ut_time);	
            printf(" ");				
            #ifdef	SHOWHOST
            printf("(%s)", utbufp->ut_host);	
            #endif
            printf("
      ");				
      
            return 0;
       }
       int main()
       {
            struct utmp	 current_record;	
            int  utmpfd;		
            int  reclen = sizeof(current_record);
      
             /*打开UTMP_FILE读取信息,如果打开失败则输出失败信息。*/
          	 if ( (utmpfd = open(UTMP_FILE, O_RDONLY)) == -1 ){
            perror( UTMP_FILE );	
            exit(1);
       }
            /*读取信息到存储器中,reclen就是是读的字节数,然后再调用函数打印出来。*/
       while ( read(utmpfd, &current_record, reclen) == reclen )
       {
            show_info(&current_record);
            close(utmpfd);
            return 0;			
       }
      

    cp

    ——复制文件
    cp src dst

    cp能干什么,查阅一下:

    cp

     #include        <stdio.h>//标准输入输出
     #include        <stdlib.h>//C标准函数库
     #include        <unistd.h>//Unix类系统定义符号常量
     #include        <fcntl.h>//定义了很多宏和open,fcntl函数原型
    
     #define BUFFERSIZE      4096//定义存储器容量
     #define COPYMODE        0644//定义复制的长度
    
     void oops(char *, char *);
    
     int main(int argc, char *argv[])
     {
         int in_fd, out_fd, n_chars;//三个描述符值
         char buf[BUFFERSIZE];//存储器位置
    
    /*cp的参数有两个,分别是要复制的文件,和目的目录,这样一共应该是有三个操作数
    所以要先检查argc的值是否为三,如果不是,返回标准错误*/
    if (argc != 3) {
    	fprintf(stderr, "usage: %s source destination
    ", *argv);
    	exit(1);
    }
    /*检查cp的第一个参数,要复制的文件,用open打开,in_fd为open返回的描述符
    如果返回-1,代表打开失败,提示错误*/
    if ((in_fd = open(argv[1], O_RDONLY)) == -1)
    	oops("Cannot open ", argv[1]);
    
    /*检查cp的第二个参数,复制的目的地址,用create在目的地址创建新文件,out_fd为open返回的描述符
    如果返回-1,代表创建失败,提示错误*/
    if ((out_fd = creat(argv[2], COPYMODE)) == -1)
    	oops("Cannot creat", argv[2]);
    
    /*cp指令的动作就是读取一个文件的内容到存储器,在新的地址创建空白文件,再从存储器将内容写入新文件。
    这里判断复制是否成功:
    如果能读取顺利,而读取的位数和写的位数不同,是写错误;
    如果读取失败,是读错误。*/
    while ((n_chars = read(in_fd, buf, BUFFERSIZE)) > 0)
    	if (write(out_fd, buf, n_chars) != n_chars)
    		oops("Write error to ", argv[2]);
    if (n_chars == -1)
    	oops("Read error from ", argv[1]);
    
    /*这里执行的是关闭文件的动作,in_fd和out_fd两个文件描述符
    所指向的文件只要有一个关闭错误,就提示关闭错误。*/
    if (close(in_fd) == -1 || close(out_fd) == -1)
    	oops("Error closing files", "");
    }
    
     /*这个是用来输出错误信息的函数*/
    void oops(char *s1, char *s2)
    {
       fprintf(stderr, "Error: %s ", s1);
       perror(s2);//用来将上一个函数发生错误的原因输出到标准设备(stderr)
       exit(1);
    }
    

    ls

    ——读取文件名和文件属性

    ls能干什么:

    • ls -l

    • ls -a

    • ls -lu:最后访问时间

    • ls -s:以块为单位的文件大小

    • ls -t:按时间排序

    • ls -F:显示文件类型

    ls -l能做什么?

    显示文件信息:模式(文件类型file(1),访问控制),链接数,文件所有者,组,大小,最后修改时间,文件名

    ls(1)

    #include	<stdio.h>
    #include	<sys/types.h>
    #include	<dirent.h>
    
    void do_ls(char []);
    
    int main(int argc, char *argv[])
    {
       /*如果操作数只有1个,表明ls后面没有带参数,默认为当前目录,.表示当前目录。*/
       if ( argc == 1 )
          do_ls( "." );
       /*如果ls后面有参数,就把参数读入argv中。*/
       else
    	  while ( --argc ){
    	  	 printf("%s:
    ", *++argv );
    		 do_ls( *argv );
    	  }
       return 0;
    }
    
    /*因为ls和dir功能相近,用dir来实现ls*/
    void do_ls( char dirname[] )
    {
        DIR		*dir_ptr;
        struct dirent	*direntp;
    
        /*如果没有指向的那个地址,报错*/
        if ( ( dir_ptr = opendir( dirname ) ) == NULL )
    	    fprintf(stderr,"ls1: cannot open %s
    ", dirname);
        else
        {
           /*递归的方式来读取*/
    	   while ( ( direntp = readdir( dir_ptr ) ) != NULL )
    		  printf("%s
    ", direntp->d_name );
    	   closedir(dir_ptr);
        }
    }
    

    ls2

    ls2前半部分和ls1一样,所不同的只是多出来了一部分,用来显示文件的详细信息,比如用户名,群组名,大小,创建时间,读写权限等。

    参考资料:

        《深入理解操作系统》
        
        闫佳歆博客关于实践代码部分
  • 相关阅读:
    js 字符串转化成数字
    SDK编程之多线程编程
    C/C++内存泄漏及检测
    那些争议最大的编程观点(转)
    DB2日常维护——REORG TABLE命令优化数据库性能(转)
    ireport报表学习
    自定义hexo的某个主题
    mac下搭建码云gitee+hexo博客
    python日期及时间格式转换
    python获取中文首字母
  • 原文地址:https://www.cnblogs.com/lhc-java/p/4966452.html
Copyright © 2011-2022 走看看