Prex Home / Browse Source - Prex Version: 0.9.0

root/usr/server/fs/devfs/devfs_vnops.c

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

DEFINITIONS

This source file includes following definitions.
  1. devfs_open
  2. devfs_close
  3. devfs_read
  4. devfs_write
  5. devfs_ioctl
  6. devfs_lookup
  7. devfs_readdir
  8. devfs_init

   1 /*
   2  * Copyright (c) 2005-2007, Kohsuke Ohtani
   3  * All rights reserved.
   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 author nor the names of any co-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 AUTHOR 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 AUTHOR 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  * devfs - device file system.
  32  */
  33 
  34 #include <sys/prex.h>
  35 #include <sys/device.h>
  36 #include <sys/stat.h>
  37 #include <sys/vnode.h>
  38 #include <sys/file.h>
  39 #include <sys/mount.h>
  40 #include <sys/syslog.h>
  41 
  42 #include <ctype.h>
  43 #include <unistd.h>
  44 #include <errno.h>
  45 #include <string.h>
  46 #include <stdlib.h>
  47 #include <limits.h>
  48 #include <fcntl.h>
  49 
  50 #include "devfs.h"
  51 
  52 
  53 #define devfs_mount     ((vfsop_mount_t)vfs_nullop)
  54 #define devfs_unmount   ((vfsop_umount_t)vfs_nullop)
  55 #define devfs_sync      ((vfsop_sync_t)vfs_nullop)
  56 #define devfs_vget      ((vfsop_vget_t)vfs_nullop)
  57 #define devfs_statfs    ((vfsop_statfs_t)vfs_nullop)
  58 
  59 static int devfs_open   (vnode_t, int);
  60 static int devfs_close  (vnode_t, file_t);
  61 static int devfs_read   (vnode_t, file_t, void *, size_t, size_t *);
  62 static int devfs_write  (vnode_t, file_t, void *, size_t, size_t *);
  63 #define devfs_seek      ((vnop_seek_t)vop_nullop)
  64 static int devfs_ioctl  (vnode_t, file_t, u_long, void *);
  65 #define devfs_fsync     ((vnop_fsync_t)vop_nullop)
  66 static int devfs_readdir(vnode_t, file_t, struct dirent *);
  67 static int devfs_lookup (vnode_t, char *, vnode_t);
  68 #define devfs_create    ((vnop_create_t)vop_einval)
  69 #define devfs_remove    ((vnop_remove_t)vop_einval)
  70 #define devfs_rename    ((vnop_rename_t)vop_einval)
  71 #define devfs_mkdir     ((vnop_mkdir_t)vop_einval)
  72 #define devfs_rmdir     ((vnop_rmdir_t)vop_einval)
  73 #define devfs_getattr   ((vnop_getattr_t)vop_nullop)
  74 #define devfs_setattr   ((vnop_setattr_t)vop_nullop)
  75 #define devfs_inactive  ((vnop_inactive_t)vop_nullop)
  76 #define devfs_truncate  ((vnop_truncate_t)vop_nullop)
  77 
  78 /*
  79  * vnode operations
  80  */
  81 struct vnops devfs_vnops = {
  82         devfs_open,             /* open */
  83         devfs_close,            /* close */
  84         devfs_read,             /* read */
  85         devfs_write,            /* write */
  86         devfs_seek,             /* seek */
  87         devfs_ioctl,            /* ioctl */
  88         devfs_fsync,            /* fsync */
  89         devfs_readdir,          /* readdir */
  90         devfs_lookup,           /* lookup */
  91         devfs_create,           /* create */
  92         devfs_remove,           /* remove */
  93         devfs_rename,           /* remame */
  94         devfs_mkdir,            /* mkdir */
  95         devfs_rmdir,            /* rmdir */
  96         devfs_getattr,          /* getattr */
  97         devfs_setattr,          /* setattr */
  98         devfs_inactive,         /* inactive */
  99         devfs_truncate,         /* truncate */
 100 };
 101 
 102 /*
 103  * File system operations
 104  */
 105 struct vfsops devfs_vfsops = {
 106         devfs_mount,            /* mount */
 107         devfs_unmount,          /* unmount */
 108         devfs_sync,             /* sync */
 109         devfs_vget,             /* vget */
 110         devfs_statfs,           /* statfs */
 111         &devfs_vnops,           /* vnops */
 112 };
 113 
 114 static int
 115 devfs_open(vnode_t vp, int flags)
 116 {
 117         char *path;
 118         device_t dev;
 119         int error;
 120 
 121         DPRINTF(("devfs_open: path=%s\n", vp->v_path));
 122 
 123         path = vp->v_path;
 124         if (!strcmp(path, "/")) /* root ? */
 125                 return 0;
 126 
 127         if (vp->v_flags & VPROTDEV) {
 128                 DPRINTF(("devfs_open: failed to open protected device.\n"));
 129                 return EPERM;
 130         }
 131         if (*path == '/')
 132                 path++;
 133         error = device_open(path, flags & DO_RWMASK, &dev);
 134         if (error) {
 135                 DPRINTF(("devfs_open: can not open device = %s error=%d\n",
 136                          path, error));
 137                 return error;
 138         }
 139         vp->v_data = (void *)dev;       /* Store private data */
 140         return 0;
 141 }
 142 
 143 static int
 144 devfs_close(vnode_t vp, file_t fp)
 145 {
 146 
 147         DPRINTF(("devfs_close: fp=%x\n", fp));
 148 
 149         if (!strcmp(vp->v_path, "/"))   /* root ? */
 150                 return 0;
 151 
 152         return device_close((device_t)vp->v_data);
 153 }
 154 
 155 static int
 156 devfs_read(vnode_t vp, file_t fp, void *buf, size_t size, size_t *result)
 157 {
 158         int error;
 159         size_t len;
 160 
 161         len = size;
 162         error = device_read((device_t)vp->v_data, buf, &len, fp->f_offset);
 163         if (!error)
 164                 *result = len;
 165         return error;
 166 }
 167 
 168 static int
 169 devfs_write(vnode_t vp, file_t fp, void *buf, size_t size, size_t *result)
 170 {
 171         int error;
 172         size_t len;
 173 
 174         len = size;
 175         error = device_write((device_t)vp->v_data, buf, &len, fp->f_offset);
 176         if (!error)
 177                 *result = len;
 178         DPRINTF(("devfs_write: error=%d len=%d\n", error, len));
 179         return error;
 180 }
 181 
 182 static int
 183 devfs_ioctl(vnode_t vp, file_t fp, u_long cmd, void *arg)
 184 {
 185         int error;
 186 
 187         error = device_ioctl((device_t)vp->v_data, cmd, arg);
 188         DPRINTF(("devfs_ioctl: cmd=%x\n", cmd));
 189         return error;
 190 }
 191 
 192 static int
 193 devfs_lookup(vnode_t dvp, char *name, vnode_t vp)
 194 {
 195         struct devinfo info;
 196         int error, i;
 197 
 198         DPRINTF(("devfs_lookup:%s\n", name));
 199 
 200         if (*name == '\0')
 201                 return ENOENT;
 202 
 203         i = 0;
 204         error = 0;
 205         info.cookie = 0;
 206         for (;;) {
 207                 error = sys_info(INFO_DEVICE, &info);
 208                 if (error)
 209                         return ENOENT;
 210                 if (!strncmp(info.name, name, MAXDEVNAME))
 211                         break;
 212                 i++;
 213         }
 214         vp->v_type = (info.flags & D_CHR) ? VCHR : VBLK;
 215         if (info.flags & D_TTY)
 216                 vp->v_flags |= VISTTY;
 217 
 218         if (info.flags & D_PROT)
 219                 vp->v_flags |= VPROTDEV;
 220         else
 221                 vp->v_mode = (mode_t)(S_IRUSR | S_IWUSR);
 222         return 0;
 223 }
 224 
 225 /*
 226  * @vp: vnode of the directory.
 227  */
 228 static int
 229 devfs_readdir(vnode_t vp, file_t fp, struct dirent *dir)
 230 {
 231         struct devinfo info;
 232         int error, i;
 233 
 234         DPRINTF(("devfs_readdir offset=%d\n", fp->f_offset));
 235 
 236         i = 0;
 237         error = 0;
 238         info.cookie = 0;
 239         do {
 240                 error = sys_info(INFO_DEVICE, &info);
 241                 if (error)
 242                         return ENOENT;
 243         } while (i++ != fp->f_offset);
 244 
 245         dir->d_type = 0;
 246         if (info.flags & D_CHR)
 247                 dir->d_type = DT_CHR;
 248         else if (info.flags & D_BLK)
 249                 dir->d_type = DT_BLK;
 250         strlcpy((char *)&dir->d_name, info.name, sizeof(dir->d_name));
 251         dir->d_fileno = (uint32_t)fp->f_offset;
 252         dir->d_namlen = (uint16_t)strlen(dir->d_name);
 253 
 254         DPRINTF(("devfs_readdir: %s\n", dir->d_name));
 255         fp->f_offset++;
 256         return 0;
 257 }
 258 
 259 int
 260 devfs_init(void)
 261 {
 262         return 0;
 263 }

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