#include "perl.h"
#include "XSUB.h"
+#ifdef I_UNISTD
+# include <unistd.h>
+#endif
+
/* The realpath() implementation from OpenBSD 2.9 (realpath.c 1.4)
* Renamed here to bsd_realpath() to avoid library conflicts.
* --jhi 2000-06-20 */
const char *path;
char *resolved;
{
- struct stat sb;
- int fd, n, rootd, serrno;
+#ifdef VMS
+ dTHX;
+ return Perl_rmsexpand(aTHX_ (char*)path, resolved, NULL, 0);
+#else
+ int rootd, serrno;
char *p, *q, wbuf[MAXPATHLEN];
int symlinks = 0;
/* Save the starting point. */
+#ifdef HAS_FCHDIR
+ int fd;
+
if ((fd = open(".", O_RDONLY)) < 0) {
(void)strcpy(resolved, ".");
return (NULL);
}
+#else
+ char wd[MAXPATHLEN];
+
+ if (getcwd(wd, MAXPATHLEN - 1) == NULL) {
+ (void)strcpy(resolved, ".");
+ return (NULL);
+ }
+#endif
/*
* Find the dirname and basename from the path to be resolved.
} else
p = resolved;
+#if defined(HAS_LSTAT) && defined(HAS_READLINK) && defined(HAS_SYMLINK)
+ {
+ struct stat sb;
/* Deal with the last component. */
if (lstat(p, &sb) == 0) {
if (S_ISLNK(sb.st_mode)) {
+ int n;
if (++symlinks > MAXSYMLINKS) {
errno = ELOOP;
goto err1;
p = "";
}
}
+ }
+#endif
/*
* Save the last component name and get the full pathname of
rootd = 0;
if (*wbuf) {
- if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) {
+ if (strlen(resolved) + strlen(wbuf) + (1 - rootd) + 1 > MAXPATHLEN) {
errno = ENAMETOOLONG;
goto err1;
}
}
/* Go back to where we came from. */
+#ifdef HAS_FCHDIR
if (fchdir(fd) < 0) {
serrno = errno;
goto err2;
}
+#else
+ if (chdir(wd) < 0) {
+ serrno = errno;
+ goto err2;
+ }
+#endif
/* It's okay if the close fails, what's an fd more or less? */
+#ifdef HAS_FCHDIR
(void)close(fd);
+#endif
return (resolved);
err1: serrno = errno;
+#ifdef HAS_FCHDIR
(void)fchdir(fd);
-err2: (void)close(fd);
+#else
+ (void)chdir(wd);
+#endif
+
+err2:
+#ifdef HAS_FCHDIR
+ (void)close(fd);
+#endif
errno = serrno;
return (NULL);
+#endif
}
MODULE = Cwd PACKAGE = Cwd
void
fastcwd()
+PROTOTYPE: DISABLE
PPCODE:
{
dXSTARG;
- sv_getcwd(TARG);
+ getcwd_sv(TARG);
XSprePUSH; PUSHTARG;
+#ifndef INCOMPLETE_TAINTS
+ SvTAINTED_on(TARG);
+#endif
}
void
{
dXSTARG;
char *path;
- STRLEN len;
- char *buf;
-
- New(0, buf, MAXPATHLEN, char);
- if (buf) {
- buf[MAXPATHLEN] = 0;
- if (pathsv)
- path = SvPV(pathsv, len);
- else {
- path = ".";
- len = 1;
- }
+ char buf[MAXPATHLEN];
- if (bsd_realpath(path, buf)) {
- sv_setpvn(TARG, buf, strlen(buf));
- SvPOK_only(TARG);
- }
- else
- sv_setsv(TARG, &PL_sv_undef);
+ path = pathsv ? SvPV_nolen(pathsv) : ".";
- Safefree(buf);
+ if (bsd_realpath(path, buf)) {
+ sv_setpvn(TARG, buf, strlen(buf));
+ SvPOK_only(TARG);
+ SvTAINTED_on(TARG);
}
else
sv_setsv(TARG, &PL_sv_undef);
XSprePUSH; PUSHTARG;
+#ifndef INCOMPLETE_TAINTS
+ SvTAINTED_on(TARG);
+#endif
}