udevd.c revision 3c1898863fbf9c94cfb0258ae380b67b44c4b466
eb10a76494542fb560efd09c16b40826fc37bc5fLennart Poettering * Copyright (C) 2004-2009 Kay Sievers <kay.sievers@vrfy.org>
1486dbe1c6510376a900c8c99f8bc032c8fa9cdbLennart Poettering * Copyright (C) 2004 Chris Friesen <chris_friesen@sympatico.ca>
eb10a76494542fb560efd09c16b40826fc37bc5fLennart Poettering * Copyright (C) 2009 Canonical Ltd.
eb10a76494542fb560efd09c16b40826fc37bc5fLennart Poettering * Copyright (C) 2009 Scott James Remnant <scott@netsplit.com>
bc2708414babc5c99bb8000e63c84e87606cc15dLennart Poettering * This program is free software: you can redistribute it and/or modify
bc2708414babc5c99bb8000e63c84e87606cc15dLennart Poettering * it under the terms of the GNU General Public License as published by
bc2708414babc5c99bb8000e63c84e87606cc15dLennart Poettering * the Free Software Foundation, either version 2 of the License, or
bc2708414babc5c99bb8000e63c84e87606cc15dLennart Poettering * (at your option) any later version.
bc2708414babc5c99bb8000e63c84e87606cc15dLennart Poettering * This program is distributed in the hope that it will be useful,
bc2708414babc5c99bb8000e63c84e87606cc15dLennart Poettering * but WITHOUT ANY WARRANTY; without even the implied warranty of
bc2708414babc5c99bb8000e63c84e87606cc15dLennart Poettering * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
bc2708414babc5c99bb8000e63c84e87606cc15dLennart Poettering * GNU General Public License for more details.
bc2708414babc5c99bb8000e63c84e87606cc15dLennart Poettering * You should have received a copy of the GNU General Public License
bc2708414babc5c99bb8000e63c84e87606cc15dLennart Poettering * along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "udev.h"
static bool debug;
if (debug) {
static bool debug_trace;
static bool stop_exec_queue;
static bool reload_config;
static int max_childs;
static int childs;
static bool udev_exit;
enum poll_fd {
enum event_state {
struct event {
int exitcode;
unsigned long long int delaying_seqnum;
unsigned long long int seqnum;
const char *devpath;
const char *devpath_old;
bool is_block;
char *event;
enum worker_state {
struct worker {
int refcount;
struct worker_message {
int exitcode;
char *worker;
switch (signum) {
case SIGALRM:
case SIGTERM:
worker_exit = true;
return worker;
childs--;
switch (pid) {
int err;
int failed = 0;
&orig_sigmask);
alarm(0);
if (err != 0)
else if (failed != 0)
while (!worker_exit) {
int fdcount;
if (fdcount < 0)
exit(0);
childs++;
if (count < 0) {
int max;
if (max-- <= 0)
static int mem_size_mb(void)
FILE *f;
if (f == NULL)
long int value;
fclose(f);
return memsize;
if (major(event->devnum) != 0 && event->devnum == loop_event->devnum && event->is_block == loop_event->is_block)
static void worker_returned(void)
const char *str;
stop_exec_queue = true;
stop_exec_queue = false;
reload_config = true;
char *key;
char *val;
max_childs = i;
if (settle_pid > 0) {
settle_pid = 0;
char *buf;
reload_config = true;
int fd;
switch (signo) {
case SIGINT:
case SIGTERM:
udev_exit = true;
case SIGCHLD:
int status;
if (pid <= 0)
case SIGHUP:
reload_config = true;
int fd;
FILE *f;
const char *value;
int daemonize = false;
goto exit;
int option;
switch (option) {
daemonize = true;
debug_trace = true;
debug = true;
resolve_names = 0;
goto exit;
goto exit;
goto exit;
goto exit;
if (getuid() != 0) {
goto exit;
if (fd < 0) {
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
if (daemonize) {
switch (pid) {
goto exit;
rc = 0;
goto exit;
if (f != NULL) {
fclose(f);
setsid();
if (fd < 0) {
if (debug_trace) {
if (memsize > 0)
if (value)
while (!udev_exit) {
int fdcount;
int timeout;
if (fdcount < 0)
if (fdcount == 0)
if (reload_config) {
reload_config = 0;
rc = 0;
exit:
return rc;