diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2015-03-05 07:57:14 -0500 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2015-06-26 23:09:39 -0400 |
commit | add0dc910759dea695e812146f825ac72b8cd089 (patch) | |
tree | 023a3b4010c1eb09cfef39e1d87ab09bd28aeb07 /pp_sys.c | |
parent | 35a328a707ece9e17f07c6d0fd46efae159ade68 (diff) | |
download | perl-add0dc910759dea695e812146f825ac72b8cd089.tar.gz |
alarm() with negative argument makes no sense.
Give by default a warning, do not set the alarm, and return undef.
(the signedness problem detected by Coverity, CID 104837)
alarm() takes and returns unsigned int, not signed.
In other words, the C library function alarm() cannot fail, ever.
See for example:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/alarm.html
http://linux.die.net/man/3/alarm
https://www.freebsd.org/cgi/man.cgi?query=alarm&sektion=3
Diffstat (limited to 'pp_sys.c')
-rw-r--r-- | pp_sys.c | 31 |
1 files changed, 24 insertions, 7 deletions
@@ -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 |