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(). */
79 /* Try to open the directory */
80 if (fetch_name(name_ptr
, len
, M3
) != OK
) return(err_code
);
81 if ((vp
= eat_path(PATH_NOFLAGS
)) == NIL_VNODE
) return(err_code
);
82 return change_into(iip
, vp
);
86 /*===========================================================================*
88 *===========================================================================*/
89 PRIVATE
int change_into(iip
, vp
)
90 struct vnode
**iip
; /* pointer to the inode pointer for the dir */
91 struct vnode
*vp
; /* this is what the inode has to become */
95 /* It must be a directory and also be searchable */
96 if ((vp
->v_mode
& I_TYPE
) != I_DIRECTORY
)
99 r
= forbidden(vp
, X_BIT
); /* Check if dir is searchable*/
101 /* If error, return vnode */
107 /* Everything is OK. Make the change. */
108 put_vnode(*iip
); /* release the old directory */
109 *iip
= vp
; /* acquire the new one */
114 /*===========================================================================*
116 *===========================================================================*/
119 /* Perform the stat(name, buf) system call. */
123 if (fetch_name(m_in
.name1
, m_in
.name1_length
, M1
) != OK
) return(err_code
);
124 if ((vp
= eat_path(PATH_NOFLAGS
)) == NIL_VNODE
) return(err_code
);
125 r
= req_stat(vp
->v_fs_e
, vp
->v_inode_nr
, who_e
, m_in
.name2
, 0);
132 /*===========================================================================*
134 *===========================================================================*/
135 PUBLIC
int do_fstat()
137 /* Perform the fstat(fd, buf) system call. */
138 register struct filp
*rfilp
;
141 /* Is the file descriptor valid? */
142 if ((rfilp
= get_filp(m_in
.fd
)) == NIL_FILP
) return(err_code
);
144 /* If we read from a pipe, send position too */
145 if (rfilp
->filp_vno
->v_pipe
== I_PIPE
) {
146 if (rfilp
->filp_mode
& R_BIT
)
147 if (ex64hi(rfilp
->filp_pos
) != 0) {
148 panic("do_fstat: bad position in pipe");
150 pipe_pos
= ex64lo(rfilp
->filp_pos
);
153 return req_stat(rfilp
->filp_vno
->v_fs_e
, rfilp
->filp_vno
->v_inode_nr
,
154 who_e
, m_in
.buffer
, pipe_pos
);
158 /*===========================================================================*
160 *===========================================================================*/
161 PUBLIC
int do_fstatfs()
163 /* Perform the fstatfs(fd, buf) system call. */
166 /* Is the file descriptor valid? */
167 if( (rfilp
= get_filp(m_in
.fd
)) == NIL_FILP
) return(err_code
);
169 return req_fstatfs(rfilp
->filp_vno
->v_fs_e
, who_e
, m_in
.buffer
);
173 /*===========================================================================*
175 *===========================================================================*/
176 PUBLIC
int do_lstat()
178 /* Perform the lstat(name, buf) system call. */
182 if (fetch_name(m_in
.name1
, m_in
.name1_length
, M1
) != OK
) return(err_code
);
183 if ((vp
= eat_path(PATH_RET_SYMLINK
)) == NIL_VNODE
) return(err_code
);
184 r
= req_stat(vp
->v_fs_e
, vp
->v_inode_nr
, who_e
, m_in
.name2
, 0);