Mercurial > hg > octave-nkf > gnulib-hg
annotate lib/linkat.c @ 14152:c5273d4d49b3
Update to Unicode 5.2.0.
* lib/gen-uni-tables.c (output_predicate, output_category,
output_combclass, output_bidi_category, output_decimal_digit_test,
output_decimal_digit, output_digit_test, output_digit,
output_numeric_test, output_numeric, output_mirror, output_scripts,
output_scripts_byname, output_blocks, output_ident_category): Fix
comment header.
(is_WBP_MIDNUMLET, is_WBP_MIDLETTER): New functions, extracted from
get_wbp.
(PROP_CASED, PROP_CASE_IGNORABLE, PROP_CHANGES_WHEN_*): New enumeration
items.
(fill_properties): Also fill the peoperties Cased, Case_Ignorable,
Changes_When_Lowercased, Changes_When_Uppercased,
Changes_When_Titlecased, Changes_When_Casefolded,
Changes_When_Casemapped.
(is_property_alphabetic, is_property_default_ignorable_code_point):
Update for Unicode 5.2.0.
(is_property_cased, is_property_case_ignorable,
is_property_changes_when_lowercased,
is_property_changes_when_uppercased,
is_property_changes_when_titlecased,
is_property_changes_when_casefolded,
is_property_changes_when_casemapped): New functions.
(output_properties): Output also the properties cased, case_ignorable,
changes_when_lowercased, changes_when_uppercased,
changes_when_titlecased, changes_when_casefolded,
changes_when_casemapped.
(symbolic_width): Update for Unicode 5.2.0, incorporating changes from
Unicode TR#11 revision 17 -> 19.
(LBP_CP): New enumeration value.
(LBP_*): Adjust values accordingly.
(get_lbp): Update for Unicode 5.2.0, incorporating changes from Unicode
TR#14 revision 22 -> 24.
(debug_output_lbp): Allow for LBP_* bits >= 32. Support LBP_CP.
(fill_org_lbp, debug_output_org_lbp, output_lbp): Support LBP_CP.
(get_wbp): Update for Unicode 5.2.0, incorporating changes from Unicode
TR#29 revision 13 -> 15. Use functions is_WBP_MIDNUMLET,
is_WBP_MIDLETTER.
(output_composition_tables): Allow for 24 bits instead of 16 bits in
the code1 and code2 of each composition rule.
* lib/unicase/cased.h: Regenerated for Unicode 5.2.0.
* lib/unicase/ignorable.h: Likewise.
* lib/unicase/tocasefold.h: Likewise.
* lib/unicase/tolower.h: Likewise.
* lib/unicase/totitle.h: Likewise.
* lib/unicase/toupper.h: Likewise.
* lib/unictype/bidi_of.h: Likewise.
* lib/unictype/blocks.h: Likewise.
* lib/unictype/categ_C.h: Likewise.
* lib/unictype/categ_Cf.h: Likewise.
* lib/unictype/categ_Cn.h: Likewise.
* lib/unictype/categ_L.h: Likewise.
* lib/unictype/categ_Ll.h: Likewise.
* lib/unictype/categ_Lm.h: Likewise.
* lib/unictype/categ_Lo.h: Likewise.
* lib/unictype/categ_Lu.h: Likewise.
* lib/unictype/categ_M.h: Likewise.
* lib/unictype/categ_Mc.h: Likewise.
* lib/unictype/categ_Mn.h: Likewise.
* lib/unictype/categ_N.h: Likewise.
* lib/unictype/categ_Nd.h: Likewise.
* lib/unictype/categ_Nl.h: Likewise.
* lib/unictype/categ_No.h: Likewise.
* lib/unictype/categ_P.h: Likewise.
* lib/unictype/categ_Pd.h: Likewise.
* lib/unictype/categ_Po.h: Likewise.
* lib/unictype/categ_S.h: Likewise.
* lib/unictype/categ_Sc.h: Likewise.
* lib/unictype/categ_So.h: Likewise.
* lib/unictype/categ_of.h: Likewise.
* lib/unictype/combining.h: Likewise.
* lib/unictype/ctype_alnum.h: Likewise.
* lib/unictype/ctype_alpha.h: Likewise.
* lib/unictype/ctype_graph.h: Likewise.
* lib/unictype/ctype_lower.h: Likewise.
* lib/unictype/ctype_print.h: Likewise.
* lib/unictype/ctype_punct.h: Likewise.
* lib/unictype/ctype_upper.h: Likewise.
* lib/unictype/decdigit.h: Likewise.
* lib/unictype/digit.h: Likewise.
* lib/unictype/numeric.h: Likewise.
* lib/unictype/pr_alphabetic.h: Likewise.
* lib/unictype/pr_bidi_arabic_digit.h: Likewise.
* lib/unictype/pr_bidi_eur_num_terminator.h: Likewise.
* lib/unictype/pr_bidi_european_digit.h: Likewise.
* lib/unictype/pr_bidi_hebrew_right_to_left.h: Likewise.
* lib/unictype/pr_bidi_left_to_right.h: Likewise.
* lib/unictype/pr_bidi_non_spacing_mark.h: Likewise.
* lib/unictype/pr_bidi_other_neutral.h: Likewise.
* lib/unictype/pr_combining.h: Likewise.
* lib/unictype/pr_composite.h: Likewise.
* lib/unictype/pr_currency_symbol.h: Likewise.
* lib/unictype/pr_dash.h: Likewise.
* lib/unictype/pr_decimal_digit.h: Likewise.
* lib/unictype/pr_deprecated.h: Likewise.
* lib/unictype/pr_diacritic.h: Likewise.
* lib/unictype/pr_extender.h: Likewise.
* lib/unictype/pr_grapheme_base.h: Likewise.
* lib/unictype/pr_grapheme_extend.h: Likewise.
* lib/unictype/pr_grapheme_link.h: Likewise.
* lib/unictype/pr_id_continue.h: Likewise.
* lib/unictype/pr_id_start.h: Likewise.
* lib/unictype/pr_ideographic.h: Likewise.
* lib/unictype/pr_ignorable_control.h: Likewise.
* lib/unictype/pr_logical_order_exception.h: Likewise.
* lib/unictype/pr_lowercase.h: Likewise.
* lib/unictype/pr_numeric.h: Likewise.
* lib/unictype/pr_other_alphabetic.h: Likewise.
* lib/unictype/pr_punctuation.h: Likewise.
* lib/unictype/pr_sentence_terminal.h: Likewise.
* lib/unictype/pr_terminal_punctuation.h: Likewise.
* lib/unictype/pr_unassigned_code_value.h: Likewise.
* lib/unictype/pr_unified_ideograph.h: Likewise.
* lib/unictype/pr_uppercase.h: Likewise.
* lib/unictype/pr_xid_continue.h: Likewise.
* lib/unictype/pr_xid_start.h: Likewise.
* lib/unictype/pr_zero_width.h: Likewise.
* lib/unictype/scripts.h: Likewise.
* lib/unictype/scripts_byname.gperf: Likewise.
* lib/unictype/sy_java_ident.h: Likewise.
* lib/unigbrk/gbrkprop.h: Likewise.
* lib/unilbrk/lbrkprop1.h: Likewise.
* lib/unilbrk/lbrkprop2.h: Likewise.
* lib/unilbrk/lbrktables.h: Likewise.
* lib/unilbrk/lbrktables.c (unilbrk_table): Add a row and column for
LBP_CP. Implement rule LB30.
* lib/uniwidth/width.c (nonspacing_table_data): Add U+0816..U+0819,
U+081B..U+0823, U+0825..U+0827, U+0829..U+082D, U+0900, U+0955, U+109D,
U+1A56, U+1A58..U+1A5E, U+1A60, U+1A62, U+1A65..U+1A6C, U+1A73..U+1A7C,
U+1A7F, U+1CD0..U+1CD2, U+1CD4..U+1CE0, U+1CE2..U+1CE8, U+1CED, U+1DFD,
U+2CEF..U+2CF1, U+A6F0..U+A6F1, U+A8E0..U+A8F1, U+A980..U+A982, U+A9B3,
U+A9B6..U+A9B9, U+A9BC, U+AAB0, U+AAB2..U+AAB4, U+AAB7..U+AAB8,
U+AABE..U+AABF, U+AAC1, U+ABE5, U+ABE8, U+ABED, U+11080..U+11081,
U+110B3..U+110B6, U+110B9..U+110BA, U+110BD.
(uc_width): Return 2 also for unassigned code points of planes 2 and 3.
* lib/uninorm/composition-table.gperf: Regenerated for Unicode 5.2.0.
* lib/uninorm/composition.c (struct composition_rule): Allow for 24
bits instead of 16 bits in the code1 and code2 of each composition
rule.
(uc_composition): Update for Unicode 5.2.0.
* lib/uninorm/decomposition-table1.h: Regenerated for Unicode 5.2.0.
* lib/uninorm/decomposition-table2.h: Likewise.
* lib/uniwbrk/wbrkprop.h: Likewise.
* tests/unicase/test-cased.c: Likewise.
* tests/unicase/test-ignorable.c: Likewise.
* tests/unicase/test-uc_tolower.c: Likewise.
* tests/unicase/test-uc_totitle.c: Likewise.
* tests/unicase/test-uc_toupper.c: Likewise.
* tests/unictype/test-categ_C.c: Likewise.
* tests/unictype/test-categ_Cf.c: Likewise.
* tests/unictype/test-categ_Cn.c: Likewise.
* tests/unictype/test-categ_L.c: Likewise.
* tests/unictype/test-categ_Ll.c: Likewise.
* tests/unictype/test-categ_Lm.c: Likewise.
* tests/unictype/test-categ_Lo.c: Likewise.
* tests/unictype/test-categ_Lu.c: Likewise.
* tests/unictype/test-categ_M.c: Likewise.
* tests/unictype/test-categ_Mc.c: Likewise.
* tests/unictype/test-categ_Mn.c: Likewise.
* tests/unictype/test-categ_N.c: Likewise.
* tests/unictype/test-categ_Nd.c: Likewise.
* tests/unictype/test-categ_Nl.c: Likewise.
* tests/unictype/test-categ_No.c: Likewise.
* tests/unictype/test-categ_P.c: Likewise.
* tests/unictype/test-categ_Pd.c: Likewise.
* tests/unictype/test-categ_Po.c: Likewise.
* tests/unictype/test-categ_S.c: Likewise.
* tests/unictype/test-categ_Sc.c: Likewise.
* tests/unictype/test-categ_So.c: Likewise.
* tests/unictype/test-ctype_alnum.c: Likewise.
* tests/unictype/test-ctype_alpha.c: Likewise.
* tests/unictype/test-ctype_graph.c: Likewise.
* tests/unictype/test-ctype_lower.c: Likewise.
* tests/unictype/test-ctype_print.c: Likewise.
* tests/unictype/test-ctype_punct.c: Likewise.
* tests/unictype/test-ctype_upper.c: Likewise.
* tests/unictype/test-decdigit.h: Likewise.
* tests/unictype/test-digit.h: Likewise.
* tests/unictype/test-numeric.h: Likewise.
* tests/unictype/test-pr_alphabetic.c: Likewise.
* tests/unictype/test-pr_bidi_arabic_digit.c: Likewise.
* tests/unictype/test-pr_bidi_eur_num_terminator.c: Likewise.
* tests/unictype/test-pr_bidi_european_digit.c: Likewise.
* tests/unictype/test-pr_bidi_hebrew_right_to_left.c: Likewise.
* tests/unictype/test-pr_bidi_left_to_right.c: Likewise.
* tests/unictype/test-pr_bidi_non_spacing_mark.c: Likewise.
* tests/unictype/test-pr_bidi_other_neutral.c: Likewise.
* tests/unictype/test-pr_combining.c: Likewise.
* tests/unictype/test-pr_composite.c: Likewise.
* tests/unictype/test-pr_currency_symbol.c: Likewise.
* tests/unictype/test-pr_dash.c: Likewise.
* tests/unictype/test-pr_decimal_digit.c: Likewise.
* tests/unictype/test-pr_deprecated.c: Likewise.
* tests/unictype/test-pr_diacritic.c: Likewise.
* tests/unictype/test-pr_extender.c: Likewise.
* tests/unictype/test-pr_grapheme_base.c: Likewise.
* tests/unictype/test-pr_grapheme_extend.c: Likewise.
* tests/unictype/test-pr_grapheme_link.c: Likewise.
* tests/unictype/test-pr_id_continue.c: Likewise.
* tests/unictype/test-pr_id_start.c: Likewise.
* tests/unictype/test-pr_ideographic.c: Likewise.
* tests/unictype/test-pr_ignorable_control.c: Likewise.
* tests/unictype/test-pr_logical_order_exception.c: Likewise.
* tests/unictype/test-pr_lowercase.c: Likewise.
* tests/unictype/test-pr_numeric.c: Likewise.
* tests/unictype/test-pr_other_alphabetic.c: Likewise.
* tests/unictype/test-pr_punctuation.c: Likewise.
* tests/unictype/test-pr_sentence_terminal.c: Likewise.
* tests/unictype/test-pr_terminal_punctuation.c: Likewise.
* tests/unictype/test-pr_unassigned_code_value.c: Likewise.
* tests/unictype/test-pr_unified_ideograph.c: Likewise.
* tests/unictype/test-pr_uppercase.c: Likewise.
* tests/unictype/test-pr_xid_continue.c: Likewise.
* tests/unictype/test-pr_xid_start.c: Likewise.
* tests/unictype/test-pr_zero_width.c: Likewise.
* tests/unigbrk/test-uc-gbrk-prop.h: Likewise.
* tests/unilbrk/test-u8-possible-linebreaks.c (main): Update for
changed behaviour: line breaking is now disallowed between a letter
or '=' and '('.
* tests/unilbrk/test-u16-possible-linebreaks.c (main): Likewise.
* tests/unilbrk/test-u32-possible-linebreaks.c (main): Likewise.
* tests/unilbrk/test-ulc-possible-linebreaks.c (main): Likewise.
* tests/unilbrk/test-ulc-width-linebreaks.c (main): Likewise.
* tests/uniwidth/test-uc_width2.sh: Same updates as in
lib/uniwidth/width.c.
* tests/uninorm/NormalizationTest.txt: Update from Unicode 5.2.0,
without comments, but with the original copyright notice.
* lib/unicase/special-casing-table.gperf: Regenerated; only comment
changes.
* lib/unictype/categ_Cc.h: Likewise.
* lib/unictype/categ_Co.h: Likewise.
* lib/unictype/categ_Cs.h: Likewise.
* lib/unictype/categ_Lt.h: Likewise.
* lib/unictype/categ_Me.h: Likewise.
* lib/unictype/categ_Pc.h: Likewise.
* lib/unictype/categ_Pe.h: Likewise.
* lib/unictype/categ_Pf.h: Likewise.
* lib/unictype/categ_Pi.h: Likewise.
* lib/unictype/categ_Ps.h: Likewise.
* lib/unictype/categ_Sk.h: Likewise.
* lib/unictype/categ_Sm.h: Likewise.
* lib/unictype/categ_Z.h: Likewise.
* lib/unictype/categ_Zl.h: Likewise.
* lib/unictype/categ_Zp.h: Likewise.
* lib/unictype/categ_Zs.h: Likewise.
* lib/unictype/ctype_blank.h: Likewise.
* lib/unictype/ctype_cntrl.h: Likewise.
* lib/unictype/ctype_digit.h: Likewise.
* lib/unictype/ctype_space.h: Likewise.
* lib/unictype/ctype_xdigit.h: Likewise.
* lib/unictype/mirror.h: Likewise.
* lib/unictype/pr_ascii_hex_digit.h: Likewise.
* lib/unictype/pr_bidi_arabic_right_to_left.h: Likewise.
* lib/unictype/pr_bidi_block_separator.h: Likewise.
* lib/unictype/pr_bidi_boundary_neutral.h: Likewise.
* lib/unictype/pr_bidi_common_separator.h: Likewise.
* lib/unictype/pr_bidi_control.h: Likewise.
* lib/unictype/pr_bidi_embedding_or_override.h: Likewise.
* lib/unictype/pr_bidi_eur_num_separator.h: Likewise.
* lib/unictype/pr_bidi_pdf.h: Likewise.
* lib/unictype/pr_bidi_segment_separator.h: Likewise.
* lib/unictype/pr_bidi_whitespace.h: Likewise.
* lib/unictype/pr_default_ignorable_code_point.h: Likewise.
* lib/unictype/pr_format_control.h: Likewise.
* lib/unictype/pr_hex_digit.h: Likewise.
* lib/unictype/pr_hyphen.h: Likewise.
* lib/unictype/pr_ids_binary_operator.h: Likewise.
* lib/unictype/pr_ids_trinary_operator.h: Likewise.
* lib/unictype/pr_iso_control.h: Likewise.
* lib/unictype/pr_join_control.h: Likewise.
* lib/unictype/pr_left_of_pair.h: Likewise.
* lib/unictype/pr_line_separator.h: Likewise.
* lib/unictype/pr_math.h: Likewise.
* lib/unictype/pr_non_break.h: Likewise.
* lib/unictype/pr_not_a_character.h: Likewise.
* lib/unictype/pr_other_default_ignorable_code_point.h: Likewise.
* lib/unictype/pr_other_grapheme_extend.h: Likewise.
* lib/unictype/pr_other_id_continue.h: Likewise.
* lib/unictype/pr_other_id_start.h: Likewise.
* lib/unictype/pr_other_lowercase.h: Likewise.
* lib/unictype/pr_other_math.h: Likewise.
* lib/unictype/pr_other_uppercase.h: Likewise.
* lib/unictype/pr_paired_punctuation.h: Likewise.
* lib/unictype/pr_paragraph_separator.h: Likewise.
* lib/unictype/pr_pattern_syntax.h: Likewise.
* lib/unictype/pr_pattern_white_space.h: Likewise.
* lib/unictype/pr_private_use.h: Likewise.
* lib/unictype/pr_quotation_mark.h: Likewise.
* lib/unictype/pr_radical.h: Likewise.
* lib/unictype/pr_soft_dotted.h: Likewise.
* lib/unictype/pr_space.h: Likewise.
* lib/unictype/pr_titlecase.h: Likewise.
* lib/unictype/pr_variation_selector.h: Likewise.
* lib/unictype/pr_white_space.h: Likewise.
* lib/unictype/sy_c_ident.h: Likewise.
* lib/unictype/sy_c_whitespace.h: Likewise.
* lib/unictype/sy_java_whitespace.h: Likewise.
* modules/uni*/*: Bump version number of expected libunistring version.
Reported by Simon Josefsson.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 09 Jan 2011 11:09:25 +0100 |
parents | 97fc9a21a8fb |
children | 2330aac2ae54 |
rev | line source |
---|---|
12068 | 1 /* Create a hard link relative to open directories. |
14079
97fc9a21a8fb
maint: update almost all copyright ranges to include 2011
Jim Meyering <meyering@redhat.com>
parents:
14050
diff
changeset
|
2 Copyright (C) 2009-2011 Free Software Foundation, Inc. |
12068 | 3 |
4 This program is free software: you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 3 of the License, or | |
7 (at your option) any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License | |
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
16 | |
17 /* written by Eric Blake */ | |
18 | |
19 #include <config.h> | |
20 | |
21 #include <unistd.h> | |
22 | |
23 #include <errno.h> | |
24 #include <fcntl.h> | |
25 #include <limits.h> | |
12121
49d6e6e49816
linkat: avoid compilation failure
Jim Meyering <meyering@redhat.com>
parents:
12120
diff
changeset
|
26 #include <stdint.h> |
12120 | 27 #include <stdlib.h> |
28 #include <string.h> | |
12068 | 29 #include <sys/stat.h> |
30 | |
31 #include "areadlink.h" | |
32 #include "dirname.h" | |
33 #include "filenamecat.h" | |
34 #include "openat-priv.h" | |
35 | |
36 #if HAVE_SYS_PARAM_H | |
37 # include <sys/param.h> | |
38 #endif | |
39 #ifndef MAXSYMLINKS | |
40 # ifdef SYMLOOP_MAX | |
41 # define MAXSYMLINKS SYMLOOP_MAX | |
42 # else | |
43 # define MAXSYMLINKS 20 | |
44 # endif | |
45 #endif | |
46 | |
12120 | 47 #if !HAVE_LINKAT |
48 | |
12068 | 49 /* Create a link. If FILE1 is a symlink, either create a hardlink to |
50 that symlink, or fake it by creating an identical symlink. */ | |
12120 | 51 # if LINK_FOLLOWS_SYMLINKS == 0 |
52 # define link_immediate link | |
53 # else | |
12068 | 54 static int |
55 link_immediate (char const *file1, char const *file2) | |
56 { | |
57 char *target = areadlink (file1); | |
58 if (target) | |
59 { | |
60 /* A symlink cannot be modified in-place. Therefore, creating | |
61 an identical symlink behaves like a hard link to a symlink, | |
62 except for incorrect st_ino and st_nlink. However, we must | |
63 be careful of EXDEV. */ | |
64 struct stat st1; | |
65 struct stat st2; | |
66 char *dir = mdir_name (file2); | |
67 if (!dir) | |
68 { | |
69 free (target); | |
70 errno = ENOMEM; | |
71 return -1; | |
72 } | |
73 if (lstat (file1, &st1) == 0 && stat (dir, &st2) == 0) | |
74 { | |
75 if (st1.st_dev == st2.st_dev) | |
76 { | |
77 int result = symlink (target, file2); | |
78 int saved_errno = errno; | |
79 free (target); | |
80 free (dir); | |
81 errno = saved_errno; | |
82 return result; | |
83 } | |
84 free (target); | |
85 free (dir); | |
86 errno = EXDEV; | |
87 return -1; | |
88 } | |
89 free (target); | |
90 free (dir); | |
91 } | |
92 if (errno == ENOMEM) | |
93 return -1; | |
94 return link (file1, file2); | |
95 } | |
12120 | 96 # endif /* LINK_FOLLOWS_SYMLINKS == 0 */ |
12068 | 97 |
98 /* Create a link. If FILE1 is a symlink, create a hardlink to the | |
99 canonicalized file. */ | |
12120 | 100 # if 0 < LINK_FOLLOWS_SYMLINKS |
101 # define link_follow link | |
102 # else | |
12068 | 103 static int |
104 link_follow (char const *file1, char const *file2) | |
105 { | |
106 char *name = (char *) file1; | |
107 char *target; | |
108 int result; | |
109 int i = MAXSYMLINKS; | |
110 | |
111 /* Using realpath or canonicalize_file_name is too heavy-handed: we | |
112 don't need an absolute name, and we don't need to resolve | |
113 intermediate symlinks, just the basename of each iteration. */ | |
114 while (i-- && (target = areadlink (name))) | |
115 { | |
116 if (IS_ABSOLUTE_FILE_NAME (target)) | |
117 { | |
118 if (name != file1) | |
119 free (name); | |
120 name = target; | |
121 } | |
122 else | |
123 { | |
124 char *dir = mdir_name (name); | |
125 if (name != file1) | |
126 free (name); | |
127 if (!dir) | |
128 { | |
129 free (target); | |
130 errno = ENOMEM; | |
131 return -1; | |
132 } | |
133 name = mfile_name_concat (dir, target, NULL); | |
134 free (dir); | |
135 free (target); | |
136 if (!name) | |
137 { | |
138 errno = ENOMEM; | |
139 return -1; | |
140 } | |
141 } | |
142 } | |
143 if (i < 0) | |
144 { | |
145 target = NULL; | |
146 errno = ELOOP; | |
147 } | |
148 if (!target && errno != EINVAL) | |
149 { | |
150 if (name != file1) | |
151 { | |
152 int saved_errno = errno; | |
153 free (name); | |
154 errno = saved_errno; | |
155 } | |
156 return -1; | |
157 } | |
158 result = link (name, file2); | |
159 if (name != file1) | |
160 { | |
161 int saved_errno = errno; | |
162 free (name); | |
163 errno = saved_errno; | |
164 } | |
165 return result; | |
166 } | |
12120 | 167 # endif /* 0 < LINK_FOLLOWS_SYMLINKS */ |
12068 | 168 |
14050
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
169 /* On Solaris, link() doesn't follow symlinks by default, but does so as soon |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
170 as a library or executable takes part in the program that has been compiled |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
171 with "c99" or "cc -xc99=all" or "cc ... /usr/lib/values-xpg4.o ...". */ |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
172 # if LINK_FOLLOWS_SYMLINKS == -1 |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
173 |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
174 /* Reduce the penalty of link_immediate and link_follow by incorporating the |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
175 knowledge that link()'s behaviour depends on the __xpg4 variable. */ |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
176 extern int __xpg4; |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
177 |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
178 static int |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
179 solaris_optimized_link_immediate (char const *file1, char const *file2) |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
180 { |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
181 if (__xpg4 == 0) |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
182 return link (file1, file2); |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
183 return link_immediate (file1, file2); |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
184 } |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
185 |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
186 static int |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
187 solaris_optimized_link_follow (char const *file1, char const *file2) |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
188 { |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
189 if (__xpg4 != 0) |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
190 return link (file1, file2); |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
191 return link_follow (file1, file2); |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
192 } |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
193 |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
194 # define link_immediate solaris_optimized_link_immediate |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
195 # define link_follow solaris_optimized_link_follow |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
196 |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
197 # endif |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
13514
diff
changeset
|
198 |
12068 | 199 /* Create a link to FILE1, in the directory open on descriptor FD1, to FILE2, |
200 in the directory open on descriptor FD2. If FILE1 is a symlink, FLAG | |
201 controls whether to dereference FILE1 first. If possible, do it without | |
202 changing the working directory. Otherwise, resort to using | |
203 save_cwd/fchdir, then rename/restore_cwd. If either the save_cwd or | |
204 the restore_cwd fails, then give a diagnostic and exit nonzero. */ | |
205 | |
206 int | |
207 linkat (int fd1, char const *file1, int fd2, char const *file2, int flag) | |
208 { | |
209 if (flag & ~AT_SYMLINK_FOLLOW) | |
210 { | |
211 errno = EINVAL; | |
212 return -1; | |
213 } | |
214 return at_func2 (fd1, file1, fd2, file2, | |
215 flag ? link_follow : link_immediate); | |
216 } | |
12120 | 217 |
218 #else /* HAVE_LINKAT */ | |
219 | |
220 # undef linkat | |
221 | |
222 /* Create a link. If FILE1 is a symlink, create a hardlink to the | |
223 canonicalized file. */ | |
224 | |
225 static int | |
226 linkat_follow (int fd1, char const *file1, int fd2, char const *file2) | |
227 { | |
228 char *name = (char *) file1; | |
229 char *target; | |
230 int result; | |
231 int i = MAXSYMLINKS; | |
232 | |
233 /* There is no realpathat. */ | |
234 while (i-- && (target = areadlinkat (fd1, name))) | |
235 { | |
236 if (IS_ABSOLUTE_FILE_NAME (target)) | |
237 { | |
238 if (name != file1) | |
239 free (name); | |
240 name = target; | |
241 } | |
242 else | |
243 { | |
244 char *dir = mdir_name (name); | |
245 if (name != file1) | |
246 free (name); | |
247 if (!dir) | |
248 { | |
249 free (target); | |
250 errno = ENOMEM; | |
251 return -1; | |
252 } | |
253 name = mfile_name_concat (dir, target, NULL); | |
254 free (dir); | |
255 free (target); | |
256 if (!name) | |
257 { | |
258 errno = ENOMEM; | |
259 return -1; | |
260 } | |
261 } | |
262 } | |
263 if (i < 0) | |
264 { | |
265 target = NULL; | |
266 errno = ELOOP; | |
267 } | |
268 if (!target && errno != EINVAL) | |
269 { | |
270 if (name != file1) | |
271 { | |
272 int saved_errno = errno; | |
273 free (name); | |
274 errno = saved_errno; | |
275 } | |
276 return -1; | |
277 } | |
278 result = linkat (fd1, name, fd2, file2, 0); | |
279 if (name != file1) | |
280 { | |
281 int saved_errno = errno; | |
282 free (name); | |
283 errno = saved_errno; | |
284 } | |
285 return result; | |
286 } | |
287 | |
288 | |
289 /* Like linkat, but guarantee that AT_SYMLINK_FOLLOW works even on | |
290 older Linux kernels. */ | |
291 | |
292 int | |
293 rpl_linkat (int fd1, char const *file1, int fd2, char const *file2, int flag) | |
294 { | |
295 if (flag & ~AT_SYMLINK_FOLLOW) | |
296 { | |
297 errno = EINVAL; | |
298 return -1; | |
299 } | |
300 | |
13514
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
301 #if LINKAT_TRAILING_SLASH_BUG |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
302 /* Reject trailing slashes on non-directories. */ |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
303 { |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
304 size_t len1 = strlen (file1); |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
305 size_t len2 = strlen (file2); |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
306 if ((len1 && file1[len1 - 1] == '/') |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
307 || (len2 && file2[len2 - 1] == '/')) |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
308 { |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
309 /* Let linkat() decide whether hard-linking directories is legal. |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
310 If fstatat() fails, then linkat() should fail for the same reason; |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
311 if fstatat() succeeds, require a directory. */ |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
312 struct stat st; |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
313 if (fstatat (fd1, file1, &st, flag ? 0 : AT_SYMLINK_NOFOLLOW)) |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
314 return -1; |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
315 if (!S_ISDIR (st.st_mode)) |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
316 { |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
317 errno = ENOTDIR; |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
318 return -1; |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
319 } |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
320 } |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
321 } |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
322 #endif |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
323 |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
324 if (!flag) |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
325 return linkat (fd1, file1, fd2, file2, flag); |
6154fce586b6
linkat: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
326 |
12120 | 327 /* Cache the information on whether the system call really works. */ |
328 { | |
329 static int have_follow_really; /* 0 = unknown, 1 = yes, -1 = no */ | |
330 if (0 <= have_follow_really) | |
331 { | |
332 int result = linkat (fd1, file1, fd2, file2, flag); | |
333 if (!(result == -1 && errno == EINVAL)) | |
334 { | |
335 have_follow_really = 1; | |
336 return result; | |
337 } | |
338 have_follow_really = -1; | |
339 } | |
340 } | |
341 return linkat_follow (fd1, file1, fd2, file2); | |
342 } | |
343 | |
344 #endif /* HAVE_LINKAT */ |