Merge with git://charm.itp.tuwien.ac.at/mattems/klibc/.git#maks
diff --git a/Makefile b/Makefile
index bb018cc..b507668 100644
--- a/Makefile
+++ b/Makefile
@@ -151,4 +151,4 @@
# This does all the prep work needed to turn a freshly exported git repository
# into a release tarball tree
release: klibc.spec
- rm -f maketar.sh
+ rm -f maketar.sh .config
diff --git a/klcc/Kbuild b/klcc/Kbuild
index 7efcd24..b71581b 100644
--- a/klcc/Kbuild
+++ b/klcc/Kbuild
@@ -14,7 +14,7 @@
$(Q)echo 'KCROSS=$(KCROSS)' >> $@
$(Q)echo 'CC=$(KLIBCCC)' >> $@
$(Q)echo 'LD=$(KLIBCLD)' >> $@
- $(Q)echo 'REQFLAGS=$(filter-out -I%,$(KLIBCDEFS) $(KLIBCREQFLAGS) $(KLIBCARCHREQFLAGS))' >> $@
+ $(Q)echo 'REQFLAGS=$(filter-out -I%,$(KLIBCDEFS) $(KLIBCREQFLAGS) $(KLIBCARCHREQFLAGS) $(KLIBCCPPFLAGS))' >> $@
$(Q)echo 'OPTFLAGS=$(KLIBCOPTFLAGS)' >> $@
$(Q)echo 'LDFLAGS=$(KLIBCLDFLAGS)' >> $@
$(Q)echo 'STRIP=$(KLIBCSTRIP)' >> $@
diff --git a/klibc.spec.in b/klibc.spec.in
index 85f57ef..30c1155 100644
--- a/klibc.spec.in
+++ b/klibc.spec.in
@@ -61,7 +61,8 @@
mkdir -p %{buildroot}
%build
-make KLIBCARCH=%{_target_cpu} prefix=%{_prefix} bindir=%{_bindir} \
+make %{_smp_mflags} \
+ KLIBCARCH=%{_target_cpu} prefix=%{_prefix} bindir=%{_bindir} \
INSTALLDIR=%{klibcdir} mandir=%{_mandir} INSTALLROOT=%{buildroot}
%install
diff --git a/scripts/Kbuild.klibc b/scripts/Kbuild.klibc
index bbb86f4..227b9bd 100644
--- a/scripts/Kbuild.klibc
+++ b/scripts/Kbuild.klibc
@@ -96,7 +96,8 @@
KLIBCOBJDUMP := $(OBJDUMP)
# klibc include paths
-KLIBCCPPFLAGS := -I$(KLIBCINC)/arch/$(KLIBCARCHDIR) \
+KLIBCCPPFLAGS := -nostdinc -iwithprefix include \
+ -I$(KLIBCINC)/arch/$(KLIBCARCHDIR) \
-I$(KLIBCINC)/bits$(KLIBCBITSIZE) \
-I$(KLIBCOBJ)/../include \
-I$(KLIBCINC)
diff --git a/usr/dash/Kbuild b/usr/dash/Kbuild
index 10e9591..edaa93f 100644
--- a/usr/dash/Kbuild
+++ b/usr/dash/Kbuild
@@ -3,7 +3,7 @@
#
config-cppflags := -DBSD=1 -DSMALL -DJOBS=0 -DHAVE_CONFIG_H -DSHELL
-config-cppflags += -DGLOB_BROKEN -DFNMATCH_BROKEN -DIFS_BROKEN
+config-cppflags += -DGLOB_BROKEN -DIFS_BROKEN
EXTRA_KLIBCCFLAGS := -I$(srctree)/$(src) -I$(objtree)/$(obj)
EXTRA_KLIBCCFLAGS += -include $(srctree)/$(src)/config.h
diff --git a/usr/include/fnmatch.h b/usr/include/fnmatch.h
new file mode 100644
index 0000000..0d88140
--- /dev/null
+++ b/usr/include/fnmatch.h
@@ -0,0 +1,15 @@
+#ifndef _FNMATCH_H
+#define _FNMATCH_H
+
+#include <klibc/extern.h>
+
+#define FNM_NOMATCH 1
+
+#define FNM_PATHNAME 1
+#define FNM_FILE_NAME FNM_PATHNAME
+#define FNM_NOESCAPE 2
+#define FNM_PERIOD 4
+
+__extern int fnmatch(const char *, const char *, int);
+
+#endif /* _FNMATCH_H */
diff --git a/usr/include/getopt.h b/usr/include/getopt.h
new file mode 100644
index 0000000..71c41cd
--- /dev/null
+++ b/usr/include/getopt.h
@@ -0,0 +1,22 @@
+#ifndef _GETOPT_H
+#define _GETOPT_H
+
+#include <klibc/extern.h>
+
+struct option {
+ const char *name;
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+enum {
+ no_argument = 0,
+ required_argument = 1,
+ optional_argument = 2,
+};
+
+__extern int getopt_long(int, char *const *, const char *,
+ const struct option *, int *);
+
+#endif /* _GETOPT_H */
diff --git a/usr/include/grp.h b/usr/include/grp.h
index 19b1828..88bf79e 100644
--- a/usr/include/grp.h
+++ b/usr/include/grp.h
@@ -8,6 +8,13 @@
#include <klibc/extern.h>
#include <sys/types.h>
+struct group {
+ char *gr_name;
+ char *gr_passwd;
+ gid_t gr_gid;
+ char **gr_mem;
+};
+
__extern int setgroups(size_t, const gid_t *);
#endif /* _GRP_H */
diff --git a/usr/include/pwd.h b/usr/include/pwd.h
new file mode 100644
index 0000000..aeddbfb
--- /dev/null
+++ b/usr/include/pwd.h
@@ -0,0 +1,19 @@
+#ifndef _PWD_H
+#define _PWD_H
+
+#include <klibc/extern.h>
+#include <sys/types.h>
+
+struct passwd {
+ char *pw_name;
+ char *pw_passwd;
+ uid_t pw_uid;
+ gid_t pw_gid;
+ char *pw_gecos;
+ char *pw_dir;
+ char *pw_shell;
+};
+
+__extern struct passwd *getpwnam(const char *name);
+
+#endif /* _PWD_H */
diff --git a/usr/include/sys/prctl.h b/usr/include/sys/prctl.h
new file mode 100644
index 0000000..c12c191
--- /dev/null
+++ b/usr/include/sys/prctl.h
@@ -0,0 +1,10 @@
+#ifndef _SYS_PRCTL_H
+#define _SYS_PRCTL_H
+
+#include <klibc/extern.h>
+#include <linux/prctl.h>
+
+/* glibc has this as a varadic function, so join the club... */
+__extern int prctl(int, ...);
+
+#endif /* _SYS_PRCTL_H */
diff --git a/usr/include/sysexits.h b/usr/include/sysexits.h
new file mode 100644
index 0000000..ef454b9
--- /dev/null
+++ b/usr/include/sysexits.h
@@ -0,0 +1,26 @@
+#ifndef _SYSEXITS_H
+#define _SYSEXITS_H
+
+#define EX_OK 0 /* successful termination */
+
+#define EX__BASE 64 /* base value for error messages */
+
+#define EX_USAGE 64 /* command line usage error */
+#define EX_DATAERR 65 /* data format error */
+#define EX_NOINPUT 66 /* cannot open input */
+#define EX_NOUSER 67 /* addressee unknown */
+#define EX_NOHOST 68 /* host name unknown */
+#define EX_UNAVAILABLE 69 /* service unavailable */
+#define EX_SOFTWARE 70 /* internal software error */
+#define EX_OSERR 71 /* system error (e.g., can't fork) */
+#define EX_OSFILE 72 /* critical OS file missing */
+#define EX_CANTCREAT 73 /* can't create (user) output file */
+#define EX_IOERR 74 /* input/output error */
+#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */
+#define EX_PROTOCOL 76 /* remote error in protocol */
+#define EX_NOPERM 77 /* permission denied */
+#define EX_CONFIG 78 /* configuration error */
+
+#define EX__MAX 78 /* maximum listed value */
+
+#endif /* _SYSEXITS_H */
diff --git a/usr/include/unistd.h b/usr/include/unistd.h
index 4df42d6..c7badd8 100644
--- a/usr/include/unistd.h
+++ b/usr/include/unistd.h
@@ -98,7 +98,7 @@
__extern ssize_t read(int, void *, size_t);
__extern ssize_t write(int, const void *, size_t);
__extern ssize_t pread(int, void *, size_t, off_t);
-__extern ssize_t pwrite(int, void *, size_t, off_t);
+__extern ssize_t pwrite(int, const void *, size_t, off_t);
__extern int dup(int);
__extern int dup2(int, int);
diff --git a/usr/klibc/Kbuild b/usr/klibc/Kbuild
index 65ca2e4..906caae 100644
--- a/usr/klibc/Kbuild
+++ b/usr/klibc/Kbuild
@@ -36,11 +36,12 @@
strncat.o strlcpy.o strlcat.o \
strstr.o strncmp.o strncpy.o strrchr.o \
strxspn.o strspn.o strcspn.o strpbrk.o strsep.o strtok.o \
+ fnmatch.o \
gethostname.o getdomainname.o getcwd.o \
seteuid.o setegid.o \
getenv.o setenv.o putenv.o __put_env.o unsetenv.o \
clearenv.o nullenv.o \
- getopt.o readdir.o remove.o \
+ getopt.o getopt_long.o readdir.o remove.o \
syslog.o closelog.o pty.o getpt.o isatty.o reboot.o \
time.o utime.o llseek.o nice.o getpriority.o \
qsort.o bsearch.o \
@@ -52,7 +53,9 @@
ctype/isblank.o ctype/iscntrl.o ctype/isdigit.o \
ctype/isgraph.o ctype/islower.o ctype/isprint.o \
ctype/ispunct.o ctype/isspace.o ctype/isupper.o \
- ctype/isxdigit.o ctype/tolower.o ctype/toupper.o
+ ctype/isxdigit.o ctype/tolower.o ctype/toupper.o \
+ userdb/getgrgid.o userdb/getgrnam.o userdb/getpwnam.o \
+ userdb/getpwuid.o userdb/root_group.o userdb/root_user.o
klib-$(CONFIG_KLIBC_ERRLIST) += errlist.o
diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def
index 64b92be..c12d525 100644
--- a/usr/klibc/SYSCALLS.def
+++ b/usr/klibc/SYSCALLS.def
@@ -49,6 +49,8 @@
int setpriority(int, int, int);
int sched_setscheduler(pid_t, int, const struct sched_param *);
int sched_yield();
+<i386> int prctl@varadic(int, unsigned long, unsigned long, unsigned long, unsigned long);
+<!i386> int prctl(int, unsigned long, unsigned long, unsigned long, unsigned long);
/*
* User and group IDs
diff --git a/usr/klibc/arch/x86_64/MCONFIG b/usr/klibc/arch/x86_64/MCONFIG
index d01f5e3..a229905 100644
--- a/usr/klibc/arch/x86_64/MCONFIG
+++ b/usr/klibc/arch/x86_64/MCONFIG
@@ -16,7 +16,7 @@
#
KLIBCARCHREQFLAGS = -m64
ifeq ($(DEBUG),y)
-KLIBCOPTFLAGS += -Os -fomit-frame-pointer \
+KLIBCOPTFLAGS += -g -Os -fomit-frame-pointer \
-falign-functions=1 -falign-jumps=1 -falign-loops=1
else
KLIBCOPTFLAGS += -Os -fno-asynchronous-unwind-tables -fomit-frame-pointer \
diff --git a/usr/klibc/fnmatch.c b/usr/klibc/fnmatch.c
new file mode 100644
index 0000000..5d0a25f
--- /dev/null
+++ b/usr/klibc/fnmatch.c
@@ -0,0 +1,72 @@
+/*
+ * fnmatch.c
+ *
+ * Original implementation by Kay Sievers, modified by H. Peter Anvin.
+ */
+
+#include <fnmatch.h>
+
+int fnmatch(const char *p, const char *s, int flags)
+{
+ if (flags & FNM_PATHNAME && *s == '/')
+ return (*p != '/') || fnmatch(p+1, s+1, flags);
+ if (flags & FNM_PERIOD && *s == '.')
+ return (*p != '.') || fnmatch(p+1, s+1, flags);
+
+ flags &= ~FNM_PERIOD; /* Only applies at beginning */
+
+ if (!(flags & FNM_NOESCAPE) && *p == '\\') {
+ p++;
+ return (*p != *s) || fnmatch(p+1, s+1, flags);
+ }
+
+ if (*s == '\0') {
+ while (*p == '*')
+ p++;
+ return (*p != '\0');
+ }
+
+ switch (*p) {
+ case '[':
+ {
+ int not = 0;
+ p++;
+ if (*p == '!') {
+ not = 1;
+ p++;
+ }
+ while ((*p != '\0') && (*p != ']')) {
+ int match = 0;
+ if (p[1] == '-') {
+ if ((*s >= *p) && (*s <= p[2]))
+ match = 1;
+ p += 3;
+ } else {
+ match = (*p == *s);
+ p++;
+ }
+ if (match ^ not) {
+ while ((*p != '\0') && (*p != ']'))
+ p++;
+ if (*p == ']')
+ return fnmatch(p+1, s+1, flags);
+ }
+ }
+ }
+ break;
+ case '*':
+ if (fnmatch(p, s+1, flags))
+ return fnmatch(p+1, s, flags);
+ return 0;
+ case '\0':
+ if (*s == '\0') {
+ return 0;
+ }
+ break;
+ default:
+ if ((*p == *s) || (*p == '?'))
+ return fnmatch(p+1, s+1, flags);
+ break;
+ }
+ return 1;
+}
diff --git a/usr/klibc/getopt_long.c b/usr/klibc/getopt_long.c
new file mode 100644
index 0000000..e3d064b
--- /dev/null
+++ b/usr/klibc/getopt_long.c
@@ -0,0 +1,152 @@
+/*
+ * getopt.c
+ *
+ * getopt_long(), or at least a common subset thereof:
+ *
+ * - Option reordering is not supported
+ * - -W foo is not supported
+ * - First optstring character "-" not supported.
+ */
+
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <getopt.h>
+
+char *optarg;
+int optind, opterr, optopt;
+static struct getopt_private_state {
+ const char *optptr;
+ const char *last_optstring;
+ char *const *last_argv;
+} pvt;
+
+static inline const char *option_matches(const char *arg_str,
+ const char *opt_name)
+{
+ while (*arg_str != '\0' && *arg_str != '=') {
+ if (*arg_str++ != *opt_name++)
+ return NULL;
+ }
+
+ if (*opt_name)
+ return NULL;
+
+ return arg_str;
+}
+
+int getopt_long(int argc, char *const *argv, const char *optstring,
+ const struct option *longopts, int *longindex)
+{
+ const char *carg;
+ const char *osptr;
+ int opt;
+
+ /* getopt() relies on a number of different global state
+ variables, which can make this really confusing if there is
+ more than one use of getopt() in the same program. This
+ attempts to detect that situation by detecting if the
+ "optstring" or "argv" argument have changed since last time
+ we were called; if so, reinitialize the query state. */
+
+ if (optstring != pvt.last_optstring || argv != pvt.last_argv ||
+ optind < 1 || optind > argc) {
+ /* optind doesn't match the current query */
+ pvt.last_optstring = optstring;
+ pvt.last_argv = argv;
+ optind = 1;
+ pvt.optptr = NULL;
+ }
+
+ carg = argv[optind];
+
+ /* First, eliminate all non-option cases */
+
+ if (!carg || carg[0] != '-' || !carg[1])
+ return -1;
+
+ if (carg[1] == '-') {
+ const struct option *lo;
+ const char *opt_end = NULL;
+
+ optind++;
+
+ /* Either it's a long option, or it's -- */
+ if (!carg[2]) {
+ /* It's -- */
+ return -1;
+ }
+
+ for (lo = longopts; lo->name; lo++) {
+ if ((opt_end = option_matches(carg+2, lo->name)))
+ break;
+ }
+ if (!opt_end)
+ return '?';
+
+ if (longindex)
+ *longindex = lo-longopts;
+
+ if (*opt_end == '=') {
+ if (lo->has_arg)
+ optarg = (char *)opt_end+1;
+ else
+ return '?';
+ } else if (lo->has_arg == 1) {
+ if (!(optarg = argv[optind]))
+ return '?';
+ optind++;
+ }
+
+ if (lo->flag) {
+ *lo->flag = lo->val;
+ return 0;
+ } else {
+ return lo->val;
+ }
+ }
+
+ if ((uintptr_t) (pvt.optptr - carg) > (uintptr_t) strlen(carg)) {
+ /* Someone frobbed optind, change to new opt. */
+ pvt.optptr = carg + 1;
+ }
+
+ opt = *pvt.optptr++;
+
+ if (opt != ':' && (osptr = strchr(optstring, opt))) {
+ if (osptr[1] == ':') {
+ if (*pvt.optptr) {
+ /* Argument-taking option with attached
+ argument */
+ optarg = (char *)pvt.optptr;
+ optind++;
+ } else {
+ /* Argument-taking option with non-attached
+ argument */
+ if (argv[optind + 1]) {
+ optarg = (char *)argv[optind+1];
+ optind += 2;
+ } else {
+ /* Missing argument */
+ optind++;
+ return (optstring[0] == ':')
+ ? ':' : '?';
+ }
+ }
+ return opt;
+ } else {
+ /* Non-argument-taking option */
+ /* pvt.optptr will remember the exact position to
+ resume at */
+ if (!*pvt.optptr)
+ optind++;
+ return opt;
+ }
+ } else {
+ /* Unknown option */
+ optopt = opt;
+ if (!*pvt.optptr)
+ optind++;
+ return '?';
+ }
+}
diff --git a/usr/klibc/malloc.c b/usr/klibc/malloc.c
index f07ebd2..fbbbbbc 100644
--- a/usr/klibc/malloc.c
+++ b/usr/klibc/malloc.c
@@ -40,7 +40,7 @@
an = ah->a.next;
ap->a.next = an;
an->a.prev = ap;
-}
+}
static inline void remove_from_free_chain(struct free_arena_header *ah)
{
@@ -50,7 +50,7 @@
an = ah->next_free;
ap->next_free = an;
an->prev_free = ap;
-}
+}
static inline void remove_from_chains(struct free_arena_header *ah)
{
diff --git a/usr/klibc/tests/Kbuild b/usr/klibc/tests/Kbuild
index a97e86c..75d8bb3 100644
--- a/usr/klibc/tests/Kbuild
+++ b/usr/klibc/tests/Kbuild
@@ -15,7 +15,9 @@
environ.shared-y := environ.o
fcntl.shared-y := fcntl.o
+fnmatch.shared-y := fnmatch.o
getopttest.shared-y := getopttest.o
+getoptlong.shared-y := getoptlong.o
getpagesize.shared-y := getpagesize.o
hello.shared-y := hello.o
idtest.shared-y := idtest.o
diff --git a/usr/klibc/tests/fnmatch.c b/usr/klibc/tests/fnmatch.c
new file mode 100644
index 0000000..4150857
--- /dev/null
+++ b/usr/klibc/tests/fnmatch.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <fnmatch.h>
+
+int main(int argc, char *argv[])
+{
+ int flags = atoi(argv[3]);
+ int match = fnmatch(argv[1], argv[2], flags);
+
+ printf("\"%s\" matches \"%s\": %d\n", argv[1], argv[2], match);
+
+ return match;
+}
+
+
diff --git a/usr/klibc/tests/getoptlong.c b/usr/klibc/tests/getoptlong.c
new file mode 100644
index 0000000..c1174ab
--- /dev/null
+++ b/usr/klibc/tests/getoptlong.c
@@ -0,0 +1,57 @@
+/*
+ * getoptlong.c
+ *
+ * Simple test for getopt_long, set the environment variable GETOPTTEST
+ * to give the argument string to getopt()
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <getopt.h>
+
+static int foo = 0;
+
+static const struct option long_options[] = {
+ { "first", 1, NULL, 'f' },
+ { "second", 0, NULL, 's' },
+ { "third", 2, NULL, '3' },
+ { "fourth", 0, NULL, 4 },
+ { "set-foo", 0, &foo, 1 },
+ { NULL, 0, NULL, 0 }
+};
+
+int main(int argc, char *const *argv)
+{
+ const char *parser;
+ const char *showchar;
+ char one_char[] = "\'?\'";
+ char num_buf[16];
+ int c;
+ int longindex;
+
+ parser = getenv("GETOPTTEST");
+ if (!parser)
+ parser = "abzf:o:";
+
+ do {
+ c = getopt_long(argc, argv, parser, long_options, &longindex);
+
+ if (c == EOF) {
+ showchar = "EOF";
+ } else if (c >= 32 && c <= 126) {
+ one_char[1] = c;
+ showchar = one_char;
+ } else {
+ snprintf(num_buf, sizeof num_buf, "%d", c);
+ showchar = num_buf;
+ }
+
+ printf("c = %s, optind = %d (\"%s\"), optarg = \"%s\", "
+ "optopt = \'%c\', foo = %d, longindex = %d\n",
+ showchar, optind, argv[optind],
+ optarg, optopt, foo, longindex);
+ } while (c != -1);
+
+ return 0;
+}
diff --git a/usr/klibc/userdb/getgrgid.c b/usr/klibc/userdb/getgrgid.c
new file mode 100644
index 0000000..5e13a47
--- /dev/null
+++ b/usr/klibc/userdb/getgrgid.c
@@ -0,0 +1,16 @@
+/*
+ * getgrgid.c
+ *
+ * Dummy getgrgid() to support udev
+ */
+
+#include "userdb.h"
+
+struct group *getgrgid(gid_t gid)
+{
+ if (!gid)
+ return (struct group *)&__root_group;
+
+ errno = ENOENT;
+ return NULL;
+}
diff --git a/usr/klibc/userdb/getgrnam.c b/usr/klibc/userdb/getgrnam.c
new file mode 100644
index 0000000..8df7b8f
--- /dev/null
+++ b/usr/klibc/userdb/getgrnam.c
@@ -0,0 +1,16 @@
+/*
+ * getgrnam.c
+ *
+ * Dummy getgrnam() to support udev
+ */
+
+#include "userdb.h"
+
+struct group *getgrnam(const char *name)
+{
+ if (!strcmp(name, "root"))
+ return (struct group *)&__root_group;
+
+ errno = ENOENT;
+ return NULL;
+}
diff --git a/usr/klibc/userdb/getpwnam.c b/usr/klibc/userdb/getpwnam.c
new file mode 100644
index 0000000..ae1359c
--- /dev/null
+++ b/usr/klibc/userdb/getpwnam.c
@@ -0,0 +1,17 @@
+/*
+ * getpwnam.c
+ *
+ * Dummy getpwnam() to support udev
+ */
+
+#include "userdb.h"
+
+
+struct passwd *getpwnam(const char *name)
+{
+ if (!strcmp(name, "root"))
+ return (struct passwd *)&__root_user;
+
+ errno = ENOENT;
+ return NULL;
+}
diff --git a/usr/klibc/userdb/getpwuid.c b/usr/klibc/userdb/getpwuid.c
new file mode 100644
index 0000000..f924f29
--- /dev/null
+++ b/usr/klibc/userdb/getpwuid.c
@@ -0,0 +1,17 @@
+/*
+ * getpwuid.c
+ *
+ * Dummy getpwuid() to support udev
+ */
+
+#include "userdb.h"
+
+
+struct passwd *getpwuid(uid_t uid)
+{
+ if (!uid)
+ return (struct passwd *)&__root_user;
+
+ errno = ENOENT;
+ return NULL;
+}
diff --git a/usr/klibc/userdb/root_group.c b/usr/klibc/userdb/root_group.c
new file mode 100644
index 0000000..e936d54
--- /dev/null
+++ b/usr/klibc/userdb/root_group.c
@@ -0,0 +1,12 @@
+/*
+ * root_group.c
+ */
+
+#include "userdb.h"
+
+const struct group __root_group = {
+ .gr_name = "root",
+ .gr_passwd = "",
+ .gr_gid = 0,
+ .gr_mem = NULL
+};
diff --git a/usr/klibc/userdb/root_user.c b/usr/klibc/userdb/root_user.c
new file mode 100644
index 0000000..ee2e99a
--- /dev/null
+++ b/usr/klibc/userdb/root_user.c
@@ -0,0 +1,17 @@
+/*
+ * root_user.c
+ *
+ */
+
+#include "userdb.h"
+#include <paths.h>
+
+const struct passwd __root_user = {
+ .pw_name = "root",
+ .pw_passwd = "",
+ .pw_uid = 0,
+ .pw_gid = 0,
+ .pw_gecos = "root",
+ .pw_dir = "/",
+ .pw_shell = _PATH_BSHELL
+};
diff --git a/usr/klibc/userdb/userdb.h b/usr/klibc/userdb/userdb.h
new file mode 100644
index 0000000..dda093f
--- /dev/null
+++ b/usr/klibc/userdb/userdb.h
@@ -0,0 +1,19 @@
+/*
+ * userdb.h
+ *
+ * Common header file
+ */
+
+#ifndef USERDB_H
+#define USERDB_H
+
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <string.h>
+#include <errno.h>
+
+extern const struct passwd __root_user;
+extern const struct group __root_group;
+
+#endif /* USERDB_H */
diff --git a/usr/klibc/version b/usr/klibc/version
index d6e2616..5e99adf 100644
--- a/usr/klibc/version
+++ b/usr/klibc/version
@@ -1 +1 @@
-1.4.22
+1.4.27
diff --git a/usr/utils/nuke.c b/usr/utils/nuke.c
index 9470bcf..829bd05 100644
--- a/usr/utils/nuke.c
+++ b/usr/utils/nuke.c
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2004 H. Peter Anvin - All Rights Reserved
+ * Copyright 2004-2006 H. Peter Anvin - All Rights Reserved
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -111,7 +111,6 @@
int main(int argc, char *argv[])
{
int i;
- int err = 0;
program = argv[0];