From: Greg KH <greg@kroah.com>
To: linux-hotplug-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org
Subject: [ANNOUNCE] a very tiny /sbin/hotplug
Date: Thu, 18 Nov 2004 23:14:06 +0000 [thread overview]
Message-ID: <20041118231406.GA11239@kroah.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1385 bytes --]
So, a number of people have complained over the past few years about the
fact that /sbin/hotplug was a shell script. Funny enough, it's the
people on the huge boxes, with huge number of devices that are
complaining, not the embedded people with limited resources (ironic,
isn't it...)
Anyway, attached below is a replacement /sbin/hotplug written in c.
Compiling it with klibc gives you me the following size:
$ size hotplug
text data bss dec hex filename
4149 28 20 4197 1065 hotplug
$ ls -l hotplug
-rwxr-xr-x 1 greg users 4636 Nov 18 15:08 hotplug
Which is smaller than /bin/true on my boxes (and /bin/true is linked
dynamically, this is a static binary. Linked dynamically, it's still
smaller than /bin/true. gnu programs, go figure...)
I'll be putting this all togther in a "hotplug-ng" type tarball, as I
slowly replace the existing hotplug scripts with rewrites based on the
fact that we've learned things over the past 4 years, and dropping
support for 2.4 and previous kernels. But for now, have fun with this
program.
Oh, and yeah, I know I need to fix up the fact that if /dev/null isn't
present, we should create it ourselves and go from there. That's next
on the list after putting it all in a project.
thanks,
greg k-h
p.s. the list.h and logging.h files come from the udev project, if you
want to build this yourself.
[-- Attachment #2: hot.c --]
[-- Type: text/plain, Size: 3959 bytes --]
/*
* hot.c - /etc/hotplug.d/ multiplexer
*
* Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (C) 2004 Kay Sievers <kay@vrfy.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation version 2 of the License.
*/
/*
* This essentially emulates the following shell script logic in C:
*
* DIR="/etc/hotplug.d"
*
* for I in "${DIR}/$1/"*.hotplug "${DIR}/"default/ *.hotplug ; do
* if [ -f $I ]; then
* test -x $I && $I $1 ;
* fi
* done
* exit 1
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <dirent.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include "logging.h"
#include "list.h"
#define HOT_DIR "/etc/hotplug.d"
#define HOT_SUFFIX ".hotplug"
#define strfieldcpy(to, from) \
do { \
to[sizeof(to)-1] = '\0'; \
strncpy(to, from, sizeof(to)-1); \
} while (0)
#ifdef LOG
unsigned char logname[LOGNAME_SIZE];
void log_message(int level, const char *format, ...)
{
va_list args;
va_start(args, format);
vsyslog(level, format, args);
va_end(args);
}
#endif
static char *subsystem;
static int run_program(const char *filename)
{
pid_t pid;
dbg("running %s", filename);
pid = fork();
switch (pid) {
case 0:
/* child */
execl(filename, filename, subsystem, NULL);
dbg("exec of child failed");
_exit(1);
case -1:
dbg("fork of child failed");
break;
return -1;
default:
waitpid(pid, NULL, 0);
}
return 0;
}
struct files {
struct list_head list;
char name[PATH_MAX];
};
/* sort files in lexical order */
static int file_list_insert(char *filename, struct list_head *file_list)
{
struct files *loop_file;
struct files *new_file;
list_for_each_entry(loop_file, file_list, list) {
if (strcmp(loop_file->name, filename) > 0) {
break;
}
}
new_file = malloc(sizeof(struct files));
if (new_file == NULL) {
dbg("error malloc");
return -ENOMEM;
}
strfieldcpy(new_file->name, filename);
list_add_tail(&new_file->list, &loop_file->list);
return 0;
}
/* calls function for every file found in specified directory */
static int call_foreach_file(const char *dirname)
{
struct dirent *ent;
DIR *dir;
char *ext;
struct files *loop_file;
struct files *tmp_file;
LIST_HEAD(file_list);
dbg("open directory '%s'", dirname);
dir = opendir(dirname);
if (dir == NULL) {
dbg("unable to open '%s'", dirname);
return -1;
}
while (1) {
ent = readdir(dir);
if (ent == NULL || ent->d_name[0] == '\0')
break;
if (ent->d_name[0] == '.')
continue;
/* look for file with specified suffix */
ext = strrchr(ent->d_name, '.');
if (ext == NULL)
continue;
if (strcmp(ext, HOT_SUFFIX) != 0)
continue;
dbg("put file '%s/%s' in list", dirname, ent->d_name);
file_list_insert(ent->d_name, &file_list);
}
/* call function for every file in the list */
list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) {
char filename[PATH_MAX];
snprintf(filename, PATH_MAX, "%s/%s", dirname, loop_file->name);
filename[PATH_MAX-1] = '\0';
run_program(filename);
list_del(&loop_file->list);
free(loop_file);
}
closedir(dir);
return 0;
}
/*
* runs files in these directories in order:
* argv[1]/
* default/
*/
int main(int argc, char *argv[], char *envp[])
{
char dirname[PATH_MAX];
int fd;
fd = open("/dev/null", O_RDWR);
if (fd >= 0) {
dup2(fd, STDOUT_FILENO);
dup2(fd, STDIN_FILENO);
dup2(fd, STDERR_FILENO);
}
close(fd);
subsystem = argv[1];
logging_init("hotplug");
snprintf(dirname, PATH_MAX, "%s/%s", HOT_DIR, subsystem);
dirname[PATH_MAX-1] = '\0';
call_foreach_file(dirname);
snprintf(dirname, PATH_MAX, "%s/default", HOT_DIR);
dirname[PATH_MAX-1] = '\0';
call_foreach_file(dirname);
logging_close();
return 0;
}
next reply other threads:[~2004-11-18 23:14 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-11-18 23:14 Greg KH [this message]
2004-11-18 23:46 ` [ANNOUNCE] a very tiny /sbin/hotplug Eugene Surovegin
2004-11-18 23:53 ` Chris Larson
2004-11-19 0:18 ` Greg KH
2004-11-19 10:03 ` Robert Schwebel
2004-11-19 0:28 ` Chris Larson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20041118231406.GA11239@kroah.com \
--to=greg@kroah.com \
--cc=linux-hotplug-devel@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).