
This patch adds the implementation of the BSD socket system calls which have been introduced in an earlier patch. At the same time, it adds support for communication with socket drivers, using a new "socket device" (SDEV_) protocol. These two parts, implemented in socket.c and sdev.c respectively, form the upper and lower halves of the new BSD socket support in VFS. New mapping functionality for socket domains and drivers is added as well, implemented in smap.c. The rest of the changes mainly facilitate the separation of character and socket driver calls, and do not make any fundamental alterations. For example, while this patch changes VFS's select.c rather heavily, the new select logic for socket drivers is the exact same as for character drivers; the changes mainly separate the driver type specific parts from the generic select logic further than before. Change-Id: I2f13084dd3c8d3a68bfc69da0621120c8291f707
96 lines
2.0 KiB
C
96 lines
2.0 KiB
C
/*
|
|
* This file contains a number of device-type independent device routines.
|
|
*
|
|
* The entry points in this file are:
|
|
* do_ioctl: perform the IOCTL system call
|
|
* make_ioctl_grant: make a grant for an IOCTL request to a device
|
|
*/
|
|
|
|
#include "fs.h"
|
|
#include "vnode.h"
|
|
#include "file.h"
|
|
#include <sys/ioctl.h>
|
|
|
|
/*
|
|
* Perform the ioctl(2) system call.
|
|
*/
|
|
int
|
|
do_ioctl(void)
|
|
{
|
|
unsigned long request;
|
|
struct filp *f;
|
|
register struct vnode *vp;
|
|
vir_bytes arg;
|
|
int r, fd;
|
|
|
|
fd = job_m_in.m_lc_vfs_ioctl.fd;
|
|
request = job_m_in.m_lc_vfs_ioctl.req;
|
|
arg = (vir_bytes)job_m_in.m_lc_vfs_ioctl.arg;
|
|
|
|
if ((f = get_filp(fd, VNODE_READ)) == NULL)
|
|
return(err_code);
|
|
vp = f->filp_vno; /* get vnode pointer */
|
|
|
|
switch (vp->v_mode & S_IFMT) {
|
|
case S_IFBLK:
|
|
f->filp_ioctl_fp = fp;
|
|
|
|
r = bdev_ioctl(vp->v_sdev, who_e, request, arg);
|
|
|
|
f->filp_ioctl_fp = NULL;
|
|
break;
|
|
|
|
case S_IFCHR:
|
|
r = cdev_io(CDEV_IOCTL, vp->v_sdev, who_e, arg, 0, request,
|
|
f->filp_flags);
|
|
break;
|
|
|
|
case S_IFSOCK:
|
|
r = sdev_ioctl(vp->v_sdev, request, arg, f->filp_flags);
|
|
break;
|
|
|
|
default:
|
|
r = ENOTTY;
|
|
}
|
|
|
|
unlock_filp(f);
|
|
|
|
return r;
|
|
}
|
|
|
|
/*
|
|
* Create a magic grant for the given IOCTL request.
|
|
*/
|
|
cp_grant_id_t
|
|
make_ioctl_grant(endpoint_t driver_e, endpoint_t user_e, vir_bytes buf,
|
|
unsigned long request)
|
|
{
|
|
cp_grant_id_t grant;
|
|
int access;
|
|
size_t size;
|
|
|
|
/*
|
|
* For IOCTLs, the bytes parameter contains the IOCTL request.
|
|
* This request encodes the requested access method and buffer size.
|
|
*/
|
|
access = 0;
|
|
if (_MINIX_IOCTL_IOR(request)) access |= CPF_WRITE;
|
|
if (_MINIX_IOCTL_IOW(request)) access |= CPF_READ;
|
|
if (_MINIX_IOCTL_BIG(request))
|
|
size = _MINIX_IOCTL_SIZE_BIG(request);
|
|
else
|
|
size = _MINIX_IOCTL_SIZE(request);
|
|
|
|
/*
|
|
* Grant access to the buffer even if no I/O happens with the ioctl,
|
|
* although now that we no longer identify responses based on grants,
|
|
* this is not strictly necessary.
|
|
*/
|
|
grant = cpf_grant_magic(driver_e, user_e, buf, size, access);
|
|
|
|
if (!GRANT_VALID(grant))
|
|
panic("VFS: cpf_grant_magic failed");
|
|
|
|
return grant;
|
|
}
|