第十章 系统级I/O

cp1

#include        <stdio.h>
#include        <stdlib.h>
#include        <unistd.h>
#include        <fcntl.h>

#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\n", *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);
}

echostate

#include        <stdio.h>
#include        <stdlib.h>
#include        <termios.h>

int main()
{
        struct termios info;
        int rv;

        rv = tcgetattr( 0, &info );     /* read values from driver      */

        if ( rv == -1 ){
                perror( "tcgetattr");
                exit(1);
        }
        if ( info.c_lflag & ECHO )
                printf(" echo is on , since its bit is 1\n");
        else
                printf(" echo is OFF, since its bit is 0\n");

        return 0;
}

检查命令行中的提示符是否显示的,如果显示,输入的命令都可见;不显示则表示输入的命令不可见。

fileinfo.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

void show_stat_info(char *, struct stat *);

int main(int argc, char *argv[])
{
    struct stat info;        

    if (argc>1)
    {

        if( stat(argv[1], &info) != -1 ){
            show_stat_info( argv[1], &info );
            return 0;
        }
        else
            perror(argv[1]);
    }
    return 1;
}
void show_stat_info(char *fname, struct stat *buf)
{
    printf("   mode: %o\n", buf->st_mode);
    printf("  links: %d\n", buf->st_nlink);
    printf("   user: %d\n", buf->st_uid);
    printf("  group: %d\n", buf->st_gid);
    printf("   size: %d\n", (int)buf->st_size);
    printf("modtime: %d\n", (int)buf->st_mtime);
    printf("   name: %s\n", fname );
}

用来实现显示文件信息。

filesize.c

#include <stdio.h>
#include <sys/stat.h>

int main()
{
    struct stat infobuf;           

    if ( stat( "/etc/passwd", &infobuf) == -1 )
        perror("/etc/passwd");
    else
        printf(" The size of /etc/passwd is %d\n", infobuf.st_size );
}

计算文件字节数大小。

ls1

#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:\n", *++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\n", dirname);
    else
    {
        /*递归的方式来读取*/
        while ( ( direntp = readdir( dir_ptr ) ) != NULL )
            printf("%s\n", direntp->d_name );
        closedir(dir_ptr);
    }
}

ls2

#include    <stdio.h>
#include    <string.h>
#include    <sys/types.h>
#include    <dirent.h>
#include    <sys/stat.h>

void do_ls(char[]);
void dostat(char *);
void show_file_info( char *, struct stat *);
void mode_to_letters( int , char [] );
char *uid_to_name( uid_t );
char *gid_to_name( gid_t );

int main(int argc, char *argv[])
{
    if ( argc == 1 )
        do_ls( "." );
    else
        while ( --argc ){
            printf("%s:\n", *++argv );
            do_ls( *argv );
        }

    return 0;
}

void do_ls( char dirname[] )
{
    DIR        *dir_ptr;
    struct dirent    *direntp;        

    if ( ( dir_ptr = opendir( dirname ) ) == NULL )
        fprintf(stderr,"ls1: cannot open %s\n", dirname);
    else
    {
        while ( ( direntp = readdir( dir_ptr ) ) != NULL )
            dostat( direntp->d_name );
        closedir(dir_ptr);
    }
}

void dostat( char *filename )
{
    struct stat info;

    if ( stat(filename, &info) == -1 )
        perror( filename );
    else
        show_file_info( filename, &info );
}

void show_file_info( char *filename, struct stat *info_p )
{
    char    *uid_to_name(), *ctime(), *gid_to_name(), *filemode();
    void    mode_to_letters();
        char    modestr[11];

    mode_to_letters( info_p->st_mode, modestr );

    printf( "%s"    , modestr );
    printf( "%4d "  , (int) info_p->st_nlink);
    printf( "%-8s " , uid_to_name(info_p->st_uid) );
    printf( "%-8s " , gid_to_name(info_p->st_gid) );
    printf( "%8ld " , (long)info_p->st_size);
    printf( "%.12s ", 4+ctime(&info_p->st_mtime));
    printf( "%s\n"  , filename );

}

void mode_to_letters( int mode, char str[] )
{
    strcpy( str, "----------" );           

    if ( S_ISDIR(mode) )  str[0] = 'd';
    if ( S_ISCHR(mode) )  str[0] = 'c';
    if ( S_ISBLK(mode) )  str[0] = 'b';    

    if ( mode & S_IRUSR ) str[1] = 'r';
    if ( mode & S_IWUSR ) str[2] = 'w';
    if ( mode & S_IXUSR ) str[3] = 'x';

    if ( mode & S_IRGRP ) str[4] = 'r';
    if ( mode & S_IWGRP ) str[5] = 'w';
    if ( mode & S_IXGRP ) str[6] = 'x';

    if ( mode & S_IROTH ) str[7] = 'r';
    if ( mode & S_IWOTH ) str[8] = 'w';
    if ( mode & S_IXOTH ) str[9] = 'x';
}

#include    <pwd.h>

char *uid_to_name( uid_t uid )
{
    struct    passwd *getpwuid(), *pw_ptr;
    static  char numstr[10];

    if ( ( pw_ptr = getpwuid( uid ) ) == NULL ){
        sprintf(numstr,"%d", uid);
        return numstr;
    }
    else
        return pw_ptr->pw_name ;
}

#include    <grp.h>

char *gid_to_name( gid_t gid )
{
    struct group *getgrgid(), *grp_ptr;
    static  char numstr[10];

    if ( ( grp_ptr = getgrgid(gid) ) == NULL ){
        sprintf(numstr,"%d", gid);
        return numstr;
    }
    else
        return grp_ptr->gr_name;
}

用来显示文件的详细信息,用户名、大小、创建时间等。

setecho.c

#include        <stdio.h>
#include         <stdlib.h>
#include        <termios.h>

#define  oops(s,x) { perror(s); exit(x); }

int main(int argc, char *argv[])
{
        struct termios info;

        if ( argc == 1 )
        exit(0);

        if ( tcgetattr(0,&info) == -1 )
            oops("tcgettattr", 1);

        if ( argv[1][0] == 'y' )
                info.c_lflag |= ECHO ;/*打开提示符*/
        else
                info.c_lflag &= ~ECHO ;/*隐藏提示符*/

        if ( tcsetattr(0,TCSANOW,&info) == -1 )
               oops("tcsetattr",2);

        return 0;
}

是否显示用户输入的指令。

spwd.c

#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <sys/types.h>
#include    <sys/stat.h>
#include    <dirent.h>

ino_t    get_inode(char *);
void    printpathto(ino_t);
void    inum_to_name(ino_t , char *, int );

int main()
{
    printpathto( get_inode( "." ) );
    putchar('\n');
    return 0;
}

void printpathto( ino_t this_inode )
{
    ino_t    my_inode ;
    char    its_name[BUFSIZ];

    if ( get_inode("..") != this_inode )
    {
        chdir( ".." );                

        inum_to_name(this_inode,its_name,BUFSIZ);

        my_inode = get_inode( "." );
        printpathto( my_inode );
        printf("/%s", its_name );        

    }
}

void inum_to_name(ino_t inode_to_find , char *namebuf, int buflen)
{
    DIR        *dir_ptr;
    struct dirent    *direntp;        

    dir_ptr = opendir( "." );
    if ( dir_ptr == NULL ){
        perror( "." );
        exit(1);
    }

    while ( ( direntp = readdir( dir_ptr ) ) != NULL )
        if ( direntp->d_ino == inode_to_find )
        {
            strncpy( namebuf, direntp->d_name, buflen);
            namebuf[buflen-1] = '\0';
            closedir( dir_ptr );
            return;
        }
    fprintf(stderr, "error looking for inum %d\n", (int) inode_to_find);
    exit(1);
}

ino_t get_inode( char *fname )
{
    struct stat info;

    if ( stat( fname , &info ) == -1 ){
        fprintf(stderr, "Cannot stat ");
        perror(fname);
        exit(1);
    }
    return info.st_ino;
}

功能是列出当前目录。

testioctl.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>

int main()
{
    struct winsize size;
    if( isatty(STDOUT_FILENO) == 0)
        exit(1);
    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &size) < 0) {
        perror("ioctl TIOCGWINSZ error");
        exit(1);
    }

    printf("%d rows %d columns\n", size.ws_row, size.ws_col);
    return 0;
}

who1.c
#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("\n");                

    return 0;
}
int main()
{
    struct utmp     current_record;
    int        utmpfd;
    int        reclen = sizeof(current_record);

    if ( (utmpfd = open(UTMP_FILE, O_RDONLY)) == -1 ){
        perror( UTMP_FILE );
        exit(1);
    }
    while ( read(utmpfd, &current_record, reclen) == reclen )
        show_info(&current_record);
    close(utmpfd);
    return 0;
}

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

who2.c
与who1一样

遇到的问题

1.运行第十章代码csapp.h
解决方法:增加头文件库
参考资料:http://group.cnblogs.com/topic/73278.html

参考资料

1.教材:第十章,详细学习指导:http://group.cnblogs.com/topic/73069.html

2.课程资料:https://www.shiyanlou.com/courses/413 实验十,课程邀请码:W7FQKW4Y

3.20135202闫佳歆 - 博客园http://www.cnblogs.com/20135202yjx/

 

系统级I/O 第八周11.9~11.15的更多相关文章

  1. 系统级I/O 第八周11.1~11.8

    第十章 系统级I/O 输入输出I/O是在主存和外部设备(如磁盘,网络和终端)之间拷贝数据的过程.输入就是从I/O设备拷贝数据到主存,而输出就是从主存拷贝数据到I/O设备. 所有语言的运行时系统都提供执 ...

  2. 第八周PSP(11.5--11.9)

    2016.11.5 2016.11.6 2016.11.7 2016.11.8 2016.11.9

  3. #2019-2020-4 《Java 程序设计》第八周总结

    2019-2020-4 <Java 程序设计>第八周知识总结 第15章:泛型与集合框架 一.泛型 1.泛型(Generics)是可以建立具有类型安全的集合框架,如链表.散列映射等数据结构: ...

  4. C语言程序设计II—第八周教学

    第八周教学总结(15/4-21/4) 教学内容 本周的教学内容为: 8.4 电码加密 知识点:指针与字符串,重难点:字符指针与字符串的关联和区别: 8.5 任意个整数求和 知识点:动态内存分配的概念和 ...

  5. 20165215 2017-2018-2 《Java程序设计》第八周学习总结

    20165215 2017-2018-2 <Java程序设计>第八周学习总结 教材学习内容总结 进程与线程 进程是程序的一次动态执行过程,它对应了从代码加载.执行至执行完毕的一个完整过程. ...

  6. LINUX内核分析第八周学习总结——进程的切换和系统的一般执行过程

    LINUX内核分析第八周学习总结——进程的切换和系统的一般执行过程 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/c ...

  7. Linux内核设计第八周 ——进程的切换和系统的一般执行过程

    Linux内核设计第八周 ——进程的切换和系统的一般执行过程 第一部分 知识点总结 第二部分 实验部分 1.配置实验环境,确保menu内核可以正常启动 2.进入gdb调试,在shedule和conte ...

  8. 20135327郭皓--Linux内核分析第八周 进程的切换和系统的一般执行过程

    第八周 进程的切换和系统的一般执行过程 一.进程切换的关键代码switch_to分析 1.进程调度与进程调度的时机分析 不同类型的进程有不同的调度需求 第一种分类: I/O-bound:频繁进行I/O ...

  9. 20135337朱荟潼 Linux第八周学习总结——进程的切换和系统的一般执行过程

    第八周 进程的切换和系统的一般执行过程 一.进程切换关键代码switch_to 1.不同类型进程有不同调度需求--两种分类 2.调度策略--规则 Linux中进程优先级是动态的,周期性调整. 3.时机 ...

随机推荐

  1. docker入门(1) Centos 7 下docker的安装

    centos 7安装docker 什么是 Docker Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目.它基于 Google 公司推出的 Go ...

  2. [转载] 关于PreparedStatement.addBatch()方法

    Statement和PreparedStatement的区别就不多废话了,直接说PreparedStatement最重要的addbatch()结构的使用. 1.建立链接(打电话拨号) Connecti ...

  3. Effective Java 26 Favor generic types

    Use generic types to replace the object declaration Add one or more type parameters to its declarati ...

  4. Effective Java 28 Use bounded wildcards to increase API flexibility

    Get and Put Principle PECS stands for producer-extends(? extends T), consumer-super(? super T). For ...

  5. SpringMVC4 + Spring + MyBatis3 基于注解的最简配置

    本文使用最新版本(4.1.5)的springmvc+spring+mybatis,采用最间的配置方式来进行搭建. 1. web.xml 我们知道springmvc是基于Servlet: Dispatc ...

  6. C++杂谈(一)const限定符与const指针

    const限定符 c++有了新的const关键字,用来定义常变量,可以替C语言中的#define.关于const限定符,有以下需要注意: 1.创建后值不再改变 2.作用范围在文件内有效 3.添加ext ...

  7. 03_汇编语言(n个数找最大值)

    程序要求: 先输入一个数n(0<n<=100),再输入n个无符号数K(0<=K<=65535),找出这n个数的最大值并输出 测试实例保证输入每个数之后,都会以回车结束 代码: ...

  8. Go

    一.简介 https://zh.wikipedia.org/wiki/Go 二.安装 1)低版本 http://blog.sina.com.cn/s/blog_59cc90640102xm8r.htm ...

  9. Linux dsh

    一.简介 目前在企业网络中越来越多的出现Linux服务器,而如何方便高效的管理大量的Linux服务器是系统管理员非常关心的一个问题,而dsh正是一个通过命令行有效地管理大量Linux的工具.   二. ...

  10. openwrt简单ipk生成及Makefile解释

    前言 类似的文章其实网上比较多了,我写这个的目的: 1,网上文章良莠不齐,有些自己都没实际动手操作,随便复制粘贴,实际操作不可行. 2,基本只讲了操作,我当时最关心的Makefile文件的解释没有. ...