Statistics
| Branch: | Revision:

scoutos / prex-0.9.0 / usr / server / fs / devfs / devfs_vnops.c @ 03e9c04a

History | View | Annotate | Download (6.58 KB)

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
}