linux文件操作指令的c语言代码实现

来源:互联网 发布:tomcat 1099端口 编辑:程序博客网 时间:2024/06/07 00:34

cp 拷贝命令

#include<stdio.h>//linux文件指令cp的模拟实现#include<stdlib.h>#include<fcntl.h>#include<unistd.h>#define BUFFERSIZE 4096#define COPYMOOE 0644void oops(char *, char *);int main(int argc, char *argv[]){    int in_fd, out_fd, n_chars;    char buf[BUFFERSIZE];    if(argc != 3)    {        fprintf(stderr, "usage: %s source destination\n", *argv);        exit(1);    }    if((in_fd = open(argv[1], O_RDONLY)) == -1)    {        oops("Cannot creat ", argv[1]);    }    if((out_fd = creat(argv[2], COPYMOOE)) == -1)    {        oops("Cannot creat ", argv[2]);    }        while((n_chars = read(in_fd, buf, BUFFERSIZE)) > 0)    {        if(write(out_fd, buf, sizeof(buf)) != n_chars)        {           oops("Write error to ", argv[2]);        }    }    if(n_chars == -1)    {        oops("Read error from ",argv[1]);    }    if(close(in_fd) == -1||close(out_fd) == -1)    {        oops("Error closing files", "");    }    return 0;}void oops(char *s1, char *s2){    fprintf(stderr, "Error: %s", s1);    perror(s2);    exit(1);}/*开头四行包含了 4 个头文件,<stdio.h> 文件包含了 fprintf、perror 的函数原型定义;<unistd.h> 文件包含了 read、write 的函数原型定义;<fcntl.h> 文件包含了 open、creat 的函数原型定义、<stdlib.h> 文件包含了 exit 的函数原型定义。这些函数原型有些是系统调用、有些是库函数,通常都可以在 /usr/include 目录中找到这些头文件。接下来的 2 行以宏定义的方式定义了 2 个常量。BUFFERSIZE 用来表示缓冲区的大小、COPYMODE 用来定义创建文件的权限。接下来的一行定义了一个函数原型 oops,该函数的具体定义在最后出现,用来输出出错信息到 stderr,也就是标准错误输出的文件流。接下来主程序开始。首先定义了 2 个文件描述符、一个存放读出字节数的变量 n_chars、和一个 BUFFERSIZE 大小的字符数组用来作为拷贝文件的缓冲区。接下来判断输入参数的个数是否为 3,也就是程序名 argv[0]、拷贝源文件 argv[1]、目标文件 argv[2]。不为 3 的话就输出错误信息到 stderr,然后退出程序。接下来的 2 行,用 open 系统调用以 O_RDONLY 只读模式打开拷贝源文件,如果打开失败就输出错误信息并退出。如果想了解文件打开模式的详细内容请使用命令 man 2 open,来查看帮助文档。接下来的 2 行,用 creat 系统调用以 COPYMODE 的权限建立一个文件,如果建立失败函数的返回值为 -1 的话,就输出错误信息并退出。接下来的循环是拷贝的主要过程。它从输入文件描述符 in_fd 中,读入 BUFFERSIZE 字节的数据,存放到 buf 字符数组中。在正常读入的情况下,read 函数返回实际读入的字节数,也就是说只要没有异常情况和文件没有读到结尾,那么 n_chars 中存放的就是实际读出的字节的数字。然后 write 函数将从 buf 缓冲区中,读出 n_chars 个字符,写入 in_out 输出文件描述符。由于 write 系统调用返回的是实际写入成功的字节数。所以当读出 N 个字符,又成功写入 N 个字符到输出文件描述符中去的时候,就表示写成功了,否则就报告写入错误。最后就是用 close 系统调用关闭打开的输入和输出文件描述符。*/

这段代码的执行结果就跟cp命令一样,你可以用linux的cp命令和这个代码执行结果进行对比,结果一样。

mkdir 删除目录命令

这个是我对linux下mkdir命令的修改版,也没什么新奇的地方就是加上了一个检查,来查看你想要新建的文件是否存在,如果存在则问你坚持新建还是保留(其实没必要,就是闲的加上的)其中检验我用了两种方法
#include<stdio.h>//linux 操作指令mkdir删除目录#include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<limits.h>#include<stdlib.h>int bool_bool(char *str);int main(int argc, char *argv[]){    char path[1000];    char file[1000];    int flag = 0;    step1:    if(argc != 2)    {        printf("Usage mk<pathname>\n");        return 1;    }   // argv[1] = "test";    getwd(path);//取得当前工作目录    //if(argv[1] == )    printf("current dirctory is %s\n", path);    char *p = (char *)malloc(sizeof(char)*1000);    p = path;    if((mkdir(argv[1], S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH)< 0)&&flag == 0)//创建新目录    {   //     bool_n(argv[1]);        getwd(path);        /*if(p == path)//检验当前目录和创建前的目录是否相同,相同提示用户错误并给出解决机制        {            printf("The directory is existed!\n");            printf("Do you want creat new one? \"y\"or\"n\"\n");            if(getchar() == 'y')            {                rmdir(path);//删除新目录                printf("%s is removed\n", path);     //           bool_n(argv[1]);                getwd(path);                printf("current dirctory is %s\n", path);                flag++;                goto step1;               // return 5;            }            if(getchar() == 'n')            {                return 0;            }        }*/        if(access(path, F_OK) == 0)//这是一个文件权限校验函数,F_OK是一个权限mode,用来检验当前路径是否存在        {            printf("The directory is existed!\n");            printf("Do you want creat new one? \"y\"or\"n\"\n");            if(getchar() == 'y')            {                rmdir(path);//删除新目录                printf("%s is removed\n", path);     //           bool_n(argv[1]);                getwd(path);                printf("current dirctory is %s\n", path);                flag++;                goto step1;               // return 5;            }            if(getchar() == 'n')            {                return 0;            }                    }        printf("mkdir failed!\n");        return 2;    }        bool_n(argv[1]);    /*if(chdir(argv[1]) < 0)//改变当前目录为新目录    {        printf("chdir failed!\n");        return 3;    }*/    getwd(path);    printf("mkdir successful.\nNew current directory is %s\n",path);   /* rmdir(path);//删除新目录    printf("%s is removed\n", path);*/    return 0;}int bool_n(char *str){    if(chdir(str) < 0)//改变当前目录为新目录    {        printf("chdir failed!\n");        return 3;    }    }
运行结果:
首先我们看运行之前我的目录:

下面我们执行程序:
执行后的目录:
在f1目录存在的情况下执行:
程序检查到f1目录存在会问你Do you want create new one?然后等待用户输入y or n
程序执行以后的当前目录同图3.
让我们再执行一次这次输入n:

rm 删除文件命令

#include<stdio.h>#include<unistd.h>#include<stdlib.h>//linux操作指令rmint main(int argc, char *argv[]){    int rt;    if(argc != 2)    {        exit(2);    }    else    {        if((rt = unlink(argv[1])) != 0)        {            fprintf(stderr, "error");            exit(3);        }    }    return 0;}
这里主要就是unlink函数,你可以通过strace  ./rm test来追踪这条命令的执行过程来看文件是怎么被删除的。这里系统调用了那些函数。
程序的执行结果跟rm效果相同我就不截图了,我截一个追踪结果的截图作为参考,调用过程这里不做详解:

我们可以看到系统在检查了内存,校验了文件的权限以后调用了unlink()函数删除了文件。

以上博文如有缺陷和不足,希望指出。谢谢。

阅读全文
0 0
原创粉丝点击