Mercurial > hg > toybox
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 |
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 | 2 * |
3 * Copyright 2012 Andre Renaud <andre@bluewatersys.com> | |
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 | 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 | 8 |
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 | 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 | 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 | 22 */ |
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 | 25 #include "toys.h" |
26 | |
27 void ln_main(void) | |
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 | 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 | 88 } |