diff --git a/libc/Makefile b/libc/Makefile index d48c6904..55af2be9 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -124,6 +124,7 @@ $(CPUDIR)/signal.o \ $(CPUDIR)/syscall.o \ dispmsg_issue.o \ dlfcn.o \ +dup2.o \ dup.o \ env.o \ errorprint.o \ diff --git a/libc/dup2.cpp b/libc/dup2.cpp new file mode 100644 index 00000000..6c9264ec --- /dev/null +++ b/libc/dup2.cpp @@ -0,0 +1,33 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2012. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + dup2.cpp + Duplicates a file descriptor. + +*******************************************************************************/ + +#include +#include + +DEFN_SYSCALL2(int, sys_dup2, SYSCALL_DUP2, int, int); + +extern "C" int dup2(int oldfd, int newfd) +{ + return sys_dup2(oldfd, newfd); +} diff --git a/libc/include/unistd.h b/libc/include/unistd.h index b1936082..0640cda6 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -91,7 +91,6 @@ unsigned alarm(unsigned); size_t confstr(int, char*, size_t); char* crypt(const char*, const char*); char* ctermid(char*); -int dup2(int, int); void encrypt(char [64], int); int faccessat(int, const char*, int, int); int fchdir(int); @@ -153,6 +152,7 @@ int access(const char*, int); int chdir(const char*); int chown(const char*, uid_t, gid_t); int close(int); +int dup2(int, int); int dup(int); void _exit(int) __attribute__ ((noreturn)); int execl(const char*, const char*, ...); diff --git a/sortix/include/sortix/syscallnum.h b/sortix/include/sortix/syscallnum.h index 6a19dd6a..08fc24e1 100644 --- a/sortix/include/sortix/syscallnum.h +++ b/sortix/include/sortix/syscallnum.h @@ -81,6 +81,7 @@ #define SYSCALL_CHMOD 57 #define SYSCALL_CHOWN 58 #define SYSCALL_LINK 59 -#define SYSCALL_MAX_NUM 60 /* index of highest constant + 1 */ +#define SYSCALL_DUP2 60 +#define SYSCALL_MAX_NUM 61 /* index of highest constant + 1 */ #endif diff --git a/sortix/io.cpp b/sortix/io.cpp index 081c2c7e..7a5ce2ab 100644 --- a/sortix/io.cpp +++ b/sortix/io.cpp @@ -122,6 +122,12 @@ static int sys_dup(int fd) return dtable->Allocate(desc, 0); } +static int sys_dup2(int oldfd, int newfd) +{ + Ref dtable = CurrentProcess()->GetDTable(); + return dtable->Copy(oldfd, newfd); +} + // TODO: If this function fails the file may still have been created. Does a // standard prohibit this and is that the wrong thing? static int sys_openat(int dirfd, const char* path, int flags, mode_t mode) @@ -424,6 +430,7 @@ void Init() Syscall::Register(SYSCALL_CHOWN, (void*) sys_chown); Syscall::Register(SYSCALL_CLOSE, (void*) sys_close); Syscall::Register(SYSCALL_DUP, (void*) sys_dup); + Syscall::Register(SYSCALL_DUP2, (void*) sys_dup2); Syscall::Register(SYSCALL_FCNTL, (void*) sys_fcntl); Syscall::Register(SYSCALL_FSTATAT, (void*) sys_fstatat); Syscall::Register(SYSCALL_FSTAT, (void*) sys_fstat);