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