root/kern/vfs/vfscwd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vfs_getcurdir
  2. vfs_setcurdir
  3. vfs_clearcurdir
  4. vfs_chdir
  5. 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 }

/* [<][>][^][v][top][bottom][index][help] */