system programming 第三讲 ls-la 的实现 lseek fcntl 高级io

实现ls -la

/*************************************************************************
	> File Name: 6.stat_la.c
	> Author: 
	> Mail: 
	> Created Time: Wed 01 Sep 2021 01:54:58 PM UTC
 ************************************************************************/

#include "head.h"

int main(int argc, char *argv[]){
    char dir_name[256] = {0};
    if(argc == 1){
        strcpy(dir_name, ".");
    }else{
        strcpy(dir_name, argv[1]);
    }
    DIR *dir = NULL;
    if ((dir = opendir(dir_name)) == NULL){
        perror("opendir");
        exit(1);
    }
    while(1){
        int stat_num;
        struct stat statbuf;
        struct dirent *dir_file;
        if((dir_file = readdir(dir)) == NULL){
            break;
        }
        if ((stat_num = lstat(dir_file->d_name, &statbuf )) != 0){
            perror("stat");
            exit(1);
        }
        mode_t val = statbuf.st_mode;
        char a;
        switch (val & S_IFMT){
            case S_IFLNK: a = 'l'; break;
            case S_IFBLK: a = 'b'; break;
            case S_IFCHR: a = 'c'; break;
            case S_IFDIR: a = 'd'; break;
            case S_IFIFO: a = 'p'; break;
            case S_IFREG: a = '-'; break;
            case S_IFSOCK: a = 's'; break;
            default: printf("unknown?");

        }
        struct passwd *gpu_passwd;
        struct group *ggg_group;
        gpu_passwd = getpwuid(statbuf.st_uid);
        ggg_group = getgrgid(statbuf.st_gid);

        printf("%ld", statbuf.st_ino);
        printf("%c", a);
        printf("%c", (val & S_IRUSR)? 'r':'-');
        printf("%c", (val & S_IWUSR)? 'w':'-');
        printf("%c", (val & S_IXUSR)? 'x':'-');
        printf("%c", (val & S_IRGRP)? 'r':'-');
        printf("%c", (val & S_IWGRP)? 'w':'-');
        printf("%c", (val & S_IXGRP)? 'x':'-');
        printf("%c", (val & S_IROTH)? 'r':'-');
        printf("%c", (val & S_IWOTH)? 'w':'-');
        printf("%c", (val & S_IXOTH)? 'x':'-');

        printf("%s", gpu_passwd->pw_name);
        printf("%s", ggg_group->gr_name);

        printf(" %ld", statbuf.st_size);

        printf("%s", dir_file->d_name);
        printf("\n");
    }
    return 0;

}

lseek

#include "head.h"
int main(int argc, char **argv){
    //1. 打开文件 方式 判断是否成功
    //2. lseek 确定文件的大小
    int fd;
    if((fd = open(argv[1], O_RDONLY)) < 0){
        perror("open");
        exit(1); 
    }
    char c;
    printf("position %ld\n", lseek(fd, 0, SEEK_CUR));
    read(fd, &c, 1);
    write(STDOUT_FILENO, &c, 1);
    printf("\nposition %ld\n", lseek(fd, 0, SEEK_CUR));
    
    printf("\nposition %ld\n", lseek(fd, 3, SEEK_CUR));
    
    read(fd, &c, 1);
    write(STDOUT_FILENO, &c, 1);

    printf("\nposition %ld\n", lseek(fd, 0, SEEK_END)); //这个可以用来输出文件的大小
    return 0;
}

请添加图片描述
输出的22 和a.txt的大小一样,其实就是a.txt的大小
请添加图片描述
输出的2356 和 6.stat-la.c 大小一致

fcntl

#include "head.h"
int main(int argc, char **argv){
    //1.打开文件 确定一个打开方式 判断
    //2.fcntl获得 fd 属性
    int fd;
    if ((fd = open(argv[1], O_RDONLY)) < 0){
        perror("open");
        exit(1);
    }
    int flag;
    if((flag = fcntl(fd, F_GETFL)) < 0){
        perror("fcntl");
        exit(1);
    }
    flag |= O_NONBLOCK;
    fcntl(fd, F_SETFL, flag);
    printf("%d\n", flag);
    switch(flag & O_ACCMODE){
        case O_RDONLY:
            printf("rdonly\n");
            break;
        case O_WRONLY:
            printf("wronly\n");
            break;
        case O_RDWR:
            printf("rdwr\n");
            break;
        default:
            printf("no\n");
            break;

    }
    if ((flag & O_NONBLOCK) == O_NONBLOCK){
        printf("o_nonblock\n");
    }
    printf("O_NONBLOCK = %d = %o\n", flag & O_NONBLOCK, flag & O_NONBLOCK);
    return 0;

}

open/fcntl

#define O_ACCMODE      0003
#define O_RDONLY         00
#define O_WRONLY         01
#define O_RDWR           02
#ifndef O_CREAT
# define O_CREAT       0100 /* Not fcntl.  */
#endif
#ifndef O_EXCL
# define O_EXCL        0200 /* Not fcntl.  */
#endif
#ifndef O_NOCTTY
# define O_NOCTTY      0400 /* Not fcntl.  */
#endif
#ifndef O_TRUNC
# define O_TRUNC      01000 /* Not fcntl.  */
#endif
#ifndef O_APPEND
# define O_APPEND     02000
#endif
#ifndef O_NONBLOCK
# define O_NONBLOCK   04000

请添加图片描述
请添加图片描述
O_NONBLOCK 04000(八进制是一样的)

#include "head.h"
int main(int argc, char **argv){
    //1.打开文件 确定一个打开方式 判断
    //2.fcntl获得 fd 属性
    int fd;
    if ((fd = open(argv[1], O_RDONLY)) < 0){
        perror("open");
        exit(1);
    }
    int flag;
    if((flag = fcntl(fd, F_GETFL)) < 0){
        perror("fcntl");
        exit(1);
    }
    flag |= O_NONBLOCK;
    fcntl(fd, F_SETFL, flag);
    printf("%d\n", flag);
    switch(flag & O_ACCMODE){
        case O_RDONLY:
            printf("rdonly\n");
            break;
        case O_WRONLY:
            printf("wronly\n");
            break;
        case O_RDWR:
            printf("rdwr\n");
            break;
        default:
            printf("no\n");
            break;

    }
    if ((flag & O_NONBLOCK) == O_NONBLOCK){
        printf("o_nonblock\n");
    }
    printf("O_NONBLOCK = %d = %o\n", flag & O_NONBLOCK, flag & O_NONBLOCK);
    int flag1, flag2;
    flag1 = flag & (~O_NONBLOCK);
    //flag &= ~O_NONBLOCK; //O_NONBLOCK取反再与()老师讲的
    //fcntl(fd, F_SETFL, flag1);
    //flag1 = fcntl(fd, F_GETFL);
    flag2 = flag ^ O_NONBLOCK;
    printf("O_NONBLOCK = %o\n", flag1 & O_NONBLOCK);
    printf("O_NONBLOCK = %o\n", flag2 & O_NONBLOCK);
    return 0;

}

请添加图片描述

这里老师讲了如何去掉标识位(比如这里去掉O_NONBLOCK),但我觉得用异或更好?试了一下是对的,不知道是不是满足所有情况。

高级IO

dd

请添加图片描述
请添加图片描述
所以4MB最快

视频两小时之后

#include"head.h"

int main(){
    int fd;

    if ((fd = open("/dev/tty", O_RDONLY | O_NONBLOCK)) < 0){
        perror("open");
        exit(1); 
    }
    ssize_t size;
    char buff[10] = {0};
    while(1){
        size = read(fd, buff, 10);
        if(~size){
            for (int i = 0; i < size; i++){
                printf("%c", buff[i]);
            }
            break;

        }
        fprintf(stdout, "try again\n");
        sleep(1);
    }
    return 0;
}

请添加图片描述
因为是以行为输入,所以必须要输入一行(一个换行符)才是可以的,否则一直处于阻塞状态。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值