diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2009-04-23 00:26:52 +1000 |
---|---|---|
committer | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2009-04-23 04:44:46 +1000 |
commit | 4b6faf7807ca7fb77ec07b474aac4fa6edf6bfff (patch) | |
tree | e5265f7e2018bbc3f146e90d791a96035677890c /shell | |
parent | 580765e16aca68132babc09a02b4ea6c220c1988 (diff) | |
download | busybox-w32-4b6faf7807ca7fb77ec07b474aac4fa6edf6bfff.tar.gz busybox-w32-4b6faf7807ca7fb77ec07b474aac4fa6edf6bfff.tar.bz2 busybox-w32-4b6faf7807ca7fb77ec07b474aac4fa6edf6bfff.zip |
shell/ash: replace updatepwd()
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash_mingw.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/shell/ash_mingw.c b/shell/ash_mingw.c index c36973164..42a9e41a7 100644 --- a/shell/ash_mingw.c +++ b/shell/ash_mingw.c | |||
@@ -1041,3 +1041,92 @@ static int set_exitstatus(int val, const char **argv,int *out) | |||
1041 | return -1; | 1041 | return -1; |
1042 | } | 1042 | } |
1043 | 1043 | ||
1044 | static const char * | ||
1045 | updatepwd(const char *dir) | ||
1046 | { | ||
1047 | char *new; | ||
1048 | char *p; | ||
1049 | char *cdcomppath; | ||
1050 | const char *lim; | ||
1051 | /* | ||
1052 | * There are four cases | ||
1053 | * absdrive + abspath: c:/path | ||
1054 | * absdrive + !abspath: c:path | ||
1055 | * !absdrive + abspath: /path | ||
1056 | * !absdrive + !abspath: path | ||
1057 | * | ||
1058 | * Damn DOS! | ||
1059 | * c:path behaviour is "undefined" | ||
1060 | * To properly handle this case, I have to keep track of cwd | ||
1061 | * of every drive, which is too painful to do. | ||
1062 | * So when c:path is given, I assume it's c:${curdir}path | ||
1063 | * with ${curdir} comes from the current drive | ||
1064 | */ | ||
1065 | int absdrive = *dir && dir[1] == ':'; | ||
1066 | int abspath = absdrive ? dir[2] == '/' : *dir == '/'; | ||
1067 | char *drive; | ||
1068 | |||
1069 | cdcomppath = ststrdup(dir); | ||
1070 | STARTSTACKSTR(new); | ||
1071 | if (!absdrive && curdir == nullstr) | ||
1072 | return 0; | ||
1073 | if (!abspath) { | ||
1074 | if (curdir == nullstr) | ||
1075 | return 0; | ||
1076 | new = stack_putstr(curdir, new); | ||
1077 | } | ||
1078 | new = makestrspace(strlen(dir) + 2, new); | ||
1079 | |||
1080 | drive = stackblock(); | ||
1081 | if (absdrive) { | ||
1082 | *drive = *dir; | ||
1083 | cdcomppath += 2; | ||
1084 | dir += 2; | ||
1085 | } else { | ||
1086 | *drive = *curdir; | ||
1087 | } | ||
1088 | drive[1] = ':'; /* in case of absolute drive+path */ | ||
1089 | |||
1090 | if (abspath) | ||
1091 | new = drive + 2; | ||
1092 | lim = drive + 3; | ||
1093 | if (!abspath) { | ||
1094 | if (new[-1] != '/') | ||
1095 | USTPUTC('/', new); | ||
1096 | if (new > lim && *lim == '/') | ||
1097 | lim++; | ||
1098 | } else { | ||
1099 | USTPUTC('/', new); | ||
1100 | cdcomppath ++; | ||
1101 | if (dir[1] == '/' && dir[2] != '/') { | ||
1102 | USTPUTC('/', new); | ||
1103 | cdcomppath++; | ||
1104 | lim++; | ||
1105 | } | ||
1106 | } | ||
1107 | p = strtok(cdcomppath, "/"); | ||
1108 | while (p) { | ||
1109 | switch (*p) { | ||
1110 | case '.': | ||
1111 | if (p[1] == '.' && p[2] == '\0') { | ||
1112 | while (new > lim) { | ||
1113 | STUNPUTC(new); | ||
1114 | if (new[-1] == '/') | ||
1115 | break; | ||
1116 | } | ||
1117 | break; | ||
1118 | } | ||
1119 | if (p[1] == '\0') | ||
1120 | break; | ||
1121 | /* fall through */ | ||
1122 | default: | ||
1123 | new = stack_putstr(p, new); | ||
1124 | USTPUTC('/', new); | ||
1125 | } | ||
1126 | p = strtok(0, "/"); | ||
1127 | } | ||
1128 | if (new > lim) | ||
1129 | STUNPUTC(new); | ||
1130 | *new = 0; | ||
1131 | return stackblock(); | ||
1132 | } | ||