1 | /* ----------------------------------------------------------------------- * |
2 | * |
3 | * Copyright 2016 The NASM Authors - All Rights Reserved |
4 | * See the file AUTHORS included with the NASM distribution for |
5 | * the specific copyright holders. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following |
9 | * conditions are met: |
10 | * |
11 | * * Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. |
13 | * * Redistributions in binary form must reproduce the above |
14 | * copyright notice, this list of conditions and the following |
15 | * disclaimer in the documentation and/or other materials provided |
16 | * with the distribution. |
17 | * |
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
19 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
20 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
25 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
26 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
29 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
30 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | * |
32 | * ----------------------------------------------------------------------- */ |
33 | |
34 | /* |
35 | * realpath.c As system-independent as possible implementation of realpath() |
36 | */ |
37 | |
38 | #include "compiler.h" |
39 | |
40 | #include <stdlib.h> |
41 | #include <errno.h> |
42 | #include <limits.h> |
43 | #ifdef HAVE_UNISTD_H |
44 | # include <unistd.h> |
45 | #endif |
46 | #ifdef HAVE_SYS_PARAM_H |
47 | # include <sys/param.h> |
48 | #endif |
49 | |
50 | #include "nasmlib.h" |
51 | |
52 | #ifdef HAVE_CANONICALIZE_FILE_NAME |
53 | |
54 | /* |
55 | * GNU-specific, but avoids the realpath(..., NULL) |
56 | * portability problem if it exists. |
57 | */ |
58 | char *nasm_realpath(const char *rel_path) |
59 | { |
60 | char *rp = canonicalize_file_name(rel_path); |
61 | return rp ? rp : nasm_strdup(rel_path); |
62 | } |
63 | |
64 | #elif defined(HAVE_REALPATH) |
65 | |
66 | /* |
67 | * POSIX.1-2008 defines realpath(..., NULL); POSIX.1-2001 doesn't guarantee |
68 | * that a NULL second argument is supported. |
69 | */ |
70 | |
71 | char *nasm_realpath(const char *rel_path) |
72 | { |
73 | char *rp; |
74 | |
75 | rp = realpath(rel_path, NULL); |
76 | |
77 | /* Not all implemetations of realpath() support a NULL second argument */ |
78 | if (!rp && errno == EINVAL) { |
79 | long path_max = -1; |
80 | char *rp; |
81 | |
82 | #if defined(HAVE_PATHCONF) && defined(_PC_PATH_MAX) |
83 | path_max = pathconf(rel_path, _PC_PATH_MAX); /* POSIX */ |
84 | #endif |
85 | |
86 | if (path_max < 0) { |
87 | #ifdef PATH_MAX |
88 | path_max = PATH_MAX; /* SUSv2 */ |
89 | #elif defined(MAXPATHLEN) |
90 | path_max = MAXPATHLEN; /* Solaris */ |
91 | #else |
92 | path_max = 65536; /* Crazily high, we hope */ |
93 | #endif |
94 | } |
95 | |
96 | rp = nasm_malloc(path_max); |
97 | |
98 | if (!realpath(rel_path, rp)) { |
99 | nasm_free(rp); |
100 | rp = NULL; |
101 | } else { |
102 | /* On some systems, pathconf() can return a very large value */ |
103 | |
104 | rp[path_max - 1] = '\0'; /* Just in case overrun is possible */ |
105 | rp = nasm_realloc(rp, strlen(rp) + 1); |
106 | } |
107 | } |
108 | |
109 | return rp ? rp : nasm_strdup(rel_path); |
110 | } |
111 | |
112 | #elif defined(HAVE__FULLPATH) |
113 | |
114 | /* |
115 | * win32/win64 API |
116 | */ |
117 | |
118 | char *nasm_realpath(const char *rel_path) |
119 | { |
120 | char *rp = _fullpath(NULL, rel_path, 0); |
121 | return rp ? rp : nasm_strdup(rel_path); |
122 | } |
123 | |
124 | #else |
125 | |
126 | /* |
127 | * There is nothing we know how to do here, so hope it just works anyway. |
128 | */ |
129 | |
130 | char *nasm_realpath(const char *rel_path) |
131 | { |
132 | return nasm_strdup(rel_path); |
133 | } |
134 | |
135 | #endif |
136 | |