[klibc] module-init-tools ported to klibc

Vassilis Virvilis vasvir at iit.demokritos.gr
Mon May 23 08:03:04 PDT 2005


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 at kroah.com>
+ * Copyright (C) 2005 Kay Sievers <kay at vrfy.org>
+ * Copyright (C) 2005 Vassilis Virvilis <vasvir at 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 at vrfy.org>
+ * Copyright (C) 2005 Vassilis Virvilis <vasvir at 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>
 


More information about the klibc mailing list