Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/libbb/xreadlink.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/libbb/xreadlink.c
r1765 r2725 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 * xreadlink.c - safe implementation of readlink. 4 * Returns a NULL on failure... 3 * xreadlink.c - safe implementation of readlink. 4 * Returns a NULL on failure... 5 * 6 * Licensed under GPLv2, see file LICENSE in this source tree. 5 7 */ 6 8 … … 9 11 /* 10 12 * NOTE: This function returns a malloced char* that you will have to free 11 * yourself. You have been warned.13 * yourself. 12 14 */ 13 char *xmalloc_readlink(const char *path)15 char* FAST_FUNC xmalloc_readlink(const char *path) 14 16 { 15 17 enum { GROWBY = 80 }; /* how large we will grow strings by */ … … 19 21 20 22 do { 21 buf = xrealloc(buf, bufsize += GROWBY); 23 bufsize += GROWBY; 24 buf = xrealloc(buf, bufsize); 22 25 readsize = readlink(path, buf, bufsize); 23 26 if (readsize == -1) { … … 32 35 } 33 36 34 char *xmalloc_readlink_or_warn(const char *path) 37 /* 38 * This routine is not the same as realpath(), which 39 * canonicalizes the given path completely. This routine only 40 * follows trailing symlinks until a real file is reached and 41 * returns its name. If the path ends in a dangling link or if 42 * the target doesn't exist, the path is returned in any case. 43 * Intermediate symlinks in the path are not expanded -- only 44 * those at the tail. 45 * A malloced char* is returned, which must be freed by the caller. 46 */ 47 char* FAST_FUNC xmalloc_follow_symlinks(const char *path) 48 { 49 char *buf; 50 char *lpc; 51 char *linkpath; 52 int bufsize; 53 int looping = MAXSYMLINKS + 1; 54 55 buf = xstrdup(path); 56 goto jump_in; 57 58 while (1) { 59 linkpath = xmalloc_readlink(buf); 60 if (!linkpath) { 61 /* not a symlink, or doesn't exist */ 62 if (errno == EINVAL || errno == ENOENT) 63 return buf; 64 goto free_buf_ret_null; 65 } 66 67 if (!--looping) { 68 free(linkpath); 69 free_buf_ret_null: 70 free(buf); 71 return NULL; 72 } 73 74 if (*linkpath != '/') { 75 bufsize += strlen(linkpath); 76 buf = xrealloc(buf, bufsize); 77 lpc = bb_get_last_path_component_strip(buf); 78 strcpy(lpc, linkpath); 79 free(linkpath); 80 } else { 81 free(buf); 82 buf = linkpath; 83 jump_in: 84 bufsize = strlen(buf) + 1; 85 } 86 } 87 } 88 89 char* FAST_FUNC xmalloc_readlink_or_warn(const char *path) 35 90 { 36 91 char *buf = xmalloc_readlink(path); 37 92 if (!buf) { 38 93 /* EINVAL => "file: Invalid argument" => puzzled user */ 39 bb_error_msg("%s: cannot read link (not a symlink?)", path); 94 const char *errmsg = "not a symlink"; 95 int err = errno; 96 if (err != EINVAL) 97 errmsg = strerror(err); 98 bb_error_msg("%s: cannot read link: %s", path, errmsg); 40 99 } 41 100 return buf; 42 101 } 43 102 44 /* UNUSED */ 45 #if 0 46 char *xmalloc_realpath(const char *path) 103 char* FAST_FUNC xmalloc_realpath(const char *path) 47 104 { 48 105 #if defined(__GLIBC__) && !defined(__UCLIBC__) 49 106 /* glibc provides a non-standard extension */ 107 /* new: POSIX.1-2008 specifies this behavior as well */ 50 108 return realpath(path, NULL); 51 109 #else 52 110 char buf[PATH_MAX+1]; 53 111 54 /* on error returns NULL (xstrdup(NULL) == NULL) */112 /* on error returns NULL (xstrdup(NULL) == NULL) */ 55 113 return xstrdup(realpath(path, buf)); 56 114 #endif 57 115 } 58 #endif
Note:
See TracChangeset
for help on using the changeset viewer.