From: Jarkko Hietaniemi Date: Wed, 20 Jun 2001 13:07:18 +0000 (+0000) Subject: No point in going into memory-saving contortions X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=8f95b30d1b432a64a1797b0957af01437ea8f0d4;p=p5sagit%2Fp5-mst-13.2.git No point in going into memory-saving contortions with getcwd() since there's a danger of buffer overflow. Also make the POSIX extension to use sv_getcwd(). Finally, a missed proto.h fragment. p4raw-id: //depot/perl@10748 --- diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs index 49ea57e..e5e5f16 100644 --- a/ext/POSIX/POSIX.xs +++ b/ext/POSIX/POSIX.xs @@ -1744,40 +1744,12 @@ char * ttyname(fd) int fd -#XXX: use sv_getcwd() void getcwd() - PPCODE: -#ifdef HAS_GETCWD - char * buf; - int buflen = 128; - - New(0, buf, buflen, char); - /* Many getcwd()s know how to automatically allocate memory - * for the directory if the buffer argument is NULL but... - * (1) we cannot assume all getcwd()s do that - * (2) this may interfere with Perl's malloc - * So let's not. --jhi */ - while ((getcwd(buf, buflen) == NULL) && errno == ERANGE) { - buflen += 128; - if (buflen > MAXPATHLEN) { - Safefree(buf); - buf = NULL; - break; - } - Renew(buf, buflen, char); - } - if (buf) { - PUSHs(sv_2mortal(newSVpv(buf, 0))); - Safefree(buf); - } - else - PUSHs(&PL_sv_undef); -#else - require_pv("Cwd.pm"); - /* Module require may have grown the stack */ - SPAGAIN; - PUSHMARK(sp); - PUTBACK; - XSRETURN(call_pv("Cwd::cwd", GIMME_V)); -#endif + PPCODE: + { + dXSTARG; + sv_getcwd(TARG); + XSprePUSH; PUSHTARG; + } + diff --git a/proto.h b/proto.h index 927f3b5..eaa6ed7 100644 --- a/proto.h +++ b/proto.h @@ -780,7 +780,7 @@ PERL_CALLCONV void Perl_sv_pos_b2u(pTHX_ SV* sv, I32* offsetp); PERL_CALLCONV char* Perl_sv_pvn_force(pTHX_ SV* sv, STRLEN* lp); PERL_CALLCONV char* Perl_sv_pvutf8n_force(pTHX_ SV* sv, STRLEN* lp); PERL_CALLCONV char* Perl_sv_pvbyten_force(pTHX_ SV* sv, STRLEN* lp); -PERL_CALLCONV int Perl_sv_realpath(pTHX_ SV* sv, char *path, STRLEN len); +PERL_CALLCONV int Perl_sv_realpath(pTHX_ SV* sv, char *path, STRLEN maxlen); PERL_CALLCONV char* Perl_sv_reftype(pTHX_ SV* sv, int ob); PERL_CALLCONV void Perl_sv_replace(pTHX_ SV* sv, SV* nsv); PERL_CALLCONV void Perl_sv_report_used(pTHX); diff --git a/util.c b/util.c index 1d69fe5..838c362 100644 --- a/util.c +++ b/util.c @@ -3604,36 +3604,48 @@ Fill the sv with current working directory * because you might chdir out of a directory that you can't chdir * back into. */ -/* XXX: this needs more porting #ifndef HAS_GETCWD */ int Perl_sv_getcwd(pTHX_ register SV *sv) { #ifndef PERL_MICRO -#ifndef HAS_GETCWD +#ifdef HAS_GETCWD + { + char* buf; + + SvPOK_off(sv); + New(0, buf, MAXPATHLEN, char); + if (buf) { + buf[MAXPATHLEN] = 0; + /* Yes, some getcwd()s automatically allocate a buffer + * if given a NULL one. Portability is the problem. + * XXX Configure probe needed. */ + if (getcwd(buf, MAXPATHLEN - 1)) { + STRLEN len = strlen(buf); + sv_setpvn(sv, buf, len); + SvPOK_only(sv); + SvCUR_set(sv, len); + } + else + sv_setsv(sv, &PL_sv_undef); + Safefree(buf); + } + else + sv_setsv(sv, &PL_sv_undef); + + return SvPOK(sv) ? TRUE : FALSE; + } + +#else + struct stat statbuf; int orig_cdev, orig_cino, cdev, cino, odev, oino, tdev, tino; int namelen, pathlen=0; DIR *dir; Direntry_t *dp; -#endif (void)SvUPGRADE(sv, SVt_PV); -#ifdef HAS_GETCWD - - SvGROW(sv, 128); - while ((getcwd(SvPVX(sv), SvLEN(sv)-1) == NULL) && errno == ERANGE) { - if (SvLEN(sv) + 128 >= MAXPATHLEN) { - SV_CWD_RETURN_UNDEF; - } - SvGROW(sv, SvLEN(sv) + 128); - } - SvCUR_set(sv, strlen(SvPVX(sv))); - SvPOK_only(sv); - -#else - if (PerlLIO_lstat(".", &statbuf) < 0) { SV_CWD_RETURN_UNDEF; }