annotate toys/posix/ln.c @ 1776:7bf68329eb3b draft default tip

Repository switched to git at https://github.com/landley/toybox
author Rob Landley <rob@landley.net>
date Thu, 09 Apr 2015 02:28:32 -0500
parents 58d9f1b61f0a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
1 /* ln.c - Create filesystem links
461
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
2 *
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
3 * Copyright 2012 Andre Renaud <andre@bluewatersys.com>
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
4 *
656
6df4ccc0acbe Regularize command headers, update links to standards documents.
Rob Landley <rob@landley.net>
parents: 653
diff changeset
5 * See http://opengroup.org/onlinepubs/9699919799/utilities/ln.html
461
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
6
1144
58daf9c9a0b1 ln -v support from Ashwini Sharma (comment tweak from me)
Rob Landley <rob@landley.net>
parents: 782
diff changeset
7 USE_LN(NEWTOY(ln, "<1vnfs", TOYFLAG_BIN))
461
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
8
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
9 config LN
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
10 bool "ln"
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
11 default y
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
12 help
1144
58daf9c9a0b1 ln -v support from Ashwini Sharma (comment tweak from me)
Rob Landley <rob@landley.net>
parents: 782
diff changeset
13 usage: ln [-sfnv] [FROM...] TO
461
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
14
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
15 Create a link between FROM and TO.
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
16 With only one argument, create link in current directory.
461
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
17
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
18 -s Create a symbolic link
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
19 -f Force the creation of the link, even if TO already exists
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
20 -n Symlink at destination treated as file
1144
58daf9c9a0b1 ln -v support from Ashwini Sharma (comment tweak from me)
Rob Landley <rob@landley.net>
parents: 782
diff changeset
21 -v Verbose
461
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
22 */
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
23
674
7e846e281e38 New build infrastructure to generate FLAG_ macros and TT alias, #define FOR_commandname before #including toys.h to trigger it. Rename DEFINE_GLOBALS() to just GLOBALS() (because I could never remember if it was DECLARE_GLOBALS). Convert existing commands to use new infrastructure, and replace optflag constants with FLAG_ macros where appropriate.
Rob Landley <rob@landley.net>
parents: 656
diff changeset
24 #define FOR_ln
461
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
25 #include "toys.h"
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
26
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
27 void ln_main(void)
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
28 {
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
29 char *dest = toys.optargs[--toys.optc], *new;
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
30 struct stat buf;
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
31 int i;
462
3947b397c328 Teach ln about multiple arguments.
Rob Landley <rob@landley.net>
parents: 461
diff changeset
32
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
33 // With one argument, create link in current directory.
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
34 if (!toys.optc) {
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
35 toys.optc++;
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
36 dest=".";
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
37 }
462
3947b397c328 Teach ln about multiple arguments.
Rob Landley <rob@landley.net>
parents: 461
diff changeset
38
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
39 // Is destination a directory?
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
40 if (((toys.optflags&FLAG_n) ? lstat : stat)(dest, &buf)
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
41 || !S_ISDIR(buf.st_mode))
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
42 {
1713
58d9f1b61f0a Patches from Elliott Hughes to add missing arguments to error_exit() calls.
Rob Landley <rob@landley.net>
parents: 1531
diff changeset
43 if (toys.optc>1) error_exit("'%s' not a directory", dest);
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
44 buf.st_mode = 0;
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
45 }
461
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
46
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
47 for (i=0; i<toys.optc; i++) {
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
48 int rc;
1531
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
49 char *oldnew, *try = toys.optargs[i];
462
3947b397c328 Teach ln about multiple arguments.
Rob Landley <rob@landley.net>
parents: 461
diff changeset
50
1183
0752b2d58909 Rename xmsprintf() to just xmprintf().
Rob Landley <rob@landley.net>
parents: 1144
diff changeset
51 if (S_ISDIR(buf.st_mode)) new = xmprintf("%s/%s", dest, basename(try));
782
3d7526f6115b Use basename() where appropriate.
Rob Landley <rob@landley.net>
parents: 750
diff changeset
52 else new = dest;
1531
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
53
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
54 // Force needs to unlink the existing target (if any). Do that by creating
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
55 // a temp version and renaming it over the old one, so we can retain the
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
56 // old file in cases we can't replace it (such as hardlink between mounts).
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
57 oldnew = new;
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
58 if (toys.optflags & FLAG_f) {
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
59 new = xmprintf("%s_XXXXXX", new);
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
60 rc = mkstemp(new);
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
61 if (rc >= 0) {
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
62 close(rc);
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
63 if (unlink(new)) perror_msg("unlink '%s'", new);
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
64 }
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
65 }
462
3947b397c328 Teach ln about multiple arguments.
Rob Landley <rob@landley.net>
parents: 461
diff changeset
66
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
67 rc = (toys.optflags & FLAG_s) ? symlink(try, new) : link(try, new);
1531
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
68 if (toys.optflags & FLAG_f) {
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
69 if (!rc) {
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
70 int temp;
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
71
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
72 rc = rename(new, oldnew);
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
73 temp = errno;
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
74 if (rc && unlink(new)) perror_msg("unlink '%s'", new);
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
75 errno = temp;
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
76 }
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
77 free(new);
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
78 new = oldnew;
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
79 }
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
80 if (rc)
1531
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
81 perror_msg("cannot create %s link from '%s' to '%s'",
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
82 (toys.optflags & FLAG_s) ? "symbolic" : "hard", try, new);
1531
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
83 else
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
84 if (toys.optflags & FLAG_v) fprintf(stderr, "'%s' -> '%s'\n", new, try);
3ff823086c99 Teach ln -f to leave original target alone if link creation fails.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
85
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
86 if (new != dest) free(new);
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
87 }
461
ca74293f87f1 Add ln from Andre Renaud.
Rob Landley <rob@landley.net>
parents:
diff changeset
88 }