00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <types.h>
00035 #include <kern/errno.h>
00036 #include <stat.h>
00037 #include <lib.h>
00038 #include <uio.h>
00039 #include <proc.h>
00040 #include <current.h>
00041 #include <vfs.h>
00042 #include <fs.h>
00043 #include <vnode.h>
00044
00045
00046
00047
00048 int
00049 vfs_getcurdir(struct vnode **ret)
00050 {
00051 int rv = 0;
00052
00053 spinlock_acquire(&curproc->p_lock);
00054 if (curproc->p_cwd!=NULL) {
00055 VOP_INCREF(curproc->p_cwd);
00056 *ret = curproc->p_cwd;
00057 }
00058 else {
00059 rv = ENOENT;
00060 }
00061 spinlock_release(&curproc->p_lock);
00062
00063 return rv;
00064 }
00065
00066
00067
00068
00069
00070 int
00071 vfs_setcurdir(struct vnode *dir)
00072 {
00073 struct vnode *old;
00074 mode_t vtype;
00075 int result;
00076
00077 result = VOP_GETTYPE(dir, &vtype);
00078 if (result) {
00079 return result;
00080 }
00081 if (vtype != S_IFDIR) {
00082 return ENOTDIR;
00083 }
00084
00085 VOP_INCREF(dir);
00086
00087 spinlock_acquire(&curproc->p_lock);
00088 old = curproc->p_cwd;
00089 curproc->p_cwd = dir;
00090 spinlock_release(&curproc->p_lock);
00091
00092 if (old!=NULL) {
00093 VOP_DECREF(old);
00094 }
00095
00096 return 0;
00097 }
00098
00099
00100
00101
00102 int
00103 vfs_clearcurdir(void)
00104 {
00105 struct vnode *old;
00106
00107 spinlock_acquire(&curproc->p_lock);
00108 old = curproc->p_cwd;
00109 curproc->p_cwd = NULL;
00110 spinlock_release(&curproc->p_lock);
00111
00112 if (old!=NULL) {
00113 VOP_DECREF(old);
00114 }
00115
00116 return 0;
00117 }
00118
00119
00120
00121
00122
00123 int
00124 vfs_chdir(char *path)
00125 {
00126 struct vnode *vn;
00127 int result;
00128
00129 result = vfs_lookup(path, &vn);
00130 if (result) {
00131 return result;
00132 }
00133 result = vfs_setcurdir(vn);
00134 VOP_DECREF(vn);
00135 return result;
00136 }
00137
00138
00139
00140
00141
00142
00143 int
00144 vfs_getcwd(struct uio *uio)
00145 {
00146 struct vnode *cwd;
00147 int result;
00148 const char *name;
00149 char colon=':';
00150
00151 KASSERT(uio->uio_rw==UIO_READ);
00152
00153 result = vfs_getcurdir(&cwd);
00154 if (result) {
00155 return result;
00156 }
00157
00158
00159 KASSERT(cwd->vn_fs != NULL);
00160
00161 name = FSOP_GETVOLNAME(cwd->vn_fs);
00162 if (name==NULL) {
00163 vfs_biglock_acquire();
00164 name = vfs_getdevname(cwd->vn_fs);
00165 vfs_biglock_release();
00166 }
00167 KASSERT(name != NULL);
00168
00169 result = uiomove((char *)name, strlen(name), uio);
00170 if (result) {
00171 goto out;
00172 }
00173 result = uiomove(&colon, 1, uio);
00174 if (result) {
00175 goto out;
00176 }
00177
00178 result = VOP_NAMEFILE(cwd, uio);
00179
00180 out:
00181
00182 VOP_DECREF(cwd);
00183 return result;
00184 }