4 * Copyright (C) 2009 Enrico Zini <enrico@enricozini.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 // Return the earliest ID in the queue, or -1 if none are found
32 // Queue is null for all queues, otherwise a queue name
33 public static Event earliestID(string? queue = null)
35 Event res = { -1, 0 };
38 argv[0] = "/usr/bin/atq";
53 if (!Process.spawn_async_with_pipes("/", argv, null, SpawnFlags.STDERR_TO_DEV_NULL, null, out pid, null, out stdout, null))
55 } catch (SpawnError e) {
56 stderr.printf("Cannot run 'at -q': %s\n", e.message);
60 FileStream fs = FileStream.fdopen(stdout, "r");
66 while ((line = fs.gets(buf)) != null)
68 if (!line[0].isdigit()) continue;
70 ulong id = line.to_ulong(out rest, 10);
72 rest = t.strptime(rest.offset(1), "%a %b %d %H:%M:%S %Y");
73 if (rest == null) continue;
74 if (rest.size() < 2) continue;
75 //stderr.printf("PARSE QUEUE rest %s\n", rest);
76 // Skip the queue of tasks currently being executed
77 //if (rest[1] == '=') continue;
78 // Skip entries not in the wanted queue
79 if (queue != null && rest[1] != queue[0]) continue;
80 time_t tt = t.mktime();
81 if (res.deadline == 0 || tt < res.deadline) {
86 Process.close_pid(pid);
90 public delegate bool jobParser(int fd);
92 // Get the contents of a job given its id
93 public static bool jobContents(int id, jobParser parser)
96 argv[0] = "/usr/bin/at";
98 argv[2] = id.to_string();
106 if (!Process.spawn_async_with_pipes("/", argv, null, SpawnFlags.STDERR_TO_DEV_NULL, null, out pid, null, out stdoutfd, null))
108 } catch (SpawnError e) {
109 stderr.printf("Cannot run 'at -c': %s\n", e.message);
113 bool res = parser(stdoutfd);
115 Process.close_pid(pid);
121 TODO: schedule alarms via at
125 atq -q z can be used to list the jobs (for example, at startup, or after a job has run)
126 at -c id can be used to query a job, parsing its contents (which can have
127 comments or variables being set)
128 zavai --notify ... can be used to notify the job (and start zavai if it's not running)
130 Alarm needs to be able to serialize itself to an at invocation and to
131 deserialize itself from the output of at -c
133 Alarm needs to deserialize also a job with no special markers whatsoever: a
139 public class Alarm : Object
141 // TODO: make a factory method to construct from an "at -c" output
143 // TODO: make a method that provides an at invocation
145 public signal void trigger(Alarm a);
147 public time_t deadline;
150 public Alarm(time_t deadline, string label)
152 this.deadline = deadline;
158 // Schedule a task that notifies a string
159 // TODO public void schedule_label(const Alarm a);
161 // Return the next item in the queue due to be run
162 // TODO public Alarm? next_scheduled();