getitimer(2)
๐ getitimer, setitimer โ get or set value of an interval timer ๐
okay bestie, welcome to getitimer(2), aka the System Calls Manual corner of the universe, where we talk about interval timers. no cap, this one is lowkey iconic โ it's the original clock-girl API. stick with me and you'll be setting timers like a main character ๐ฐ๏ธโจ
๐ LIBRARY
Standard C library (libc, -lc) ๐ซถ
โจ SYNOPSIS
#include <sys/time.h>
int getitimer(int which, struct itimerval *curr_value);
int setitimer(int which, const struct itimerval *restrict new_value,
struct itimerval *_Nullable restrict old_value);
๐ฆ DESCRIPTION
So basically these system calls are your VIP pass to interval timers โ and before you ask, an interval timer is a timer that expires at some point in the future, and then (optionally) keeps expiring at regular intervals after that. it's giving alarm clock that never quits ๐
When a timer expires, a signal gets generated for the calling process, and the timer resets itself to the specified interval โ but only if the interval is nonzero. if it's zero, it's a one-and-done situation, periodt.
There are three types of timers, and you pick which one you want with the which argument. each one counts against a different clock and fires a different signal when it hits zero:
ITIMER_REALโ this one counts down in real time (like, wall clock time, the actual passage of minutes of your life). Every time it expires, aSIGALRMsignal gets generated.ITIMER_VIRTUALโ this one counts down against the user-mode CPU time that the process has consumed. (and yes, that measurement includes CPU time eaten up by all threads in the process.) Every expiration generates aSIGVTALRMsignal.ITIMER_PROFโ this one counts down against the total CPU time consumed by the process, meaning user and system time both. (again, the measurement covers all threads in the process.) Every expiration generates aSIGPROFsignal.
When you pair it up with ITIMER_VIRTUAL, this timer can be used to profile the user and system CPU time consumed by the process. slay, honestly.
Reminder: a process has only one of each of the three types of timers. no duplicates, bestie, that's not how this works ๐
Timer values are defined by these structures, and you're gonna want them memorized:
struct itimerval {
struct timeval it_interval; /* Interval for periodic timer */
struct timeval it_value; /* Time until next expiration */
};
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
๐ getitimer()
The getitimer() function takes the current value of the timer you specified with which and places it in the buffer that curr_value points to.
The it_value substructure gets populated with the amount of time remaining until the next expiration of that timer. this value changes as the timer ticks down, and it'll be reset to it_interval when the timer expires. and if both fields of it_value are zero, then the timer is currently disarmed โ i.e. inactive, not doing anything, asleep, resting ๐ฆ
The it_interval substructure gets populated with the timer interval. if both fields of it_interval are zero, then this is a single-shot timer โ it expires just once and then that's it, goodbye.
๐ setitimer()
The setitimer() function arms or disarms the timer specified by which, by setting the timer to whatever value new_value says. And if old_value is non-NULL, the buffer it points to is used to return the previous value of the timer โ like, the exact same info that getitimer() would hand you. cute, right? ๐
If either field in new_value.it_value is nonzero, then the timer gets armed to initially expire at the specified time. If both fields in new_value.it_value are zero, then the timer is disarmed.
The new_value.it_interval field is what specifies the new interval for the timer. and if both of its subfields are zero? single-shot, bestie, one expiration and we're out ๐ธ
๐ฅ RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set to indicate the error.
๐ ERRORS
EFAULTโnew_value,old_value, orcurr_valueis not a valid pointer.EINVALโwhichis not one ofITIMER_REAL,ITIMER_VIRTUAL, orITIMER_PROF; or (since Linux 2.6.22) one of thetv_usecfields in the structure pointed to bynew_valuecontains a value outside the range[0, 999999].
๐ VERSIONS
The standards are silent on the meaning of this call:
setitimer(which, NULL, &old_value);
Lots of systems (Solaris, the BSDs, and probably some others too) treat that as being equivalent to:
getitimer(which, &old_value);
In Linux though, it's treated as being equivalent to a call where the new_value fields are zero โ meaning the timer gets disabled.
๐จ bestie do NOT use this Linux misfeature. it is nonportable and unnecessary. it's giving red flag behavior. walk away.
โญ STANDARDS
None. literally none, bestie, it's unstandardized. ๐
๐ HISTORY
4.2BSD, SVr4, SUSv1, POSIX.1-2001. then POSIX.1-2008 marked getitimer() and setitimer() obsolete, recommending you use the POSIX timers API instead (timer_gettime(2), timer_settime(2), etc.). and then POSIX.1-2024 straight up removed them. it's giving retirement party ๐ญ
๐ง NOTES
Timers will never expire before the time you requested, but they may expire some (short) time afterward โ how short depends on the system timer resolution and on the system load; peep time(7) for that. (but also, see BUGS below, because plot twist.)
If the timer expires while the process is active (which is always true for ITIMER_VIRTUAL), the signal gets delivered immediately when it's generated. no waiting around ๐
A child created via fork(2) does not inherit its parent's interval timers. Interval timers are preserved across an execve(2). noted, bestie.
POSIX.1 leaves the interaction between setitimer() and these three interfaces โ alarm(2), sleep(3), and usleep(3) โ unspecified. so like, don't count on anything there ๐
๐ BUGS
The generation of a signal and the delivery of a signal are two distinct things, and only one instance of each of the signals listed above can be pending for a process at a time. So under very heavy loading, an ITIMER_REAL timer may expire before the signal from a previous expiration has even been delivered. and the second signal in that case? lost. gone. vanished. ๐
Before Linux 2.6.16, timer values were represented in jiffies. If you tried to set a timer with a value whose jiffies representation exceeds MAX_SEC_IN_JIFFIES (which is defined in include/linux/jiffies.h), then the timer gets silently truncated to that ceiling value. On Linux/i386 (where, since Linux 2.6.13, the default jiffy is 0.004 seconds), that means the ceiling value for a timer is approximately 99.42 days. Since Linux 2.6.16 though, the kernel uses a different internal representation for times, and this ceiling is removed. we love growth ๐ซถ
On certain systems (i386 included), Linux kernels before Linux 2.6.12 have a bug that produces premature timer expirations of up to one jiffy under some circumstances. this bug is fixed in Linux 2.6.12. okay so we're fine now.
POSIX.1-2001 says setitimer() should fail if a tv_usec value is specified that's outside the range [0, 999999]. But โ up to and including Linux 2.6.21, Linux didn't give an error at all, and instead silently adjusted the corresponding seconds value for the timer. From Linux 2.6.22 onward, this nonconformance has been repaired: an improper tv_usec value results in an EINVAL error. character development, honestly. โจ
๐ SEE ALSO
gettimeofday(2), sigaction(2), signal(2), timer_create(2), timerfd_create(2), time(7)
and that's the whole page, bestie!! this was written by the Linux man-pages crew, version 6.20, dated 2026-02-08. go forth and timer responsibly ๐โจ๐ธ
๐ฆ where this page comes from
- arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- Copyright 1993, Darren Senn <sinster@scintilla.santa-clara.ca.us>
- Copyright 2016, Michael Kerrisk <mtk.manpages@gmail.com>
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms