aboutsummaryrefslogtreecommitdiff
path: root/coreutils/ln.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-10-21 23:40:20 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-10-21 23:40:20 +0000
commitf24e1f40e032e99cf57a05730e7632b825d3016d (patch)
treea6d0fa74d59e67d1570c54157f5ebcc47b4522d0 /coreutils/ln.c
parent8d73c35916cbae67f5d0269b128de40f9992ddc6 (diff)
downloadbusybox-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.c43
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 }