linux命令之——mv.c 文件解读 (coreutils-8.9)
2011-02-11 15:44
357 查看
本来今天是想吧unp那个实例搞定的,中途学了会Makefile 糊里糊涂的就研究了一下mv.c文件。
相信像上篇文章中使用mv命令的你早已很是熟悉这个命令了,咱们看看他的具体实现吧,本来是想直接在系统中找到他的,后来发现他却是个比Linux还要早的历史产物归属于GUN,直接到ftp://ftp.gnu.org/gnu/这里有个叫coreutils的文件夹就是啦,里面是我们用的各种命令,我下载的
是8.5写着个东西时候最新的版本了!
废话不多说,咱赶紧看看mv.c都干了什么吧!
上面的代码我翻译了mv.c的部分注释也加了一些我自己的注释
这段是main函数对上面两个主要函数的调用,其他的地方先略着,有兴趣的自己看看吧~~~
可以看出movefile函数主要是处理了目录的情况,和路径的问题,然后把实际的工作交给了do_move,然后do_move函数主要完成了当出现跨文件系统的时候怎么处理文件copy的后续工作,mv命令主要还是使用了copy.c中的copy函数,这个文件暂时我还没看全,先写这些防备忘记也分享给大家共同进步。
我这个英语很不给力,大家别见笑,想看原版的直接下载就好……
相信像上篇文章中使用mv命令的你早已很是熟悉这个命令了,咱们看看他的具体实现吧,本来是想直接在系统中找到他的,后来发现他却是个比Linux还要早的历史产物归属于GUN,直接到ftp://ftp.gnu.org/gnu/这里有个叫coreutils的文件夹就是啦,里面是我们用的各种命令,我下载的
是8.5写着个东西时候最新的版本了!
废话不多说,咱赶紧看看mv.c都干了什么吧!
/* 移动SOURCE到DEST.主要处理跨文件系统的情况如果SOURCE是一个目录, DEST必须不存在. 如果成功了返回true. */ static bool do_move (const char *source, const char *dest, const struct cp_options *x) { bool copy_into_self; bool rename_succeeded; bool ok = copy (source, dest, false, x, ©_into_self, &rename_succeeded); if (ok) { char const *dir_to_remove; if (copy_into_self) { /* 通常当SOURCE和DEST一样或者是DEST的父目录的时候copy会返回copy_into_self在这种情况 下我们知道SOURCE是作为一个父目录出现的,移动一个目录到他自己里是没有意义的 and 除此之 外在某些情况下这么做会带来很不直观的结果,在一个空目录中执行 `mkdir b; touch a c; mv * b'.这时候会返回错误,mv: 无法将目录 “b” 移动至自身的子目录 “b/b” 下。通过一个 特征值处理这个问题, 删除copied-into-self目录, DEST (`b/b' 在这个例子中),并返回失 败. */ dir_to_remove = NULL; ok = false; } else if (rename_succeeded) { /* SOURCE成功的rename到DEST不许要删除任何文件,或者权限拒绝重命名一个文件 */ dir_to_remove = NULL; } else { /* 这个可能意味着SOURCE和DEST在不同的设备中也可能被认为是尽管SOURCE和DEST在同一个设 备中但是rename是不被允许的. 就好象你用ftpfs向ftp服务器申请上传,下载,删除但是不能重命名一样 在检查can-rename的时候设备号是不可靠的,因为有些系统从不同物理设备上建立文件但是他 们有相同的st_dev字段(NFS就是这样的) 如果SOURCE成功的copy到DECT,那么我们必须删除SOURCE 这个函数通常用在复制只是当重命名失败并且设置errno等于EXDEV */ dir_to_remove = source; } if (dir_to_remove != NULL) { struct rm_options rm_options; enum RM_status status; char const *dir[2]; rm_option_init (&rm_options); rm_options.verbose = x->verbose; dir[0] = dir_to_remove; dir[1] = NULL; status = rm ((void*) dir, &rm_options); assert (VALID_STATUS (status)); if (status == RM_ERROR) ok = false; } } return ok; } /* 移动文件SOURCE到DEST.主要处理DEST是目录的时候如果DEST_IS_DIR则DEST是目录 如果成功返回true. */ static bool movefile (char *source, char *dest, bool dest_is_dir, const struct cp_options *x) { bool ok; /* 这段代码处理由于重命名函数的不同语义导致的mv语义上的歧义 有些系统(如:GNU/Linux)的重命名函数处理最后的‘/’, 一些别的系统(如: Solaris 5,6,7)的重命名函数忽略最后的‘/’ (此处引用源代码中的注释) */ if (remove_trailing_slashes) /* bool strip_trailing_slashes(char *file) 函数删除FILE最后的‘/’ */ strip_trailing_slashes (source); /* 如果第二个参数是目录 */ if (dest_is_dir) { /* 获取source整个路径名的最后部分 */ char const *src_basename = last_component (source); /* 将获取的最后部分和dest连接构成新的目标路径 */ char *new_dest = file_name_concat (dest, src_basename, NULL); strip_trailing_slashes (new_dest); ok = do_move (source, new_dest, x); /* 释放申请的内存 */ free (new_dest); } /* 如果第二个参数不是目录 */ else { ok = do_move (source, dest, x); } return ok; }
上面的代码我翻译了mv.c的部分注释也加了一些我自己的注释
int main (int argc, char **argv) { ... if (target_directory) { int i; /* Initialize the hash table only if we'll need it. The problem it is used to detect can arise only if there are two or more files to move. */ if (2 <= n_files) dest_info_init (&x); ok = true; for (i = 0; i < n_files; ++i) ok &= movefile (file[i], target_directory, true, &x); } else ok = movefile (file[0], file[1], false, &x); ... }
这段是main函数对上面两个主要函数的调用,其他的地方先略着,有兴趣的自己看看吧~~~
可以看出movefile函数主要是处理了目录的情况,和路径的问题,然后把实际的工作交给了do_move,然后do_move函数主要完成了当出现跨文件系统的时候怎么处理文件copy的后续工作,mv命令主要还是使用了copy.c中的copy函数,这个文件暂时我还没看全,先写这些防备忘记也分享给大家共同进步。
我这个英语很不给力,大家别见笑,想看原版的直接下载就好……
相关文章推荐
- LinuxStudyNote(12)-Linux常用命令(2)-文件处理命令(7)mv文件目录剪切及更名
- Linux命令---- mv移动或重命名文件/目录
- Linux基础文件管理命令之rm,mv,cp,touch
- Linux下重命名文件或文件夹(mv命令与rename命令)
- linux 操作系统中文件的剪切命令mv
- Linux命令:目录重命名与移动mv,删除文件rm,目录创建mkdir删除rmdir,查看file,cat,more,tail,head
- linux-14基础命令之-复制(cp)移动(mv),删除(rm),拷贝文件(dd)
- Linux命令 find和mv的结合使用:查找文件,移动到某个目录
- mv命令--Linux命令应用大词典729个命令解读
- 我使用过的Linux命令之mv - 文件或目录改名、移动位置
- linux命令---复制和移动文件 cp和mv
- linux下文件的复制、移动与删除命令为:cp,mv,rm
- Linux 文件管理命令详解 cp,mv,install (笔记)
- Linux命令 find和mv的结合使用:查找文件,移动到某个目录
- Linux中文件的可读,可写,可执行权限的解读以及chmod,chown,chgrp命令的用法
- Linux 命令 - mv: 移动或重命名文件
- linux命令学习-文件目录之mv命令
- Linux文件管理类命令之mv
- mv命令--Linux命令应用大词典729个命令解读
- Linux文件操作详解(九)--文件/文件夹的重命名和移动(mv命令)