系统编程相关的系统调用

系统编程

命令行解析

GETOPT 函数
头文件 : <unistd.h>

原型 : int getopt(int argc, char * const argv[], const char *optstring);
argc  argv : 由main 函数的参数直接传递而来
optstring : 一个包含准确选项的字符串
返回值 : 返回下一个选项
// 四个全局变量   通常和while一起使用
//char *optarg  指向当前选项的参数
//int optind 下一个选项的索引
//int optopt 最后一个已知选项
//int opterr 向stderr打印错误
man 3 getopt
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "ab:c::")) != -1) {
        switch (opt) {
            case 'a' :
                printf("opt a found\n");
                printf("ind = %d\n", optind);
                break;
            case 'b' :
                printf("opt b found\n");
                printf("ind = %d\n", optind);
                printf("arg for b = %s\n", optarg);
                break;
            case 'c' :
                printf("opt c found\n");break;
            default :
                fprintf(stderr, "Usage : %s -a -b arg -c[carg]", argv[0]);
                exit(1);
        }
    }

    return 0;
}

文件与目录基本操作

open

多个进程打开同一个文件, 内核只会维护一个父本,每个进程进行写的时候在用户空间有缓冲,按下保存后才写入,并且后面写入的会覆盖前面的。

用户只能通过系统调用来进入内核(相当于要办事先填表) 填好表之后调用open()下沉到内核(内核也有缓冲机制)进行等待IO,等待cpu调度。

返回一个文件描述符 进程对文件进行标号(每个进程有个表记录自己的标号)

用户态下沉到内核态 内核态打开文件返回到用户态

系统调用 内核实现的时候也是有缓冲的(在open中 O_DIRECT 这个可以最小化缓冲称为直接IO )

man open  //具体查看man
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);  //加了权限的
//第一个参数是文件名   
//第二个参数是个位掩码   O_RDONLY,  O_WRONLY, or O_RDWR.


void perror(const char *s); //int errno;  有个全局变量  当出错了旧设置他多以perror要放在判断里面
int main(int argc, char **argv) {
    int fd;
    if ((fd = open(argv[1], O_RDONLY)) < 0) {
        fprintf(stderr, "ERROR!\n");
        perror("open");
    }
    perror("open2");  // 如果出错errno已经被设置了
}

int close(int fd); //内核有个计数器  当为0时释放内存
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
// 实现cp功能   用系统调用实现
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
    int fd, fd2;
    if (argc != 3) {
        fprintf(stderr, "Usage : %s faild", argv[0]);
    } 
    if ((fd = open(argv[1], O_RDONLY)) < 0) {
        perror("open");
        exit(1);
    }
    if ((fd2 = open(argv[2], O_CREAT | O_RDWR, 0666)) < 0) {  //要给权限不然全是零  
        perror("open");                                       //umask会对other进行减法操作
        exit(1);
    }
    while (1) {
        char buff[512] = {0};
        ssize_t size = read(fd, buff, sizeof(buff)); 
        printf("%s", buff);
        write(fd2, buff, size);                    //读到多少就写多少
        if (size <= 0) {
            break;
        }
    }
    close(fd);
    close(fd2);

    return 0;
}

fopen() 标准io提供的一系列函数

FILE *fopen(const char *pathname, const char *mode);
//打开一个文件流
int fseek(FILE *stream, long offset, int whence);
//在文件流里寻找   whence   可以设置SEEK_SET,SEEK_CUR, or SEEK_END
//实现cp功能   ./a.out  -r 1.c  -w 2.c    用标准IO实现
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int main(int argc, char **argv) {
	int opt;
    char rfile[50] = {0}, wfile[20] = {0};
    FILE *r, *w;
    while ((opt = getopt(argc, argv, "r:w:")) != -1) {
        switch(opt) {
            case 'r':
                strcpy(rfile, optarg);
                break;
            case 'w':
                strcpy(wfile, optarg);
                break;
            default:
                fprintf(stderr, "Usage : %s -r -w\n", argv[0]);
                exit(1);
        }
    }	

    if ((strlen(rfile) == 0) || strlen(wfile) == 0) {
        fprintf(stderr, "Usage : %s -r -w \n", argv[0]);
        exit(1);
    }
    if ((r = fopen(rfile, "r")) == NULL) {
        perror(rfile);
        exit(1);
    }
    if ((w = fopen(wfile, "w")) == NULL) {
        perror(wfile);
        exit(1);
    }
    while (1) {
        char buff[512] = {0};
        size_t size = fread(buff, 1, sizeof(buff), r);
        if (size <= 0) {
            break;
        }
        fwrite(buff, 1, size, w);
    }
    fclose(r);
    fclose(w);
    return 0;
}

目录操作

#include <dirent.h>
DIR *opendir(const char *name);
struct dirent *readdir(DIR *dirp);
int chdir(const char *path);

 struct dirent {
               ino_t          d_ino;       
               off_t          d_off;       
               unsigned short d_reclen;    
               unsigned char  d_type;                                      
               char           d_name[256];
           };

实现ls
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h> 

int main(int argc, char **argv) {
    DIR *dir = NULL;
    char dir_name[256] = {0};
    if (argc == 1) {
        strcpy(dir_name, ".");
    } else {
        strcpy(dir_name, argv[1]);
    }
    if ((dir = opendir(dir_name)) == NULL) {
        perror(dir_name);
        exit(1);
    }

    while (1) {
        struct dirent *dir_ptr;
        if((dir_ptr = readdir(dir)) == NULL) {
            break;
        }
        printf("%s\n", dir_ptr->d_name);
    }
    closedir(dir);

    return 0;
}

// 还有一些命令来完善ls
//stat  查看文件具体信息
int stat(const char *pathname, struct stat *statbuf);
 struct stat {
               dev_t     st_dev;         
               ino_t     st_ino;         
               mode_t    st_mode;    //stat.h文件里   
               nlink_t   st_nlink;       
               uid_t     st_uid;    //    getpwuid 
               gid_t     st_gid;    //    getgrgid
               dev_t     st_rdev;      
               off_t     st_size;       
               blksize_t st_blksize;    
               blkcnt_t  st_blocks;      

               struct timespec st_atim; 
               struct timespec st_mtim;  
               struct timespec st_ctim;  
           };

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值