Special handling of pipe() on alpha
diff --git a/SYSCALLS b/SYSCALLS
index 7815050..62a3471 100644
--- a/SYSCALLS
+++ b/SYSCALLS
@@ -74,7 +74,7 @@
<!alpha> int utime(const char *, struct utimbuf *)
int mkdir(const char *, mode_t)
int rmdir(const char *)
-<!mips,mips64> int pipe(int *)
+<!alpha,mips,mips64> int pipe(int *)
mode_t umask(mode_t)
int chroot(const char *)
int symlink(const char *, const char *)
diff --git a/arch/alpha/Makefile.inc b/arch/alpha/Makefile.inc
index b8ab8b1..a29c48c 100644
--- a/arch/alpha/Makefile.inc
+++ b/arch/alpha/Makefile.inc
@@ -24,7 +24,8 @@
arch/$(ARCH)/__divlu.o \
arch/$(ARCH)/__remlu.o \
arch/$(ARCH)/__divl.o \
- arch/$(ARCH)/__reml.o
+ arch/$(ARCH)/__reml.o \
+ arch/$(ARCH)/pipe.o
ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
diff --git a/arch/alpha/pipe.c b/arch/alpha/pipe.c
new file mode 100644
index 0000000..8c587a9
--- /dev/null
+++ b/arch/alpha/pipe.c
@@ -0,0 +1,29 @@
+#include <unistd.h>
+#include <sys/syscall.h>
+
+/* pipe() on alpha returns both file descriptors in registers --
+ $0 and $20 respectively. This is unlike any other system call,
+ as far as I can tell. */
+
+int pipe(int *fds)
+{
+ long sc_err;
+ register long sc_0 __asm__("$0");
+ register long sc_19 __asm__("$19");
+ register long sc_20 __asm__("$20");
+
+ sc_0 = __NR_pipe;
+ asm volatile("callsys" : "=r" (sc_0), "=r" (sc_19), "=r" (sc_20)
+ : "0" (sc_0)
+ : _syscall_clobbers);
+
+ if ( sc_19 ) {
+ errno = sc_19;
+ return -1;
+ }
+
+ fds[0] = sc_0;
+ fds[1] = sc_20;
+
+ return 0;
+}
diff --git a/klibc/SYSCALLS b/klibc/SYSCALLS
index 7815050..62a3471 100644
--- a/klibc/SYSCALLS
+++ b/klibc/SYSCALLS
@@ -74,7 +74,7 @@
<!alpha> int utime(const char *, struct utimbuf *)
int mkdir(const char *, mode_t)
int rmdir(const char *)
-<!mips,mips64> int pipe(int *)
+<!alpha,mips,mips64> int pipe(int *)
mode_t umask(mode_t)
int chroot(const char *)
int symlink(const char *, const char *)
diff --git a/klibc/arch/alpha/Makefile.inc b/klibc/arch/alpha/Makefile.inc
index b8ab8b1..a29c48c 100644
--- a/klibc/arch/alpha/Makefile.inc
+++ b/klibc/arch/alpha/Makefile.inc
@@ -24,7 +24,8 @@
arch/$(ARCH)/__divlu.o \
arch/$(ARCH)/__remlu.o \
arch/$(ARCH)/__divl.o \
- arch/$(ARCH)/__reml.o
+ arch/$(ARCH)/__reml.o \
+ arch/$(ARCH)/pipe.o
ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
diff --git a/klibc/arch/alpha/pipe.c b/klibc/arch/alpha/pipe.c
new file mode 100644
index 0000000..8c587a9
--- /dev/null
+++ b/klibc/arch/alpha/pipe.c
@@ -0,0 +1,29 @@
+#include <unistd.h>
+#include <sys/syscall.h>
+
+/* pipe() on alpha returns both file descriptors in registers --
+ $0 and $20 respectively. This is unlike any other system call,
+ as far as I can tell. */
+
+int pipe(int *fds)
+{
+ long sc_err;
+ register long sc_0 __asm__("$0");
+ register long sc_19 __asm__("$19");
+ register long sc_20 __asm__("$20");
+
+ sc_0 = __NR_pipe;
+ asm volatile("callsys" : "=r" (sc_0), "=r" (sc_19), "=r" (sc_20)
+ : "0" (sc_0)
+ : _syscall_clobbers);
+
+ if ( sc_19 ) {
+ errno = sc_19;
+ return -1;
+ }
+
+ fds[0] = sc_0;
+ fds[1] = sc_20;
+
+ return 0;
+}