Skip to content

Commit 0301e89

Browse files
author
Zefram
committed
properly define perl_parse() return value
perl_parse()'s return value has historically had conflicting purposes. perlmain.c uses it as a truth value, but perlembed.pod has shown it being used as an exit code. perl_parse() has not had its own documentation. What the function has actually done is to return zero for normal completion and an exit code for early termination. For this to be a usable convention depended on early termination never using exit code 0, and that's specifically *native* exit code 0, which could have any significance. In fact exit code 0 could arise for a compile-time termination even on Unix through "CHECK { exit 0 }", and the mishandling of that situation was bug [perl #2754]. Since perl_destruct() provides a native exit code unencumbered by any attempt to simultaneously be a truth value, perl_parse() doesn't really need to provide an exit code. So define that perl_parse()'s return value is principally a truth value. Change the perlembed tutorial to show it being so used, with an exit code coming from perl_destruct(). However, most of the historical usage of perl_parse()'s return value as an exit code can be preserved. Make it return 0x100 for exit(0), which both serves as the essential truth value and on Unix also serves as the proper exit code, because that set bit will be masked off when actually exiting. This works on Unix but will have variable effect on other OSes; at least it will reliably indicate an actual exit. perl_run() has a similar problem in the interpretation of its return value, but not affecting the main perl executable, because perlmain.c ignores its return value. Similarly define that it is principally a truth value, with preserved usage of non-zero return values as exit codes, with exit code 0 transformed into 0x100. This requires some extra logic to distinguish between local completion and exit(0), which were not previously distinguished. Fully document perl_parse(), perl_run(), and perl_destruct() as API functions. Make the perlembed tutorial always show a proper exit from main(), using "exit(EXIT_SUCCESS)" for portability when errors are not being checked. Make perlembed always show a null argv[argc] being supplied to perl_parse(), where an argv is constructed. (Commit 54c85bb added a note to perlembed saying that that's required, but didn't fix the examples to show it being done.)
1 parent c9ffefc commit 0301e89

3 files changed

Lines changed: 163 additions & 31 deletions

File tree

perl.c

Lines changed: 135 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -593,9 +593,33 @@ Perl_dump_sv_child(pTHX_ SV *sv)
593593
#endif
594594

595595
/*
596-
=for apidoc perl_destruct
597-
598-
Shuts down a Perl interpreter. See L<perlembed>.
596+
=for apidoc Am|int|perl_destruct|PerlInterpreter *my_perl
597+
598+
Shuts down a Perl interpreter. See L<perlembed> for a tutorial.
599+
600+
C<my_perl> points to the Perl interpreter. It must have been previously
601+
created through the use of L</perl_alloc> and L</perl_construct>. It may
602+
have been initialised through L</perl_parse>, and may have been used
603+
through L</perl_run> and other means. This function should be called for
604+
any Perl interpreter that has been constructed with L</perl_construct>,
605+
even if subsequent operations on it failed, for example if L</perl_parse>
606+
returned a non-zero value.
607+
608+
If the interpreter's C<PL_exit_flags> word has the
609+
C<PERL_EXIT_DESTRUCT_END> flag set, then this function will execute code
610+
in C<END> blocks before performing the rest of destruction. If it is
611+
desired to make any use of the interpreter between L</perl_parse> and
612+
L</perl_destruct> other than just calling L</perl_run>, then this flag
613+
should be set early on. This matters if L</perl_run> will not be called,
614+
or if anything else will be done in addition to calling L</perl_run>.
615+
616+
Returns a value be a suitable value to pass to the C library function
617+
C<exit> (or to return from C<main>), to serve as an exit code indicating
618+
the nature of the way the interpreter terminated. This takes into account
619+
any failure of L</perl_parse> and any early exit from L</perl_run>.
620+
The exit code is of the type required by the host operating system,
621+
so because of differing exit code conventions it is not portable to
622+
interpret specific numeric values as having specific meanings.
599623
600624
=cut
601625
*/
@@ -1570,9 +1594,62 @@ Perl_call_atexit(pTHX_ ATEXIT_t fn, void *ptr)
15701594
}
15711595

15721596
/*
1573-
=for apidoc perl_parse
1574-
1575-
Tells a Perl interpreter to parse a Perl script. See L<perlembed>.
1597+
=for apidoc Am|int|perl_parse|PerlInterpreter *my_perl|XSINIT_t xsinit|int argc|char **argv|char **env
1598+
1599+
Tells a Perl interpreter to parse a Perl script. This performs most
1600+
of the initialisation of a Perl interpreter. See L<perlembed> for
1601+
a tutorial.
1602+
1603+
C<my_perl> points to the Perl interpreter that is to parse the script.
1604+
It must have been previously created through the use of L</perl_alloc>
1605+
and L</perl_construct>. C<xsinit> points to a callback function that
1606+
will be called to set up the ability for this Perl interpreter to load
1607+
XS extensions, or may be null to perform no such setup.
1608+
1609+
C<argc> and C<argv> supply a set of command-line arguments to the Perl
1610+
interpreter, as would normally be passed to the C<main> function of
1611+
a C program. C<argv[argc]> must be null. These arguments are where
1612+
the script to parse is specified, either by naming a script file or by
1613+
providing a script in a C<-e> option.
1614+
1615+
C<env> specifies a set of environment variables that will be used by
1616+
this Perl interpreter. If non-null, it must point to a null-terminated
1617+
array of environment strings. If null, the Perl interpreter will use
1618+
the environment supplied by the C<environ> global variable.
1619+
1620+
This function initialises the interpreter, and parses and compiles the
1621+
script specified by the command-line arguments. This includes executing
1622+
code in C<BEGIN>, C<UNITCHECK>, and C<CHECK> blocks. It does not execute
1623+
C<INIT> blocks or the main program.
1624+
1625+
Returns an integer of slightly tricky interpretation. The correct
1626+
use of the return value is as a truth value indicating whether there
1627+
was a failure in initialisation. If zero is returned, this indicates
1628+
that initialisation was successful, and it is safe to proceed to call
1629+
L</perl_run> and make other use of it. If a non-zero value is returned,
1630+
this indicates some problem that means the interpreter wants to terminate.
1631+
The interpreter should not be just abandoned upon such failure; the caller
1632+
should proceed to shut the interpreter down cleanly with L</perl_destruct>
1633+
and free it with L</perl_free>.
1634+
1635+
For historical reasons, the non-zero return value also attempts to
1636+
be a suitable value to pass to the C library function C<exit> (or to
1637+
return from C<main>), to serve as an exit code indicating the nature
1638+
of the way initialisation terminated. However, this isn't portable,
1639+
due to differing exit code conventions. An attempt is made to return
1640+
an exit code of the type required by the host operating system, but
1641+
because it is constrained to be non-zero, it is not necessarily possible
1642+
to indicate every type of exit. It is only reliable on Unix, where a
1643+
zero exit code can be augmented with a set bit that will be ignored.
1644+
In any case, this function is not the correct place to acquire an exit
1645+
code: one should get that from L</perl_destruct>.
1646+
1647+
In most cases, if something happens during initialisation and parsing
1648+
that causes the Perl interpreter to want to exit, this will cause this
1649+
function to return normally with a non-zero return value. Historically,
1650+
a call to the Perl built-in function C<exit> from inside a C<BEGIN>
1651+
block has been an exception, causing the process to actually exit.
1652+
That behaviour may change in the future.
15761653
15771654
=cut
15781655
*/
@@ -1774,6 +1851,7 @@ perl_parse(pTHXx_ XSINIT_t xsinit, int argc, char **argv, char **env)
17741851
call_list(oldscope, PL_checkav);
17751852
}
17761853
ret = STATUS_EXIT;
1854+
if (ret == 0) ret = 0x100;
17771855
break;
17781856
case 3:
17791857
PerlIO_printf(Perl_error_log, "panic: top_env\n");
@@ -2483,9 +2561,47 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
24832561
}
24842562

24852563
/*
2486-
=for apidoc perl_run
2487-
2488-
Tells a Perl interpreter to run. See L<perlembed>.
2564+
=for apidoc Am|int|perl_run|PerlInterpreter *my_perl
2565+
2566+
Tells a Perl interpreter to run its main program. See L<perlembed>
2567+
for a tutorial.
2568+
2569+
C<my_perl> points to the Perl interpreter. It must have been previously
2570+
created through the use of L</perl_alloc> and L</perl_construct>, and
2571+
initialised through L</perl_parse>. This function should not be called
2572+
if L</perl_parse> returned a non-zero value, indicating a failure in
2573+
initialisation or compilation.
2574+
2575+
This function executes code in C<INIT> blocks, and then executes the
2576+
main program. The code to be executed is that established by the prior
2577+
call to L</perl_parse>. If the interpreter's C<PL_exit_flags> word
2578+
does not have the C<PERL_EXIT_DESTRUCT_END> flag set, then this function
2579+
will also execute code in C<END> blocks. If it is desired to make any
2580+
further use of the interpreter after calling this function, then C<END>
2581+
blocks should be postponed to L</perl_destruct> time by setting that flag.
2582+
2583+
Returns an integer of slightly tricky interpretation. The correct use
2584+
of the return value is as a truth value indicating whether the program
2585+
terminated non-locally. If zero is returned, this indicates that
2586+
the program ran to completion, and it is safe to make other use of the
2587+
interpreter (provided that the C<PERL_EXIT_DESTRUCT_END> flag was set as
2588+
described above). If a non-zero value is returned, this indicates that
2589+
the interpreter wants to terminate early. The interpreter should not be
2590+
just abandoned because of this desire to terminate; the caller should
2591+
proceed to shut the interpreter down cleanly with L</perl_destruct>
2592+
and free it with L</perl_free>.
2593+
2594+
For historical reasons, the non-zero return value also attempts to
2595+
be a suitable value to pass to the C library function C<exit> (or to
2596+
return from C<main>), to serve as an exit code indicating the nature of
2597+
the way the program terminated. However, this isn't portable, due to
2598+
differing exit code conventions. An attempt is made to return an exit
2599+
code of the type required by the host operating system, but because
2600+
it is constrained to be non-zero, it is not necessarily possible to
2601+
indicate every type of exit. It is only reliable on Unix, where a zero
2602+
exit code can be augmented with a set bit that will be ignored. In any
2603+
case, this function is not the correct place to acquire an exit code:
2604+
one should get that from L</perl_destruct>.
24892605
24902606
=cut
24912607
*/
@@ -2494,7 +2610,7 @@ int
24942610
perl_run(pTHXx)
24952611
{
24962612
I32 oldscope;
2497-
int ret = 0;
2613+
int ret = 0, exit_called = 0;
24982614
dJMPENV;
24992615

25002616
PERL_ARGS_ASSERT_PERL_RUN;
@@ -2515,8 +2631,10 @@ perl_run(pTHXx)
25152631
case 0: /* normal completion */
25162632
redo_body:
25172633
run_body(oldscope);
2518-
/* FALLTHROUGH */
2634+
goto handle_exit;
25192635
case 2: /* my_exit() */
2636+
exit_called = 1;
2637+
handle_exit:
25202638
while (PL_scopestack_ix > oldscope)
25212639
LEAVE;
25222640
FREETMPS;
@@ -2530,7 +2648,12 @@ perl_run(pTHXx)
25302648
if (PerlEnv_getenv("PERL_DEBUG_MSTATS"))
25312649
dump_mstats("after execution: ");
25322650
#endif
2533-
ret = STATUS_EXIT;
2651+
if (exit_called) {
2652+
ret = STATUS_EXIT;
2653+
if (ret == 0) ret = 0x100;
2654+
} else {
2655+
ret = 0;
2656+
}
25342657
break;
25352658
case 3:
25362659
if (PL_restartop) {

pod/perlembed.pod

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ version of I<miniperlmain.c> containing the essentials of embedding:
192192
perl_destruct(my_perl);
193193
perl_free(my_perl);
194194
PERL_SYS_TERM();
195+
exit(EXIT_SUCCESS);
195196
}
196197

197198
Notice that we don't use the C<env> pointer. Normally handed to
@@ -267,6 +268,7 @@ That's shown below, in a program I'll call I<showtime.c>.
267268
perl_destruct(my_perl);
268269
perl_free(my_perl);
269270
PERL_SYS_TERM();
271+
exit(EXIT_SUCCESS);
270272
}
271273

272274
where I<showtime> is a Perl subroutine that takes no arguments (that's the
@@ -325,7 +327,7 @@ the first, a C<float> from the second, and a C<char *> from the third.
325327

326328
main (int argc, char **argv, char **env)
327329
{
328-
char *embedding[] = { "", "-e", "0" };
330+
char *embedding[] = { "", "-e", "0", NULL };
329331

330332
PERL_SYS_INIT3(&argc,&argv,&env);
331333
my_perl = perl_alloc();
@@ -504,7 +506,7 @@ been wrapped here):
504506

505507
main (int argc, char **argv, char **env)
506508
{
507-
char *embedding[] = { "", "-e", "0" };
509+
char *embedding[] = { "", "-e", "0", NULL };
508510
AV *match_list;
509511
I32 num_matches, i;
510512
SV *text;
@@ -645,7 +647,7 @@ deep breath...
645647

646648
int main (int argc, char **argv, char **env)
647649
{
648-
char *my_argv[] = { "", "power.pl" };
650+
char *my_argv[] = { "", "power.pl", NULL };
649651

650652
PERL_SYS_INIT3(&argc,&argv,&env);
651653
my_perl = perl_alloc();
@@ -660,6 +662,7 @@ deep breath...
660662
perl_destruct(my_perl);
661663
perl_free(my_perl);
662664
PERL_SYS_TERM();
665+
exit(EXIT_SUCCESS);
663666
}
664667

665668

@@ -794,25 +797,25 @@ with L<perlfunc/my> whenever possible.
794797
int
795798
main(int argc, char **argv, char **env)
796799
{
797-
char *embedding[] = { "", "persistent.pl" };
800+
char *embedding[] = { "", "persistent.pl", NULL };
798801
char *args[] = { "", DO_CLEAN, NULL };
799802
char filename[BUFFER_SIZE];
800-
int exitstatus = 0;
803+
int failing, exitstatus;
801804

802805
PERL_SYS_INIT3(&argc,&argv,&env);
803806
if((my_perl = perl_alloc()) == NULL) {
804807
fprintf(stderr, "no memory!");
805-
exit(1);
808+
exit(EXIT_FAILURE);
806809
}
807810
perl_construct(my_perl);
808811

809812
PL_origalen = 1; /* don't let $0 assignment update the
810813
proctitle or embedding[0] */
811-
exitstatus = perl_parse(my_perl, NULL, 2, embedding, NULL);
814+
failing = perl_parse(my_perl, NULL, 2, embedding, NULL);
812815
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
813-
if(!exitstatus) {
814-
exitstatus = perl_run(my_perl);
815-
816+
if(!failing)
817+
failing = perl_run(my_perl);
818+
if(!failing) {
816819
while(printf("Enter file name: ") &&
817820
fgets(filename, BUFFER_SIZE, stdin)) {
818821

@@ -830,7 +833,7 @@ with L<perlfunc/my> whenever possible.
830833
}
831834

832835
PL_perl_destruct_level = 0;
833-
perl_destruct(my_perl);
836+
exitstatus = perl_destruct(my_perl);
834837
perl_free(my_perl);
835838
PERL_SYS_TERM();
836839
exit(exitstatus);
@@ -951,8 +954,8 @@ Let's give it a try:
951954
int main(int argc, char **argv, char **env)
952955
{
953956
PerlInterpreter *one_perl, *two_perl;
954-
char *one_args[] = { "one_perl", SAY_HELLO };
955-
char *two_args[] = { "two_perl", SAY_HELLO };
957+
char *one_args[] = { "one_perl", SAY_HELLO, NULL };
958+
char *two_args[] = { "two_perl", SAY_HELLO, NULL };
956959

957960
PERL_SYS_INIT3(&argc,&argv,&env);
958961
one_perl = perl_alloc();
@@ -983,6 +986,7 @@ Let's give it a try:
983986
PERL_SET_CONTEXT(two_perl);
984987
perl_free(two_perl);
985988
PERL_SYS_TERM();
989+
exit(EXIT_SUCCESS);
986990
}
987991

988992
Note the calls to PERL_SET_CONTEXT(). These are necessary to initialize

t/op/blocks.t

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ BEGIN {
66
set_up_inc('../lib');
77
}
88

9-
plan tests => 11;
9+
plan tests => 18;
1010

1111
my @expect = qw(
1212
b1
@@ -146,11 +146,16 @@ expEct
146146
fresh_perl_is('END { print "ok\n" } INIT { bless {} and exit }', "ok\n",
147147
{}, 'null PL_curcop in newGP');
148148

149-
fresh_perl_is('BEGIN{exit 0}; print "still here"', '', {}, 'RT #2754: BEGIN{exit 0} should exit');
150-
TODO: {
151-
local $TODO = 'RT #2754: CHECK{exit 0} is broken';
152-
fresh_perl_is('CHECK{exit 0}; print "still here"', '', {}, 'RT #2754: CHECK{exit 0} should exit');
153-
}
149+
# [perl #2754] exit(0) didn't exit from inside a UNITCHECK or CHECK block
150+
fresh_perl_is('BEGIN{exit 0}; print "still here"', '', {}, 'BEGIN{exit 0} should exit');
151+
fresh_perl_is('BEGIN{exit 1}; print "still here"', '', {}, 'BEGIN{exit 1} should exit');
152+
fresh_perl_like('BEGIN{die}; print "still here"', qr/\ADied[^\n]*\.\nBEGIN failed[^\n]*\.\z/, {}, 'BEGIN{die} should exit');
153+
fresh_perl_is('UNITCHECK{exit 0}; print "still here"', '', {}, 'UNITCHECK{exit 0} should exit');
154+
fresh_perl_is('UNITCHECK{exit 1}; print "still here"', '', {}, 'UNITCHECK{exit 1} should exit');
155+
fresh_perl_like('UNITCHECK{die}; print "still here"', qr/\ADied[^\n]*\.\nUNITCHECK failed[^\n]*\.\z/, {}, 'UNITCHECK{die} should exit');
156+
fresh_perl_is('CHECK{exit 0}; print "still here"', '', {}, 'CHECK{exit 0} should exit');
157+
fresh_perl_is('CHECK{exit 1}; print "still here"', '', {}, 'CHECK{exit 1} should exit');
158+
fresh_perl_like('CHECK{die}; print "still here"', qr/\ADied[^\n]*\.\nCHECK failed[^\n]*\.\z/, {}, 'CHECK{die} should exit');
154159

155160
TODO: {
156161
local $TODO = 'RT #2917: INIT{} in eval is wrongly considered too late';

0 commit comments

Comments
 (0)