1 /* This file contains the code for performing four system calls relating to
2 * status and directories.
4 * The entry points into this file are
5 * do_chdir: perform the CHDIR system call
6 * do_chroot: perform the CHROOT system call
7 * do_lstat: perform the LSTAT system call
8 * do_stat: perform the STAT system call
9 * do_fstat: perform the FSTAT system call
10 * do_fstatfs: perform the FSTATFS system call
15 #include <sys/statfs.h>
16 #include <minix/com.h>
17 #include <minix/u64.h>
22 #include <minix/vfsif.h>
26 FORWARD
_PROTOTYPE( int change
, (struct vnode
**iip
, char *name_ptr
, int len
));
27 FORWARD
_PROTOTYPE( int change_into
, (struct vnode
**iip
, struct vnode
*vp
));
30 /*===========================================================================*
32 *===========================================================================*/
33 PUBLIC
int do_fchdir()
35 /* Change directory on already-opened fd. */
38 /* Is the file descriptor valid? */
39 if ((rfilp
= get_filp(m_in
.fd
)) == NIL_FILP
) return(err_code
);
40 dup_vnode(rfilp
->filp_vno
); /* Change into expects a reference. */
41 return change_into(&fp
->fp_wd
, rfilp
->filp_vno
);
45 /*===========================================================================*
47 *===========================================================================*/
50 /* Perform the chdir(name) system call. */
52 return change(&fp
->fp_wd
, m_in
.name
, m_in
.name_length
);
56 /*===========================================================================*
58 *===========================================================================*/
59 PUBLIC
int do_chroot()
61 /* Perform the chroot(name) system call. */
63 if (!super_user
) return(EPERM
); /* only su may chroot() */
64 return change(&fp
->fp_rd
, m_in
.name
, m_in
.name_length
);
68 /*===========================================================================*
70 *===========================================================================*/
71 PRIVATE
int change(iip
, name_ptr
, len
)
72 struct vnode
**iip
; /* pointer to the inode pointer for the dir */
73 char *name_ptr
; /* pointer to the directory name to change to */
74 int len
; /* length of the directory name string */
76 /* Do the actual work for chdir() and chroot(). */
80 /* Try to open the directory */
81 if (fetch_name(name_ptr
, len
, M3
) != OK
) return(err_code
);
82 if ((vp
= eat_path(PATH_NOFLAGS
)) == NIL_VNODE
) return(err_code
);
83 return change_into(iip
, vp
);
87 /*===========================================================================*
89 *===========================================================================*/
90 PRIVATE
int change_into(iip
, vp
)
91 struct vnode
**iip
; /* pointer to the inode pointer for the dir */
92 struct vnode
*vp
; /* this is what the inode has to become */
96 /* It must be a directory and also be searchable */
97 if ((vp
->v_mode
& I_TYPE
) != I_DIRECTORY
)
100 r
= forbidden(vp
, X_BIT
); /* Check if dir is searchable*/
102 /* If error, return vnode */
108 /* Everything is OK. Make the change. */
109 put_vnode(*iip
); /* release the old directory */
110 *iip
= vp
; /* acquire the new one */
115 /*===========================================================================*
117 *===========================================================================*/
120 /* Perform the stat(name, buf) system call. */
124 if (fetch_name(m_in
.name1
, m_in
.name1_length
, M1
) != OK
) return(err_code
);
125 if ((vp
= eat_path(PATH_NOFLAGS
)) == NIL_VNODE
) return(err_code
);
126 r
= req_stat(vp
->v_fs_e
, vp
->v_inode_nr
, who_e
, m_in
.name2
, 0);
133 /*===========================================================================*
135 *===========================================================================*/
136 PUBLIC
int do_fstat()
138 /* Perform the fstat(fd, buf) system call. */
139 register struct filp
*rfilp
;
142 /* Is the file descriptor valid? */
143 if ((rfilp
= get_filp(m_in
.fd
)) == NIL_FILP
) return(err_code
);
145 /* If we read from a pipe, send position too */
146 if (rfilp
->filp_vno
->v_pipe
== I_PIPE
) {
147 if (rfilp
->filp_mode
& R_BIT
)
148 if (ex64hi(rfilp
->filp_pos
) != 0) {
149 panic("do_fstat: bad position in pipe");
151 pipe_pos
= ex64lo(rfilp
->filp_pos
);
154 return req_stat(rfilp
->filp_vno
->v_fs_e
, rfilp
->filp_vno
->v_inode_nr
,
155 who_e
, m_in
.buffer
, pipe_pos
);
159 /*===========================================================================*
161 *===========================================================================*/
162 PUBLIC
int do_fstatfs()
164 /* Perform the fstatfs(fd, buf) system call. */
167 /* Is the file descriptor valid? */
168 if( (rfilp
= get_filp(m_in
.fd
)) == NIL_FILP
) return(err_code
);
170 return req_fstatfs(rfilp
->filp_vno
->v_fs_e
, who_e
, m_in
.buffer
);
174 /*===========================================================================*
176 *===========================================================================*/
177 PUBLIC
int do_lstat()
179 /* Perform the lstat(name, buf) system call. */
183 if (fetch_name(m_in
.name1
, m_in
.name1_length
, M1
) != OK
) return(err_code
);
184 if ((vp
= eat_path(PATH_RET_SYMLINK
)) == NIL_VNODE
) return(err_code
);
185 r
= req_stat(vp
->v_fs_e
, vp
->v_inode_nr
, who_e
, m_in
.name2
, 0);