/* Shadow password support for solaris - pdo@cs.umd.edu
* Not just Solaris: at least HP-UX, IRIX, Linux.
* the API is from SysV. --jhi */
+#ifdef __hpux__
+/* There is a MAXINT coming from <shadow.h> <- <hpsecurity.h> <- <values.h>
+ * and another MAXINT from "perl.h" <- <sys/param.h>. */
+#undef MAXINT
+#endif
#include <shadow.h>
#endif
# include <sys/access.h>
#endif
+#if defined(HAS_FCNTL) && defined(F_SETFD) && !defined(FD_CLOEXEC)
+# define FD_CLOEXEC 1 /* NeXT needs this */
+#endif
+
#undef PERL_EFF_ACCESS_R_OK /* EFFective uid/gid ACCESS R_OK */
#undef PERL_EFF_ACCESS_W_OK
#undef PERL_EFF_ACCESS_X_OK
|| defined(HAS_SETREGID) || defined(HAS_SETRESGID))
/* The Hard Way. */
STATIC int
-S_emulate_eaccess(pTHX_ const char* path, int mode)
+S_emulate_eaccess(pTHX_ const char* path, Mode_t mode)
{
Uid_t ruid = getuid();
Uid_t euid = geteuid();
#if !defined(PERL_EFF_ACCESS_R_OK)
STATIC int
-S_emulate_eaccess(pTHX_ const char* path, int mode)
+S_emulate_eaccess(pTHX_ const char* path, Mode_t mode)
{
Perl_croak(aTHX_ "switching effective uid is not implemented");
/*NOTREACHED*/
djSP; dTARGET;
GV *gv;
SV *sv;
+ SV *name;
+ I32 have_name = 0;
char *tmps;
STRLEN len;
MAGIC *mg;
+ if (MAXARG > 2) {
+ name = POPs;
+ have_name = 1;
+ }
if (MAXARG > 1)
sv = POPs;
if (!isGV(TOPs))
PUSHMARK(SP);
XPUSHs(SvTIED_obj((SV*)gv, mg));
XPUSHs(sv);
+ if (have_name)
+ XPUSHs(name);
PUTBACK;
ENTER;
call_method("OPEN", G_SCALAR);
}
tmps = SvPV(sv, len);
- if (do_open(gv, tmps, len, FALSE, O_RDONLY, 0, Nullfp))
+ if (do_open9(gv, tmps, len, FALSE, O_RDONLY, 0, Nullfp, name, have_name))
PUSHi( (I32)PL_forkprocess );
else if (PL_forkprocess == 0) /* we are a new child */
PUSHi(0);
if (ckWARN(WARN_UNTIE)) {
MAGIC * mg ;
if (mg = SvTIED_mg(sv, how)) {
+#ifdef IV_IS_QUAD
+ if (mg && SvREFCNT(SvRV(mg->mg_obj)) > 1)
+ Perl_warner(aTHX_ WARN_UNTIE,
+ "untie attempted while %" PERL_PRIu64 " inner references still exist",
+ (UV)SvREFCNT(SvRV(mg->mg_obj)) - 1 ) ;
+#else
if (mg && SvREFCNT(SvRV(mg->mg_obj)) > 1)
Perl_warner(aTHX_ WARN_UNTIE,
"untie attempted while %lu inner references still exist",
(unsigned long)SvREFCNT(SvRV(mg->mg_obj)) - 1 ) ;
+#endif
}
}
fp = IoOFP(io);
if (!fp) {
if (ckWARN2(WARN_CLOSED,WARN_IO)) {
+ SV* sv = sv_newmortal();
+ gv_efullname3(sv, gv, Nullch);
if (IoIFP(io))
- Perl_warner(aTHX_ WARN_IO, "Filehandle only opened for input");
+ Perl_warner(aTHX_ WARN_IO,
+ "Filehandle %s opened only for input",
+ SvPV_nolen(sv));
else if (ckWARN(WARN_CLOSED))
- Perl_warner(aTHX_ WARN_CLOSED, "Write on closed filehandle");
+ Perl_warner(aTHX_ WARN_CLOSED,
+ "Write on closed filehandle %s", SvPV_nolen(sv));
}
PUSHs(&PL_sv_no);
}
sv = NEWSV(0,0);
if (!(io = GvIO(gv))) {
if (ckWARN(WARN_UNOPENED)) {
- gv_fullname3(sv, gv, Nullch);
- Perl_warner(aTHX_ WARN_UNOPENED, "Filehandle %s never opened", SvPV(sv,n_a));
+ gv_efullname3(sv, gv, Nullch);
+ Perl_warner(aTHX_ WARN_UNOPENED,
+ "Filehandle %s never opened", SvPV(sv,n_a));
}
SETERRNO(EBADF,RMS$_IFI);
goto just_say_no;
}
else if (!(fp = IoOFP(io))) {
if (ckWARN2(WARN_CLOSED,WARN_IO)) {
- gv_fullname3(sv, gv, Nullch);
+ gv_efullname3(sv, gv, Nullch);
if (IoIFP(io))
- Perl_warner(aTHX_ WARN_IO, "Filehandle %s opened only for input",
- SvPV(sv,n_a));
+ Perl_warner(aTHX_ WARN_IO,
+ "Filehandle %s opened only for input",
+ SvPV(sv,n_a));
else if (ckWARN(WARN_CLOSED))
- Perl_warner(aTHX_ WARN_CLOSED, "printf on closed filehandle %s",
- SvPV(sv,n_a));
+ Perl_warner(aTHX_ WARN_CLOSED,
+ "printf on closed filehandle %s", SvPV(sv,n_a));
}
SETERRNO(EBADF,IoIFP(io)?RMS$_FAC:RMS$_IFI);
goto just_say_no;
if (length == 0 && PerlIO_error(IoIFP(io)))
length = -1;
}
- if (length < 0)
+ if (length < 0) {
+ if ((IoTYPE(io) == '>' || IoIFP(io) == PerlIO_stdout()
+ || IoIFP(io) == PerlIO_stderr()) && ckWARN(WARN_IO))
+ {
+ SV* sv = sv_newmortal();
+ gv_efullname3(sv, gv, Nullch);
+ Perl_warner(aTHX_ WARN_IO, "Filehandle %s opened only for output",
+ SvPV_nolen(sv));
+ }
goto say_undef;
+ }
SvCUR_set(bufsv, length+offset);
*SvEND(bufsv) = '\0';
(void)SvPOK_only(bufsv);
else
#endif
{
+ /* See the note at doio.c:do_print about filesize limits. --jhi */
length = PerlLIO_write(PerlIO_fileno(IoIFP(io)),
buffer+offset, length);
}
djSP;
GV *gv;
int whence = POPi;
- Off_t offset = POPl;
+ Off_t offset = (Off_t)SvIVx(POPs);
MAGIC *mg;
gv = PL_last_in_gv = (GV*)POPs;
}
else {
retval = SvIV(argsv);
- s = (char*)retval; /* ouch */
+ s = INT2PTR(char*,retval); /* ouch */
}
TAINT_PROPER(optype == OP_IOCTL ? "ioctl" : "fcntl");
if (max) {
EXTEND(SP, max);
EXTEND_MORTAL(max);
- PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_dev)));
- PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_ino)));
- PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_mode)));
- PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_nlink)));
- PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_uid)));
- PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_gid)));
+ PUSHs(sv_2mortal(newSViv(PL_statcache.st_dev)));
+ PUSHs(sv_2mortal(newSViv(PL_statcache.st_ino)));
+ PUSHs(sv_2mortal(newSViv(PL_statcache.st_mode)));
+ PUSHs(sv_2mortal(newSViv(PL_statcache.st_nlink)));
+ PUSHs(sv_2mortal(newSViv(PL_statcache.st_uid)));
+ PUSHs(sv_2mortal(newSViv(PL_statcache.st_gid)));
#ifdef USE_STAT_RDEV
- PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_rdev)));
+ PUSHs(sv_2mortal(newSViv(PL_statcache.st_rdev)));
#else
PUSHs(sv_2mortal(newSVpvn("", 0)));
#endif
- PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_size)));
+ PUSHs(sv_2mortal(newSViv(PL_statcache.st_size)));
#ifdef BIG_TIME
- PUSHs(sv_2mortal(newSVnv((U32)PL_statcache.st_atime)));
- PUSHs(sv_2mortal(newSVnv((U32)PL_statcache.st_mtime)));
- PUSHs(sv_2mortal(newSVnv((U32)PL_statcache.st_ctime)));
+ PUSHs(sv_2mortal(newSVnv(PL_statcache.st_atime)));
+ PUSHs(sv_2mortal(newSVnv(PL_statcache.st_mtime)));
+ PUSHs(sv_2mortal(newSVnv(PL_statcache.st_ctime)));
#else
- PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_atime)));
- PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_mtime)));
- PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_ctime)));
+ PUSHs(sv_2mortal(newSViv(PL_statcache.st_atime)));
+ PUSHs(sv_2mortal(newSViv(PL_statcache.st_mtime)));
+ PUSHs(sv_2mortal(newSViv(PL_statcache.st_ctime)));
#endif
#ifdef USE_STAT_BLOCKS
- PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_blksize)));
- PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_blocks)));
+ PUSHs(sv_2mortal(newSViv(PL_statcache.st_blksize)));
+ PUSHs(sv_2mortal(newSViv(PL_statcache.st_blocks)));
#else
PUSHs(sv_2mortal(newSVpvn("", 0)));
PUSHs(sv_2mortal(newSVpvn("", 0)));
djSP; dTARGET;
if (result < 0)
RETPUSHUNDEF;
- PUSHn( ((I32)PL_basetime - (I32)PL_statcache.st_mtime) / 86400.0 );
+ PUSHn( (PL_basetime - PL_statcache.st_mtime) / 86400.0 );
RETURN;
}
djSP; dTARGET;
if (result < 0)
RETPUSHUNDEF;
- PUSHn( ((I32)PL_basetime - (I32)PL_statcache.st_atime) / 86400.0 );
+ PUSHn( (PL_basetime - PL_statcache.st_atime) / 86400.0 );
RETURN;
}
djSP; dTARGET;
if (result < 0)
RETPUSHUNDEF;
- PUSHn( ((I32)PL_basetime - (I32)PL_statcache.st_ctime) / 86400.0 );
+ PUSHn( (PL_basetime - PL_statcache.st_ctime) / 86400.0 );
RETURN;
}
PP(pp_wait)
{
-#if !defined(DOSISH) || defined(OS2) || defined(WIN32) || defined(CYGWIN32)
+#if !defined(DOSISH) || defined(OS2) || defined(WIN32)
djSP; dTARGET;
Pid_t childpid;
int argflags;
PP(pp_waitpid)
{
-#if !defined(DOSISH) || defined(OS2) || defined(WIN32) || defined(CYGWIN32)
+#if !defined(DOSISH) || defined(OS2) || defined(WIN32)
djSP; dTARGET;
Pid_t childpid;
int optype;
int status;
Sigsave_t ihand,qhand; /* place to save signals during system() */
STRLEN n_a;
+ I32 did_pipes = 0;
+ int pp[2];
if (SP - MARK == 1) {
if (PL_tainting) {
}
PERL_FLUSHALL_FOR_CHILD;
#if (defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(OS2)
+ if (PerlProc_pipe(pp) >= 0)
+ did_pipes = 1;
while ((childpid = vfork()) == -1) {
if (errno != EAGAIN) {
value = -1;
SP = ORIGMARK;
PUSHi(value);
+ if (did_pipes) {
+ PerlLIO_close(pp[0]);
+ PerlLIO_close(pp[1]);
+ }
RETURN;
}
sleep(5);
}
if (childpid > 0) {
+ if (did_pipes)
+ PerlLIO_close(pp[1]);
rsignal_save(SIGINT, SIG_IGN, &ihand);
rsignal_save(SIGQUIT, SIG_IGN, &qhand);
do {
STATUS_NATIVE_SET(result == -1 ? -1 : status);
do_execfree(); /* free any memory child malloced on vfork */
SP = ORIGMARK;
+ if (did_pipes) {
+ int errkid;
+ int n = 0, n1;
+
+ while (n < sizeof(int)) {
+ n1 = PerlLIO_read(pp[0],
+ (void*)(((char*)&errkid)+n),
+ (sizeof(int)) - n);
+ if (n1 <= 0)
+ break;
+ n += n1;
+ }
+ PerlLIO_close(pp[0]);
+ if (n) { /* Error */
+ if (n != sizeof(int))
+ Perl_croak(aTHX_ "panic: kid popen errno read");
+ errno = errkid; /* Propagate errno from kid */
+ STATUS_CURRENT = -1;
+ }
+ }
PUSHi(STATUS_CURRENT);
RETURN;
}
+ if (did_pipes) {
+ PerlLIO_close(pp[0]);
+#if defined(HAS_FCNTL) && defined(F_SETFD)
+ fcntl(pp[1], F_SETFD, FD_CLOEXEC);
+#endif
+ }
if (PL_op->op_flags & OPf_STACKED) {
SV *really = *++MARK;
- value = (I32)do_aexec(really, MARK, SP);
+ value = (I32)do_aexec5(really, MARK, SP, pp[1], did_pipes);
}
else if (SP - MARK != 1)
- value = (I32)do_aexec(Nullsv, MARK, SP);
+ value = (I32)do_aexec5(Nullsv, MARK, SP, pp[1], did_pipes);
else {
- value = (I32)do_exec(SvPVx(sv_mortalcopy(*SP), n_a));
+ value = (I32)do_exec3(SvPVx(sv_mortalcopy(*SP), n_a), pp[1], did_pipes);
}
PerlProc__exit(-1);
#else /* ! FORK or VMS or OS/2 */
if (PL_op->op_flags & OPf_STACKED) {
SV *really = *++MARK;
- value = (I32)do_aspawn(aTHX_ really, (void **)MARK, (void **)SP);
+ value = (I32)do_aspawn(really, (void **)MARK, (void **)SP);
}
else if (SP - MARK != 1)
- value = (I32)do_aspawn(aTHX_ Nullsv, (void **)MARK, (void **)SP);
+ value = (I32)do_aspawn(Nullsv, (void **)MARK, (void **)SP);
else {
- value = (I32)do_spawn(aTHX_ SvPVx(sv_mortalcopy(*SP), n_a));
+ value = (I32)do_spawn(SvPVx(sv_mortalcopy(*SP), n_a));
}
STATUS_NATIVE_SET(value);
do_execfree();
#else
# ifdef __OPEN_VM
{
- (void ) do_aspawn(aTHX_ Nullsv, MARK, SP);
+ (void ) do_aspawn(Nullsv, MARK, SP);
value = 0;
}
# else
value = (I32)vms_do_exec(SvPVx(sv_mortalcopy(*SP), n_a));
#else
# ifdef __OPEN_VM
- (void) do_spawn(aTHX_ SvPVx(sv_mortalcopy(*SP), n_a));
+ (void) do_spawn(SvPVx(sv_mortalcopy(*SP), n_a));
value = 0;
# else
value = (I32)do_exec(SvPVx(sv_mortalcopy(*SP), n_a));
{
#ifdef HAS_GETPGRP
djSP; dTARGET;
- int pid;
- I32 value;
+ Pid_t pid;
+ Pid_t pgrp;
if (MAXARG < 1)
pid = 0;
else
pid = SvIVx(POPs);
#ifdef BSD_GETPGRP
- value = (I32)BSD_GETPGRP(pid);
+ pgrp = (I32)BSD_GETPGRP(pid);
#else
if (pid != 0 && pid != getpid())
DIE(aTHX_ "POSIX getpgrp can't take an argument");
- value = (I32)getpgrp();
+ pgrp = getpgrp();
#endif
- XPUSHi(value);
+ XPUSHi(pgrp);
RETURN;
#else
DIE(aTHX_ PL_no_func, "getpgrp()");
{
#ifdef HAS_SETPGRP
djSP; dTARGET;
- int pgrp;
- int pid;
+ Pid_t pgrp;
+ Pid_t pid;
if (MAXARG < 2) {
pgrp = 0;
pid = 0;
if (!tmbuf)
RETPUSHUNDEF;
tsv = Perl_newSVpvf(aTHX_ "%s %s %2d %02d:%02d:%02d %d",
- dayname[tmbuf->tm_wday],
- monname[tmbuf->tm_mon],
- tmbuf->tm_mday,
- tmbuf->tm_hour,
- tmbuf->tm_min,
- tmbuf->tm_sec,
- tmbuf->tm_year + 1900);
+ dayname[tmbuf->tm_wday],
+ monname[tmbuf->tm_mon],
+ tmbuf->tm_mday,
+ tmbuf->tm_hour,
+ tmbuf->tm_min,
+ tmbuf->tm_sec,
+ tmbuf->tm_year + 1900);
PUSHs(sv_2mortal(tsv));
}
else if (tmbuf) {
- PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_sec)));
- PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_min)));
- PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_hour)));
- PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_mday)));
- PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_mon)));
- PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_year)));
- PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_wday)));
- PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_yday)));
- PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_isdst)));
+ PUSHs(sv_2mortal(newSViv(tmbuf->tm_sec)));
+ PUSHs(sv_2mortal(newSViv(tmbuf->tm_min)));
+ PUSHs(sv_2mortal(newSViv(tmbuf->tm_hour)));
+ PUSHs(sv_2mortal(newSViv(tmbuf->tm_mday)));
+ PUSHs(sv_2mortal(newSViv(tmbuf->tm_mon)));
+ PUSHs(sv_2mortal(newSViv(tmbuf->tm_year)));
+ PUSHs(sv_2mortal(newSViv(tmbuf->tm_wday)));
+ PUSHs(sv_2mortal(newSViv(tmbuf->tm_yday)));
+ PUSHs(sv_2mortal(newSViv(tmbuf->tm_isdst)));
}
RETURN;
}
EXTEND(SP, 1);
if (anum < 0)
RETPUSHUNDEF;
- PUSHi((I32)anum);
+ PUSHi(anum);
RETURN;
#else
DIE(aTHX_ PL_no_func, "Unsupported function alarm");
register SV *sv;
struct passwd *pwent;
STRLEN n_a;
-#ifdef HAS_GETSPENT
+#if defined(HAS_GETSPENT) || defined(HAS_GETSPNAM)
struct spwd *spwent = NULL;
#endif
spwent = getspnam(pwent->pw_name);
}
# endif
+# ifdef HAS_GETSPENT
else
spwent = (struct spwd *)getspent();
+# endif
#endif
EXTEND(SP, 10);
PUSHs(sv = sv_mortalcopy(&PL_sv_no));
#ifdef PWPASSWD
-# ifdef HAS_GETSPENT
+# if defined(HAS_GETSPENT) || defined(HAS_GETSPNAM)
if (spwent)
sv_setpv(sv, spwent->sp_pwdp);
else
PP(pp_spwent)
{
djSP;
-#if defined(HAS_PASSWD) && defined(HAS_SETPWENT) && !defined(CYGWIN32)
+#if defined(HAS_PASSWD) && defined(HAS_SETPWENT)
setpwent();
# ifdef HAS_SETSPENT
setspent();
return -1;
}
flock.l_whence = SEEK_SET;
- flock.l_start = flock.l_len = 0L;
+ flock.l_start = flock.l_len = (Off_t)0;
return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &flock);
}