else {
PerlIO *that_fp = NULL;
int wanted_fd;
+ UV uv;
if (num_svs > 1) {
/* diag_listed_as: More than one argument to '%s' open */
Perl_croak(aTHX_ "More than one argument to '%c&' open",IoTYPE(io));
wanted_fd = SvUV(*svp);
num_svs = 0;
}
- else if (isDIGIT(*type)) {
- wanted_fd = grok_atou(type, NULL);
+ else if (isDIGIT(*type)
+ && grok_atoUV(type, &uv, NULL)
+ && uv <= INT_MAX
+ ) {
+ wanted_fd = (int)uv;
}
else {
const IO* thatio;
else if (IoTYPE(thatio) == IoTYPE_SOCKET)
IoTYPE(io) = IoTYPE_SOCKET;
}
- else
- wanted_fd = -1;
+ else {
+ SETERRNO(EBADF, RMS_IFI);
+ fp = NULL;
+ goto say_false;
+ }
}
if (!num_svs)
type = NULL;
int ofd = PerlIO_fileno(fp);
int dupfd = ofd >= 0 ? PerlLIO_dup(ofd) : -1;
#if defined(HAS_FCNTL) && defined(F_SETFD)
- /* Assume if we have F_SETFD we have F_GETFD */
- int coe = ofd >= 0 ? fcntl(ofd, F_GETFD) : -1;
- if (coe < 0) {
+ /* Assume if we have F_SETFD we have F_GETFD. */
+ /* Get a copy of all the fd flags. */
+ int fd_flags = ofd >= 0 ? fcntl(ofd, F_GETFD) : -1;
+ if (fd_flags < 0) {
if (dupfd >= 0)
PerlLIO_close(dupfd);
goto say_false;
PerlIO_close(fp);
PerlLIO_dup2(dupfd, ofd);
#if defined(HAS_FCNTL) && defined(F_SETFD)
- /* The dup trick has lost close-on-exec on ofd */
- fcntl(ofd,F_SETFD, coe);
+ /* The dup trick has lost close-on-exec on ofd,
+ * and possibly any other flags, so restore them. */
+ fcntl(ofd,F_SETFD, fd_flags);
#endif
PerlLIO_close(dupfd);
}
PerlIO_clearerr(fp);
fd = PerlIO_fileno(fp);
}
-#if defined(HAS_FCNTL) && defined(F_SETFD)
- if (fd >= 0) {
- if (fcntl(fd, F_SETFD, fd > PL_maxsysfd) < 0) {
- PerlLIO_close(fd);
- goto say_false;
- }
+#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
+ if (fd > PL_maxsysfd && fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
+ PerlLIO_close(fd);
+ goto say_false;
}
#endif
IoIFP(io) = fp;
}
return TRUE;
-say_false:
+ say_false:
IoIFP(io) = saveifp;
IoOFP(io) = saveofp;
IoTYPE(io) = savetype;
if (!PL_argvoutgv)
PL_argvoutgv = gv_fetchpvs("ARGVOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO);
- if (io && (IoFLAGS(io) & IOf_ARGV) && (IoFLAGS(io) & IOf_START)) {
+ if (io && (IoFLAGS(io) & (IOf_ARGV|IOf_START)) == (IOf_ARGV|IOf_START)) {
IoFLAGS(io) &= ~IOf_START;
if (PL_inplace) {
assert(PL_defoutgv);
Perl_ck_warner_d(aTHX_ packWARN(WARN_IO),
"Warning: unable to close filehandle %"
HEKf" properly: %"SVf,
- GvNAME_HEK(gv), get_sv("!",GV_ADD));
+ HEKfARG(GvNAME_HEK(gv)),
+ SVfARG(get_sv("!",GV_ADD)));
else
Perl_ck_warner_d(aTHX_ packWARN(WARN_IO),
"Warning: unable to close filehandle "
"properly: %"SVf,
- get_sv("!",GV_ADD));
+ SVfARG(get_sv("!",GV_ADD)));
}
}
else if (not_implicit) {
if (io && (fp = IoIFP(io))) {
int fd = PerlIO_fileno(fp);
- if (fd >= 0) {
+ if (fd < 0 || (whence == SEEK_SET && pos < 0)) {
+ SETERRNO(EINVAL,LIB_INVARG);
+ return -1;
+ } else {
return PerlLIO_lseek(fd, pos, whence);
}
}
}
else {
const char *end;
-fail_discipline:
+ fail_discipline:
end = strchr(s+1, ':');
if (!end)
end = s+len;
{
const int e = errno;
PERL_ARGS_ASSERT_EXEC_FAILED;
- if (ckWARN(WARN_EXEC))
- Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
- cmd, Strerror(e));
+#ifdef __amigaos4__
+ if (e)
+#endif
+ {
+ if (ckWARN(WARN_EXEC))
+ Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
+ cmd, Strerror(e));
+ }
if (do_report) {
/* XXX silently ignore failures */
PERL_UNUSED_RESULT(PerlLIO_write(fd, (void*)&e, sizeof(int)));
}
}
-bool
+DO_EXEC_TYPE
Perl_do_aexec5(pTHX_ SV *really, SV **mark, SV **sp,
int fd, int do_report)
{
dVAR;
+ DO_EXEC_TYPE result = DO_EXEC_FAILURE;
PERL_ARGS_ASSERT_DO_AEXEC5;
+ PERL_UNUSED_VAR(result); /* if DO_EXEC_TYPE is bool */
#if defined(__SYMBIAN32__) || defined(__LIBCATAMOUNT__)
Perl_croak(aTHX_ "exec? I'm not *that* kind of operating system");
#else
(really && *tmps != '/')) /* will execvp use PATH? */
TAINT_ENV(); /* testing IFS here is overkill, probably */
PERL_FPU_PRE_EXEC
- if (really && *tmps)
- PerlProc_execvp(tmps,EXEC_ARGV_CAST(PL_Argv));
- else
- PerlProc_execvp(PL_Argv[0],EXEC_ARGV_CAST(PL_Argv));
+ if (really && *tmps) {
+ result =
+ (DO_EXEC_TYPE)
+ PerlProc_execvp(tmps,EXEC_ARGV_CAST(PL_Argv));
+ } else {
+ result =
+ (DO_EXEC_TYPE)
+ PerlProc_execvp(PL_Argv[0],EXEC_ARGV_CAST(PL_Argv));
+ }
PERL_FPU_POST_EXEC
S_exec_failed(aTHX_ (really ? tmps : PL_Argv[0]), fd, do_report);
}
do_execfree();
#endif
- return FALSE;
+ return DO_EXEC_RETVAL(result);
}
void
#ifdef PERL_DEFAULT_DO_EXEC3_IMPLEMENTATION
-bool
+DO_EXEC_TYPE
Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report)
{
dVAR;
char *cmd;
/* Make a copy so we can change it */
const Size_t cmdlen = strlen(incmd) + 1;
+ DO_EXEC_TYPE result = DO_EXEC_FAILURE;
+ PERL_UNUSED_VAR(result); /* if DO_EXEC_TYPE is bool */
PERL_ARGS_ASSERT_DO_EXEC3;
if (s[-1] == '\'') {
*--s = '\0';
PERL_FPU_PRE_EXEC
- PerlProc_execl(PL_cshname, "csh", flags, ncmd, (char*)NULL);
+ result =
+ (DO_EXEC_TYPE)
+ PerlProc_execl(PL_cshname, "csh", flags, ncmd, (char*)NULL);
PERL_FPU_POST_EXEC
*s = '\'';
S_exec_failed(aTHX_ PL_cshname, fd, do_report);
Safefree(buf);
- return FALSE;
+ return DO_EXEC_RETVAL(result);
}
}
}
}
doshell:
PERL_FPU_PRE_EXEC
- PerlProc_execl(PL_sh_path, "sh", "-c", cmd, (char *)NULL);
+ result =
+ (DO_EXEC_TYPE)
+ PerlProc_execl(PL_sh_path, "sh", "-c", cmd, (char *)NULL);
PERL_FPU_POST_EXEC
S_exec_failed(aTHX_ PL_sh_path, fd, do_report);
+#if defined (__amigaos4__)
+ amigaos_post_exec(fd, do_report);
+#endif
Safefree(buf);
- return FALSE;
+ return DO_EXEC_RETVAL(result);
}
}
*a = NULL;
if (PL_Argv[0]) {
PERL_FPU_PRE_EXEC
- PerlProc_execvp(PL_Argv[0],EXEC_ARGV_CAST(PL_Argv));
+ result =
+ (DO_EXEC_TYPE)
+ PerlProc_execvp(PL_Argv[0],EXEC_ARGV_CAST(PL_Argv));
PERL_FPU_POST_EXEC
if (errno == ENOEXEC) { /* for system V NIH syndrome */
do_execfree();
}
do_execfree();
Safefree(buf);
- return FALSE;
+ return DO_EXEC_RETVAL(result);
}
#endif /* OS2 || WIN32 */
if (msize < 0)
Perl_croak(aTHX_ "Arg too short for msgsnd");
SETERRNO(0,0);
- return msgsnd(id, (struct msgbuf *)mbuf, msize, flags);
+ if (id >= 0 && flags >= 0) {
+ return msgsnd(id, (struct msgbuf *)mbuf, msize, flags);
+ } else {
+ SETERRNO(EINVAL,LIB_INVARG);
+ return -1;
+ }
#else
PERL_UNUSED_ARG(sp);
PERL_UNUSED_ARG(mark);
mbuf = SvGROW(mstr, sizeof(long)+msize+1);
SETERRNO(0,0);
- ret = msgrcv(id, (struct msgbuf *)mbuf, msize, mtype, flags);
+ if (id >= 0 && msize >= 0 && flags >= 0) {
+ ret = msgrcv(id, (struct msgbuf *)mbuf, msize, mtype, flags);
+ } else {
+ SETERRNO(EINVAL,LIB_INVARG);
+ ret = -1;
+ }
if (ret >= 0) {
SvCUR_set(mstr, sizeof(long)+ret);
*SvEND(mstr) = '\0';
SETERRNO(EFAULT,SS_ACCVIO); /* can't do as caller requested */
return -1;
}
- shm = (char *)shmat(id, NULL, (optype == OP_SHMREAD) ? SHM_RDONLY : 0);
+ if (id >= 0) {
+ shm = (char *)shmat(id, NULL, (optype == OP_SHMREAD) ? SHM_RDONLY : 0);
+ } else {
+ SETERRNO(EINVAL,LIB_INVARG);
+ return -1;
+ }
if (shm == (char *)-1) /* I hate System V IPC, I really do */
return -1;
if (optype == OP_SHMREAD) {
Function called by C<do_readline> to spawn a glob (or do the glob inside
perl on VMS). This code used to be inline, but now perl uses C<File::Glob>
this glob starter is only used by miniperl during the build process.
-Moving it away shrinks pp_hot.c; shrinking pp_hot.c helps speed perl up.
+Moving it away shrinks F<pp_hot.c>; shrinking F<pp_hot.c> helps speed perl up.
=cut
*/
}
/*
- * Local variables:
- * c-indentation-style: bsd
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- *
* ex: set ts=8 sts=4 sw=4 et:
*/