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_stat: perform the STAT system call
8 * do_fstat: perform the FSTAT system call
9 * do_fstatfs: perform the FSTATFS system call
10 * do_lstat: perform the LSTAT system call
13 * Jul 2006 (Balazs Gerofi)
18 #include <sys/statfs.h>
19 #include <minix/com.h>
20 #include <minix/u64.h>
26 #include <minix/vfsif.h>
30 FORWARD
_PROTOTYPE( int change
, (struct vnode
**iip
, char *name_ptr
, int len
));
31 FORWARD
_PROTOTYPE( int change_into
, (struct vnode
**iip
, struct vnode
*vp
));
33 /*===========================================================================*
35 *===========================================================================*/
36 PUBLIC
int do_fchdir()
38 /* Change directory on already-opened fd. */
42 /* Is the file descriptor valid? */
43 if ( (rfilp
= get_filp(m_in
.fd
)) == NIL_FILP
) return(err_code
);
46 if ((rfilp
->filp_vno
->v_mode
& I_TYPE
) != I_DIRECTORY
)
49 /* Issue request and handle error */
50 r
= forbidden(rfilp
->filp_vno
, X_BIT
);
51 if (r
!= OK
) return r
;
53 rfilp
->filp_vno
->v_ref_count
++; /* change_into expects a reference */
55 return change_into(&fp
->fp_wd
, rfilp
->filp_vno
);
58 /*===========================================================================*
60 *===========================================================================*/
63 /* Change directory. This function is also called by MM to simulate a chdir
64 * in order to do EXEC, etc. It also changes the root directory, the uids and
65 * gids, and the umask.
68 register struct fproc
*rfp
;
70 if (who_e
== PM_PROC_NR
) {
72 if(isokendpt(m_in
.endpt1
, &slot
) != OK
)
77 dup_vnode(fp
->fp_rd
= rfp
->fp_rd
);
79 dup_vnode(fp
->fp_wd
= rfp
->fp_wd
);
81 /* MM uses access() to check permissions. To make this work, pretend
82 * that the user's real ids are the same as the user's effective ids.
83 * FS calls other than access() do not use the real ids, so are not
87 fp
->fp_effuid
= rfp
->fp_effuid
;
89 fp
->fp_effgid
= rfp
->fp_effgid
;
90 fp
->fp_umask
= rfp
->fp_umask
;
94 /* Perform the chdir(name) system call. */
95 r
= change(&fp
->fp_wd
, m_in
.name
, m_in
.name_length
);
99 /*===========================================================================*
101 *===========================================================================*/
102 PUBLIC
int do_chroot()
104 /* Perform the chroot(name) system call. */
108 if (!super_user
) return(EPERM
); /* only su may chroot() */
110 r
= change(&fp
->fp_rd
, m_in
.name
, m_in
.name_length
);
115 /*===========================================================================*
117 *===========================================================================*/
118 PRIVATE
int change(iip
, name_ptr
, len
)
119 struct vnode
**iip
; /* pointer to the inode pointer for the dir */
120 char *name_ptr
; /* pointer to the directory name to change to */
121 int len
; /* length of the directory name string */
123 /* Do the actual work for chdir() and chroot(). */
125 struct lookup_req lookup_req
;
128 if (fetch_name(name_ptr
, len
, M3
) != OK
) return(err_code
);
130 /* Fill in lookup request fields */
131 lookup_req
.path
= user_fullpath
;
132 lookup_req
.lastc
= NULL
;
133 lookup_req
.flags
= EAT_PATH
;
136 if ((r
= lookup_vp(&lookup_req
, &vp
)) != OK
) return r
;
139 if ((vp
->v_mode
& I_TYPE
) != I_DIRECTORY
)
146 r
= forbidden(vp
, X_BIT
);
152 return change_into(iip
, vp
);
156 /*===========================================================================*
158 *===========================================================================*/
159 PRIVATE
int change_into(iip
, vp
)
160 struct vnode
**iip
; /* pointer to the inode pointer for the dir */
161 struct vnode
*vp
; /* this is what the inode has to become */
163 /* Everything is OK. Make the change. */
164 put_vnode(*iip
); /* release the old directory */
165 *iip
= vp
; /* acquire the new one */
171 /*===========================================================================*
173 *===========================================================================*/
176 /* Perform the stat(name, buf) system call. */
177 struct node_details res
;
178 struct lookup_req lookup_req
;
181 if (fetch_name(m_in
.name1
, m_in
.name1_length
, M1
) != OK
) return(err_code
);
183 /* Fill in lookup request fields */
184 lookup_req
.path
= user_fullpath
;
185 lookup_req
.lastc
= NULL
;
186 lookup_req
.flags
= EAT_PATH
;
189 if ((r
= lookup(&lookup_req
, &res
)) != OK
) return r
;
192 return req_stat(res
.fs_e
, res
.inode_nr
, who_e
, m_in
.name2
, 0);
197 /*===========================================================================*
199 *===========================================================================*/
200 PUBLIC
int do_fstat()
202 /* Perform the fstat(fd, buf) system call. */
203 register struct filp
*rfilp
;
206 /* Is the file descriptor valid? */
207 if ( (rfilp
= get_filp(m_in
.fd
)) == NIL_FILP
) {
211 /* If we read from a pipe, send position too */
213 if (rfilp
->filp_vno
->v_pipe
== I_PIPE
) {
214 if (rfilp
->filp_mode
& R_BIT
)
215 if (ex64hi(rfilp
->filp_pos
) != 0)
217 panic(__FILE__
, "do_fstat: bad position in pipe",
220 pipe_pos
= ex64lo(rfilp
->filp_pos
);
224 return req_stat(rfilp
->filp_vno
->v_fs_e
, rfilp
->filp_vno
->v_inode_nr
,
225 who_e
, m_in
.buffer
, pipe_pos
);
230 /*===========================================================================*
232 *===========================================================================*/
233 PUBLIC
int do_fstatfs()
235 /* Perform the fstatfs(fd, buf) system call. */
236 register struct filp
*rfilp
;
238 /* Is the file descriptor valid? */
239 if ( (rfilp
= get_filp(m_in
.fd
)) == NIL_FILP
) return(err_code
);
242 return req_fstatfs(rfilp
->filp_vno
->v_fs_e
, rfilp
->filp_vno
->v_inode_nr
,
248 /*===========================================================================*
250 *===========================================================================*/
251 PUBLIC
int do_lstat()
253 /* Perform the lstat(name, buf) system call. */
254 struct node_details res
;
255 struct lookup_req lookup_req
;
258 if (fetch_name(m_in
.name1
, m_in
.name1_length
, M1
) != OK
) return(err_code
);
260 /* Fill in lookup request fields */
261 lookup_req
.path
= user_fullpath
;
262 lookup_req
.lastc
= NULL
;
263 lookup_req
.flags
= EAT_PATH_OPAQUE
;
266 if ((r
= lookup(&lookup_req
, &res
)) != OK
) return r
;
269 return req_stat(res
.fs_e
, res
.inode_nr
, who_e
, m_in
.name2
, 0);