diff options
-rw-r--r-- | pod/perldiag.pod | 5 | ||||
-rw-r--r-- | pp_sys.c | 31 | ||||
-rw-r--r-- | t/lib/warnings/pp_sys | 9 |
3 files changed, 38 insertions, 7 deletions
diff --git a/pod/perldiag.pod b/pod/perldiag.pod index 1d53e5df92..558fd62428 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -7099,6 +7099,11 @@ You likely need to figure out how this multi-byte character got mixed up with your single-byte locale (or perhaps you thought you had a UTF-8 locale, but Perl disagrees). +=item %s() with negative argument + +(S misc) Certain operations make no sense with negative arguments. +Warning is given and the operation is not done. + =item Within []-length '%c' not allowed (F) The count in the (un)pack template may be replaced by C<[TEMPLATE]> @@ -4708,13 +4708,30 @@ PP(pp_alarm) { #ifdef HAS_ALARM dSP; dTARGET; - int anum; - anum = POPi; - anum = alarm((unsigned int)anum); - if (anum < 0) - RETPUSHUNDEF; - PUSHi(anum); - RETURN; + /* alarm() takes an unsigned int number of seconds, and return the + * unsigned int number of seconds remaining in the previous alarm + * (alarms don't stack). Therefore negative return values are not + * possible. */ + int anum = POPi; + if (anum < 0) { + /* Note that while the C library function alarm() as such has + * no errors defined (or in other words, properly behaving client + * code shouldn't expect any), alarm() being obsoleted by + * setitimer() and often being implemented in terms of + * setitimer(), can fail. */ + /* diag_listed_as: %s() with negative argument */ + Perl_ck_warner_d(aTHX_ packWARN(WARN_MISC), + "alarm() with negative argument"); + SETERRNO(EINVAL, LIB_INVARG); + RETPUSHUNDEF; + } + else { + unsigned int retval = alarm(anum); + if ((int)retval < 0) /* Strictly speaking "cannot happen". */ + RETPUSHUNDEF; + PUSHu(retval); + RETURN; + } #else DIE(aTHX_ PL_no_func, "alarm"); #endif diff --git a/t/lib/warnings/pp_sys b/t/lib/warnings/pp_sys index 0dce57f9a5..1100cf2bcb 100644 --- a/t/lib/warnings/pp_sys +++ b/t/lib/warnings/pp_sys @@ -921,3 +921,12 @@ gmtime(NaN) too large at - line 6. gmtime(NaN) failed at - line 6. localtime(NaN) too large at - line 7. localtime(NaN) failed at - line 7. + +######## +# pp_sys.c [pp_alarm] +alarm(-1); +no warnings "misc"; +alarm(-1); + +EXPECT +alarm() with negative argument at - line 2. |