~vcs-imports/busybox/trunk

« back to all changes in this revision

Viewing changes to libbb/xreadlink.c

  • Committer: Denys Vlasenko
  • Date: 2020-12-29 15:53:11 UTC
  • Revision ID: git-v1:77a51a2709de1b646ab493f0bf771d896de6efc2
randomconfig fixes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>

Show diffs side-by-side

added added

removed removed

Lines of Context:
123
123
#endif
124
124
}
125
125
 
126
 
char* FAST_FUNC xmalloc_realpath_coreutils(char *path)
 
126
char* FAST_FUNC xmalloc_realpath_coreutils(const char *path)
127
127
{
128
128
        char *buf;
129
129
 
137
137
         * (the directory must exist).
138
138
         */
139
139
        if (!buf && errno == ENOENT) {
140
 
                char *target, c, *last_slash;
141
 
                size_t i;
142
 
 
143
 
                target = xmalloc_readlink(path);
144
 
                if (target) {
145
 
                        /*
146
 
                         * $ ln -s /bin/qwe symlink  # note: /bin is a link to /usr/bin
147
 
                         * $ readlink -f symlink
148
 
                         * /usr/bin/qwe
149
 
                         * $ realpath symlink
150
 
                         * /usr/bin/qwe
151
 
                         */
152
 
                        if (target[0] != '/') {
 
140
                char *last_slash = strrchr(path, '/');
 
141
                if (last_slash) {
 
142
                        *last_slash++ = '\0';
 
143
                        buf = xmalloc_realpath(path);
 
144
                        if (buf) {
 
145
                                unsigned len = strlen(buf);
 
146
                                buf = xrealloc(buf, len + strlen(last_slash) + 2);
 
147
                                buf[len++] = '/';
 
148
                                strcpy(buf + len, last_slash);
 
149
                        }
 
150
                } else {
 
151
                        char *target = xmalloc_readlink(path);
 
152
                        if (target) {
 
153
                                char *cwd;
 
154
                                if (target[0] == '/') {
 
155
                                        /*
 
156
                                         * $ ln -s /bin/qwe symlink  # note: /bin is a link to /usr/bin
 
157
                                         * $ readlink -f symlink
 
158
                                         * /usr/bin/qwe/target_does_not_exist
 
159
                                         * $ realpath symlink
 
160
                                         * /usr/bin/qwe/target_does_not_exist
 
161
                                         */
 
162
                                        buf = xmalloc_realpath_coreutils(target);
 
163
                                        free(target);
 
164
                                        return buf;
 
165
                                }
153
166
                                /*
154
167
                                 * $ ln -s target_does_not_exist symlink
155
168
                                 * $ readlink -f symlink
157
170
                                 * $ realpath symlink
158
171
                                 * /CURDIR/target_does_not_exist
159
172
                                 */
160
 
                                char *cwd = xrealloc_getcwd_or_warn(NULL);
161
 
                                char *tmp = concat_path_file(cwd, target);
 
173
                                cwd = xrealloc_getcwd_or_warn(NULL);
 
174
                                buf = concat_path_file(cwd, target);
162
175
                                free(cwd);
163
176
                                free(target);
164
 
                                target = tmp;
165
 
                        }
166
 
                        buf = xmalloc_realpath_coreutils(target);
167
 
                        free(target);
168
 
                        return buf;
169
 
                }
170
 
 
171
 
                /* ignore leading and trailing slashes */
172
 
                while (path[0] == '/' && path[1] == '/')
173
 
                        ++path;
174
 
                i = strlen(path) - 1;
175
 
                while (i > 0 && path[i] == '/')
176
 
                        i--;
177
 
                c = path[i + 1];
178
 
                path[i + 1] = '\0';
179
 
 
180
 
                last_slash = strrchr(path, '/');
181
 
                if (last_slash == path)
182
 
                        buf = xstrdup(path);
183
 
                else if (last_slash) {
184
 
                        *last_slash = '\0';
185
 
                        buf = xmalloc_realpath(path);
186
 
                        *last_slash++ = '/';
187
 
                        if (buf) {
188
 
                                unsigned len = strlen(buf);
189
 
                                buf = xrealloc(buf, len + strlen(last_slash) + 2);
190
 
                                buf[len++] = '/';
191
 
                                strcpy(buf + len, last_slash);
192
 
                        }
193
 
                }
194
 
                path[i + 1] = c;
 
177
                                return buf;
 
178
                        }
 
179
                }
195
180
        }
196
181
 
197
182
        return buf;