曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 5355|回复: 1
打印 上一主题 下一主题

cp 命令的基本实现

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2008-11-16 23:18:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
编写一个基本的 cp 命令:

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

#define BUFFERSIZE 4096
#define COPYMODE   0644


void oops(char *s1, char *s2);

int main(int ac, char *av[])
{
    int in_fd, out_fd, n_chars;
    char buf[ BUFFERSIZE ];


    if(ac != 3){       /*cp命令必须带有 2 个参数,一个是被复制的源文件,一个是需要复制的文件*/
    fprintf( stderr,"usage: %s source destination\n", *av);
    exit(1);
    }

    if( (in_fd = open(av[1],O_RDONLY) ) == -1 ) /*先测试被复制的文件是否能打开*/
    oops("Cannot open ", av[1]);  

/*能成功创建文件吗?先创建0字节文件然后复制时被填充*/
    if( (out_fd = creat(av[2],COPYMODE) ) == -1 )
    oops("Cannot creat ", av[2]);

/*读取到的数据字节数给 n_chars */
    while( (n_chars = read(in_fd, buf, BUFFERSIZE)) > 0 ) /*由文件指针控制着一直读到完为止*/
    if( write( out_fd, buf, n_chars ) != n_chars)   /*所有的读到的数据都完整的写了吗?*/
        oops("Write error from ", av[2]);           /*写发生错误了*/
    if( n_chars == -1 )
    oops("Read error from", av[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);
}

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
沙发
 楼主| 发表于 2008-11-19 23:17:59 | 只看该作者

增加是否覆盖已有文件选项

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

#define  BUFFERSIZE   4096
#define  COPYMODE     0644





main(int ac, char *av[])
{
    int in_fd, out_fd, n_chars;
    char buf[BUFFERSIZE];
    char *src  = NULL;
    char *dest = NULL;
    int  i_option = 0;

 
    while( --ac ){                        /*参数赋值,后续需要检查*/
    if( strcmp("-i", *++av) == 0 )
        i_option = 1;
    else if( !src )
        src = *av;
    else if( !dest )
        dest = *av;
    else
        usage();        /*还有参数则出错(至多允许有3个参数)*/
    }

    if( !src || !dest )
    usage();                 /*复制源和复制目的文件两者必须同时存在*/

    if( (in_fd=open(src, O_RDONLY) ) == -1 )    /*源文件可用?*/
    oops("Cannot open", src);        

/*不指定 -i 参数 or 复制目的文件没有已存在 or 输入 y 或者 Y 确定要覆盖已存在的目的文件*/
    if( !i_option || !exists(dest) || ok_to_replace(dest) )
    if( (out_fd = creat( dest, COPYMODE )) == -1/*创建目的文件并指定相应的权限,如文件已经存在则会被创建的文件所覆盖*/
         oops("Cannot creat", dest);     

    while( ( n_chars = read(in_fd, buf, BUFFERSIZE) ) > 0/*一次读取 BUFFERSIZE 字节数据*/
    if( write(out_fd, buf, n_chars) != n_chars )             /*写 BUFFERSIZE 数字若不等于读出的 BUFFERSIZE 则出错*/
    oops("Write error to ", dest);
   
   if( n_chars == -1 )
       oops("Read error from",src);          /*读源文件出错*/

if( close(in_fd) == -1 || close(out_fd) == -1 )       /*关闭文件出错*/
       oops("Error closing files", "");

    return 0;
}

    oops(char *s1,char *s2)
   {
       fprintf(stderr, "Error: %s", s1);
       perror(s2);
       exit(1);
   }


    usage()
    {
    fprintf(stderr, "usage: cp [-i] source dest\\n");
    exit(1);
    }

int exists(char *filename)
{
    int fd;

    if( fd = open(filename, O_RDONLY) )      /* 尝试读取目的文件,出错则返回 -1 */
    close(fd);
    return(fd != -1);
}

int ok_to_replace(char *filename)
{
    char ans[10];
    char c;
    int retval = 0;

    fprintf(stderr, "cp: Ok to replace '%s'? ", filename);

    if( scanf("%9s",ans) == 1 ){
    if( *ans == 'y' || *ans == 'Y'/*要覆盖已存在的文件*/
        retval = 1;
    }

/*输入 EOF 或者 回车 则返回(retval=0)*/
    while( ( c = getchar() ) != EOF && c != '\\n' );

    return retval;    
}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-6 08:34 , Processed in 0.079028 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表