xcp - 带有状态显示的 Linux 复制命令

本文介绍了作者重写的一个名为xcp的Linux复制命令,旨在替代原始的cp命令,尤其在复制大量文件时能显示进度。xcp通过遍历源文件两次来实现,首次用于统计,第二次执行复制。作者还优化了代码风格,减少了递归函数的栈空间使用,并调整参数处理以匹配cp的常用习惯。文章提供了xcp.c源代码和Makefile供读者参考。
摘要由CSDN通过智能技术生成

好长时间没有更新了,偶然看到几年前写的一个复制工具,代码惨不忍睹,所以重写了一遍.

目的: xcp - 代替 Linux 的 cp 命令,复制大量文件时显示进度

实现: 遍历源文件两次,第一次统计,第二次复制

本次更新内容: 用统一的编码风格整理代码,减少递归函数使用的栈空间,调整参数处理方式使之同 cp 的习惯用法保持一致

 

附1: xcp.c

// #define _FILE_OFFSET_BITS 64

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <sys/time.h>
#include <stdarg.h>
#include <errno.h>
#include <assert.h>

/*
* 复制文件可以显示进度
*
* 两个思路:遍历文件一次,把文件名记录在一个列表,后续操作直接从列表中得到文件名
* 或者遍历两遍,第一次统计,第二次执行
*
* 关于进度条
* 1. 用定时器每隔1秒刷新一次要注意函数重入的问题
* 2. 两个线程工作线程统计/拷贝主线程刷新状态,似乎小题大做了
* 3. 一个线程有变化时刷新,这样就无法现实动画
*
* 2013-10-22
* 1. 添加命令行选项的处理。
* 2. 添加文件无法访问/目录无法创建或者文件/目录已经存在的情况的处理。
* 3. 如果没有任何文件成功复制时的提示信息BUG(在有文件detected的情况下)。
* 4. 复制文件,目标是已经存在的目录名时自动添加文件名而不是直接复制。
* 5. 结束时用human_time 来显示用去的时间。
*
* 2013-10-23
* 1. 统计阶段也要显示动画
*
* 2013-10-24
* 1. overwrite 提示后等待用户输入和定时器冲突的问题
*
* 2013-10-29
 1. 多源拷贝在主函数做个循环,都要补齐文件名,判断是否存在等.
*
* 2020-1-10
* v0.2 重写整个程序
* 1. 使之符合 cp 命令的习惯
* 2. 遵循 linux 编码风格
*
* 2020-1-11
* v0.3 添加覆盖时 yes/no to all 选项
* v0.3.1 细节修订
* v0.3.2 细节修订
* v0.3.3 代码格式修订
*/

#define MAX_FMTSTR_LENGTH			2048/*传递给print_message函数的格式字符串最大长度*/
#define COPY_BUF_SIZE				4096 /*复制文件时每次读取的长度*/
#define MAX_PATH_LENGTH				(PATH_MAX + 1)/*路径的最大长度*/
#define GBYTES						(1024 * 1024 * 1024)
#define MBYTES						(1024 * 1024)
#define KBYTES						1024
#define HOUR						(60 * 60)
#define MINUTE						60
#define OP_CONTINUE					0
#define OP_SKIP						1
#define OP_CANCEL					2 /*walk 函数终止遍历退出*/

#define MSGT_PROMPT					0
#define MSGT_WARNING				1
#define MSGT_ERROR					2
#define MSGT_VERBOSE				3

/*启用大文件支持*/
//#define _LARGEFILE64_SOURCE
//#define _FILE_OFFSET_BITS 64

//#ifdef _LARGEFILE64_SOURCE
//#define stat stat64
//#define fopen fopen64
//#define fread fread64
//#define fwrite fwrite64
//#endif

typedef int (*op_func_t)(const char*, const char*, const struct stat*, const struct stat*);
typedef void (*sig_handler_t)(int);

/* 全局变量 */
int g_sum_file = 0;
int g_sum_dir = 0;
long long g_sum_size = 0;
int g_copied_file = 0;
int g_copied_dir = 0;
long long g_copied_size = 0;
time_t g_copy_start_time = 0;
int g_status_pause = 0;
int g_opt_d = 0;
int g_opt_f = 0;
int g_opt_q = 0;
int g_opt_r = 0;
int g_opt_v = 0;
char g_copy_buf[COPY_BUF_SIZE];
int g_auto_choice = 0;

/*显示为可读数字*/
static char *human_size(long long s, char *hs)
{
	if (s >= GBYTES) {
		sprintf(hs, "%.2fGB", (s * 1.0) / GBYTES);
	} else if (s >= 1024 * 1024) {
		sprintf(hs, "%.2fMB", (s * 1.0) / MBYTES);
	} else if (s > 1024) {
		sprintf(hs, "%.2fKB", (s * 1.0) / KBYTES);
	} else {
		sprintf(hs, "%lldB", s);
	}
	return hs;
}

/* human readable time */
static char *human_time(time_t t, char *text)
{
	int h, m, s;
	h = (int)(t / HOUR);
	m = (int)((t % HOUR) / MINUTE);
	s = (int)(t % HOU
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值