-rw-r--r-- | core/opiealarm/opiealarm.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/core/opiealarm/opiealarm.c b/core/opiealarm/opiealarm.c index 998cabd..90a743f 100644 --- a/core/opiealarm/opiealarm.c +++ b/core/opiealarm/opiealarm.c | |||
@@ -72,48 +72,49 @@ void usage ( void ) | |||
72 | } | 72 | } |
73 | 73 | ||
74 | int fork_with_pidfile ( void ) | 74 | int fork_with_pidfile ( void ) |
75 | { | 75 | { |
76 | FILE *fp; | 76 | FILE *fp; |
77 | pid_t pid; | 77 | pid_t pid; |
78 | 78 | ||
79 | pid = fork ( ); | 79 | pid = fork ( ); |
80 | 80 | ||
81 | if ( pid > 0 ) { | 81 | if ( pid > 0 ) { |
82 | // We can not just exit now, because the kernel could suspend | 82 | // We can not just exit now, because the kernel could suspend |
83 | // the iPAQ just before the child process sets the RTC. | 83 | // the iPAQ just before the child process sets the RTC. |
84 | // Solution: just wait for SIGUSR1 - the child process will | 84 | // Solution: just wait for SIGUSR1 - the child process will |
85 | // signal this when it thinks it is safe to exit. | 85 | // signal this when it thinks it is safe to exit. |
86 | 86 | ||
87 | signal ( SIGUSR1, sig_handler_parent ); | 87 | signal ( SIGUSR1, sig_handler_parent ); |
88 | while ( 1 ) | 88 | while ( 1 ) |
89 | sleep ( 1000 ); | 89 | sleep ( 1000 ); |
90 | exit ( 0 ); | 90 | exit ( 0 ); |
91 | } | 91 | } |
92 | else if ( pid < 0 ) { | 92 | else if ( pid < 0 ) { |
93 | perror ( "forking failed" ); | 93 | perror ( "forking failed" ); |
94 | return 0; | 94 | return 0; |
95 | } | 95 | } |
96 | //sleep( 60 ); | ||
96 | 97 | ||
97 | // child process needs to react to SIGUSR2. This is sent when | 98 | // child process needs to react to SIGUSR2. This is sent when |
98 | // a new opiealarm process is started. | 99 | // a new opiealarm process is started. |
99 | 100 | ||
100 | signal ( SIGUSR2, sig_handler_child ); | 101 | signal ( SIGUSR2, sig_handler_child ); |
101 | 102 | ||
102 | // save pid | 103 | // save pid |
103 | if (( fp = fopen ( PIDFILE, "w" ))) { | 104 | if (( fp = fopen ( PIDFILE, "w" ))) { |
104 | fprintf ( fp, "%d", getpid ( )); | 105 | fprintf ( fp, "%d", getpid ( )); |
105 | fclose ( fp ); | 106 | fclose ( fp ); |
106 | 107 | ||
107 | // detach | 108 | // detach |
108 | close ( 0 ); | 109 | close ( 0 ); |
109 | close ( 1 ); | 110 | close ( 1 ); |
110 | close ( 2 ); | 111 | close ( 2 ); |
111 | 112 | ||
112 | setpgid ( 0, 0 ); | 113 | setpgid ( 0, 0 ); |
113 | 114 | ||
114 | return 1; | 115 | return 1; |
115 | } | 116 | } |
116 | else { | 117 | else { |
117 | perror ( PIDFILE ); | 118 | perror ( PIDFILE ); |
118 | return 0; | 119 | return 0; |
119 | } | 120 | } |
@@ -185,49 +186,49 @@ int main ( int argc, char **argv ) | |||
185 | usage ( ); | 186 | usage ( ); |
186 | 187 | ||
187 | 188 | ||
188 | parent_pid = getpid ( ); | 189 | parent_pid = getpid ( ); |
189 | 190 | ||
190 | // kill running opiealarm | 191 | // kill running opiealarm |
191 | opiealarm_was_running = kill_with_pidfile ( ); | 192 | opiealarm_was_running = kill_with_pidfile ( ); |
192 | remove_pidfile ( ); | 193 | remove_pidfile ( ); |
193 | 194 | ||
194 | switch ( mode ) { | 195 | switch ( mode ) { |
195 | case 'r': opt = resume ( ac_resusp ); | 196 | case 'r': opt = resume ( ac_resusp ); |
196 | break; | 197 | break; |
197 | case 's': | 198 | case 's': |
198 | default : opt = suspend ( fix_rtc ); | 199 | default : opt = suspend ( fix_rtc ); |
199 | break; | 200 | break; |
200 | } | 201 | } |
201 | 202 | ||
202 | parent_pid = 0; | 203 | parent_pid = 0; |
203 | return opt; | 204 | return opt; |
204 | } | 205 | } |
205 | 206 | ||
206 | 207 | ||
207 | int suspend ( int fix_rtc ) | 208 | int suspend ( int fix_rtc ) |
208 | { | 209 | { |
209 | FILE *fp; | 210 | FILE *fp = NULL; |
210 | char buf [64]; | 211 | char buf [64]; |
211 | time_t alrt, syst, rtct; | 212 | time_t alrt, syst, rtct; |
212 | struct tm alr, sys, rtc; | 213 | struct tm alr, sys, rtc; |
213 | int fd; | 214 | int fd; |
214 | int rtc_sys_diff; | 215 | int rtc_sys_diff; |
215 | 216 | ||
216 | 217 | ||
217 | if ( !fork_with_pidfile ( )) | 218 | if ( !fork_with_pidfile ( )) |
218 | return 3; | 219 | return 3; |
219 | 220 | ||
220 | // we are the child process from here on ... | 221 | // we are the child process from here on ... |
221 | 222 | ||
222 | tzset ( ); // not sure if it is really needed -- it probably doesn't hurt ... | 223 | tzset ( ); // not sure if it is really needed -- it probably doesn't hurt ... |
223 | 224 | ||
224 | time ( &syst );// get the UNIX system time | 225 | time ( &syst );// get the UNIX system time |
225 | sys = *localtime ( &syst ); | 226 | sys = *localtime ( &syst ); |
226 | 227 | ||
227 | do { | 228 | do { |
228 | 229 | ||
229 | if (( fd = open ( "/dev/misc/rtc", O_RDWR )) < 0 ) | 230 | if (( fd = open ( "/dev/misc/rtc", O_RDWR )) < 0 ) |
230 | if (( fd = open ( "/dev/rtc", O_RDWR )) < 0 ) | 231 | if (( fd = open ( "/dev/rtc", O_RDWR )) < 0 ) |
231 | break; // ( 1, "rtc" ); | 232 | break; // ( 1, "rtc" ); |
232 | 233 | ||
233 | memset ( &rtc, 0, sizeof ( struct tm )); // get the RTC time | 234 | memset ( &rtc, 0, sizeof ( struct tm )); // get the RTC time |
@@ -237,49 +238,49 @@ int suspend ( int fix_rtc ) | |||
237 | 238 | ||
238 | rtct = mktime ( &rtc ); | 239 | rtct = mktime ( &rtc ); |
239 | 240 | ||
240 | rtc_sys_diff = ( syst - rtct ) - sys. tm_gmtoff; // calculate the difference between system and hardware time | 241 | rtc_sys_diff = ( syst - rtct ) - sys. tm_gmtoff; // calculate the difference between system and hardware time |
241 | 242 | ||
242 | if ( fix_rtc && (( rtc_sys_diff < -3 ) || ( rtc_sys_diff > 3 ))) { | 243 | if ( fix_rtc && (( rtc_sys_diff < -3 ) || ( rtc_sys_diff > 3 ))) { |
243 | struct tm set; | 244 | struct tm set; |
244 | set = *gmtime ( &syst ); | 245 | set = *gmtime ( &syst ); |
245 | 246 | ||
246 | // if the difference between system and hardware time is more than 3 seconds, | 247 | // if the difference between system and hardware time is more than 3 seconds, |
247 | // we have to set the RTC (hwclock --systohc), or alarms won't work reliably. | 248 | // we have to set the RTC (hwclock --systohc), or alarms won't work reliably. |
248 | 249 | ||
249 | if ( ioctl ( fd, RTC_SET_TIME, &set ) < 0 ) | 250 | if ( ioctl ( fd, RTC_SET_TIME, &set ) < 0 ) |
250 | break; // ( 1, "ioctl RTC_SET_TIME" ); | 251 | break; // ( 1, "ioctl RTC_SET_TIME" ); |
251 | } | 252 | } |
252 | 253 | ||
253 | // read the wakeup time from TIMEFILE | 254 | // read the wakeup time from TIMEFILE |
254 | if (!( fp = fopen ( TIMEFILE, "r" ))) | 255 | if (!( fp = fopen ( TIMEFILE, "r" ))) |
255 | break; // ( 1, TIMEFILE ); | 256 | break; // ( 1, TIMEFILE ); |
256 | 257 | ||
257 | if ( !fgets ( buf, sizeof( buf ) - 1, fp )) | 258 | if ( !fgets ( buf, sizeof( buf ) - 1, fp )) |
258 | break; // ( 1, TIMEFILE ); | 259 | break; // ( 1, TIMEFILE ); |
259 | 260 | ||
260 | fclose ( fp ); | 261 | fclose ( fp ); |
261 | fp = 0; | 262 | fp = NULL; |
262 | 263 | ||
263 | alrt = atoi ( buf ); // get the alarm time | 264 | alrt = atoi ( buf ); // get the alarm time |
264 | 265 | ||
265 | if ( alrt == 0 ) | 266 | if ( alrt == 0 ) |
266 | break; // ( 0, TIMEFILE " contains an invalid time description" ); | 267 | break; // ( 0, TIMEFILE " contains an invalid time description" ); |
267 | alrt -= 5; // wake up 5 sec before the specified time | 268 | alrt -= 5; // wake up 5 sec before the specified time |
268 | 269 | ||
269 | alr = *gmtime ( &alrt ); | 270 | alr = *gmtime ( &alrt ); |
270 | 271 | ||
271 | if ( ioctl ( fd, RTC_ALM_SET, &alr ) < 0 ) // set RTC alarm time | 272 | if ( ioctl ( fd, RTC_ALM_SET, &alr ) < 0 ) // set RTC alarm time |
272 | break; // ( 1, "ioctl RTC_ALM_SET" ); | 273 | break; // ( 1, "ioctl RTC_ALM_SET" ); |
273 | 274 | ||
274 | if ( ioctl ( fd, RTC_AIE_ON, 0 ) < 0 ) | 275 | if ( ioctl ( fd, RTC_AIE_ON, 0 ) < 0 ) |
275 | break; // ( 1, "ioctl RTC_AIE_ON" ); // enable RTC alarm irq | 276 | break; // ( 1, "ioctl RTC_AIE_ON" ); // enable RTC alarm irq |
276 | 277 | ||
277 | // tell the parent it is safe to exit now .. we have set the RTC alarm | 278 | // tell the parent it is safe to exit now .. we have set the RTC alarm |
278 | kill ( parent_pid, SIGUSR1 ); | 279 | kill ( parent_pid, SIGUSR1 ); |
279 | 280 | ||
280 | if ( read ( fd, buf, sizeof( unsigned long )) < 0 ) // wait for the RTC alarm irq | 281 | if ( read ( fd, buf, sizeof( unsigned long )) < 0 ) // wait for the RTC alarm irq |
281 | break; // ( 1, "read rtc alarm" ); | 282 | break; // ( 1, "read rtc alarm" ); |
282 | 283 | ||
283 | // iPAQ woke up via RTC irq -- otherwise we would have received a SIGUSR2 | 284 | // iPAQ woke up via RTC irq -- otherwise we would have received a SIGUSR2 |
284 | // from the "resume instance" of opiealarm. | 285 | // from the "resume instance" of opiealarm. |
285 | 286 | ||
@@ -350,34 +351,34 @@ int resume ( int resuspend ) | |||
350 | 351 | ||
351 | // sleep <resuspend> seconds - this method is much more precise than sleep() ! | 352 | // sleep <resuspend> seconds - this method is much more precise than sleep() ! |
352 | time ( &start ); | 353 | time ( &start ); |
353 | do { | 354 | do { |
354 | sleep ( 1 ); | 355 | sleep ( 1 ); |
355 | time ( &now ); | 356 | time ( &now ); |
356 | } while (( now - start ) < resuspend ); | 357 | } while (( now - start ) < resuspend ); |
357 | 358 | ||
358 | if ( onac ( )) { // still on ac ? | 359 | if ( onac ( )) { // still on ac ? |
359 | argv[0] = "qcop"; | 360 | argv[0] = "qcop"; |
360 | argv[1] = "QPE/Desktop"; | 361 | argv[1] = "QPE/Desktop"; |
361 | argv[2] = "suspend()"; | 362 | argv[2] = "suspend()"; |
362 | argv[3] = 0; | 363 | argv[3] = 0; |
363 | 364 | ||
364 | // hard coded for now ...but needed | 365 | // hard coded for now ...but needed |
365 | // another way would be to simulate a power-button press | 366 | // another way would be to simulate a power-button press |
366 | 367 | ||
367 | setenv ( "LOGNAME", "root", 1 ); | 368 | setenv ( "LOGNAME", "root", 1 ); |
368 | setenv ( "HOME", "/root", 1 ); | 369 | setenv ( "HOME", "/root", 1 ); |
369 | setenv ( "LD_LIBRARY_PATH", "/opt/QtPalmtop/lib", 1 ); | 370 | setenv ( "LD_LIBRARY_PATH", "/opt/QtPalmtop/lib", 1 ); |
370 | setenv ( "QTDIR", "/opt/QtPalmtop", 1 ); | 371 | setenv ( "QTDIR", "/opt/QtPalmtop", 1 ); |
371 | 372 | ||
372 | remove_pidfile ( ); | 373 | remove_pidfile ( ); |
373 | 374 | ||
374 | // no need for system() since this process is no longer usefull anyway | 375 | // no need for system() since this process is no longer usefull anyway |
375 | execv ( "/opt/QtPalmtop/bin/qcop", argv ); | 376 | execv ( "/opt/QtPalmtop/bin/qcop", argv ); |
376 | 377 | ||
377 | perror ( "exec for qcop failed" ); | 378 | perror ( "exec for qcop failed" ); |
378 | return 5; | 379 | return 5; |
379 | } | 380 | } |
380 | } | 381 | } |
381 | } | 382 | } |
382 | return 0; | 383 | return 0; |
383 | } | 384 | } |