diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-10-21 23:40:20 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-10-21 23:40:20 +0000 |
commit | f24e1f40e032e99cf57a05730e7632b825d3016d (patch) | |
tree | a6d0fa74d59e67d1570c54157f5ebcc47b4522d0 /coreutils/ln.c | |
parent | 8d73c35916cbae67f5d0269b128de40f9992ddc6 (diff) | |
download | busybox-w32-f24e1f40e032e99cf57a05730e7632b825d3016d.tar.gz busybox-w32-f24e1f40e032e99cf57a05730e7632b825d3016d.tar.bz2 busybox-w32-f24e1f40e032e99cf57a05730e7632b825d3016d.zip |
cp: add support for -s, -l. Fix free(nonmalloc) bug.
Add doc on POSIX's rules on -i and -f (insane!).
ln: make "ln dangling_symlink new_link" work.
Diffstat (limited to 'coreutils/ln.c')
-rw-r--r-- | coreutils/ln.c | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/coreutils/ln.c b/coreutils/ln.c index cd6e470be..231a3bf03 100644 --- a/coreutils/ln.c +++ b/coreutils/ln.c | |||
@@ -49,36 +49,39 @@ int ln_main(int argc, char **argv) | |||
49 | src = last; | 49 | src = last; |
50 | 50 | ||
51 | if (is_directory(src, | 51 | if (is_directory(src, |
52 | (flag & LN_NODEREFERENCE) ^ LN_NODEREFERENCE, | 52 | (flag & LN_NODEREFERENCE) ^ LN_NODEREFERENCE, |
53 | NULL)) { | 53 | NULL)) { |
54 | src_name = xstrdup(*argv); | 54 | src_name = xstrdup(*argv); |
55 | src = concat_path_file(src, bb_get_last_path_component(src_name)); | 55 | src = concat_path_file(src, bb_get_last_path_component(src_name)); |
56 | free(src_name); | 56 | free(src_name); |
57 | src_name = src; | 57 | src_name = src; |
58 | } | 58 | } |
59 | if (!(flag & LN_SYMLINK) && stat(*argv, &statbuf)) { | 59 | if (!(flag & LN_SYMLINK) && stat(*argv, &statbuf)) { |
60 | bb_perror_msg("%s", *argv); | 60 | // coreutils: "ln dangling_symlink new_hardlink" works |
61 | status = EXIT_FAILURE; | 61 | if (lstat(*argv, &statbuf) || !S_ISLNK(statbuf.st_mode)) { |
62 | free(src_name); | 62 | bb_perror_msg("%s", *argv); |
63 | continue; | 63 | status = EXIT_FAILURE; |
64 | free(src_name); | ||
65 | continue; | ||
66 | } | ||
64 | } | 67 | } |
65 | 68 | ||
66 | if (flag & LN_BACKUP) { | 69 | if (flag & LN_BACKUP) { |
67 | char *backup; | 70 | char *backup; |
68 | backup = xasprintf("%s%s", src, suffix); | 71 | backup = xasprintf("%s%s", src, suffix); |
69 | if (rename(src, backup) < 0 && errno != ENOENT) { | 72 | if (rename(src, backup) < 0 && errno != ENOENT) { |
70 | bb_perror_msg("%s", src); | 73 | bb_perror_msg("%s", src); |
71 | status = EXIT_FAILURE; | 74 | status = EXIT_FAILURE; |
72 | free(backup); | ||
73 | continue; | ||
74 | } | ||
75 | free(backup); | 75 | free(backup); |
76 | /* | 76 | continue; |
77 | * When the source and dest are both hard links to the same | 77 | } |
78 | * inode, a rename may succeed even though nothing happened. | 78 | free(backup); |
79 | * Therefore, always unlink(). | 79 | /* |
80 | */ | 80 | * When the source and dest are both hard links to the same |
81 | unlink(src); | 81 | * inode, a rename may succeed even though nothing happened. |
82 | * Therefore, always unlink(). | ||
83 | */ | ||
84 | unlink(src); | ||
82 | } else if (flag & LN_FORCE) { | 85 | } else if (flag & LN_FORCE) { |
83 | unlink(src); | 86 | unlink(src); |
84 | } | 87 | } |