Kernel, libc: Add dup2()
This commit is contained in:
parent
af46b8d9ac
commit
af452e2b2a
@ -63,6 +63,6 @@ int main()
|
||||
{
|
||||
msleep(100);
|
||||
}
|
||||
if (result == child) { return 0; }
|
||||
if (result == child) return 0;
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ int main()
|
||||
perror("getchar");
|
||||
return 1;
|
||||
}
|
||||
if (feof(stdin)) { return 0; }
|
||||
if (feof(stdin)) return 0;
|
||||
assert(false); // we should never get here
|
||||
}
|
||||
command_concat_char(&shell_command, (char)c);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define SYS_pstat 21
|
||||
#define SYS_getdents 22
|
||||
#define SYS_stat 23
|
||||
#define SYS_dup2 24
|
||||
|
||||
struct stat;
|
||||
struct pstat;
|
||||
@ -59,4 +60,5 @@ void sys_access(Context* context, const char* path, int amode);
|
||||
void sys_fstat(Context* context, int fd, struct stat* buf);
|
||||
void sys_pstat(Context* context, long pid, struct pstat* buf);
|
||||
void sys_getdents(Context* context, int fd, struct luna_dirent* buf, size_t count);
|
||||
void sys_stat(Context* context, const char* path, struct stat* buf);
|
||||
void sys_stat(Context* context, const char* path, struct stat* buf);
|
||||
void sys_dup2(Context* context, int fd, int fd2);
|
@ -36,6 +36,7 @@ void Syscall::entry(Context* context)
|
||||
case SYS_getdents:
|
||||
sys_getdents(context, (int)context->rdi, (struct luna_dirent*)context->rsi, (size_t)context->rdx);
|
||||
break;
|
||||
case SYS_dup2: sys_dup2(context, (int)context->rdi, (int)context->rsi); break;
|
||||
default: context->rax = -ENOSYS; break;
|
||||
}
|
||||
VMM::exit_syscall_context();
|
||||
|
@ -201,7 +201,7 @@ void sys_read(Context* context, int fd, size_t size, char* buffer)
|
||||
}
|
||||
int err;
|
||||
Descriptor* file = Scheduler::current_task()->descriptor_from_fd(fd, err);
|
||||
if (!err)
|
||||
if (!file)
|
||||
{
|
||||
context->rax = -err;
|
||||
return;
|
||||
@ -270,4 +270,30 @@ void sys_access(Context* context, const char* path, int) // FIXME: Use the amode
|
||||
else
|
||||
context->rax = 0;
|
||||
kfree(kpath);
|
||||
}
|
||||
|
||||
void sys_dup2(Context* context, int fd, int fd2)
|
||||
{
|
||||
int err;
|
||||
Descriptor* file1 = Scheduler::current_task()->descriptor_from_fd(fd, err);
|
||||
if (!file1)
|
||||
{
|
||||
context->rax = -err;
|
||||
return;
|
||||
}
|
||||
if (!file1->is_open())
|
||||
{
|
||||
context->rax = -EBADF;
|
||||
return;
|
||||
}
|
||||
Descriptor* file2 = Scheduler::current_task()->descriptor_from_fd(fd2, err);
|
||||
if (!file2)
|
||||
{
|
||||
context->rax = -err;
|
||||
return;
|
||||
}
|
||||
if (file2->is_open()) file2->close();
|
||||
*file2 = *file1;
|
||||
kinfoln("dup2(): overwrote fd %d with fd %d", fd2, fd);
|
||||
context->rax = fd2;
|
||||
}
|
@ -25,5 +25,6 @@
|
||||
#define SYS_pstat 21
|
||||
#define SYS_getdents 22
|
||||
#define SYS_stat 23
|
||||
#define SYS_dup2 24
|
||||
|
||||
#endif
|
@ -63,6 +63,9 @@ extern "C"
|
||||
/* Returns a copy of the file descriptor fd. */
|
||||
int dup(int fd);
|
||||
|
||||
/* Causes the file descriptor fd2 to refer to the file descriptor fd. */
|
||||
int dup2(int fd, int fd2);
|
||||
|
||||
/* Checks if the current program can access the file or directory at path. */
|
||||
int access(const char* path, int amode);
|
||||
|
||||
|
@ -25,6 +25,7 @@ extern "C" long syscall(long number, ...)
|
||||
case SYS_access:
|
||||
case SYS_fstat:
|
||||
case SYS_stat:
|
||||
case SYS_dup2:
|
||||
case SYS_pstat:
|
||||
case SYS_open: {
|
||||
arg arg0 = va_arg(ap, arg);
|
||||
|
@ -73,6 +73,11 @@ extern "C"
|
||||
return fcntl(fd, F_DUPFD, 0);
|
||||
}
|
||||
|
||||
int dup2(int fd, int fd2)
|
||||
{
|
||||
return (int)syscall(SYS_dup2, fd, fd2);
|
||||
}
|
||||
|
||||
int access(const char* path, int amode)
|
||||
{
|
||||
return (int)syscall(SYS_access, path, amode);
|
||||
|
Loading…
Reference in New Issue
Block a user