handle drive-qualified nōn-absolute pathnames in do_realpath(), untested
the idea here is that: - /foo/bar and a:/foo/bar are absolute - foo/bar is relative - a:foo/bar needs to be handled specially, mostly per making it into an absolute (“a:/” + getcwd(a:) + “foo/bar”)
This commit is contained in:
parent
d5a29d5e60
commit
5db583cd81
35
misc.c
35
misc.c
@ -32,7 +32,7 @@
|
||||
#include <grp.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.283 2017/10/11 21:49:06 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.284 2017/10/11 23:23:02 tg Exp $");
|
||||
|
||||
#define KSH_CHVT_FLAG
|
||||
#ifdef MKSH_SMALL
|
||||
@ -1661,6 +1661,15 @@ do_realpath(const char *upath)
|
||||
if (mksh_abspath(upath)) {
|
||||
/* upath is an absolute pathname */
|
||||
strdupx(ipath, upath, ATEMP);
|
||||
#ifdef MKSH_DOSPATH
|
||||
} else if (mksh_drvltr(upath)) {
|
||||
/* upath is a drive-relative pathname */
|
||||
if (!getdrvwd(&ldest, ord(*upath)))
|
||||
return (NULL);
|
||||
/* A:foo -> A:/cwd/foo; A: -> A:/cwd */
|
||||
ipath = shf_smprintf(Tf_sss, ldest,
|
||||
upath[2] ? "/" : "", upath + 2);
|
||||
#endif
|
||||
} else {
|
||||
/* upath is a relative pathname, prepend cwd */
|
||||
if ((tp = ksh_get_wd()) == NULL || !mksh_abspath(tp))
|
||||
@ -1762,11 +1771,23 @@ do_realpath(const char *upath)
|
||||
* restart if symlink target is an absolute path,
|
||||
* otherwise continue with currently resolved prefix
|
||||
*/
|
||||
#ifdef MKSH_DOSPATH
|
||||
assemble_symlink:
|
||||
#endif
|
||||
/* append rest of current input path to link target */
|
||||
tp = shf_smprintf(Tf_sss, ldest, *ip ? "/" : "", ip);
|
||||
afree(ipath, ATEMP);
|
||||
ip = ipath = tp;
|
||||
if (!mksh_abspath(ldest)) {
|
||||
if (!mksh_abspath(ipath)) {
|
||||
#ifdef MKSH_DOSPATH
|
||||
/* symlink target might be drive-relative */
|
||||
if (mksh_drvltr(ipath)) {
|
||||
if (!getdrvwd(&ldest, ord(*ipath)))
|
||||
goto notfound;
|
||||
ip += 2;
|
||||
goto assemble_symlink;
|
||||
}
|
||||
#endif
|
||||
/* symlink target is a relative path */
|
||||
xp = Xrestpos(xs, xp, pos);
|
||||
} else
|
||||
@ -1775,7 +1796,7 @@ do_realpath(const char *upath)
|
||||
/* symlink target is an absolute path */
|
||||
xp = Xstring(xs, xp);
|
||||
beginning_of_a_pathname:
|
||||
/* assert: mksh_cdirsep((ip == ipath)[0]) */
|
||||
/* assert: mksh_abspath(ip == ipath) */
|
||||
/* assert: xp == xs.beg => start of path */
|
||||
|
||||
/* exactly two leading slashes? (SUSv4 3.266) */
|
||||
@ -1789,14 +1810,6 @@ do_realpath(const char *upath)
|
||||
/* keep it */
|
||||
Xput(xs, xp, *ip++);
|
||||
Xput(xs, xp, *ip++);
|
||||
/*
|
||||
* XXX if (!mksh_cdirsep(*ip)): we
|
||||
* XXX must get the cwd on that drive
|
||||
* XXX and prepend it here as this is
|
||||
* XXX a drive-qualified relative path
|
||||
* XXX which we are supposed to convert
|
||||
* XXX to an absolute (with drive) one
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
54
os2.c
54
os2.c
@ -21,16 +21,19 @@
|
||||
*/
|
||||
|
||||
#define INCL_DOS
|
||||
#define INCL_DOSFILEMGR
|
||||
#define INCL_DOSMISC
|
||||
#include <os2.h>
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
#include <klibc/startup.h>
|
||||
#include <errno.h>
|
||||
#include <io.h>
|
||||
#include <unistd.h>
|
||||
#include <process.h>
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/os2.c,v 1.2 2017/04/29 22:04:29 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/os2.c,v 1.3 2017/10/11 23:23:03 tg Exp $");
|
||||
|
||||
static char *remove_trailing_dots(char *);
|
||||
static int access_stat_ex(int (*)(), const char *, void *);
|
||||
@ -557,3 +560,52 @@ cleanup(void)
|
||||
{
|
||||
cleanup_temps();
|
||||
}
|
||||
|
||||
int
|
||||
getdrvwd(char **cpp, unsigned int drvltr)
|
||||
{
|
||||
PBYTE *cp;
|
||||
ULONG sz;
|
||||
APIRET rc;
|
||||
ULONG drvno;
|
||||
|
||||
if (DosQuerySysInfo(QSV_MAX_PATH_LENGTH, QSV_MAX_PATH_LENGTH,
|
||||
&sz, sizeof(sz)) != 0) {
|
||||
errno = EDOOFUS;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* allocate 'X:/' plus sz plus NUL */
|
||||
checkoktoadd((size_t)sz, (size_t)4);
|
||||
cp = aresize(*cpp, (size_t)sz + (size_t)4, ATEMP);
|
||||
cp[0] = drvltr;
|
||||
cp[1] = ':';
|
||||
cp[2] = '/';
|
||||
drvno = (rtt2asc(drvltr) | 0x20U) - rtt2asc('a') + 1;
|
||||
/* NUL is part of space within buffer passed */
|
||||
++sz;
|
||||
if ((rc = DosQueryCurrentDir(drvno, cp + 3, &sz)) == 0) {
|
||||
/* success! */
|
||||
*cpp = cp;
|
||||
return (0);
|
||||
}
|
||||
afree(cp, ATEMP);
|
||||
*cpp = NULL;
|
||||
switch (rc) {
|
||||
case 15: /* invalid drive */
|
||||
errno = ENOTBLK;
|
||||
break;
|
||||
case 26: /* not dos disk */
|
||||
errno = ENODEV;
|
||||
break;
|
||||
case 108: /* drive locked */
|
||||
errno = EDEADLK;
|
||||
break;
|
||||
case 111: /* buffer overflow */
|
||||
errno = ENAMETOOLONG;
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
3
sh.h
3
sh.h
@ -182,7 +182,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef EXTERN
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.846 2017/10/11 21:52:46 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.847 2017/10/11 23:23:03 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R56 2017/08/29"
|
||||
|
||||
@ -2566,6 +2566,7 @@ void setextlibpath(const char *, const char *);
|
||||
int access_ex(int (*)(const char *, int), const char *, int);
|
||||
int stat_ex(const char *, struct stat *);
|
||||
const char *real_exec_name(const char *);
|
||||
int getdrvwd(char **, unsigned int);
|
||||
#endif
|
||||
/* shf.c */
|
||||
struct shf *shf_open(const char *, int, int, int);
|
||||
|
Loading…
x
Reference in New Issue
Block a user