/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- vfs_getcurdir
- vfs_setcurdir
- vfs_clearcurdir
- vfs_chdir
- vfs_getcwd
1 /*
2 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3 * The President and Fellows of Harvard College.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 /*
31 * VFS operations involving the current directory.
32 */
33
34 #include <types.h>
35 #include <kern/errno.h>
36 #include <stat.h>
37 #include <lib.h>
38 #include <uio.h>
39 #include <proc.h>
40 #include <current.h>
41 #include <vfs.h>
42 #include <fs.h>
43 #include <vnode.h>
44
45 /*
46 * Get current directory as a vnode.
47 */
48 int
49 vfs_getcurdir(struct vnode **ret)
50 {
51 int rv = 0;
52
53 spinlock_acquire(&curproc->p_lock);
54 if (curproc->p_cwd!=NULL) {
55 VOP_INCREF(curproc->p_cwd);
56 *ret = curproc->p_cwd;
57 }
58 else {
59 rv = ENOENT;
60 }
61 spinlock_release(&curproc->p_lock);
62
63 return rv;
64 }
65
66 /*
67 * Set current directory as a vnode.
68 * The passed vnode must in fact be a directory.
69 */
70 int
71 vfs_setcurdir(struct vnode *dir)
72 {
73 struct vnode *old;
74 mode_t vtype;
75 int result;
76
77 result = VOP_GETTYPE(dir, &vtype);
78 if (result) {
79 return result;
80 }
81 if (vtype != S_IFDIR) {
82 return ENOTDIR;
83 }
84
85 VOP_INCREF(dir);
86
87 spinlock_acquire(&curproc->p_lock);
88 old = curproc->p_cwd;
89 curproc->p_cwd = dir;
90 spinlock_release(&curproc->p_lock);
91
92 if (old!=NULL) {
93 VOP_DECREF(old);
94 }
95
96 return 0;
97 }
98
99 /*
100 * Set current directory to "none".
101 */
102 int
103 vfs_clearcurdir(void)
104 {
105 struct vnode *old;
106
107 spinlock_acquire(&curproc->p_lock);
108 old = curproc->p_cwd;
109 curproc->p_cwd = NULL;
110 spinlock_release(&curproc->p_lock);
111
112 if (old!=NULL) {
113 VOP_DECREF(old);
114 }
115
116 return 0;
117 }
118
119 /*
120 * Set current directory, as a pathname. Use vfs_lookup to translate
121 * it to a vnode.
122 */
123 int
124 vfs_chdir(char *path)
125 {
126 struct vnode *vn;
127 int result;
128
129 result = vfs_lookup(path, &vn);
130 if (result) {
131 return result;
132 }
133 result = vfs_setcurdir(vn);
134 VOP_DECREF(vn);
135 return result;
136 }
137
138 /*
139 * Get current directory, as a pathname.
140 * Use VOP_NAMEFILE to get the pathname and FSOP_GETVOLNAME to get the
141 * volume name.
142 */
143 int
144 vfs_getcwd(struct uio *uio)
145 {
146 struct vnode *cwd;
147 int result;
148 const char *name;
149 char colon=':';
150
151 KASSERT(uio->uio_rw==UIO_READ);
152
153 result = vfs_getcurdir(&cwd);
154 if (result) {
155 return result;
156 }
157
158 /* The current dir must be a directory, and thus it is not a device. */
159 KASSERT(cwd->vn_fs != NULL);
160
161 name = FSOP_GETVOLNAME(cwd->vn_fs);
162 if (name==NULL) {
163 vfs_biglock_acquire();
164 name = vfs_getdevname(cwd->vn_fs);
165 vfs_biglock_release();
166 }
167 KASSERT(name != NULL);
168
169 result = uiomove((char *)name, strlen(name), uio);
170 if (result) {
171 goto out;
172 }
173 result = uiomove(&colon, 1, uio);
174 if (result) {
175 goto out;
176 }
177
178 result = VOP_NAMEFILE(cwd, uio);
179
180 out:
181
182 VOP_DECREF(cwd);
183 return result;
184 }