实现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;
}
因为是以行为输入,所以必须要输入一行(一个换行符)才是可以的,否则一直处于阻塞状态。