]>
git.ipfire.org Git - thirdparty/bash.git/blob - examples/loadables/realpath.c
ef836713827ee0787a809e21f44aa1f9889a40a3
2 * realpath -- canonicalize pathnames, resolving symlinks
4 * usage: realpath [-cqsv] [-a name] pathname [pathname...]
6 * options: -a name assign each canonicalized pathname to indexed array
8 * -c check whether or not each resolved path exists
9 * -q no output, exit status determines whether path is valid
10 * -s strip . and .. from the pathname only, no symlink resolution
11 * -v produce verbose output
14 * exit status: 0 if all pathnames resolved
15 * 1 if any of the pathname arguments could not be resolved
18 * Bash loadable builtin version
25 Copyright (C) 1999-2009,2021,2022 Free Software Foundation, Inc.
27 This file is part of GNU Bash.
28 Bash is free software: you can redistribute it and/or modify
29 it under the terms of the GNU General Public License as published by
30 the Free Software Foundation, either version 3 of the License, or
31 (at your option) any later version.
33 Bash is distributed in the hope that it will be useful,
34 but WITHOUT ANY WARRANTY; without even the implied warranty of
35 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 GNU General Public License for more details.
38 You should have received a copy of the GNU General Public License
39 along with Bash. If not, see <http://www.gnu.org/licenses/>.
44 #include <sys/types.h>
57 #include "bashgetopt.h"
64 extern char *sh_realpath();
67 realpath_builtin(WORD_LIST
*list
)
69 int opt
, cflag
, vflag
, qflag
, sflag
, aflag
, es
;
70 char *r
, realbuf
[PATH_MAX
], *p
, *newpath
;
72 #if defined (ARRAY_VARS)
83 vflag
= cflag
= qflag
= aflag
= sflag
= 0;
84 #if defined (ARRAY_VARS)
89 reset_internal_getopt();
90 while ((opt
= internal_getopt (list
, "a:cqsv")) != -1) {
92 #if defined (ARRAY_VARS)
124 #if defined (ARRAY_VARS)
125 if (aflag
&& legal_identifier (aname
) == 0) {
127 return (EXECUTION_FAILURE
);
129 if (aname
&& builtin_unbind_variable (aname
) == -2)
130 return (EXECUTION_FAILURE
);
132 v
= find_or_make_array_variable (aname
, 1);
133 if (v
== 0 || readonly_p (v
) || noassign_p (v
)) {
134 if (v
&& readonly_p (v
))
135 err_readonly (aname
);
136 return (EXECUTION_FAILURE
);
137 } else if (array_p (v
) == 0) {
138 builtin_error ("%s: not an indexed array", aname
);
139 return (EXECUTION_FAILURE
);
142 VUNSETATTR (v
, att_invisible
);
143 array_flush (array_cell (v
));
147 for (es
= EXECUTION_SUCCESS
; list
; list
= list
->next
) {
148 p
= list
->word
->word
;
150 /* sh_canonpath doesn't convert to absolute pathnames */
151 newpath
= make_absolute(p
, get_string_value("PWD"));
152 r
= sh_canonpath(newpath
, PATH_CHECKDOTDOT
|PATH_CHECKEXISTS
);
155 r
= sh_realpath(p
, realbuf
);
157 es
= EXECUTION_FAILURE
;
159 builtin_error("%s: cannot resolve: %s", p
, strerror(errno
));
162 if (cflag
&& (stat(r
, &sb
) < 0)) {
163 es
= EXECUTION_FAILURE
;
165 builtin_error("%s: %s", p
, strerror(errno
));
169 bind_array_element (v
, ind
, r
, 0);
174 printf ("%s -> ", p
);
183 char *realpath_doc
[] = {
184 "Display pathname in canonical form.",
186 "Display the canonicalized version of each PATHNAME argument, resolving",
188 "The -a option stores each canonicalized PATHNAME argument into the indexed",
190 "The -c option checks whether or not each resolved name exists.",
191 "The -q option produces no output; the exit status determines the",
192 "validity of each PATHNAME, but any array assignment is still performed.",
193 "If the -s option is supplied, canonicalize . and .. pathname components",
194 "without resolving symbolic links.",
195 "The -v option produces verbose output.",
196 "The exit status is 0 if each PATHNAME was resolved; non-zero otherwise.",
200 struct builtin realpath_struct
= {
201 "realpath", /* builtin name */
202 realpath_builtin
, /* function implementing the builtin */
203 BUILTIN_ENABLED
, /* initial flags for builtin */
204 realpath_doc
, /* array of long documentation strings */
205 "realpath [-a varname] [-cqsv] pathname [pathname...]", /* usage synopsis */
206 0 /* reserved for internal use */