panic() cleanup.
[minix.git] / servers / vfs / stadir.c
blob7beffde92b4b319cd828508a5a5e96e2efbf2714
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
13 #include "fs.h"
14 #include <sys/stat.h>
15 #include <sys/statfs.h>
16 #include <minix/com.h>
17 #include <minix/u64.h>
18 #include <string.h>
19 #include "file.h"
20 #include "fproc.h"
21 #include "param.h"
22 #include <minix/vfsif.h>
23 #include "vnode.h"
24 #include "vmnt.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 /*===========================================================================*
31 * do_fchdir *
32 *===========================================================================*/
33 PUBLIC int do_fchdir()
35 /* Change directory on already-opened fd. */
36 struct filp *rfilp;
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 /*===========================================================================*
46 * do_chdir *
47 *===========================================================================*/
48 PUBLIC int do_chdir()
50 /* Perform the chdir(name) system call. */
52 return change(&fp->fp_wd, m_in.name, m_in.name_length);
56 /*===========================================================================*
57 * do_chroot *
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 /*===========================================================================*
69 * change *
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(). */
77 struct vnode *vp;
78 int r;
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 /*===========================================================================*
88 * change_into *
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 */
94 int r;
96 /* It must be a directory and also be searchable */
97 if ((vp->v_mode & I_TYPE) != I_DIRECTORY)
98 r = ENOTDIR;
99 else
100 r = forbidden(vp, X_BIT); /* Check if dir is searchable*/
102 /* If error, return vnode */
103 if (r != OK) {
104 put_vnode(vp);
105 return(r);
108 /* Everything is OK. Make the change. */
109 put_vnode(*iip); /* release the old directory */
110 *iip = vp; /* acquire the new one */
111 return(OK);
115 /*===========================================================================*
116 * do_stat *
117 *===========================================================================*/
118 PUBLIC int do_stat()
120 /* Perform the stat(name, buf) system call. */
121 int r;
122 struct vnode *vp;
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);
128 put_vnode(vp);
129 return r;
133 /*===========================================================================*
134 * do_fstat *
135 *===========================================================================*/
136 PUBLIC int do_fstat()
138 /* Perform the fstat(fd, buf) system call. */
139 register struct filp *rfilp;
140 int pipe_pos = 0;
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 /*===========================================================================*
160 * do_fstatfs *
161 *===========================================================================*/
162 PUBLIC int do_fstatfs()
164 /* Perform the fstatfs(fd, buf) system call. */
165 struct filp *rfilp;
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 /*===========================================================================*
175 * do_lstat *
176 *===========================================================================*/
177 PUBLIC int do_lstat()
179 /* Perform the lstat(name, buf) system call. */
180 struct vnode *vp;
181 int r;
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);
187 put_vnode(vp);
188 return(r);