summaryrefslogtreecommitdiff
path: root/pp_sys.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2015-03-05 07:57:14 -0500
committerJarkko Hietaniemi <jhi@iki.fi>2015-06-26 23:09:39 -0400
commitadd0dc910759dea695e812146f825ac72b8cd089 (patch)
tree023a3b4010c1eb09cfef39e1d87ab09bd28aeb07 /pp_sys.c
parent35a328a707ece9e17f07c6d0fd46efae159ade68 (diff)
downloadperl-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.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/pp_sys.c b/pp_sys.c
index 6770063267..b92f001731 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -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