/* perl.c
*
- * Copyright (c) 1987-1996 Larry Wall
+ * Copyright (c) 1987-1997 Larry Wall
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
#include <unistd.h>
#endif
+#if !defined(STANDARD_C) && !defined(HAS_GETENV_PROTOTYPE)
+char *getenv _((char *)); /* Usually in <stdlib.h> */
+#endif
+
dEXTCONST char rcsid[] = "perl.c\nPatch level: ###\n";
#ifdef IAMSUID
static void init_postdump_symbols _((int, char **, char **));
static void init_predump_symbols _((void));
static void init_stacks _((void));
+static void my_exit_jump _((void)) __attribute__((noreturn));
static void nuke_stacks _((void));
static void open_script _((char *, bool, SV *));
static void usage _((char *));
init_ids();
+ start_env.je_prev = NULL;
+ start_env.je_ret = -1;
+ start_env.je_mustcatch = TRUE;
+ top_env = &start_env;
+ STATUS_ALL_SUCCESS;
+
SET_NUMERIC_STANDARD();
#if defined(SUBVERSION) && SUBVERSION > 0
sprintf(patchlevel, "%7.5f", (double) 5
}
#endif
- /* unhook hooks which will soon be, or use, destroyed data */
- SvREFCNT_dec(warnhook);
- warnhook = Nullsv;
- SvREFCNT_dec(diehook);
- diehook = Nullsv;
- SvREFCNT_dec(parsehook);
- parsehook = Nullsv;
-
LEAVE;
FREETMPS;
- /* We must account for everything. First the syntax tree. */
+ /* We must account for everything. */
+
+ /* Destroy the main CV and syntax tree */
if (main_root) {
curpad = AvARRAY(comppad);
op_free(main_root);
- main_root = 0;
+ main_root = Nullop;
}
+ main_start = Nullop;
+ SvREFCNT_dec(main_cv);
+ main_cv = Nullcv;
+
if (sv_objcount) {
/*
* Try to destruct global references. We do this first so that the
sv_clean_objs();
}
+ /* unhook hooks which will soon be, or use, destroyed data */
+ SvREFCNT_dec(warnhook);
+ warnhook = Nullsv;
+ SvREFCNT_dec(diehook);
+ diehook = Nullsv;
+ SvREFCNT_dec(parsehook);
+ parsehook = Nullsv;
+
if (destruct_level == 0){
DEBUG_P(debprofdump());
FREETMPS;
if (destruct_level >= 2) {
if (scopestack_ix != 0)
- warn("Unbalanced scopes: %d more ENTERs than LEAVEs\n", scopestack_ix);
+ warn("Unbalanced scopes: %ld more ENTERs than LEAVEs\n",
+ (long)scopestack_ix);
if (savestack_ix != 0)
- warn("Unbalanced saves: %d more saves than restores\n", savestack_ix);
+ warn("Unbalanced saves: %ld more saves than restores\n",
+ (long)savestack_ix);
if (tmps_floor != -1)
- warn("Unbalanced tmps: %d more allocs than frees\n", tmps_floor + 1);
+ warn("Unbalanced tmps: %ld more allocs than frees\n",
+ (long)tmps_floor + 1);
if (cxstack_ix != -1)
- warn("Unbalanced context: %d more PUSHes than POPs\n", cxstack_ix + 1);
+ warn("Unbalanced context: %ld more PUSHes than POPs\n",
+ (long)cxstack_ix + 1);
}
/* Now absolutely destruct everything, somehow or other, loops or no. */
SvREFCNT_dec(strtab);
if (sv_count != 0)
- warn("Scalars leaked: %d\n", sv_count);
+ warn("Scalars leaked: %ld\n", (long)sv_count);
sv_free_arenas();
return;
Safefree(sv_interp);
}
-#if !defined(STANDARD_C) && !defined(HAS_GETENV_PROTOTYPE)
-char *getenv _((char *)); /* Usually in <stdlib.h> */
-#endif
int
perl_parse(sv_interp, xsinit, argc, argv, env)
char *scriptname = NULL;
VOL bool dosearch = FALSE;
char *validarg = "";
+ I32 oldscope;
AV* comppadlist;
+ dJMPENV;
+ int ret;
#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
#ifdef IAMSUID
return 0;
}
- if (main_root)
+ if (main_root) {
+ curpad = AvARRAY(comppad);
op_free(main_root);
- main_root = 0;
+ main_root = Nullop;
+ }
+ main_start = Nullop;
+ SvREFCNT_dec(main_cv);
+ main_cv = Nullcv;
+
+ time(&basetime);
+ oldscope = scopestack_ix;
- switch (Sigsetjmp(top_env,1)) {
+ JMPENV_PUSH(ret);
+ switch (ret) {
case 1:
-#ifdef VMS
- statusvalue = 255;
-#else
- statusvalue = 1;
-#endif
+ STATUS_ALL_FAILURE;
+ /* FALL THROUGH */
case 2:
+ /* my_exit() was called */
+ while (scopestack_ix > oldscope)
+ LEAVE;
curstash = defstash;
if (endav)
- calllist(endav);
- return(statusvalue); /* my_exit() was called */
+ call_list(oldscope, endav);
+ JMPENV_POP;
+ return STATUS_NATIVE_EXPORT;
case 3:
+ JMPENV_POP;
PerlIO_printf(PerlIO_stderr(), "panic: top_env\n");
return 1;
}
sv = newSVpv("",0); /* first used for -I flags */
SAVEFREESV(sv);
init_main_stash();
+
for (argc--,argv++; argc > 0; argc--,argv++) {
if (argv[0][0] != '-' || !argv[0][1])
break;
case 'n':
case 'p':
case 's':
- case 'T':
case 'u':
case 'U':
case 'v':
goto reswitch;
break;
+ case 'T':
+ tainting = TRUE;
+ s++;
+ goto reswitch;
+
case 'e':
if (euid != uid || egid != gid)
croak("No -e allowed in setuid scripts");
#else
sv_catpv(Sv,"print \"\\nCharacteristics of this binary (from libperl): \\n\",");
#endif
-#if defined(DEBUGGING) || defined(NOEMBED) || defined(MULTIPLICITY)
+#if defined(DEBUGGING) || defined(NO_EMBED) || defined(MULTIPLICITY)
strcpy(buf,"\" Compile-time options:");
# ifdef DEBUGGING
strcat(buf," DEBUGGING");
# endif
-# ifdef NOEMBED
- strcat(buf," NOEMBED");
+# ifdef NO_EMBED
+ strcat(buf," NO_EMBED");
# endif
# ifdef MULTIPLICITY
strcat(buf," MULTIPLICITY");
sv_catpv(Sv,buf);
#endif
#if defined(LOCAL_PATCH_COUNT)
- if (LOCAL_PATCH_COUNT > 0)
- { int i;
- sv_catpv(Sv,"print \" Locally applied patches:\\n\",");
+ if (LOCAL_PATCH_COUNT > 0) {
+ int i;
+ sv_catpv(Sv,"\" Locally applied patches:\\n\",");
for (i = 1; i <= LOCAL_PATCH_COUNT; i++) {
if (localpatches[i]) {
sprintf(buf,"\" \\t%s\\n\",",localpatches[i]);
}
}
#endif
- sprintf(buf,"\" Built under %s\\n\",",OSNAME);
+ sprintf(buf,"\" Built under %s\\n\"",OSNAME);
sv_catpv(Sv,buf);
#ifdef __DATE__
# ifdef __TIME__
- sprintf(buf,"\" Compiled at %s %s\\n\"",__DATE__,__TIME__);
+ sprintf(buf,",\" Compiled at %s %s\\n\"",__DATE__,__TIME__);
# else
- sprintf(buf,"\" Compiled on %s\\n\"",__DATE__);
+ sprintf(buf,",\" Compiled on %s\\n\"",__DATE__);
# endif
sv_catpv(Sv,buf);
#endif
- sv_catpv(Sv,"; $\"=\"\\n \"; print \" \\@INC:\\n @INC\\n\"");
+ sv_catpv(Sv, "; \
+$\"=\"\\n \"; \
+@env = map { \"$_=\\\"$ENV{$_}\\\"\" } sort grep {/^PERL/} keys %ENV; \
+print \" \\%ENV:\\n @env\\n\" if @env; \
+print \" \\@INC:\\n @INC\\n\";");
}
else {
Sv = newSVpv("config_vars(qw(",0);
}
}
switch_end:
+
+ if (!tainting && (s = getenv("PERL5OPT"))) {
+ for (;;) {
+ while (isSPACE(*s))
+ s++;
+ if (*s == '-') {
+ s++;
+ if (isSPACE(*s))
+ continue;
+ }
+ if (!*s)
+ break;
+ if (!strchr("DIMUdmw", *s))
+ croak("Illegal switch in PERL5OPT: -%c", *s);
+ s = moreswitches(s);
+ }
+ }
+
if (!scriptname)
scriptname = argv[0];
if (e_fp) {
- if (PerlIO_flush(e_fp) || PerlIO_error(e_fp) || PerlIO_close(e_fp))
+ if (PerlIO_flush(e_fp) || PerlIO_error(e_fp) || PerlIO_close(e_fp)) {
+#ifndef MULTIPLICITY
+ warn("Did you forget to compile with -DMULTIPLICITY?");
+#endif
croak("Can't write to temp file for -e: %s", Strerror(errno));
+ }
e_fp = Nullfp;
argc++,argv--;
scriptname = e_tmpname;
if (doextract)
find_beginning();
- compcv = (CV*)NEWSV(1104,0);
+ main_cv = compcv = (CV*)NEWSV(1104,0);
sv_upgrade((SV *)compcv, SVt_PVCV);
CvUNIQUE_on(compcv);
ENTER;
restartop = 0;
+ JMPENV_POP;
return 0;
}
perl_run(sv_interp)
PerlInterpreter *sv_interp;
{
+ I32 oldscope;
+ dJMPENV;
+ int ret;
+
if (!(curinterp = sv_interp))
return 255;
- switch (Sigsetjmp(top_env,1)) {
+
+ oldscope = scopestack_ix;
+
+ JMPENV_PUSH(ret);
+ switch (ret) {
case 1:
cxstack_ix = -1; /* start context stack again */
break;
case 2:
+ /* my_exit() was called */
+ while (scopestack_ix > oldscope)
+ LEAVE;
curstash = defstash;
if (endav)
- calllist(endav);
+ call_list(oldscope, endav);
FREETMPS;
#ifdef DEBUGGING_MSTATS
if (getenv("PERL_DEBUG_MSTATS"))
dump_mstats("after execution: ");
#endif
- return(statusvalue); /* my_exit() was called */
+ JMPENV_POP;
+ return STATUS_NATIVE_EXPORT;
case 3:
if (!restartop) {
PerlIO_printf(PerlIO_stderr(), "panic: restartop\n");
FREETMPS;
+ JMPENV_POP;
return 1;
}
if (curstack != mainstack) {
runops();
}
else if (main_start) {
+ CvDEPTH(main_cv) = 1;
op = main_start;
runops();
}
my_exit(0);
+ /* NOTREACHED */
return 0;
}
-void
-my_exit(status)
-U32 status;
-{
- register CONTEXT *cx;
- I32 gimme;
- SV **newsp;
-
- statusvalue = FIXSTATUS(status);
- if (cxstack_ix >= 0) {
- if (cxstack_ix > 0)
- dounwind(0);
- POPBLOCK(cx,curpm);
- LEAVE;
- }
- Siglongjmp(top_env, 2);
-}
-
SV*
perl_get_sv(name, create)
char* name;
{
LOGOP myop; /* fake syntax tree node */
SV** sp = stack_sp;
- I32 oldmark = TOPMARK;
+ I32 oldmark;
I32 retval;
- Sigjmp_buf oldtop;
I32 oldscope;
static CV *DBcv;
-
+ bool oldcatch = CATCH_GET;
+ dJMPENV;
+ int ret;
+
if (flags & G_DISCARD) {
ENTER;
SAVETMPS;
}
+ Zero(&myop, 1, LOGOP);
+ myop.op_next = Nullop;
+ if (!(flags & G_NOARGS))
+ myop.op_flags |= OPf_STACKED;
+ myop.op_flags |= ((flags & G_VOID) ? OPf_WANT_VOID :
+ (flags & G_ARRAY) ? OPf_WANT_LIST :
+ OPf_WANT_SCALAR);
SAVESPTR(op);
op = (OP*)&myop;
- Zero(op, 1, LOGOP);
+
EXTEND(stack_sp, 1);
*++stack_sp = sv;
+ oldmark = TOPMARK;
oldscope = scopestack_ix;
- if (!(flags & G_NOARGS))
- myop.op_flags = OPf_STACKED;
- myop.op_next = Nullop;
- myop.op_flags |= OPf_KNOW;
- if (flags & G_ARRAY)
- myop.op_flags |= OPf_LIST;
-
if (perldb && curstash != debstash
/* Handle first BEGIN of -d. */
&& (DBcv || (DBcv = GvCV(DBsub)))
op->op_private |= OPpENTERSUB_DB;
if (flags & G_EVAL) {
- Copy(top_env, oldtop, 1, Sigjmp_buf);
-
cLOGOP->op_other = op;
markstack_ptr--;
/* we're trying to emulate pp_entertry() here */
{
register CONTEXT *cx;
- I32 gimme = GIMME;
+ I32 gimme = GIMME_V;
ENTER;
SAVETMPS;
}
markstack_ptr++;
- restart:
- switch (Sigsetjmp(top_env,1)) {
+ JMPENV_PUSH(ret);
+ switch (ret) {
case 0:
break;
case 1:
-#ifdef VMS
- statusvalue = 255; /* XXX I don't think we use 1 anymore. */
-#else
- statusvalue = 1;
-#endif
+ STATUS_ALL_FAILURE;
/* FALL THROUGH */
case 2:
/* my_exit() was called */
curstash = defstash;
FREETMPS;
- Copy(oldtop, top_env, 1, Sigjmp_buf);
+ JMPENV_POP;
if (statusvalue)
croak("Callback called exit");
- my_exit(statusvalue);
+ my_exit_jump();
/* NOTREACHED */
case 3:
if (restartop) {
op = restartop;
restartop = 0;
- goto restart;
+ break;
}
stack_sp = stack_base + oldmark;
if (flags & G_ARRAY)
goto cleanup;
}
}
+ else
+ CATCH_SET(TRUE);
if (op == (OP*)&myop)
op = pp_entersub();
curpm = newpm;
LEAVE;
}
- Copy(oldtop, top_env, 1, Sigjmp_buf);
+ JMPENV_POP;
}
+ else
+ CATCH_SET(oldcatch);
+
if (flags & G_DISCARD) {
stack_sp = stack_base + oldmark;
retval = 0;
SV** sp = stack_sp;
I32 oldmark = sp - stack_base;
I32 retval;
- Sigjmp_buf oldtop;
I32 oldscope;
+ dJMPENV;
+ int ret;
if (flags & G_DISCARD) {
ENTER;
myop.op_flags = OPf_STACKED;
myop.op_next = Nullop;
myop.op_type = OP_ENTEREVAL;
- myop.op_flags |= OPf_KNOW;
+ myop.op_flags |= ((flags & G_VOID) ? OPf_WANT_VOID :
+ (flags & G_ARRAY) ? OPf_WANT_LIST :
+ OPf_WANT_SCALAR);
if (flags & G_KEEPERR)
myop.op_flags |= OPf_SPECIAL;
- if (flags & G_ARRAY)
- myop.op_flags |= OPf_LIST;
- Copy(top_env, oldtop, 1, Sigjmp_buf);
-
-restart:
- switch (Sigsetjmp(top_env,1)) {
+ JMPENV_PUSH(ret);
+ switch (ret) {
case 0:
break;
case 1:
-#ifdef VMS
- statusvalue = 255; /* XXX I don't think we use 1 anymore. */
-#else
- statusvalue = 1;
-#endif
+ STATUS_ALL_FAILURE;
/* FALL THROUGH */
case 2:
/* my_exit() was called */
curstash = defstash;
FREETMPS;
- Copy(oldtop, top_env, 1, Sigjmp_buf);
+ JMPENV_POP;
if (statusvalue)
croak("Callback called exit");
- my_exit(statusvalue);
+ my_exit_jump();
/* NOTREACHED */
case 3:
if (restartop) {
op = restartop;
restartop = 0;
- goto restart;
+ break;
}
stack_sp = stack_base + oldmark;
if (flags & G_ARRAY)
sv_setpv(GvSV(errgv),"");
cleanup:
- Copy(oldtop, top_env, 1, Sigjmp_buf);
+ JMPENV_POP;
if (flags & G_DISCARD) {
stack_sp = stack_base + oldmark;
retval = 0;
s++;
return s;
case 'T':
- tainting = TRUE;
+ if (!tainting)
+ croak("Too late for \"-T\" option");
s++;
return s;
case 'u':
#endif
#ifdef OS2
printf("\n\nOS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n"
- "Version 5 port Copyright (c) 1994-1996, Andreas Kaiser, Ilya Zakharevich\n");
+ "Version 5 port Copyright (c) 1994-1997, Andreas Kaiser, Ilya Zakharevich\n");
#endif
#ifdef atarist
printf("atariST series port, ++jrb bammi@cadence.com\n");
case '\n':
case '\t':
break;
+#ifdef ALTERNATE_SHEBANG
+ case 'S': /* OS/2 needs -S on "extproc" line. */
+ break;
+#endif
case 'P':
if (preprocess)
return s+1;
extern int etext;
sprintf (buf, "%s.perldump", origfilename);
- sprintf (tokenbuf, "%s/perl", BIN);
+ sprintf (tokenbuf, "%s/perl", BIN_EXP);
status = unexec(buf, tokenbuf, &etext, sbrk(0), 0);
if (status)
# ifdef VMS
# include <lib$routines.h>
lib$signal(SS$_DEBUG); /* ssdef.h #included from vmsish.h */
-#else
+# else
ABORT(); /* for use with undump */
-#endif
+# endif
#endif
}
char *cpp = CPPSTDIN;
if (strEQ(cpp,"cppstdin"))
- sprintf(tokenbuf, "%s/%s", SCRIPTDIR, cpp);
+ sprintf(tokenbuf, "%s/%s", BIN_EXP, cpp);
else
sprintf(tokenbuf, "%s", cpp);
sv_catpv(sv,"-I");
#ifndef IAMSUID /* in case script is not readable before setuid */
if (euid && Stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
statbuf.st_mode & (S_ISUID|S_ISGID)) {
- (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
+ (void)sprintf(buf, "%s/sperl%s", BIN_EXP, patchlevel);
execv(buf, origargv); /* try again */
croak("Can't do setuid\n");
}
(void)PerlIO_close(rsfp);
if (rsfp = my_popen("/bin/mail root","w")) { /* heh, heh */
PerlIO_printf(rsfp,
-"User %d tried to run dev %d ino %d in place of dev %d ino %d!\n\
-(Filename of set-id script was %s, uid %d gid %d.)\n\nSincerely,\nperl\n",
- uid,tmpstatbuf.st_dev, tmpstatbuf.st_ino,
- statbuf.st_dev, statbuf.st_ino,
+"User %ld tried to run dev %ld ino %ld in place of dev %ld ino %ld!\n\
+(Filename of set-id script was %s, uid %ld gid %ld.)\n\nSincerely,\nperl\n",
+ (long)uid,(long)tmpstatbuf.st_dev, (long)tmpstatbuf.st_ino,
+ (long)statbuf.st_dev, (long)statbuf.st_ino,
SvPVX(GvSV(curcop->cop_filegv)),
- statbuf.st_uid, statbuf.st_gid);
+ (long)statbuf.st_uid, (long)statbuf.st_gid);
(void)my_pclose(rsfp);
}
croak("Permission denied\n");
if (euid) { /* oops, we're not the setuid root perl */
(void)PerlIO_close(rsfp);
#ifndef IAMSUID
- (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
+ (void)sprintf(buf, "%s/sperl%s", BIN_EXP, patchlevel);
execv(buf, origargv); /* try again */
#endif
croak("Can't do setuid\n");
fcntl(PerlIO_fileno(rsfp),F_SETFD,0); /* ensure no close-on-exec */
#endif
- (void)sprintf(tokenbuf, "%s/perl%s", BIN, patchlevel);
+ (void)sprintf(tokenbuf, "%s/perl%s", BIN_EXP, patchlevel);
execv(tokenbuf, origargv); /* try again */
croak("Can't do setuid\n");
#endif /* IAMSUID */
sv_setpv(GvSV(tmpgv),origfilename);
magicname("0", "0", 1);
}
- if (tmpgv = gv_fetchpv("\024",TRUE, SVt_PV))
- time(&basetime);
if (tmpgv = gv_fetchpv("\030",TRUE, SVt_PV))
sv_setpv(GvSV(tmpgv),origargv[0]);
if (argvgv = gv_fetchpv("ARGV",TRUE, SVt_PVAV)) {
HV *hv;
GvMULTI_on(envgv);
hv = GvHVn(envgv);
- hv_clear(hv);
+ hv_magic(hv, envgv, 'E');
#ifndef VMS /* VMS doesn't have environ array */
/* Note that if the supplied env parameter is actually a copy
of the global environ then it may now point to free'd memory
*/
if (!env)
env = environ;
- if (env != environ) {
+ if (env != environ)
environ[0] = Nullch;
- hv_magic(hv, envgv, 'E');
- }
for (; *env; env++) {
if (!(s = strchr(*env,'=')))
continue;
*s++ = '\0';
sv = newSVpv(s--,0);
- sv_magic(sv, sv, 'e', *env, s - *env);
(void)hv_store(hv, *env, s - *env, sv, 0);
*s = '=';
}
#ifdef DYNAMIC_ENV_FETCH
HvNAME(hv) = savepv(ENV_HV_NAME);
#endif
- hv_magic(hv, envgv, 'E');
}
TAINT_NOT;
if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV))
- sv_setiv(GvSV(tmpgv),(I32)getpid());
+ sv_setiv(GvSV(tmpgv), (IV)getpid());
}
static void
+ sizeof("//auto"));
New(55, archpat_auto, len, char);
sprintf(archpat_auto, "/%s/%s/auto", ARCHNAME, patchlevel);
+#ifdef VMS
+ for (len = sizeof(ARCHNAME) + 2;
+ archpat_auto[len] != '\0' && archpat_auto[len] != '/'; len++)
+ if (archpat_auto[len] == '.') archpat_auto[len] = '_';
+#endif
}
}
*/
if (addsubdirs) {
struct stat tmpstatbuf;
+#ifdef VMS
+ char *unix;
+ STRLEN len;
- /* .../archname/version if -d .../archname/auto */
+ if ((unix = tounixspec_ts(SvPV(libdir,na),Nullch)) != Nullch) {
+ len = strlen(unix);
+ while (unix[len-1] == '/') len--; /* Cosmetic */
+ sv_usepvn(libdir,unix,len);
+ }
+ else
+ PerlIO_printf(PerlIO_stderr(),
+ "Failed to unixify @INC element \"%s\"\n",
+ SvPV(libdir,na));
+#endif
+ /* .../archname/version if -d .../archname/version/auto */
sv_setsv(subdir, libdir);
sv_catpv(subdir, archpat_auto);
if (Stat(SvPVX(subdir), &tmpstatbuf) >= 0 &&
av_push(GvAVn(incgv),
newSVpv(SvPVX(subdir), SvCUR(subdir) - sizeof "auto"));
- /* .../archname/version if -d .../archname/version/auto */
+ /* .../archname if -d .../archname/auto */
sv_insert(subdir, SvCUR(libdir) + sizeof(ARCHNAME),
strlen(patchlevel) + 1, "", 0);
if (Stat(SvPVX(subdir), &tmpstatbuf) >= 0 &&
}
void
-calllist(list)
+call_list(oldscope, list)
+I32 oldscope;
AV* list;
{
- Sigjmp_buf oldtop;
- STRLEN len;
line_t oldline = curcop->cop_line;
-
- Copy(top_env, oldtop, 1, Sigjmp_buf);
+ STRLEN len;
+ dJMPENV;
+ int ret;
while (AvFILL(list) >= 0) {
CV *cv = (CV*)av_shift(list);
SAVEFREESV(cv);
- switch (Sigsetjmp(top_env,1)) {
+ JMPENV_PUSH(ret);
+ switch (ret) {
case 0: {
SV* atsv = GvSV(errgv);
PUSHMARK(stack_sp);
perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
(void)SvPV(atsv, len);
if (len) {
- Copy(oldtop, top_env, 1, Sigjmp_buf);
+ JMPENV_POP;
curcop = &compiling;
curcop->cop_line = oldline;
if (list == beginav)
sv_catpv(atsv, "BEGIN failed--compilation aborted");
else
sv_catpv(atsv, "END failed--cleanup aborted");
+ while (scopestack_ix > oldscope)
+ LEAVE;
croak("%s", SvPVX(atsv));
}
}
break;
case 1:
-#ifdef VMS
- statusvalue = 255; /* XXX I don't think we use 1 anymore. */
-#else
- statusvalue = 1;
-#endif
+ STATUS_ALL_FAILURE;
/* FALL THROUGH */
case 2:
/* my_exit() was called */
+ while (scopestack_ix > oldscope)
+ LEAVE;
curstash = defstash;
if (endav)
- calllist(endav);
+ call_list(oldscope, endav);
FREETMPS;
- Copy(oldtop, top_env, 1, Sigjmp_buf);
+ JMPENV_POP;
curcop = &compiling;
curcop->cop_line = oldline;
if (statusvalue) {
else
croak("END failed--cleanup aborted");
}
- my_exit(statusvalue);
+ my_exit_jump();
/* NOTREACHED */
- return;
case 3:
if (!restartop) {
PerlIO_printf(PerlIO_stderr(), "panic: restartop\n");
FREETMPS;
break;
}
- Copy(oldtop, top_env, 1, Sigjmp_buf);
+ JMPENV_POP;
curcop = &compiling;
curcop->cop_line = oldline;
- Siglongjmp(top_env, 3);
+ JMPENV_JUMP(3);
}
+ JMPENV_POP;
}
+}
- Copy(oldtop, top_env, 1, Sigjmp_buf);
+void
+my_exit(status)
+U32 status;
+{
+ switch (status) {
+ case 0:
+ STATUS_ALL_SUCCESS;
+ break;
+ case 1:
+ STATUS_ALL_FAILURE;
+ break;
+ default:
+ STATUS_NATIVE_SET(status);
+ break;
+ }
+ my_exit_jump();
}
+void
+my_failure_exit()
+{
+#ifdef VMS
+ if (vaxc$errno & 1) {
+ if (STATUS_NATIVE & 1) /* fortuitiously includes "-1" */
+ STATUS_NATIVE_SET(44);
+ }
+ else {
+ if (!vaxc$errno && errno) /* unlikely */
+ STATUS_NATIVE_SET(44);
+ else
+ STATUS_NATIVE_SET(vaxc$errno);
+ }
+#else
+ if (errno & 255)
+ STATUS_POSIX_SET(errno);
+ else if (STATUS_POSIX == 0)
+ STATUS_POSIX_SET(255);
+#endif
+ my_exit_jump();
+}
+
+static void
+my_exit_jump()
+{
+ register CONTEXT *cx;
+ I32 gimme;
+ SV **newsp;
+
+ if (e_tmpname) {
+ if (e_fp) {
+ PerlIO_close(e_fp);
+ e_fp = Nullfp;
+ }
+ (void)UNLINK(e_tmpname);
+ Safefree(e_tmpname);
+ e_tmpname = Nullch;
+ }
+
+ if (cxstack_ix >= 0) {
+ if (cxstack_ix > 0)
+ dounwind(0);
+ POPBLOCK(cx,curpm);
+ LEAVE;
+ }
+
+ JMPENV_JUMP(2);
+}