Cai Xianchao <[EMAIL PROTECTED]> wrote: > The file TODO described a bug of cp (package:coreutils-6.9): > "cp --recursive: perform dir traversals in source and dest hierarchy > rather than forming full file names. The latter (current) approach > fails unnecessarily when the names become very long." > > We find that if the length of file name is not shorter than PATH_MAX, > it will fail. > > Now, we have solved the problem by using the *at functions which were > added to linux in kernel 2.6.16. If the kernel is older than 2.6.16, > cp will run the same as before.
Thank you very much for working on that problem! I wish you had announced your plan earlier -- I could have saved you some time. There are approximately 20 places in your patch where code like this has been added: fchdir (dst_relative_fd); ret_abandon_move = abandon_move (x, dst_relative_path, &dst_sb); fchdir (currentpath_fd); True, that does achieve the goal of allowing longer names, but at the expense of changing the current directory. copy.c must not change the process's working directory, first because it is intended to be library-like, but also because ping-ponging back and forth via fchdir is unnecessary and hurts performance. Of course, on systems that lack native openat, copy still calls *at functions, but they go through gnulib's portability layer, which may call fchdir/chdir. But that's ok, because it affects only older and less-functional systems. Instead, you should use fts to perform the source-tree traversal. That handles most of the tricky details for you -- on the source side. However, in order to traverse the destination tree, you will have to maintain a single primary file descriptor, initially open on the parent of the destination directory -- or maybe on the destination directory itself. Then, as you create each new subdirectory (via mkdirat), you would advance that primary descriptor to a new one open on the just-created directory. Also, there is no need for #if directives like this: #if defined __USE_ATFILE && defined PATH_MAX For examples of some of the things you will have to do with fts, see du.c, and ch*.c. Note also that with a file-descriptor-based traversal, it is no longer necessary to form full, relative file names while performing a traversal (except for diagnostics). And in fact, if you are not careful in how/when you form full names, you can mistakenly end up making the code inefficient (O(Depth^2)) for a deep hierarchy. For an example of how to do that, see the obstacks in remove.c's "struct dirstack_state". If you pursue this, the FSF will need a copyright assignment from the author(s) of the work, and I see none on file yet. Have you already completed/mailed the necessary forms? If not, let me know and I'll send them. _______________________________________________ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils