diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-08-24 21:46:24 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-08-24 21:46:24 +0000 |
commit | 6666ac42a5cd63a8b18ec72f6c1364f31ef53921 (patch) | |
tree | 64110c3cfad98cada86b87d1e6059173ca33dbd7 /coreutils/cp.c | |
parent | 2062fc415524e966862c60a6e35d03285f366cbb (diff) | |
download | busybox-w32-6666ac42a5cd63a8b18ec72f6c1364f31ef53921.tar.gz busybox-w32-6666ac42a5cd63a8b18ec72f6c1364f31ef53921.tar.bz2 busybox-w32-6666ac42a5cd63a8b18ec72f6c1364f31ef53921.zip |
cp,mv: simpler arg[cv] handling -> smallish code savings
Diffstat (limited to 'coreutils/cp.c')
-rw-r--r-- | coreutils/cp.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/coreutils/cp.c b/coreutils/cp.c index 884fbf70f..5b575819c 100644 --- a/coreutils/cp.c +++ b/coreutils/cp.c | |||
@@ -40,12 +40,16 @@ int cp_main(int argc, char **argv) | |||
40 | OPT_L = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3), | 40 | OPT_L = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3), |
41 | }; | 41 | }; |
42 | 42 | ||
43 | // Need at least two arguments | ||
43 | // Soft- and hardlinking don't mix | 44 | // Soft- and hardlinking don't mix |
44 | // -P and -d are the same (-P is POSIX, -d is GNU) | 45 | // -P and -d are the same (-P is POSIX, -d is GNU) |
45 | // -r and -R are the same | 46 | // -r and -R are the same |
46 | // -a = -pdR | 47 | // -a = -pdR |
47 | opt_complementary = "l--s:s--l:Pd:rR:apdR"; | 48 | opt_complementary = "-2:l--s:s--l:Pd:rR:apdR"; |
48 | flags = getopt32(argv, FILEUTILS_CP_OPTSTR "arPHL"); | 49 | flags = getopt32(argv, FILEUTILS_CP_OPTSTR "arPHL"); |
50 | argc -= optind; | ||
51 | argv += optind; | ||
52 | flags ^= FILEUTILS_DEREFERENCE; /* The sense of this flag was reversed. */ | ||
49 | /* Default behavior of cp is to dereference, so we don't have to do | 53 | /* Default behavior of cp is to dereference, so we don't have to do |
50 | * anything special when we are given -L. | 54 | * anything special when we are given -L. |
51 | * The behavior of -H is *almost* like -L, but not quite, so let's | 55 | * The behavior of -H is *almost* like -L, but not quite, so let's |
@@ -60,19 +64,12 @@ int cp_main(int argc, char **argv) | |||
60 | } | 64 | } |
61 | #endif | 65 | #endif |
62 | 66 | ||
63 | flags ^= FILEUTILS_DEREFERENCE; /* The sense of this flag was reversed. */ | ||
64 | |||
65 | if (optind + 2 > argc) { | ||
66 | bb_show_usage(); | ||
67 | } | ||
68 | |||
69 | last = argv[argc - 1]; | 67 | last = argv[argc - 1]; |
70 | argv += optind; | ||
71 | |||
72 | /* If there are only two arguments and... */ | 68 | /* If there are only two arguments and... */ |
73 | if (optind + 2 == argc) { | 69 | if (argc == 2) { |
74 | s_flags = cp_mv_stat2(*argv, &source_stat, | 70 | s_flags = cp_mv_stat2(*argv, &source_stat, |
75 | (flags & FILEUTILS_DEREFERENCE) ? stat : lstat); | 71 | (flags & FILEUTILS_DEREFERENCE) ? stat : lstat); |
72 | /* TODO: does coreutils cp exit? "cp BAD GOOD dir"... */ | ||
76 | if (s_flags < 0) | 73 | if (s_flags < 0) |
77 | return EXIT_FAILURE; | 74 | return EXIT_FAILURE; |
78 | d_flags = cp_mv_stat(last, &dest_stat); | 75 | d_flags = cp_mv_stat(last, &dest_stat); |
@@ -85,19 +82,24 @@ int cp_main(int argc, char **argv) | |||
85 | ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags) | 82 | ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags) |
86 | ) { | 83 | ) { |
87 | /* ...do a simple copy. */ | 84 | /* ...do a simple copy. */ |
88 | dest = xstrdup(last); | 85 | dest = last; |
89 | goto DO_COPY; /* Note: optind+2==argc implies argv[1]==last below. */ | 86 | goto DO_COPY; /* NB: argc==2 -> *++argv==last */ |
90 | } | 87 | } |
91 | } | 88 | } |
92 | 89 | ||
93 | do { | 90 | while (1) { |
94 | dest = concat_path_file(last, bb_get_last_path_component(*argv)); | 91 | dest = concat_path_file(last, bb_get_last_path_component(*argv)); |
95 | DO_COPY: | 92 | DO_COPY: |
96 | if (copy_file(*argv, dest, flags) < 0) { | 93 | if (copy_file(*argv, dest, flags) < 0) { |
97 | status = 1; | 94 | status = 1; |
98 | } | 95 | } |
96 | if (*++argv == last) { | ||
97 | /* possibly leaking dest... */ | ||
98 | break; | ||
99 | } | ||
99 | free((void*)dest); | 100 | free((void*)dest); |
100 | } while (*++argv != last); | 101 | } |
101 | 102 | ||
103 | /* Exit. We are NOEXEC, not NOFORK. We do exit at the end of main() */ | ||
102 | return status; | 104 | return status; |
103 | } | 105 | } |