Halo,
I don't know if this is already done but the following two patches (one
for klibc) and a big one (several smaller incorporated to one) to
modules-init-tools enables running modprobe and friends in early user space.
There are some issues so I post here for discussion
The porting strategy was copied from the udev package. I make a file
mod_libc_wrapper.{c,h} in order to provide the missing functionality.
The port was quite easy. The following pieces were:
1)
int fnmatch(pattern, string, flags) (3) implementation. I copied this
one, from udev package. I would post it against libc but the udev
implementation does not care for flags. Luckily module-init-tools only
use fnmatch with flags = 0. I think it is not correct for klibc to
deviate from the standard so I placed this functionality in
module-init-tools.
2)
getopt_long
This one I short circuited with the simple getopt() provided from klibc.
It works for me here except --long-arguments are not supported any more.
Again this is half assed functionality and I left it in module-init-tools.
3)
char *index(const char *s, int c);
I teach the module-init-tools that strchr is equally good unless. IMO
strchr and index are interchangeable unless I am missing something
really nasty here. This can be also a define in klibc. It will enrich
klibc with a function without actually increase its size.
4) some elf magic defines
This is the patch for klibc. I really don't kown if they belong there. I
copied them from glibc headers. Would it be a problem? If it is then you
(we?) should inject them somehow to module-init-tools (since it is GPL)
and we can get done with that port. Also note beeing defines they do not
bloat klibc (in size).
That's all folks...
.bill
-------------- next part --------------
diff -ur module-init-tools-3.2-pre5/depmod.c module-init-tools/depmod.c
--- module-init-tools-3.2-pre5/depmod.c 2005-04-30 15:38:46.000000000 +0300
+++ module-init-tools/depmod.c 2005-05-22 01:19:06.000000000 +0300
@@ -6,7 +6,11 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
-#include <getopt.h>
+#ifndef __KLIBC__
+# include <getopt.h>
+#else
+# include "mod_libc_wrapper.h"
+#endif
#include <string.h>
#include <errno.h>
#include <unistd.h>
diff -ur module-init-tools-3.2-pre5/Makefile.am module-init-tools/Makefile.am
--- module-init-tools-3.2-pre5/Makefile.am 2005-05-12 07:35:25.000000000 +0300
+++ module-init-tools/Makefile.am 2005-05-23 17:27:26.000000000 +0300
@@ -1,9 +1,9 @@
insmod_SOURCES = insmod.c testing.h
lsmod_SOURCES = lsmod.c testing.h
-modprobe_SOURCES = modprobe.c zlibsupport.c testing.h zlibsupport.h
-rmmod_SOURCES = rmmod.c testing.h
-depmod_SOURCES = depmod.c moduleops.c tables.c zlibsupport.c depmod.h
moduleops.h tables.h list.h testing.h zlibsupport.h
-modinfo_SOURCES = modinfo.c zlibsupport.c testing.h zlibsupport.h
+modprobe_SOURCES = modprobe.c zlibsupport.c mod_libc_wrapper.c testing.h
zlibsupport.h mod_libc_wrapper.h
+rmmod_SOURCES = rmmod.c mod_libc_wrapper.c testing.h mod_libc_wrapper.h
+depmod_SOURCES = depmod.c moduleops.c tables.c zlibsupport.c mod_libc_wrapper.c
depmod.h moduleops.h tables.h list.h testing.h zlibsupport.h mod_libc_wrapper.h
+modinfo_SOURCES = modinfo.c zlibsupport.c mod_libc_wrapper.c testing.h
zlibsupport.h mod_libc_wrapper.h
insmod_static_SOURCES = insmod.c
insmod_static_LDFLAGS = -static
diff -ur module-init-tools-3.2-pre5/modinfo.c module-init-tools/modinfo.c
--- module-init-tools-3.2-pre5/modinfo.c 2005-01-18 05:25:23.000000000 +0200
+++ module-init-tools/modinfo.c 2005-05-22 01:20:37.000000000 +0300
@@ -2,7 +2,12 @@
#define _GNU_SOURCE /* asprintf rocks */
#include <elf.h>
#include <unistd.h>
-#include <getopt.h>
+#ifndef __KLIBC__
+# include <getopt.h>
+#else
+# include "mod_libc_wrapper.h"
+# undef _GNU_SOURCE /* ha ha */
+#endif
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
diff -ur module-init-tools-3.2-pre5/mod_libc_wrapper.c
module-init-tools/mod_libc_wrapper.c
--- module-init-tools-3.2-pre5/mod_libc_wrapper.c 2005-05-23 17:29:30.000000000
+0300
+++ module-init-tools/mod_libc_wrapper.c 2005-05-22 11:30:16.000000000 +0300
@@ -0,0 +1,108 @@
+/*
+ * mod_libc_wrapper - wrapping of functions missing in a specific libc
+ * or not working in a statically compiled binary
+ *
+ * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2005 Kay Sievers <kay@vrfy.org>
+ * Copyright (C) 2005 Vassilis Virvilis <vasvir@yahoo.gr>
+ *
+ * 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 program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "mod_libc_wrapper.h"
+
+#ifndef HAVE_GETOPT_LONG
+#include "unistd.h"
+
+int getopt_long(int argc, char *const argv[],
+ const char *optstring,
+ const struct option *longopts, int *longindex)
+{
+ /* TODO: the rest of getopt_long */
+ return getopt(argc, argv, optstring);
+}
+
+#endif
+
+#ifndef HAVE_FNMATCH
+
+/* shamelessly copied from udev */
+/* compare string with pattern (supports * ? [0-9] [!A-Z]) */
+static int strcmp_pattern(const char *p, const char *s)
+{
+ if (s[0] == '\0') {
+ while (p[0] == '*')
+ p++;
+ return (p[0] != '\0');
+ }
+ switch (p[0]) {
+ case '[':
+ {
+ int not = 0;
+ p++;
+ if (p[0] == '!') {
+ not = 1;
+ p++;
+ }
+ while ((p[0] != '\0') && (p[0] != ']')) {
+ int match = 0;
+ if (p[1] == '-') {
+ if ((s[0] >= p[0]) && (s[0] <= p[2]))
+ match = 1;
+ p += 3;
+ } else {
+ match = (p[0] == s[0]);
+ p++;
+ }
+ if (match ^ not) {
+ while ((p[0] != '\0') && (p[0] != ']'))
+ p++;
+ if (p[0] == ']')
+ return strcmp_pattern(p+1, s+1);
+ }
+ }
+ }
+ break;
+ case '*':
+ if (strcmp_pattern(p, s+1))
+ return strcmp_pattern(p+1, s);
+ return 0;
+ case '\0':
+ if (s[0] == '\0') {
+ return 0;
+ }
+ break;
+ default:
+ if ((p[0] == s[0]) || (p[0] == '?'))
+ return strcmp_pattern(p+1, s+1);
+ break;
+ }
+ return 1;
+}
+
+/* shamelessly thin wrapper around real worker copied from udev. */
+int fnmatch(const char *pattern, const char *string, int flags)
+{
+ if (flags) {
+ fprintf(stderr,
+ "Warning: flags (%d) in fnmatch are not supported yet\n", flags);
+ }
+ return strcmp_pattern(pattern, string);
+}
+
+#endif
diff -ur module-init-tools-3.2-pre5/mod_libc_wrapper.h
module-init-tools/mod_libc_wrapper.h
--- module-init-tools-3.2-pre5/mod_libc_wrapper.h 2005-05-23 17:29:30.000000000
+0300
+++ module-init-tools/mod_libc_wrapper.h 2005-05-22 01:31:20.000000000 +0300
@@ -0,0 +1,45 @@
+/*
+ * mod_libc_wrapper - wrapping of functions missing in a specific libc
+ * or not working in a statically compiled binary
+ *
+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2005 Vassilis Virvilis <vasvir@yahoo.gr>
+ *
+ * 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 program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _MOD__LIBC_WRAPPER_H_
+#define _MOD_LIBC_WRAPPER_H_
+
+#ifndef HAVE_GETOPT_LONG
+
+struct option {
+ const char *name;
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+extern int getopt_long(int argc, char *const argv[],
+ const char *optstring,
+ const struct option *longopts, int *longindex);
+
+#endif
+
+#ifndef HAVE_FNMATCH
+extern int fnmatch(const char *pattern, const char *string, int flags);
+#endif
+
+#endif /* _MOD_LIBC_WRAPPER_H_ */
diff -ur module-init-tools-3.2-pre5/modprobe.c module-init-tools/modprobe.c
--- module-init-tools-3.2-pre5/modprobe.c 2005-05-12 04:58:22.000000000 +0300
+++ module-init-tools/modprobe.c 2005-05-22 01:31:57.000000000 +0300
@@ -33,8 +33,13 @@
#include <dirent.h>
#include <limits.h>
#include <elf.h>
-#include <getopt.h>
-#include <fnmatch.h>
+#ifndef __KLIBC__
+# include <getopt.h>
+# include <fnmatch.h>
+#else
+# include "mod_libc_wrapper.h"
+# undef _GNU_SOURCE /* ha ha */
+#endif
#include <asm/unistd.h>
#include <sys/wait.h>
#include <syslog.h>
@@ -270,7 +275,7 @@
char *modname;
/* Ignore lines without : or which start with a # */
- ptr = index(line, ':');
+ ptr = strchr(line, ':');
if (ptr == NULL || line[strspn(line, "\t ")] == '#')
return 0;
diff -ur module-init-tools-3.2-pre5/rmmod.c module-init-tools/rmmod.c
--- module-init-tools-3.2-pre5/rmmod.c 2004-02-25 09:10:51.000000000 +0200
+++ module-init-tools/rmmod.c 2005-05-22 01:19:54.000000000 +0300
@@ -24,7 +24,11 @@
#include <fcntl.h>
#include <asm/unistd.h>
#include <stdarg.h>
-#include <getopt.h>
+#ifndef __KLIBC__
+# include <getopt.h>
+#else
+# include "mod_libc_wrapper.h"
+#endif
#include <syslog.h>
#include "backwards_compat.c"
-------------- next part --------------
Index: include/elf.h
==================================================================---
efac3d95dbcebf5870fc69dbf652f0225a162961/include/elf.h (mode:100644)
+++ 75852caa45a517d4b0df05e6cd364b9ad0a5d98d/include/elf.h (mode:100644)
@@ -5,6 +5,13 @@
#ifndef _ELF_H
#define _ELF_H
+/* copied from GLIBC: Is this a bad (license wise) thing? */
+#define ELF32_ST_TYPE(val) ((val) & 0xf)
+#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val)
+#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)
+#define ELF64_ST_BIND(val) ELF32_ST_BIND (val)
+#define STB_WEAK 2 /* Weak symbol */
+
#include <sys/elf32.h>
#include <sys/elf64.h>