Implement /dev/null

This commit is contained in:
Theodore Dubois 2017-12-15 15:54:31 -08:00
parent 77afbe3aa3
commit fd88906165
4 changed files with 32 additions and 5 deletions

View File

@ -8,14 +8,37 @@ struct dev_ops *block_devs[] = {
};
struct dev_ops *char_devs[] = {
[0 ... 255] = NULL,
[1] = &null_dev,
[4] = &tty_dev,
};
int dev_open(int major, int minor, int type, struct fd *fd) {
struct dev_ops *dev = (type == DEV_BLOCK ? block_devs : char_devs)[major];
if (dev == NULL)
return _ENODEV;
return _ENXIO;
fd->ops = &dev->fd;
if (!dev->open)
return 0;
return dev->open(major, minor, type, fd);
}
// this device seemed so simple it was hardly worth making a new file for it
static int null_open(int major, int minor, int type, struct fd *fd) {
if (minor != 3)
return _ENXIO;
return 0;
}
static ssize_t null_read(struct fd *fd, void *buf, size_t bufsize) {
return 0;
}
static ssize_t null_write(struct fd *fd, const void *buf, size_t bufsize) {
return bufsize;
}
struct dev_ops null_dev = {
.open = null_open,
.fd = {
.read = null_read,
.write = null_write,
},
};

View File

@ -43,4 +43,6 @@ extern struct dev_ops *char_devs[];
int dev_open(int major, int minor, int type, struct fd *fd);
extern struct dev_ops null_dev;
#endif

View File

@ -54,7 +54,7 @@ struct fd *generic_openat(struct fd *at, const char *path_raw, int flags, int mo
assert(!S_ISLNK(stat.mode));
if (S_ISBLK(stat.mode) || S_ISCHR(stat.mode)) {
int type;
if (stat.mode & S_IFBLK)
if (S_ISBLK(stat.mode))
type = DEV_BLOCK;
else
type = DEV_CHAR;

View File

@ -123,9 +123,11 @@ dword_t sys_close(fd_t f) {
if (fd == NULL)
return _EBADF;
if (--fd->refcount == 0) {
int err = fd->ops->close(fd);
if (err < 0)
return err;
if (fd->ops->close) {
int err = fd->ops->close(fd);
if (err < 0)
return err;
}
free(fd);
}
current->files[f] = NULL;