Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2000-12-09 04:20:32 +0300
committerJeff Johnston <jjohnstn@redhat.com>2000-12-09 04:20:32 +0300
commit2efbc2a7dfa35d14c29c5c66837dc09f07c949ac (patch)
treee4a03a7344f83176b68f65a551ee04daa9f229ff /newlib/libc/sys/linux/realpath.c
parenta08c98bb808d1a1806c93be0b7934a19f48b5a0a (diff)
2000-12-08 Werner Almesberger <Werner.Almesberger@epfl.ch>
* configure.host: Added x86 linux target. * libc/unix/getpass.c (_PATH_PASSWD, _PASSWORD_LEN): Default definitions provided if not already defined. * libc/sys/linux/crt0.c: New file. * libc/sys/linux/Makefile.am: Ditto. * libc/sys/linux/Makefile.in: Ditto. * libc/sys/linux/aclocal.m4: Ditto. * libc/sys/linux/brk.c: Ditto. * libc/sys/linux/configure: Ditto. * libc/sys/linux/configure.in: Ditto. * libc/sys/linux/getoptlong.c: Ditto. * libc/sys/linux/ids.c: Ditto. * libc/sys/linux/inode.c: Ditto. * libc/sys/linux/io.c: Ditto. * libc/sys/linux/linux.c: Ditto. * libc/sys/linux/process.c: Ditto. * libc/sys/linux/realpath.c: Ditto. * libc/sys/linux/select.c: Ditto. * libc/sys/linux/signal.c: Ditto. * libc/sys/linux/systat.c: Ditto. * libc/sys/linux/termios.c: Ditto. * libc/sys/linux/time.c: Ditto. * libc/sys/linux/wait.c: Ditto. * libc/sys/linux/include/alloca.h: Ditto. * libc/sys/linux/include/getopt.h: Ditto. * libc/sys/linux/include/stdint.h: Ditto. * libc/sys/linux/include/unistd.h: Ditto. * libc/sys/linux/sys/cdefs.h: Ditto. * libc/sys/linux/sys/dirent.h: Ditto. * libc/sys/linux/sys/errno.h: Ditto. * libc/sys/linux/sys/fcntl.h: Ditto. * libc/sys/linux/sys/file.h: Ditto. * libc/sys/linux/sys/ioctl.h: Ditto. * libc/sys/linux/sys/resource.h: Ditto. * libc/sys/linux/sys/signal.h: Ditto. * libc/sys/linux/sys/stat.h: Ditto. * libc/sys/linux/sys/syscall.h: Ditto. * libc/sys/linux/sys/termios.h: Ditto. * libc/sys/linux/sys/time.h: Ditto. * libc/sys/linux/sys/types.h: Ditto. * libc/sys/linux/sys/utmp.h: Ditto. * libc/sys/linux/sys/utsname.h: Ditto. * libc/sys/linux/sys/wait.h: Ditto.
Diffstat (limited to 'newlib/libc/sys/linux/realpath.c')
-rw-r--r--newlib/libc/sys/linux/realpath.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/newlib/libc/sys/linux/realpath.c b/newlib/libc/sys/linux/realpath.c
new file mode 100644
index 000000000..8aa5eb445
--- /dev/null
+++ b/newlib/libc/sys/linux/realpath.c
@@ -0,0 +1,92 @@
+/* realpath.c - Return the canonicalized absolute pathname */
+
+/* Written 2000 by Werner Almesberger */
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+
+/* FIXME: buffer overrun possible, loops forever on cyclic symlinks */
+
+
+/*
+ * Canonical name: never ends with a slash
+ */
+
+static int resolve_path(char *path,char *result,char *pos)
+{
+ if (*path == '/') {
+ *result = '/';
+ pos = result+1;
+ path++;
+ }
+ *pos = 0;
+ if (!*path) return 0;
+ while (1) {
+ char *slash;
+ struct stat st;
+
+ slash = *path ? strchr(path,'/') : NULL;
+ if (slash) *slash = 0;
+ if (!path[0] || (path[0] == '.' &&
+ (!path[1] || (path[1] == '.' && !path[2])))) {
+ pos--;
+ if (pos != result && path[0] && path[1])
+ while (*--pos != '/');
+ }
+ else {
+ strcpy(pos,path);
+ if (lstat(result,&st) < 0) return -1;
+ if (S_ISLNK(st.st_mode)) {
+ char buf[PATH_MAX];
+
+ if (readlink(result,buf,sizeof(buf)) < 0) return -1;
+ *pos = 0;
+ if (slash) {
+ *slash = '/';
+ strcat(buf,slash);
+ }
+ strcpy(path,buf);
+ if (*path == '/') result[1] = 0;
+ pos = strchr(result,0);
+ continue;
+ }
+ pos = strchr(result,0);
+ }
+ if (slash) {
+ *pos++ = '/';
+ path = slash+1;
+ }
+ *pos = 0;
+ if (!slash) break;
+ }
+ return 0;
+}
+
+
+char *realpath(const char *path,char *resolved_path)
+{
+ char cwd[PATH_MAX];
+ char *path_copy;
+ int res;
+
+ if (!*path) {
+ errno = ENOENT; /* SUSv2 */
+ return NULL;
+ }
+ if (!getcwd(cwd,sizeof(cwd))) return NULL;
+ strcpy(resolved_path,"/");
+ if (resolve_path(cwd,resolved_path,resolved_path)) return NULL;
+ strcat(resolved_path,"/");
+ path_copy = strdup(path);
+ if (!path_copy) return NULL;
+ res = resolve_path(path_copy,resolved_path,strchr(resolved_path,0));
+ free(path_copy);
+ if (res) return NULL;
+ return resolved_path;
+}