Kernel/LibC: add basic dup2
This commit is contained in:
parent
4eb95c963d
commit
a549336530
|
@ -85,6 +85,7 @@ namespace Kernel
|
||||||
BAN::ErrorOr<long> sys_creat(BAN::StringView name, mode_t);
|
BAN::ErrorOr<long> sys_creat(BAN::StringView name, mode_t);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_pipe(int fildes[2]);
|
BAN::ErrorOr<long> sys_pipe(int fildes[2]);
|
||||||
|
BAN::ErrorOr<long> sys_dup2(int fildes, int fildes2);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_seek(int fd, off_t offset, int whence);
|
BAN::ErrorOr<long> sys_seek(int fd, off_t offset, int whence);
|
||||||
BAN::ErrorOr<long> sys_tell(int fd);
|
BAN::ErrorOr<long> sys_tell(int fd);
|
||||||
|
|
|
@ -135,8 +135,13 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
m_threads.clear();
|
m_threads.clear();
|
||||||
for (auto& open_fd : m_open_files)
|
|
||||||
open_fd.inode = nullptr;
|
for (int fd = 0; fd < (int)m_open_files.size(); fd++)
|
||||||
|
{
|
||||||
|
if (validate_fd(fd).is_error())
|
||||||
|
continue;
|
||||||
|
(void)sys_close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: We must unmap ranges while the page table is still alive
|
// NOTE: We must unmap ranges while the page table is still alive
|
||||||
for (auto* range : m_mapped_ranges)
|
for (auto* range : m_mapped_ranges)
|
||||||
|
@ -624,6 +629,34 @@ namespace Kernel
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<long> Process::sys_dup2(int fildes, int fildes2)
|
||||||
|
{
|
||||||
|
// FIXME: m_open_files should be BAN::Array<BAN::RefPtr<OpenFileDescription>, OPEN_MAX> for accurate dup2
|
||||||
|
|
||||||
|
if (fildes2 < 0 || fildes2 >= 100)
|
||||||
|
return BAN::Error::from_errno(EBADF);
|
||||||
|
|
||||||
|
LockGuard _(m_lock);
|
||||||
|
|
||||||
|
TRY(validate_fd(fildes));
|
||||||
|
if (fildes == fildes2)
|
||||||
|
return fildes;
|
||||||
|
|
||||||
|
if (m_open_files.size() <= (size_t)fildes2)
|
||||||
|
TRY(m_open_files.resize(fildes2 + 1));
|
||||||
|
|
||||||
|
if (!validate_fd(fildes2).is_error())
|
||||||
|
TRY(sys_close(fildes2));
|
||||||
|
|
||||||
|
m_open_files[fildes2] = m_open_files[fildes];
|
||||||
|
m_open_files[fildes2].flags &= ~O_CLOEXEC;
|
||||||
|
|
||||||
|
if (m_open_files[fildes].flags & O_WRONLY && m_open_files[fildes].inode->is_pipe())
|
||||||
|
((Pipe*)m_open_files[fildes].inode.ptr())->clone_writing();
|
||||||
|
|
||||||
|
return fildes;
|
||||||
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_seek(int fd, off_t offset, int whence)
|
BAN::ErrorOr<long> Process::sys_seek(int fd, off_t offset, int whence)
|
||||||
{
|
{
|
||||||
LockGuard _(m_lock);
|
LockGuard _(m_lock);
|
||||||
|
|
|
@ -135,6 +135,9 @@ namespace Kernel
|
||||||
case SYS_PIPE:
|
case SYS_PIPE:
|
||||||
ret = Process::current().sys_pipe((int*)arg1);
|
ret = Process::current().sys_pipe((int*)arg1);
|
||||||
break;
|
break;
|
||||||
|
case SYS_DUP2:
|
||||||
|
ret = Process::current().sys_dup2((int)arg1, (int)arg2);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dwarnln("Unknown syscall {}", syscall);
|
dwarnln("Unknown syscall {}", syscall);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -40,6 +40,7 @@ __BEGIN_DECLS
|
||||||
#define SYS_SET_PWD 33
|
#define SYS_SET_PWD 33
|
||||||
#define SYS_CLOCK_GETTIME 34
|
#define SYS_CLOCK_GETTIME 34
|
||||||
#define SYS_PIPE 35
|
#define SYS_PIPE 35
|
||||||
|
#define SYS_DUP2 36
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -257,6 +257,13 @@ long syscall(long syscall, ...)
|
||||||
ret = Kernel::syscall(SYS_PIPE, (uintptr_t)fildes);
|
ret = Kernel::syscall(SYS_PIPE, (uintptr_t)fildes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SYS_DUP2:
|
||||||
|
{
|
||||||
|
int fildes = va_arg(args, int);
|
||||||
|
int fildes2 = va_arg(args, int);
|
||||||
|
ret = Kernel::syscall(SYS_DUP2, fildes, fildes2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
puts("LibC: Unhandeled syscall");
|
puts("LibC: Unhandeled syscall");
|
||||||
ret = -ENOSYS;
|
ret = -ENOSYS;
|
||||||
|
@ -289,6 +296,11 @@ ssize_t write(int fildes, const void* buf, size_t nbyte)
|
||||||
return syscall(SYS_WRITE, fildes, buf, nbyte);
|
return syscall(SYS_WRITE, fildes, buf, nbyte);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dup2(int fildes, int fildes2)
|
||||||
|
{
|
||||||
|
return syscall(SYS_DUP2, fildes, fildes2);
|
||||||
|
}
|
||||||
|
|
||||||
int execl(const char* pathname, const char* arg0, ...)
|
int execl(const char* pathname, const char* arg0, ...)
|
||||||
{
|
{
|
||||||
if (arg0 == nullptr)
|
if (arg0 == nullptr)
|
||||||
|
|
Loading…
Reference in New Issue