MCPcopy Create free account
hub / github.com/apache/cloudberry / resolve_symlinks

Function resolve_symlinks

src/common/exec.c:234–319  ·  view source on GitHub ↗

* resolve_symlinks - resolve symlinks to the underlying file * * Replace "path" by the absolute path to the referenced file. * * Returns 0 if OK, -1 if error. * * Note: we are not particularly tense about producing nice error messages * because we are not really expecting error here; we just determined that * the symlink does point to a valid executable. */

Source from the content-addressed store, hash-verified

232 * the symlink does point to a valid executable.
233 */
234static int
235resolve_symlinks(char *path)
236{
237#ifdef HAVE_READLINK
238 struct stat buf;
239 char orig_wd[MAXPGPATH],
240 link_buf[MAXPGPATH];
241 char *fname;
242
243 /*
244 * To resolve a symlink properly, we have to chdir into its directory and
245 * then chdir to where the symlink points; otherwise we may fail to
246 * resolve relative links correctly (consider cases involving mount
247 * points, for example). After following the final symlink, we use
248 * getcwd() to figure out where the heck we're at.
249 *
250 * One might think we could skip all this if path doesn't point to a
251 * symlink to start with, but that's wrong. We also want to get rid of
252 * any directory symlinks that are present in the given path. We expect
253 * getcwd() to give us an accurate, symlink-free path.
254 */
255 if (!getcwd(orig_wd, MAXPGPATH))
256 {
257 log_error(errcode_for_file_access(),
258 _("could not identify current directory: %m"));
259 return -1;
260 }
261
262 for (;;)
263 {
264 char *lsep;
265 int rllen;
266
267 lsep = last_dir_separator(path);
268 if (lsep)
269 {
270 *lsep = '\0';
271 if (chdir(path) == -1)
272 {
273 log_error(errcode_for_file_access(),
274 _("could not change directory to \"%s\": %m"), path);
275 return -1;
276 }
277 fname = lsep + 1;
278 }
279 else
280 fname = path;
281
282 if (lstat(fname, &buf) < 0 ||
283 !S_ISLNK(buf.st_mode))
284 break;
285
286 errno = 0;
287 rllen = readlink(fname, link_buf, sizeof(link_buf));
288 if (rllen < 0 || rllen >= sizeof(link_buf))
289 {
290 log_error(errcode_for_file_access(),
291 _("could not read symbolic link \"%s\": %m"), fname);

Callers 1

find_my_execFunction · 0.85

Calls 5

last_dir_separatorFunction · 0.85
strlcpyFunction · 0.85
join_path_componentsFunction · 0.85
canonicalize_pathFunction · 0.85
errcode_for_file_accessFunction · 0.50

Tested by

no test coverage detected