diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2001-06-20 13:53:46 +0000 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2001-06-20 13:53:46 +0000 |
commit | 03d70c897754d6af90de9d0ffe2857d000d6f2d7 (patch) | |
tree | 051d38cf50d3028fa41ded5e0161132bb2913419 /util.c | |
parent | d66afad431e53e41f069708879a4d0e18d8b143b (diff) | |
download | perl-03d70c897754d6af90de9d0ffe2857d000d6f2d7.tar.gz |
Replace our implementation of realpath() with OpenBSD's
(src/lib/libc/stdlib/realpath.c 1.4).
p4raw-id: //depot/perl@10750
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 147 |
1 files changed, 0 insertions, 147 deletions
@@ -3753,150 +3753,3 @@ Perl_sv_getcwd(pTHX_ register SV *sv) #endif } -/* -=for apidoc sv_realpath - -Emulate realpath(3). - -The real realpath() is not used because it's a known can of worms. -We may have bugs but hey, they are our very own. - -=cut - */ -int -Perl_sv_realpath(pTHX_ SV *sv, char *path, STRLEN maxlen) -{ -#ifndef PERL_MICRO - char name[MAXPATHLEN] = { 0 }; - char dotdots[MAXPATHLEN] = { 0 }; - char *s; - STRLEN pathlen, namelen; - DIR *parent; - Direntry_t *dp; - struct stat cst, pst, tst; - - if (!sv || !path || !maxlen) { - Perl_warn(aTHX_ "sv_realpath: realpath(0x%x, 0x%x, "")", - sv, path, maxlen); - SV_CWD_RETURN_UNDEF; - } - - /* Is the source buffer too long? - * Don't use strlen() to avoid running off the end. */ - if (maxlen >= MAXPATHLEN) - pathlen = maxlen; - else { - s = memchr(path, '\0', MAXPATHLEN); - pathlen = s ? s - path : MAXPATHLEN; - } - if (pathlen >= MAXPATHLEN) { - Perl_warn(aTHX_ "sv_realpath: source too large"); - SV_CWD_RETURN_UNDEF; - } - - if (PerlLIO_stat(path, &cst) < 0) { - Perl_warn(aTHX_ "sv_realpath: stat(\"%s\"): %s", - path, Strerror(errno)); - SV_CWD_RETURN_UNDEF; - } - - (void)SvUPGRADE(sv, SVt_PV); - - Copy(path, dotdots, maxlen, char); - - pathlen = 0; - - for (;;) { - strcat(dotdots, "/.."); - StructCopy(&cst, &pst, struct stat); - - if (PerlLIO_stat(dotdots, &cst) < 0) { - Perl_warn(aTHX_ "sv_realpath: stat(\"%s\"): %s", - dotdots, Strerror(errno)); - SV_CWD_RETURN_UNDEF; - } - - if (pst.st_dev == cst.st_dev && pst.st_ino == cst.st_ino) { - /* We've reached the root: previous is same as current */ - break; - } else { - STRLEN dotdotslen = strlen(dotdots); - - /* Scan through the dir looking for name of previous */ - if (!(parent = PerlDir_open(dotdots))) { - Perl_warn(aTHX_ "sv_realpath: opendir(\"%s\"): %s", - dotdots, Strerror(errno)); - SV_CWD_RETURN_UNDEF; - } - - SETERRNO(0,SS$_NORMAL); /* for readdir() */ - while ((dp = PerlDir_read(parent)) != NULL) { - if (SV_CWD_ISDOT(dp)) { - continue; - } - - Copy(dotdots, name, dotdotslen, char); - name[dotdotslen] = '/'; -#ifdef DIRNAMLEN - namelen = dp->d_namlen; -#else - namelen = strlen(dp->d_name); -#endif - Copy(dp->d_name, name + dotdotslen + 1, namelen, char); - name[dotdotslen + 1 + namelen] = 0; - - if (PerlLIO_lstat(name, &tst) < 0) { - PerlDir_close(parent); - Perl_warn(aTHX_ "sv_realpath: lstat(\"%s\"): %s", - name, Strerror(errno)); - SV_CWD_RETURN_UNDEF; - } - - if (tst.st_dev == pst.st_dev && tst.st_ino == pst.st_ino) - break; - - SETERRNO(0,SS$_NORMAL); /* for readdir() */ - } - - if (!dp && errno) { - Perl_warn(aTHX_ "sv_realpath: readdir(\"%s\"): %s", - dotdots, Strerror(errno)); - SV_CWD_RETURN_UNDEF; - } - - if (pathlen + namelen + 1 >= MAXPATHLEN) { - Perl_warn(aTHX_ "sv_realpath: too long name"); - SV_CWD_RETURN_UNDEF; - } - - SvGROW(sv, pathlen + namelen + 1); - if (pathlen) { - /* shift down */ - Move(SvPVX(sv), SvPVX(sv) + namelen + 1, pathlen, char); - } - - *SvPVX(sv) = '/'; - Move(dp->d_name, SvPVX(sv)+1, namelen, char); - pathlen += (namelen + 1); - -#ifdef VOID_CLOSEDIR - PerlDir_close(parent); -#else - if (PerlDir_close(parent) < 0) { - Perl_warn(aTHX_ "sv_realpath: closedir(\"%s\"): %s", - dotdots, Strerror(errno)); - SV_CWD_RETURN_UNDEF; - } -#endif - } - } - - SvCUR_set(sv, pathlen); - SvPOK_only(sv); - - return TRUE; -#else - return FALSE; /* MICROPERL */ -#endif -} - |