Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/kern/syscall/dup2.c
2098 views
1
#include <types.h>
2
#include <lib.h>
3
#include <kern/errno.h>
4
#include <filedesc.h>
5
#include <file.h>
6
#include <current.h>
7
#include <syscall.h>
8
9
int
10
sys_dup2( int oldfd, int newfd, int *retval ) {
11
struct proc *p = NULL;
12
struct file *f_old = NULL;
13
struct file *f_new = NULL;
14
int err;
15
16
KASSERT( curthread != NULL );
17
KASSERT( curthread->td_proc != NULL );
18
19
p = curthread->td_proc;
20
21
//make sure both file handles are valid
22
if( (oldfd < 0 || newfd < 0) || (newfd >= MAX_OPEN_FILES) )
23
return EBADF;
24
25
//get the old file
26
err = file_get( p, oldfd, &f_old );
27
if( err )
28
return EBADF;
29
30
//if the new-file already exists
31
//we must close it.
32
if( file_descriptor_exists( p, newfd ) ) {
33
err = file_close_descriptor( p, newfd );
34
//if we had a problem closing, dup2()
35
//cannot continue running.
36
if( err ) {
37
F_UNLOCK( f_old );
38
return err;
39
}
40
}
41
42
//at this point, we simply copy the pointers.
43
f_new = f_old;
44
45
//attach f_new into newfd
46
err = fd_attach_into( p->p_fd, f_new, newfd );
47
if( err ) {
48
F_UNLOCK( f_old );
49
return err;
50
}
51
52
//increase the reference count.
53
f_old->f_refcount++;
54
VOP_INCREF(f_old->f_vnode);
55
56
//unlock and return
57
F_UNLOCK( f_old );
58
*retval = newfd;
59
60
return 0;
61
}
62
63