add proper error handling for all final exec calls
[hband-tools.git] / admin-tools / dmaster-signal
blob9ceb99fcba13ce36d0431f7df810432ddc855225
1 #!/usr/bin/env perl
3 use Pod::Usage;
4 use Socket;
5 use Config;
6 @signal_names = split ' ', $Config{'sig_name'};
7 @signal_numbers{@signal_names} = split ' ', $Config{'sig_num'};
8 require "syscall.ph";
10 $0 = 'dmaster-signal';
11 $daemon_id = shift @ARGV;
12 $signal = shift @ARGV;
14 unless($daemon_id and defined $signal)
16 pod2usage(-exitval=>2, -verbose=>99);
19 $signal_num = $signal_numbers{$signal} // $signal;
20 die "$0: unknown signal: $signal\n" unless $signal_num =~ /^\d+$/;
23 $management_socket_path = ($ENV{'XDG_CACHE_HOME'} || '/var/run').'/dmaster.sock';
24 $management_socket_addr = sockaddr_un($management_socket_path);
25 socket($management_socket, AF_UNIX, SOCK_STREAM, 0) or die "socket: $!\n";
26 connect($management_socket, $management_socket_addr) or die "connect: $management_socket_path: $!\n";
28 while(<$management_socket>)
30 chomp;
31 last if /^END$/;
32 if(/^dmaster\.pid\s+(\d+)$/)
34 $dmaster_pid = $1;
36 elsif(/^daemon\.(.+)\.pidfd\.fileno\s+(\d+)$/ and $1 eq $daemon_id)
38 $target_pidfd = $2;
42 if(not $dmaster_pid)
44 die "$0: could not find dmaster pid\n";
46 if(not $target_pidfd)
48 die "$0: could not find daemon's pidfd: $daemon_id\n";
52 $flags = 0;
53 $! = 0;
54 $dmaster_pidfd = syscall SYS_pidfd_open(), int $dmaster_pid, $flags;
55 if($dmaster_pidfd == -1)
57 die "pidfd_open: $!\n";
61 $flags = 0;
62 $! = 0;
63 $pidfd = syscall SYS_pidfd_getfd(), int $dmaster_pidfd, int $target_pidfd, $flags;
64 if($pidfd == -1)
66 die "pidfd_getfd: $!\n";
70 print {$management_socket} "\n";
71 close $management_socket;
74 $flags = 0;
75 $! = 0;
76 $ret = syscall SYS_pidfd_send_signal(), int $pidfd, int $signal_num, undef, $flags;
77 if($ret == -1)
79 die "pidfd_send_signal: $!\n";
82 exit 0;
86 __END__
88 =pod
90 =head1 NAME
92 dmaster-signal - Send a signal to a daemon managed by dmaster
94 =head1 SYNOPSIS
96 dmaster-signal I<DAEMON-ID> I<SIGNAL>
98 =head1 DESCRIPTION
100 dmaster-signal(1) utilizes PIDFD to reliably send signal to the daemon
101 managed by dmaster(1) and specified by I<DAEMON-ID>.
103 I<SIGNAL> is either numeric or symbolic signal name.
105 =head1 SEE ALSO
107 dmaster(1), pidfd_send_signal(2), signal(7)
109 =cut