Merge with git://charm.itp.tuwien.ac.at/mattems/klibc/.git#maks
diff --git a/README b/README
index eb72e1c..8a988f1 100644
--- a/README
+++ b/README
@@ -11,11 +11,22 @@
 
 	http://www.zytor.com/mailman/listinfo/klibc/
 
-There is also a cvsweb repository at:
+klibc is maintained in the git version control system.  The git
+repository can be viewed on the web at:
 
-	http://www.zytor.com/cvsweb.cgi/klibc/
+	http://www.kernel.org/git/?p=libs/klibc/klibc.git;a=summary
 
-There is no direct public CVS access yet, however, the CVS repository
-is available for rsync from:
+To clone the klibc repository using Cogito:
 
-	rsync://rsync.kernel.org/pub/linux/libs/klibc/cvsroot/
+	git clone git://git.kernel.org/pub/scm/libs/klibc/klibc.git <workdir>
+
+To update an already cloned tree:
+
+	git pull
+
+For more information on git, see:
+
+	http://git.or.cz/
+	http://www.kernel.org/pub/software/scm/git/docs/tutorial.html
+	http://www.kernel.org/pub/software/scm/git/docs
+
diff --git a/klcc/klcc.in b/klcc/klcc.in
index a7bccd8..d4313a5 100644
--- a/klcc/klcc.in
+++ b/klcc/klcc.in
@@ -180,8 +180,12 @@
 	$strip = 1;
     } elsif ( $a eq '-o' ) {
 	$output = shift(@ARGV);
-    } elsif ( $a eq '-x' ) {
-	$lang = shift(@ARGV);
+    } elsif ( $a =~ /^\-x(.*)$/ ) {
+	# -x can be conjoined or disjoined
+	$lang = $1;
+	if ( $lang eq '' ) {
+	    $lang = shift(@ARGV);
+	}
     } elsif ( $a eq '-nostdinc' ) {
 	push(@ccopt, $a);
 	@includes = ();
diff --git a/scripts/Kbuild.klibc b/scripts/Kbuild.klibc
index 3aa40cd..bbb86f4 100644
--- a/scripts/Kbuild.klibc
+++ b/scripts/Kbuild.klibc
@@ -17,10 +17,10 @@
 # If the userspace program consist of composite files do the following:
 # Kbuild:
 #
-# static-y   := kinit
-# kinit-y := main.o netdev.c
-# So ipconfig will be linked statically using the two .o files
-# specified with ipconfig-y.
+# static-y := kinit
+# kinit-y  := main.o netdev.c
+# So kinit will be linked statically using the two .o files
+# specified with kinit-y.
 #
 # Are part of the program located in a sub-directory do like this:
 # kinit-y += ipconfig/
@@ -28,6 +28,9 @@
 # And in the subdirectory:
 # ipconfig/Kbuild:
 # lib-y := packet.o dhcp_proto.o
+# # All .o files listed with lib-y will be used to create a single .a file.
+# # The .a file is created before any subdirectories are visited so it
+# # may be used in the sub-directory programs.
 #
 #####
 # For a klibc libary file do like this
@@ -174,7 +177,7 @@
 output-dirs := $(dir $(kprog-dirs) $(kprog-objs))
 output-dirs += $(foreach f, $(hostprogs-y) $(targets), \
                $(if $(dir $(f)), $(dir $(f))))
-output-dirs += $(klib-dirs)
+output-dirs += $(dir $(klib-objs))
 output-dirs := $(strip $(sort $(filter-out ./,$(output-dirs))))
 
 # prefix so we get full dir
@@ -313,15 +316,18 @@
 
 stripobj  = $(subst $(obj)/,,$@)
 addliba   = $(addprefix $(obj)/, $(patsubst %/, %/lib.a, $(1)))
-link-deps = $(if $($(stripobj)-y), $(call addliba, $($(stripobj)-y)), $@.o)
+link-deps = $(if $($(stripobj)-y), $(call addliba, $($(stripobj)-y)), $@.o) \
+	    $(call objectify,$($(stripobj)-lib))
 
 quiet_cmd_ld-static = KLIBCLD $@
       cmd_ld-static = $(KLIBCLD) $(KLIBCLDFLAGS) -o $@		\
                        $(EXTRA_KLIBCLDFLAGS)			\
                        $(KLIBCCRT0)				\
+		       --start-group				\
                        $(link-deps)				\
-                       --start-group $(KLIBCLIBC)		\
-		       $(KLIBCLIBGCC) --end-group ;		\
+                       $(KLIBCLIBC)				\
+		       $(KLIBCLIBGCC)				\
+		       --end-group ;				\
                       cp -f $@ $@.g ;				\
                       $(KLIBCSTRIP) $(KLIBCSTRIPFLAGS) $@
 
@@ -333,9 +339,11 @@
       cmd_ld-shared = $(KLIBCLD) $(KLIBCLDFLAGS) -o $@		\
                        $(EXTRA_KLIBCLDFLAGS)			\
                        $(KLIBCEMAIN) $(KLIBCCRTSHARED)		\
+                       --start-group				\
                        $(link-deps)				\
-                       --start-group -R $(KLIBCLIBCSHARED)	\
-	               $(KLIBCLIBGCC) --end-group ;		\
+                       -R $(KLIBCLIBCSHARED)			\
+	               $(KLIBCLIBGCC)				\
+		       --end-group ;				\
                       cp -f $@ $@.g ;				\
                       $(KLIBCSTRIP) $(KLIBCSTRIPFLAGS) $@
 
@@ -363,7 +371,7 @@
 # ---------------------------------------------------------------------------
 
 .PHONY: $(subdir-y) $(kprog-dirs) $(klib-dirs)
-$(sort $(subdir-y) $(kprog-dirs) $(klib-dirs)):
+$(sort $(subdir-y) $(kprog-dirs) $(klib-dirs)): $(lib-target)
 	$(Q)$(MAKE) $(klibc)=$@
 
 # Add FORCE to the prequisites of a target to force it to be always rebuilt.
diff --git a/usr/include/sys/mman.h b/usr/include/sys/mman.h
index c146ec8..56f0b65 100644
--- a/usr/include/sys/mman.h
+++ b/usr/include/sys/mman.h
@@ -14,6 +14,8 @@
 __extern void *mmap(void *, size_t, int, int, int, off_t);
 __extern int munmap(void *, size_t);
 __extern void *mremap(void *, size_t, size_t, unsigned long);
+__extern int shm_open(const char *, int, mode_t);
+__extern int shm_unlink(const char *);
 __extern int msync(const void *, size_t, int);
 __extern int mprotect(const void *, size_t, int);
 __extern int mlockall(int);
diff --git a/usr/include/unistd.h b/usr/include/unistd.h
index dadb63d..4df42d6 100644
--- a/usr/include/unistd.h
+++ b/usr/include/unistd.h
@@ -86,6 +86,7 @@
 __extern int open(const char *, int, ...);
 __extern int openat(int, const char *, int, ...);
 #endif
+__extern int open_cloexec(const char *, int, mode_t);
 __extern int close(int);
 __extern off_t lseek(int, off_t, int);
 /* off_t is 64 bits now even on 32-bit platforms; see llseek.c */
diff --git a/usr/kinit/Kbuild b/usr/kinit/Kbuild
index 59db29b..ff1d449 100644
--- a/usr/kinit/Kbuild
+++ b/usr/kinit/Kbuild
@@ -2,9 +2,13 @@
 # Kbuild file for kinit
 #
 
-static-y := kinit
-kinit-y  := kinit.o do_mounts.o ramdisk_load.o initrd.o
-kinit-y  += getintfile.o open.o readfile.o xpio.o
+# library part of kinit. Is used by programs in sub-directories (resume et al)
+lib-y   := name_to_dev.o devname.o getarg.o
+# use lib for kinit
+kinit-y  := lib.a
+
+kinit-y  += kinit.o do_mounts.o ramdisk_load.o initrd.o
+kinit-y  += getintfile.o readfile.o xpio.o
 kinit-y  += do_mounts_md.o do_mounts_mtd.o nfsroot.o
 
 kinit-y  += ipconfig/
@@ -13,6 +17,7 @@
 kinit-y  += fstype/
 kinit-y  += resume/
 
+static-y := kinit
 shared-y := kinit.shared
 kinit.shared-y := $(kinit-y)
 
@@ -24,7 +29,7 @@
  	       -I$(srctree)/$(src)/run-init
 
 # Cleaning
-targets := kinit kinit.g kinit.shared kinit.shared.g
+targets += kinit kinit.g kinit.shared kinit.shared.g
 subdir- := fstype ipconfig nfsmount resume run-init
 
 
diff --git a/usr/kinit/kinit.h b/usr/kinit/kinit.h
index 03cc358..895f920 100644
--- a/usr/kinit/kinit.h
+++ b/usr/kinit/kinit.h
@@ -25,8 +25,6 @@
 char *get_arg(int argc, char *argv[], const char *name);
 int get_flag(int argc, char *argv[], const char *name);
 
-int open_cloexec(const char *path, int flags, mode_t mode);
-
 int getintfile(const char *path, long *val);
 
 ssize_t readfile(const char *path, char **pptr);
diff --git a/usr/kinit/resume/Kbuild b/usr/kinit/resume/Kbuild
index ce6d0ce..034195d 100644
--- a/usr/kinit/resume/Kbuild
+++ b/usr/kinit/resume/Kbuild
@@ -6,20 +6,22 @@
 shared-y := shared/resume
 
 # common .o files
-objs := resume.o resumelib.o ../getarg.o ../name_to_dev.o ../devname.o
+objs := resume.o resumelib.o
 
 # TODO - do we want a stripped version
 # TODO - do we want the static.g + shared.g directories?
 
-# Create built-in.o with all object files (used by kinit)
+# Create lib.a with all object files (used by kinit)
 lib-y := $(objs)
 
 # Additional include paths files
 KLIBCCFLAGS += -I$(srctree)/$(src)/..
 
 # .o files used to built executables
-static/resume-y := $(objs)
-shared/resume-y := $(objs)
+static/resume-y   := $(objs)
+static/resume-lib := ../lib.a
+shared/resume-y   := $(objs)
+shared/resume-lib := ../lib.a
 
 # Cleaning
 clean-dirs := static shared
diff --git a/usr/kinit/resume/resumelib.c b/usr/kinit/resume/resumelib.c
index ce5c2b2..ba1e339 100644
--- a/usr/kinit/resume/resumelib.c
+++ b/usr/kinit/resume/resumelib.c
@@ -12,7 +12,6 @@
 #include <limits.h>
 #include <sys/stat.h>
 #include <sys/sysmacros.h>
-#include <linux/config.h>	/* For CONFIG_PM_STD_PARTITION */
 
 #include "kinit.h"
 #include "do_mounts.h"
diff --git a/usr/klibc/Kbuild b/usr/klibc/Kbuild
index c2bfd2f..65ca2e4 100644
--- a/usr/klibc/Kbuild
+++ b/usr/klibc/Kbuild
@@ -18,7 +18,8 @@
 	  setpgrp.o getpgrp.o daemon.o \
 	  printf.o vprintf.o fprintf.o vfprintf.o perror.o \
 	  statfs.o fstatfs.o umount.o \
-	  open.o openat.o fopen.o fread.o fread2.o fgetc.o fgets.o \
+	  open.o openat.o open_cloexec.o \
+	  fopen.o fread.o fread2.o fgetc.o fgets.o \
 	  fwrite.o fwrite2.o fputc.o fputs.o puts.o putchar.o \
 	  sleep.o usleep.o strtotimespec.o strtotimeval.o \
 	  raise.o abort.o assert.o alarm.o pause.o \
@@ -26,7 +27,8 @@
 	  siglongjmp.o \
 	  sigaction.o sigpending.o sigprocmask.o sigsuspend.o \
 	  pselect.o ppoll.o \
-	  brk.o sbrk.o malloc.o realloc.o calloc.o mmap.o \
+	  brk.o sbrk.o malloc.o realloc.o calloc.o \
+	  mmap.o shm_open.o shm_unlink.o \
 	  memcpy.o memcmp.o memset.o memccpy.o memmem.o memswap.o \
 	  memmove.o memchr.o memrchr.o \
 	  strcasecmp.o strncasecmp.o strndup.o strerror.o strsignal.o \
diff --git a/usr/klibc/arch/parisc/Kbuild b/usr/klibc/arch/parisc/Kbuild
index d57a873..57ca5c2 100644
--- a/usr/klibc/arch/parisc/Kbuild
+++ b/usr/klibc/arch/parisc/Kbuild
@@ -2,7 +2,7 @@
 # klibc files for parisc
 #
 
-klib-y := setjmp.o syscall.o
+klib-y := setjmp.o syscall.o vfork.o
 
 always  := crt0.o
 targets := crt0.o
diff --git a/usr/klibc/arch/parisc/vfork.S b/usr/klibc/arch/parisc/vfork.S
new file mode 100644
index 0000000..97ebc8f
--- /dev/null
+++ b/usr/klibc/arch/parisc/vfork.S
@@ -0,0 +1,31 @@
+/*
+ * arch/parisc/vfork.S, "vfork() me harder. ugh." -- kyle
+ *
+ * %r20 contains the system call number, %rp contains whence we came,
+ * %rp is saved and restored across the syscall, thankfully.
+ *
+ */
+
+	.text
+	.align 64				; cache-width aligned
+	.globl	vfork
+	.type	vfork,@function
+vfork:
+	/* pid_t vfork(void) */
+	ble		0x100(%sr2, %r0)	; jump to gateway page
+	nop
+
+	ldi		-0x1000,%r19		; %r19 = -4096
+	sub		%r0,%ret0,%r22		; %r22 = -%ret0
+	cmpb,>>=,n	%r19,%ret0,1f		; if %ret0 >= -4096UL
+	ldi		-1,%ret0		; nullified on taken forward
+
+	/* store %r22 to errno... */
+	ldil		L%errno,%r1
+	ldo		R%errno(%r1),%r1
+	stw		%r22,0(%r1)
+1:
+	bv		%r0(%rp)		; jump back
+	nop
+
+	.size vfork,.-vfork
diff --git a/usr/klibc/arch/ppc/Kbuild b/usr/klibc/arch/ppc/Kbuild
index 13612ce..699380f 100644
--- a/usr/klibc/arch/ppc/Kbuild
+++ b/usr/klibc/arch/ppc/Kbuild
@@ -2,7 +2,7 @@
 # klibc files for ppc
 #
 
-klib-y := arch/$(KLIBCARCH)/setjmp.o arch/$(KLIBCARCH)/syscall.o
+klib-y := setjmp.o syscall.o
 
 klib-y += ../../libgcc/__divdi3.o     ../../libgcc/__moddi3.o
 klib-y += ../../libgcc/__udivdi3.o    ../../libgcc/__umoddi3.o
diff --git a/usr/kinit/open.c b/usr/klibc/open_cloexec.c
similarity index 92%
rename from usr/kinit/open.c
rename to usr/klibc/open_cloexec.c
index f53e2f1..e30b09d 100644
--- a/usr/kinit/open.c
+++ b/usr/klibc/open_cloexec.c
@@ -1,5 +1,5 @@
 /*
- * open.c
+ * open_cloexec.c
  *
  * A quick hack to do an open() and set the cloexec flag
  */
diff --git a/usr/klibc/shm_open.c b/usr/klibc/shm_open.c
new file mode 100644
index 0000000..8fe93aa
--- /dev/null
+++ b/usr/klibc/shm_open.c
@@ -0,0 +1,23 @@
+/*
+ * shm_open.c
+ *
+ * POSIX shared memory support
+ */
+
+#include <stdlib.h>
+#include <alloca.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+
+int shm_open(const char *path, int oflag, mode_t mode)
+{
+	int len = strlen(path);
+	char *pathbuf = alloca(len+10);
+
+	memcpy(pathbuf, "/dev/shm/", 9);
+	memcpy(pathbuf+9, path, len+1);
+
+	return open_cloexec(path, oflag, mode);
+}
diff --git a/usr/klibc/shm_unlink.c b/usr/klibc/shm_unlink.c
new file mode 100644
index 0000000..94a98a0
--- /dev/null
+++ b/usr/klibc/shm_unlink.c
@@ -0,0 +1,23 @@
+/*
+ * shm_unlink.c
+ *
+ * POSIX shared memory support
+ */
+
+#include <stdlib.h>
+#include <alloca.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+
+int shm_unlink(const char *path)
+{
+	int len = strlen(path);
+	char *pathbuf = alloca(len+10);
+
+	memcpy(pathbuf, "/dev/shm/", 9);
+	memcpy(pathbuf+9, path, len+1);
+
+	return unlink(path);
+}
diff --git a/usr/klibc/strtok.c b/usr/klibc/strtok.c
index 24aaad0..c2671af 100644
--- a/usr/klibc/strtok.c
+++ b/usr/klibc/strtok.c
@@ -11,5 +11,9 @@
 	if (s)
 		holder = s;
 
-	return strsep(&holder, delim);
+	do {
+		s = strsep(&holder, delim);
+	} while (s && !*s);
+
+	return s;
 }
diff --git a/usr/klibc/version b/usr/klibc/version
index f86e029..771411b 100644
--- a/usr/klibc/version
+++ b/usr/klibc/version
@@ -1 +1 @@
-1.4.12
+1.4.20