pikeyd165 – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**** daemon.c *****************************/
2 /* M. Moller 2013-01-16 */
3 /* Univeral RPi GPIO keyboard daemon */
4 /*******************************************/
5  
6 /*
7 Copyright (C) 2013 Michael Moller.
8 This file is part of the Universal Raspberry Pi GPIO keyboard daemon.
9  
10 This is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2.1 of the License, or (at your option) any later version.
14  
15 The software is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
19  
20 You should have received a copy of the GNU Lesser General Public
21 License along with the GNU C Library; if not, write to the Free
22 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 02111-1307 USA.
24 */
25  
26 #include <stdio.h>
27 #include <signal.h>
28 #include <syslog.h>
29 #include <errno.h>
30 #include <stdlib.h>
31 #include <fcntl.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include "daemon.h"
35  
36 #define DAEMON_NAME "pikeyd"
37  
38 void daemonShutdown(void);
39 void signal_handler(int sig);
40 void daemonize(char *rundir, char *pidfile);
41  
42 int pid_fd;
43 char *pid_lock_file;
44  
45 void daemonShutdown(void)
46 {
47 close(pid_fd);
48 unlink(pid_lock_file);
49 }
50  
51 void signal_handler(int sig)
52 {
53 switch(sig){
54 case SIGHUP:
55 syslog(LOG_WARNING, "Received SIGHUP.");
56 break;
57 case SIGINT:
58 case SIGTERM:
59 syslog(LOG_INFO, "Exiting.");
60 daemonShutdown();
61 exit(0);
62 break;
63 default:
64 syslog(LOG_WARNING, "Unhandled signal %s", strsignal(sig));
65 }
66 }
67  
68 /* get the pid from the pid lock file and terminate the daemon */
69 void daemonKill(char *pidfile)
70 {
71 int n;
72 pid_t pid;
73 char str[10];
74  
75  
76 pid_fd = open(pidfile, O_RDONLY, 0600);
77 if(pid_fd < 0){
78 perror(pidfile);
79 }
80 else{
81 if( read(pid_fd, str, 10) > 0 ){
82 pid = strtol(str, NULL, 0);
83 if(pid){
84 printf("terminating %d\n", pid);
85 n = kill(pid, SIGTERM);
86 if(n<0){
87 perror("kill");
88 }
89 }
90 }
91 close(pid_fd);
92 }
93 }
94  
95 void daemonize(char *rundir, char *pidfile)
96 {
97 int pid, sid, i, r;
98 char str[10];
99 struct sigaction newSA;
100 sigset_t newSS;
101  
102 if(getppid() == 1){
103 /* don't need to do it twice */
104 return;
105 }
106  
107 setlogmask(LOG_UPTO(LOG_INFO));
108 openlog(DAEMON_NAME, LOG_CONS | LOG_PERROR, LOG_USER);
109 syslog(LOG_INFO, "Daemon starting");
110  
111 sigemptyset(&newSS);
112 sigaddset(&newSS, SIGCHLD);
113 sigaddset(&newSS, SIGTSTP);
114 sigaddset(&newSS, SIGTTOU);
115 sigaddset(&newSS, SIGTTIN);
116 sigprocmask(SIG_BLOCK, &newSS, NULL); /* block these signals */
117  
118 newSA.sa_handler = signal_handler;
119 sigemptyset(&newSA.sa_mask);
120 newSA.sa_flags = 0;
121 sigaction(SIGHUP, &newSA, NULL);
122 sigaction(SIGTERM, &newSA, NULL);
123 sigaction(SIGINT, &newSA, NULL);
124  
125 pid = fork();
126  
127 if(pid < 0){
128 perror("fork");
129 exit(EXIT_FAILURE);
130 }
131  
132 if(pid > 0){ /* success. terminate the parent */
133 exit(0);
134 }
135  
136 /* child continues here. */
137  
138 umask(027);
139 sid = setsid();
140 if(sid < 0){
141 perror("set SID");
142 exit(EXIT_FAILURE);
143 }
144  
145 for(i = getdtablesize(); i>=0; --i){
146 close(i);
147 }
148  
149 close(STDIN_FILENO);
150 close(STDOUT_FILENO);
151 close(STDERR_FILENO);
152  
153 if( chdir(rundir) < 0 ){
154 perror(rundir);
155 }
156  
157 /* only one at a time */
158 pid_lock_file = pidfile;
159 pid_fd = open(pidfile, O_RDWR|O_CREAT, 0600);
160 if(pid_fd < 0){
161 syslog(LOG_INFO, "Could not open lock file %s. Exiting.", pidfile);
162 exit(EXIT_FAILURE);
163 }
164 if(lockf(pid_fd, F_TLOCK, 0) < 0){
165 syslog(LOG_INFO, "Could not lock lock file %s. Exiting.", pidfile);
166 unlink(pidfile);
167 exit(EXIT_FAILURE);
168 }
169 sprintf(str, "%d\n", getpid());
170 if( write(pid_fd, str, strlen(str)) < 0 ){
171 perror(pidfile);
172 }
173  
174 syslog(LOG_INFO, "Daemon running.");
175 }