Document job names.
[whenjobs.git] / lib / whenlock.ml
1 (* whenjobs
2  * Copyright (C) 2012 Red Hat Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *)
18
19 open Unix
20 open Printf
21
22 (* See [flock.c]. *)
23 external flock_exclusive_nonblocking : file_descr -> unit =
24     "whenjobs_flock_exclusive_nonblocking"
25
26 (* Global fd open on daemon_pid file.  fd is closed and the lock is
27  * released implicitly when the program exits.
28  *)
29 let pid_fd = ref stdin
30
31 let rec create_lock jobsdir =
32   let pid_file = get_pid_file jobsdir in
33   pid_fd := openfile pid_file [ O_CREAT; O_RDWR ] 0o600;
34   (try flock_exclusive_nonblocking !pid_fd
35    with Failure _ ->
36      eprintf "whenjobsd: PID file (%s) exists and cannot be locked\n"
37        pid_file;
38      eprintf "Another instance of the daemon may be running.\n";
39      exit 1
40   );
41
42   update_pid ()
43
44 and update_pid () =
45   let pid = sprintf "%d\n" (getpid ()) in
46   ignore (lseek !pid_fd 0 SEEK_SET);
47   ftruncate !pid_fd 0;
48   ignore (write !pid_fd pid 0 (String.length pid))
49
50 and test_locked jobsdir =
51   let pid_file = get_pid_file jobsdir in
52   let fd = openfile pid_file [ O_CREAT; O_RDWR ] 0o600 in
53   let r = ref false in
54   (try flock_exclusive_nonblocking fd with Failure _ -> r := true);
55   close fd;
56   !r
57
58 and kill_daemon jobsdir =
59   let pid_file = get_pid_file jobsdir in
60   let chan = open_in pid_file in
61   let pid = input_line chan in
62   close_in chan;
63   let pid = int_of_string pid in
64   kill pid 15
65
66 and get_pid_file jobsdir =
67   sprintf "%s/daemon_pid" jobsdir