The following program is a simple "alarm clock" program. You give it a time of day, and an optional message. At the given time, it prints the message on the standard output. In addition, you can give it the number of times to repeat the message, and also a delay between repetitions.
This program uses the gettimeofday
function from
section Managing the Time of Day.
All the work is done in the BEGIN
rule. The first part is argument
checking and setting of defaults; the delay, the count, and the message to
print. If the user supplied a message, but it does not contain the ASCII BEL
character (known as the "alert" character, `\a'), then it is added to
the message. (On many systems, printing the ASCII BEL generates some sort
of audible alert. Thus, when the alarm goes off, the system calls attention
to itself, in case the user is not looking at their computer or terminal.)
# alarm --- set an alarm # Arnold Robbins, arnold@gnu.ai.mit.edu, Public Domain # May 1993 # usage: alarm time [ "message" [ count [ delay ] ] ] BEGIN \ { # Initial argument sanity checking usage1 = "usage: alarm time ['message' [count [delay]]]" usage2 = sprintf("\t(%s) time ::= hh:mm", ARGV[1]) if (ARGC < 2) { print usage > "/dev/stderr" exit 1 } else if (ARGC == 5) { delay = ARGV[4] + 0 count = ARGV[3] + 0 message = ARGV[2] } else if (ARGC == 4) { count = ARGV[3] + 0 message = ARGV[2] } else if (ARGC == 3) { message = ARGV[2] } else if (ARGV[1] !~ /[0-9]?[0-9]:[0-9][0-9]/) { print usage1 > "/dev/stderr" print usage2 > "/dev/stderr" exit 1 } # set defaults for once we reach the desired time if (delay == 0) delay = 180 # 3 minutes if (count == 0) count = 5 if (message == "") message = sprintf("\aIt is now %s!\a", ARGV[1]) else if (index(message, "\a") == 0) message = "\a" message "\a"
The next section of code turns the alarm time into hours and minutes, and converts it if necessary to a 24-hour clock. Then it turns that time into a count of the seconds since midnight. Next it turns the current time into a count of seconds since midnight. The difference between the two is how long to wait before setting off the alarm.
# split up dest time split(ARGV[1], atime, ":") hour = atime[1] + 0 # force numeric minute = atime[2] + 0 # force numeric # get current broken down time gettimeofday(now) # if time given is 12-hour hours and it's after that # hour, e.g., `alarm 5:30' at 9 a.m. means 5:30 p.m., # then add 12 to real hour if (hour < 12 && now["hour"] > hour) hour += 12 # set target time in seconds since midnight target = (hour * 60 * 60) + (minute * 60) # get current time in seconds since midnight current = (now["hour"] * 60 * 60) + \ (now["minute"] * 60) + now["second"] # how long to sleep for naptime = target - current if (naptime <= 0) { print "time is in the past!" > "/dev/stderr" exit 1 }
Finally, the program uses the system
function
(see section Built-in Functions for Input/Output)
to call the sleep
utility. The sleep
utility simply pauses
for the given number of seconds. If the exit status is not zero,
the program assumes that sleep
was interrupted, and exits. If
sleep
exited with an OK status (zero), then the program prints the
message in a loop, again using sleep
to delay for however many
seconds are necessary.
# zzzzzz..... go away if interrupted if (system(sprintf("sleep %d", naptime)) != 0) exit 1 # time to notify! command = sprintf("sleep %d", delay) for (i = 1; i <= count; i++) { print message # if sleep command interrupted, go away if (system(command) != 0) break } exit 0 }
Go to the first, previous, next, last section, table of contents.