more stack for boot
[minix.git] / servers / vfs / stadir.c
blob30a0d6ce9cedc9d24f553ed884b83ceebf067ead
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;
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 /*===========================================================================*
87 * change_into *
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 */
93 int r;
95 /* It must be a directory and also be searchable */
96 if ((vp->v_mode & I_TYPE) != I_DIRECTORY)
97 r = ENOTDIR;
98 else
99 r = forbidden(vp, X_BIT); /* Check if dir is searchable*/
101 /* If error, return vnode */
102 if (r != OK) {
103 put_vnode(vp);
104 return(r);
107 /* Everything is OK. Make the change. */
108 put_vnode(*iip); /* release the old directory */
109 *iip = vp; /* acquire the new one */
110 return(OK);
114 /*===========================================================================*
115 * do_stat *
116 *===========================================================================*/
117 PUBLIC int do_stat()
119 /* Perform the stat(name, buf) system call. */
120 int r;
121 struct vnode *vp;
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);
127 put_vnode(vp);
128 return r;
132 /*===========================================================================*
133 * do_fstat *
134 *===========================================================================*/
135 PUBLIC int do_fstat()
137 /* Perform the fstat(fd, buf) system call. */
138 register struct filp *rfilp;
139 int pipe_pos = 0;
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 /*===========================================================================*
159 * do_fstatfs *
160 *===========================================================================*/
161 PUBLIC int do_fstatfs()
163 /* Perform the fstatfs(fd, buf) system call. */
164 struct filp *rfilp;
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 /*===========================================================================*
174 * do_lstat *
175 *===========================================================================*/
176 PUBLIC int do_lstat()
178 /* Perform the lstat(name, buf) system call. */
179 struct vnode *vp;
180 int r;
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);
186 put_vnode(vp);
187 return(r);