2
* Author: Timo Hoenig <thoenig@nouse.net>
3
* Copyright (c) 2003, 2004 Timo Hoenig <thoenig@nouse.net>
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, or (at your option)
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.
32
#include <sys/ioctl.h>
42
void sigterm_handler(int signal);
44
int init_sig_handler(void);
45
int init_fnfxd(int *, int *);
46
int init_shmem(t_daemon_cfg *);
47
int cp_cfg(t_daemon_cfg *);
48
int set_flags(int *, int *);
58
extern void debug(const char *, ...);
59
extern void fatal(const char *, ...);
60
extern int init_config(void);
62
extern t_daemon_cfg *cfg;
77
* Signal handler for terminating signals.
80
* - Free shared memory
83
void sigterm_handler(int signal)
85
debug("Received signal %d. Terminating.", signal);
86
/* destory shared memory */
87
shmctl(cfg->shmem.id, IPC_RMID, cfg->shmem.addr);
88
/* remove semaphore */
89
semctl(cfg->sem.id, 0, IPC_RMID);
98
* Register the signal handler for terminating signals.a
102
int init_sig_handler()
104
signal(SIGTERM, sigterm_handler);
105
signal(SIGKILL, sigterm_handler);
106
signal(SIGQUIT, sigterm_handler);
107
signal(SIGINT, sigterm_handler);
115
* Check if another instance of fnfxd is running.
124
pid = (unsigned int) getpid();
127
f = fopen(PIDFILE, "r+");
130
fscanf(f, "%i", &read_pid);
132
("According to %s, another instance of `fnfxd` is already running (PID = %i).\n"
133
"If this is not the case, please remove %s.", PIDFILE, read_pid,
145
* - Initialize shared memory segment
146
* - Attach shared memory segment
150
int init_shmem(t_daemon_cfg * config)
152
key_t shmkey = (int) SHMKEY;
154
config->shmem.key = shmkey;
156
shmget(config->shmem.key, (int) SHMSIZE, IPC_CREAT | 0666);
158
if (config->shmem.id < 0) {
159
fatal("Failed to create shared memory segment.");
163
if ((config->shmem.addr = shmat(config->shmem.id, NULL, 0)) == (char *) -1) {
164
fatal("Error while attaching shared memory segment.");
174
* - Copy configuration to shared memory segment
175
* - Let the global t_daemon_cfg *cfg point to it
179
int cp_cfg(t_daemon_cfg * config)
181
memcpy((config->shmem.addr + DCFG_OFFSET), (void *) config,
184
cfg = config->shmem.addr + DCFG_OFFSET;
192
* Set the command line flags in the configuration (in memory).
196
int set_flags(int *debug_flag, int *nodetach_flag)
198
cfg->debug_flag = *debug_flag;
199
cfg->nodetach_flag = *nodetach_flag;
207
* Check for other instances of fnfxd and register PID file.
216
f = fopen(PIDFILE, "w");
219
fprintf(f, "%u\n", cfg->pid);
223
fatal("Could not access pid file %s.", PIDFILE);
233
* - Check if /proc/acpi/toshiba and subkeys are available
242
const char *acpi_proc_keys[9] = {
254
for (i = 1; i < 7; i++) {
255
if ((f = fopen(acpi_proc_keys[i], "r+"))) {
256
cfg->acpi.config |= 1 << i;
259
else if ((i == 2) || (i == 3)) {
261
fatal("Could open %s.", acpi_proc_keys[i]);
263
"Please make sure that your kernel has enabled the Toshiba option in the ACPI section.\n"
264
"For more information read the documentation and/or http://fnfx.sf.net/index.php?section=doc#kernel.\n\n");
269
cfg->acpi.config |= 1 << 0;
277
* Initialize semaphores.
283
cfg->sem.key = SEMKEY;
285
cfg->sem.id = semget(cfg->sem.key, 3, IPC_CREAT | 0666);
286
if (cfg->sem.id < 0) {
287
fatal("Could not create semaphore with key 0x%i.", cfg->sem.key);
291
if (semctl(cfg->sem.id, 0, SETVAL, 0)) {
292
fatal("Could not initialize semaphore %i (id = %i) with 0.", 0,
296
if (semctl(cfg->sem.id, 1, SETVAL, 0)) {
297
fatal("Could not initialize semaphore %i (id = %i) with 0.", 1,
301
if (semctl(cfg->sem.id, 2, SETVAL, 0)) {
302
fatal("Could not initialize semaphore %i (id = %i) with 0.", 2,
313
* Call initialization routines.
317
int init_fnfxd(int *debug_flag, int *nodetach_flag)
324
if (init_shmem(&config))
330
if (set_flags(debug_flag, nodetach_flag))