Prepare for switch to native BSD socket API

Currently, the BSD socket API is implemented in libc, translating the
API calls to character driver operations underneath.  This approach
has several issues:

- it is inefficient, as most character driver operations are specific
  to the socket type, thus requiring that each operation start by
  bruteforcing the socket protocol family and type of the given file
  descriptor using several system calls;
- it requires that libc itself be changed every time system support
  for a new protocol is added;
- various parts of the libc implementations violate the asynchronous
  signal safety POSIX requirements.

In order to resolve all these issues at once, the plan is to turn the
BSD socket calls into system calls, thus making the BSD socket API the
"native" ABI, removing the complexity from libc and instead letting
VFS deal with the socket calls.

The overall change is going to break all networking functionality. In
order to smoothen the transition, this patch introduces the fifteen
new BSD socket system calls, and makes libc try these first before
falling back on the old behavior.  For now, the VFS implementations of
the new calls fail such that libc will always use the fallback cases.
Later on, when we introduce the actual implementation of the native
BSD socket calls, all statically linked programs will automatically
use the new ABI, thus limiting actual application breakage.

In other words: by itself, this patch does nothing, except add a bit
of transitional overhead that will disappear in the future.  The
largest part of the patch is concerned with adding full support for
the new BSD socket system calls to trace(1) - this early addition has
the advantage of making system call tracing output of several socket
calls much more readable already.

Both the system call interfaces and the trace(1) support have already
been tested using code that will be committed later on.

Change-Id: I3460812be50c78be662d857f9d3d6840f3ca917f
This commit is contained in:
David van Moolenbroek 2016-02-21 17:39:34 +00:00
parent 0df28c9fa4
commit c38dbb97aa
28 changed files with 1914 additions and 241 deletions

View File

@ -118,7 +118,22 @@
#define VFS_COPYFD (VFS_BASE + 46)
#define VFS_CHECKPERMS (VFS_BASE + 47)
#define VFS_GETSYSINFO (VFS_BASE + 48)
#define VFS_SOCKET (VFS_BASE + 49)
#define VFS_SOCKETPAIR (VFS_BASE + 50)
#define VFS_BIND (VFS_BASE + 51)
#define VFS_CONNECT (VFS_BASE + 52)
#define VFS_LISTEN (VFS_BASE + 53)
#define VFS_ACCEPT (VFS_BASE + 54)
#define VFS_SENDTO (VFS_BASE + 55)
#define VFS_SENDMSG (VFS_BASE + 56)
#define VFS_RECVFROM (VFS_BASE + 57)
#define VFS_RECVMSG (VFS_BASE + 58)
#define VFS_SETSOCKOPT (VFS_BASE + 59)
#define VFS_GETSOCKOPT (VFS_BASE + 60)
#define VFS_GETSOCKNAME (VFS_BASE + 61)
#define VFS_GETPEERNAME (VFS_BASE + 62)
#define VFS_SHUTDOWN (VFS_BASE + 63)
#define NR_VFS_CALLS 49 /* highest number from base plus one */
#define NR_VFS_CALLS 64 /* highest number from base plus one */
#endif /* !_MINIX_CALLNR_H */

View File

@ -714,6 +714,14 @@ typedef struct {
} mess_lc_vfs_link;
_ASSERT_MSG_SIZE(mess_lc_vfs_link);
typedef struct {
int fd;
int backlog;
u8_t padding[48];
} mess_lc_vfs_listen;
_ASSERT_MSG_SIZE(mess_lc_vfs_listen);
typedef struct {
off_t offset;
@ -803,6 +811,64 @@ typedef struct {
} mess_lc_vfs_select;
_ASSERT_MSG_SIZE(mess_lc_vfs_select);
typedef struct {
int fd;
vir_bytes buf; /* void * */
size_t len;
int flags;
vir_bytes addr; /* struct sockaddr * */
unsigned int addr_len; /* socklen_t */
uint8_t padding[32];
} mess_lc_vfs_sendrecv;
_ASSERT_MSG_SIZE(mess_lc_vfs_sendrecv);
typedef struct {
int fd;
int how;
uint8_t padding[48];
} mess_lc_vfs_shutdown;
_ASSERT_MSG_SIZE(mess_lc_vfs_shutdown);
typedef struct {
int fd;
vir_bytes addr; /* struct sockaddr * */
unsigned int addr_len; /* socklen_t */
uint8_t padding[44];
} mess_lc_vfs_sockaddr;
_ASSERT_MSG_SIZE(mess_lc_vfs_sockaddr);
typedef struct {
int domain;
int type;
int protocol;
uint8_t padding[44];
} mess_lc_vfs_socket;
_ASSERT_MSG_SIZE(mess_lc_vfs_socket);
typedef struct {
int fd;
vir_bytes msgbuf; /* struct msghdr * */
int flags;
uint8_t padding[44];
} mess_lc_vfs_sockmsg;
_ASSERT_MSG_SIZE(mess_lc_vfs_sockmsg);
typedef struct {
int fd;
int level;
int name;
vir_bytes buf; /* void * */
unsigned int len; /* socklen_t */
uint8_t padding[36];
} mess_lc_vfs_sockopt;
_ASSERT_MSG_SIZE(mess_lc_vfs_sockopt);
typedef struct {
size_t len;
vir_bytes name; /* const char * */
@ -1969,6 +2035,13 @@ typedef struct {
} mess_vfs_lc_lseek;
_ASSERT_MSG_SIZE(mess_vfs_lc_lseek);
typedef struct {
unsigned int len; /* socklen_t */
uint8_t padding[52];
} mess_vfs_lc_socklen;
_ASSERT_MSG_SIZE(mess_vfs_lc_socklen);
typedef struct {
endpoint_t id;
devminor_t minor;
@ -2141,6 +2214,7 @@ typedef struct noxfer_message {
mess_lc_vfs_getvfsstat m_lc_vfs_getvfsstat;
mess_lc_vfs_ioctl m_lc_vfs_ioctl;
mess_lc_vfs_link m_lc_vfs_link;
mess_lc_vfs_listen m_lc_vfs_listen;
mess_lc_vfs_lseek m_lc_vfs_lseek;
mess_lc_vfs_mknod m_lc_vfs_mknod;
mess_lc_vfs_mount m_lc_vfs_mount;
@ -2149,6 +2223,12 @@ typedef struct noxfer_message {
mess_lc_vfs_readlink m_lc_vfs_readlink;
mess_lc_vfs_readwrite m_lc_vfs_readwrite;
mess_lc_vfs_select m_lc_vfs_select;
mess_lc_vfs_sendrecv m_lc_vfs_sendrecv;
mess_lc_vfs_shutdown m_lc_vfs_shutdown;
mess_lc_vfs_sockaddr m_lc_vfs_sockaddr;
mess_lc_vfs_socket m_lc_vfs_socket;
mess_lc_vfs_sockmsg m_lc_vfs_sockmsg;
mess_lc_vfs_sockopt m_lc_vfs_sockopt;
mess_lc_vfs_stat m_lc_vfs_stat;
mess_lc_vfs_statvfs1 m_lc_vfs_statvfs1;
mess_lc_vfs_truncate m_lc_vfs_truncate;
@ -2277,6 +2357,7 @@ typedef struct noxfer_message {
mess_vfs_fs_utime m_vfs_fs_utime;
mess_vfs_lc_fdpair m_vfs_lc_fdpair;
mess_vfs_lc_lseek m_vfs_lc_lseek;
mess_vfs_lc_socklen m_vfs_lc_socklen;
mess_vfs_lchardriver_cancel m_vfs_lchardriver_cancel;
mess_vfs_lchardriver_openclose m_vfs_lchardriver_openclose;
mess_vfs_lchardriver_readwrite m_vfs_lchardriver_readwrite;

View File

@ -1,5 +1,6 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <errno.h>
#include <fcntl.h>
@ -18,20 +19,50 @@
#include <net/gen/udp.h>
#include <net/gen/udp_io.h>
#define DEBUG 0
static int _tcp_accept(int sock, struct sockaddr *__restrict address,
socklen_t *__restrict address_len);
static int _uds_accept(int sock, struct sockaddr *__restrict address,
socklen_t *__restrict address_len);
/*
* Accept a connection on a listening socket, creating a new socket.
*/
static int
__accept(int fd, struct sockaddr * __restrict address,
socklen_t * __restrict address_len)
{
message m;
int r;
if (address != NULL && address_len == NULL) {
errno = EFAULT;
return -1;
}
memset(&m, 0, sizeof(m));
m.m_lc_vfs_sockaddr.fd = fd;
m.m_lc_vfs_sockaddr.addr = (vir_bytes)address;
m.m_lc_vfs_sockaddr.addr_len = (address != NULL) ? *address_len : 0;
if ((r = _syscall(VFS_PROC_NR, VFS_ACCEPT, &m)) < 0)
return -1;
if (address != NULL)
*address_len = m.m_vfs_lc_socklen.len;
return r;
}
int accept(int sock, struct sockaddr *__restrict address,
socklen_t *__restrict address_len)
{
int r;
nwio_udpopt_t udpopt;
r = __accept(sock, address, address_len);
if (r != -1 || errno != ENOTSOCK)
return r;
r= _tcp_accept(sock, address, address_len);
if (r != -1 || errno != ENOTTY)
return r;
@ -45,19 +76,14 @@ int accept(int sock, struct sockaddr *__restrict address,
* filedescriptors that do not refer to a socket.
*/
r= ioctl(sock, NWIOGUDPOPT, &udpopt);
if (r == 0)
{
if (r == 0 || (r == -1 && errno != ENOTTY)) {
/* UDP socket */
errno= EOPNOTSUPP;
return -1;
}
if (errno == ENOTTY)
{
errno= ENOTSOCK;
return -1;
}
return r;
errno = ENOTSOCK;
return -1;
}
static int _tcp_accept(int sock, struct sockaddr *__restrict address,

View File

@ -1,5 +1,6 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <unistd.h>
#include <stdint.h>
@ -33,6 +34,22 @@ static int _udp_bind(int sock, const struct sockaddr *address,
static int _uds_bind(int sock, const struct sockaddr *address,
socklen_t address_len, struct sockaddr_un *uds_addr);
/*
* Bind a socket to a local address.
*/
static int
__bind(int fd, const struct sockaddr * address, socklen_t address_len)
{
message m;
memset(&m, 0, sizeof(m));
m.m_lc_vfs_sockaddr.fd = fd;
m.m_lc_vfs_sockaddr.addr = (vir_bytes)address;
m.m_lc_vfs_sockaddr.addr_len = address_len;
return _syscall(VFS_PROC_NR, VFS_BIND, &m);
}
int bind(int sock, const struct sockaddr *address, socklen_t address_len)
{
int r;
@ -40,6 +57,10 @@ int bind(int sock, const struct sockaddr *address, socklen_t address_len)
nwio_udpopt_t udpopt;
struct sockaddr_un uds_addr;
r = __bind(sock, address, address_len);
if (r != -1 || errno != ENOTSOCK)
return r;
r= ioctl(sock, NWIOGTCPCONF, &tcpconf);
if (r != -1 || errno != ENOTTY)
{
@ -74,10 +95,7 @@ int bind(int sock, const struct sockaddr *address, socklen_t address_len)
return _uds_bind(sock, address, address_len, &uds_addr);
}
#if DEBUG
fprintf(stderr, "bind: not implemented for fd %d\n", sock);
#endif
errno= ENOSYS;
errno = ENOTSOCK;
return -1;
}

View File

@ -1,5 +1,7 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <minix/config.h>
#include <errno.h>
@ -31,6 +33,22 @@ static int _udp_connect(int sock, const struct sockaddr *address,
static int _uds_connect(int sock, const struct sockaddr *address,
socklen_t address_len);
/*
* Connect a socket to a remote address.
*/
static int
__connect(int fd, const struct sockaddr * address, socklen_t address_len)
{
message m;
memset(&m, 0, sizeof(m));
m.m_lc_vfs_sockaddr.fd = fd;
m.m_lc_vfs_sockaddr.addr = (vir_bytes)address;
m.m_lc_vfs_sockaddr.addr_len = address_len;
return _syscall(VFS_PROC_NR, VFS_CONNECT, &m);
}
int connect(int sock, const struct sockaddr *address,
socklen_t address_len)
{
@ -38,6 +56,10 @@ int connect(int sock, const struct sockaddr *address,
nwio_tcpconf_t tcpconf;
nwio_udpopt_t udpopt;
r = __connect(sock, address, address_len);
if (r != -1 || errno != ENOTSOCK)
return r;
r= ioctl(sock, NWIOGTCPCONF, &tcpconf);
if (r != -1 || errno != ENOTTY)
{
@ -72,10 +94,7 @@ int connect(int sock, const struct sockaddr *address,
return r;
}
#if DEBUG
fprintf(stderr, "connect: not implemented for fd %d\n", sock);
#endif
errno= ENOSYS;
errno = ENOTSOCK;
return -1;
}

View File

@ -1,5 +1,6 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <errno.h>
#include <stdio.h>
@ -15,8 +16,6 @@
#include <net/gen/udp_io.h>
#include <sys/un.h>
#define DEBUG 0
static int _tcp_getpeername(int sock, struct sockaddr *__restrict address,
socklen_t *__restrict address_len, nwio_tcpconf_t *tcpconfp);
@ -26,6 +25,32 @@ static int _udp_getpeername(int sock, struct sockaddr *__restrict address,
static int _uds_getpeername(int sock, struct sockaddr *__restrict address,
socklen_t *__restrict address_len, struct sockaddr_un *uds_addr);
/*
* Get the remote address of a socket.
*/
static int
__getpeername(int fd, struct sockaddr * __restrict address,
socklen_t * __restrict address_len)
{
message m;
if (address_len == NULL) {
errno = EFAULT;
return -1;
}
memset(&m, 0, sizeof(m));
m.m_lc_vfs_sockaddr.fd = fd;
m.m_lc_vfs_sockaddr.addr = (vir_bytes)address;
m.m_lc_vfs_sockaddr.addr_len = *address_len;
if (_syscall(VFS_PROC_NR, VFS_GETPEERNAME, &m) < 0)
return -1;
*address_len = m.m_vfs_lc_socklen.len;
return 0;
}
int getpeername(int sock, struct sockaddr *__restrict address,
socklen_t *__restrict address_len)
{
@ -34,6 +59,10 @@ int getpeername(int sock, struct sockaddr *__restrict address,
nwio_udpopt_t udpopt;
struct sockaddr_un uds_addr;
r = __getpeername(sock, address, address_len);
if (r != -1 || errno != ENOTSOCK)
return r;
r= ioctl(sock, NWIOGTCPCONF, &tcpconf);
if (r != -1 || errno != ENOTTY)
{
@ -70,11 +99,7 @@ int getpeername(int sock, struct sockaddr *__restrict address,
&uds_addr);
}
#if DEBUG
fprintf(stderr, "getpeername: not implemented for fd %d\n", sock);
#endif
errno= ENOSYS;
errno = ENOTSOCK;
return -1;
}

View File

@ -1,13 +1,7 @@
/*
getsockname()
from socket emulation library for Minix 2.0.x
*/
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
@ -22,9 +16,7 @@
#include <net/gen/udp_io.h>
#include <sys/un.h>
/*
#define DEBUG 0
*/
static int _tcp_getsockname(int fd, struct sockaddr *__restrict address,
socklen_t *__restrict address_len, nwio_tcpconf_t *tcpconfp);
@ -35,6 +27,32 @@ static int _udp_getsockname(int fd, struct sockaddr *__restrict address,
static int _uds_getsockname(int fd, struct sockaddr *__restrict address,
socklen_t *__restrict address_len, struct sockaddr_un *uds_addr);
/*
* Get the local address of a socket.
*/
static int
__getsockname(int fd, struct sockaddr * __restrict address,
socklen_t * __restrict address_len)
{
message m;
if (address_len == NULL) {
errno = EFAULT;
return -1;
}
memset(&m, 0, sizeof(m));
m.m_lc_vfs_sockaddr.fd = fd;
m.m_lc_vfs_sockaddr.addr = (vir_bytes)address;
m.m_lc_vfs_sockaddr.addr_len = *address_len;
if (_syscall(VFS_PROC_NR, VFS_GETSOCKNAME, &m) < 0)
return -1;
*address_len = m.m_vfs_lc_socklen.len;
return 0;
}
int getsockname(int fd, struct sockaddr *__restrict address,
socklen_t *__restrict address_len)
{
@ -43,7 +61,11 @@ int getsockname(int fd, struct sockaddr *__restrict address,
nwio_udpopt_t udpopt;
struct sockaddr_un uds_addr;
#ifdef DEBUG
r = __getsockname(fd, address, address_len);
if (r != -1 || errno != ENOTSOCK)
return r;
#if DEBUG
fprintf(stderr,"mnx_getsockname: ioctl fd %d.\n", fd);
#endif
@ -83,11 +105,7 @@ int getsockname(int fd, struct sockaddr *__restrict address,
return _uds_getsockname(fd, address, address_len, &uds_addr);
}
#if DEBUG
fprintf(stderr, "getsockname: not implemented for fd %d\n", socket);
#endif
errno= ENOSYS;
errno = ENOTSOCK;
return -1;
}

View File

@ -1,5 +1,6 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <assert.h>
#include <errno.h>
@ -30,6 +31,34 @@ static int _uds_getsockopt(int sock, int level, int option_name,
static void getsockopt_copy(void *return_value, size_t return_len,
void *__restrict option_value, socklen_t *__restrict option_len);
/*
* Get socket options.
*/
static int
__getsockopt(int fd, int level, int option_name,
void * __restrict option_value, socklen_t * __restrict option_len)
{
message m;
if (option_len == NULL) {
errno = EFAULT;
return -1;
}
memset(&m, 0, sizeof(m));
m.m_lc_vfs_sockopt.fd = fd;
m.m_lc_vfs_sockopt.level = level;
m.m_lc_vfs_sockopt.name = option_name;
m.m_lc_vfs_sockopt.buf = (vir_bytes)option_value;
m.m_lc_vfs_sockopt.len = *option_len;
if (_syscall(VFS_PROC_NR, VFS_GETSOCKOPT, &m) < 0)
return -1;
*option_len = m.m_vfs_lc_socklen.len;
return 0;
}
int getsockopt(int sock, int level, int option_name,
void *__restrict option_value, socklen_t *__restrict option_len)
{
@ -38,6 +67,10 @@ int getsockopt(int sock, int level, int option_name,
nwio_udpopt_t udpopt;
struct sockaddr_un uds_addr;
r = __getsockopt(sock, level, option_name, option_value, option_len);
if (r != -1 || errno != ENOTSOCK)
return r;
r= ioctl(sock, NWIOGTCPOPT, &tcpopt);
if (r != -1 || errno != ENOTTY)
{
@ -74,11 +107,7 @@ int getsockopt(int sock, int level, int option_name,
option_value, option_len);
}
#if DEBUG
fprintf(stderr, "getsockopt: not implemented for fd %d\n", sock);
#endif
errno= ENOTSOCK;
errno = ENOTSOCK;
return -1;
}

View File

@ -1,5 +1,6 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <errno.h>
#include <stdio.h>
@ -14,12 +15,29 @@
#include <net/gen/udp.h>
#include <net/gen/udp_io.h>
#define DEBUG 0
/*
* Put a socket in listening mode.
*/
static int
__listen(int fd, int backlog)
{
message m;
memset(&m, 0, sizeof(m));
m.m_lc_vfs_listen.fd = fd;
m.m_lc_vfs_listen.backlog = backlog;
return _syscall(VFS_PROC_NR, VFS_LISTEN, &m);
}
int listen(int sock, int backlog)
{
int r;
r = __listen(sock, backlog);
if (r != -1 || errno != ENOTSOCK)
return r;
r= ioctl(sock, NWIOTCPLISTENQ, &backlog);
if (r != -1 || errno != ENOTTY)
return r;
@ -28,10 +46,6 @@ int listen(int sock, int backlog)
if (r != -1 || errno != ENOTTY)
return r;
#if DEBUG
fprintf(stderr, "listen: not implemented for fd %d\n", sock);
#endif
errno= ENOSYS;
errno = ENOTSOCK;
return -1;
}

View File

@ -1,5 +1,6 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <assert.h>
#include <errno.h>
@ -36,6 +37,38 @@ static ssize_t _uds_recvfrom_dgram(int sock, void *__restrict buffer,
size_t length, int flags, struct sockaddr *__restrict address,
socklen_t *__restrict address_len);
/*
* Receive a message from a socket.
*/
static ssize_t
__recvfrom(int fd, void * __restrict buffer, size_t length, int flags,
struct sockaddr * __restrict address,
socklen_t * __restrict address_len)
{
message m;
ssize_t r;
if (address != NULL && address_len == NULL) {
errno = EFAULT;
return -1;
}
memset(&m, 0, sizeof(m));
m.m_lc_vfs_sendrecv.fd = fd;
m.m_lc_vfs_sendrecv.buf = (vir_bytes)buffer;
m.m_lc_vfs_sendrecv.len = length;
m.m_lc_vfs_sendrecv.flags = flags;
m.m_lc_vfs_sendrecv.addr = (vir_bytes)address;
m.m_lc_vfs_sendrecv.addr_len = (address != NULL) ? *address_len : 0;
if ((r = _syscall(VFS_PROC_NR, VFS_RECVFROM, &m)) < 0)
return -1;
if (address != NULL)
*address_len = m.m_vfs_lc_socklen.len;
return r;
}
ssize_t recvfrom(int sock, void *__restrict buffer, size_t length,
int flags, struct sockaddr *__restrict address,
socklen_t *__restrict address_len)
@ -47,6 +80,10 @@ ssize_t recvfrom(int sock, void *__restrict buffer, size_t length,
struct sockaddr_un uds_addr;
int uds_sotype = -1;
r = __recvfrom(sock, buffer, length, flags, address, address_len);
if (r != -1 || errno != ENOTSOCK)
return r;
#if DEBUG
fprintf(stderr, "recvfrom: for fd %d\n", sock);
#endif
@ -121,12 +158,10 @@ ssize_t recvfrom(int sock, void *__restrict buffer, size_t length,
}
return rd;
}
}
#if DEBUG
fprintf(stderr, "recvfrom: not implemented for fd %d\n", sock);
#endif
abort();
errno = ENOTSOCK;
return -1;
}
static ssize_t _tcp_recvfrom(int sock, void *__restrict buffer, size_t length,

View File

@ -1,5 +1,6 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <errno.h>
#include <stdio.h>
@ -16,11 +17,82 @@
static ssize_t _uds_recvmsg_conn(int sock, struct msghdr *msg, int flags);
static ssize_t _uds_recvmsg_dgram(int sock, struct msghdr *msg, int flags);
/*
* Receive a message from a socket using a message structure.
*/
static ssize_t
__recvmsg(int fd, struct msghdr * msg, int flags)
{
struct iovec iov;
struct msghdr msg2, *msgp;
char *ptr;
message m;
ssize_t r;
/*
* Currently, MINIX3 does not support vector I/O operations. Like in
* the readv and writev implementations, we coalesce the data vector
* into a single buffer used for I/O. For future ABI compatibility, we
* then supply this buffer as a single vector element. This involves
* supplying a modified copy of the message header, as well as extra
* pre-checks. Once true vector I/O support has been added, the checks
* and vector I/O coalescing can be removed from here, leaving just the
* system call. Nothing will change at the system call ABI level.
*/
if (msg == NULL || (msg->msg_iovlen > 1 && msg->msg_iov == NULL)) {
errno = EFAULT;
return -1;
}
if (msg->msg_iovlen < 0 || msg->msg_iovlen > IOV_MAX) {
errno = EMSGSIZE; /* different from readv/writev */
return -1;
}
if (msg->msg_iovlen > 1) {
if ((r = _vectorio_setup(msg->msg_iov, msg->msg_iovlen, &ptr,
_VECTORIO_READ)) < 0)
return -1;
iov.iov_base = ptr;
iov.iov_len = r;
memcpy(&msg2, msg, sizeof(msg2));
msg2.msg_iov = &iov;
msg2.msg_iovlen = 1;
msgp = &msg2;
} else
msgp = msg;
/* Issue the actual system call. */
memset(&m, 0, sizeof(m));
m.m_lc_vfs_sockmsg.fd = fd;
m.m_lc_vfs_sockmsg.msgbuf = (vir_bytes)msgp;
m.m_lc_vfs_sockmsg.flags = flags;
r = _syscall(VFS_PROC_NR, VFS_RECVMSG, &m);
/* If we coalesced the vector, clean up and copy back the results. */
if (msgp != msg) {
_vectorio_cleanup(msg->msg_iov, msg->msg_iovlen, ptr, r,
_VECTORIO_READ);
if (r >= 0)
memcpy(msg, &msg2, sizeof(msg2));
}
return r;
}
ssize_t recvmsg(int sock, struct msghdr *msg, int flags)
{
int r;
int uds_sotype;
r = __recvmsg(sock, msg, flags);
if (r != -1 || errno != ENOTSOCK)
return r;
if (msg == NULL) {
errno= EFAULT;
return -1;
@ -39,11 +111,7 @@ ssize_t recvmsg(int sock, struct msghdr *msg, int flags)
}
}
#if DEBUG
fprintf(stderr, "recvmsg: not implemented for fd %d\n", sock);
#endif
errno= ENOSYS;
errno = ENOTSOCK;
return -1;
}

View File

@ -1,5 +1,6 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <errno.h>
#include <stdlib.h>
@ -17,11 +18,79 @@ static ssize_t _uds_sendmsg_conn(int sock, const struct msghdr *msg,
static ssize_t _uds_sendmsg_dgram(int sock, const struct msghdr *msg,
int flags);
/*
* Send a message on a socket using a message structure.
*/
static ssize_t
__sendmsg(int fd, const struct msghdr * msg, int flags)
{
struct iovec iov;
const struct msghdr *msgp;
struct msghdr msg2;
char *ptr;
message m;
ssize_t r;
/*
* Currently, MINIX3 does not support vector I/O operations. Like in
* the readv and writev implementations, we coalesce the data vector
* into a single buffer used for I/O. For future ABI compatibility, we
* then supply this buffer as a single vector element. This involves
* supplying a modified copy of the message header, as well as extra
* pre-checks. Once true vector I/O support has been added, the checks
* and vector I/O coalescing can be removed from here, leaving just the
* system call. Nothing will change at the system call ABI level.
*/
if (msg == NULL || (msg->msg_iovlen > 1 && msg->msg_iov == NULL)) {
errno = EFAULT;
return -1;
}
if (msg->msg_iovlen < 0 || msg->msg_iovlen > IOV_MAX) {
errno = EMSGSIZE; /* different from readv/writev */
return -1;
}
if (msg->msg_iovlen > 1) {
if ((r = _vectorio_setup(msg->msg_iov, msg->msg_iovlen, &ptr,
_VECTORIO_WRITE)) < 0)
return -1;
iov.iov_base = ptr;
iov.iov_len = r;
memcpy(&msg2, msg, sizeof(msg2));
msg2.msg_iov = &iov;
msg2.msg_iovlen = 1;
msgp = &msg2;
} else
msgp = msg;
memset(&m, 0, sizeof(m));
m.m_lc_vfs_sockmsg.fd = fd;
m.m_lc_vfs_sockmsg.msgbuf = (vir_bytes)msgp;
m.m_lc_vfs_sockmsg.flags = flags;
r = _syscall(VFS_PROC_NR, VFS_SENDMSG, &m);
/* If we coalesced the vector, clean up. */
if (msgp != msg) {
_vectorio_cleanup(msg->msg_iov, msg->msg_iovlen, ptr, r,
_VECTORIO_WRITE);
}
return r;
}
ssize_t sendmsg(int sock, const struct msghdr *msg, int flags)
{
int r;
int uds_sotype;
r = __sendmsg(sock, msg, flags);
if (r != -1 || errno != ENOTSOCK)
return r;
if (msg == NULL) {
errno= EFAULT;
return -1;
@ -41,11 +110,7 @@ ssize_t sendmsg(int sock, const struct msghdr *msg, int flags)
}
#if DEBUG
fprintf(stderr, "sendmsg: not implemented for fd %d\n", sock);
#endif
errno= ENOSYS;
errno = ENOTSOCK;
return -1;
}

View File

@ -1,5 +1,6 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <assert.h>
#include <errno.h>
@ -32,6 +33,26 @@ static ssize_t _uds_sendto_conn(int sock, const void *message, size_t length,
static ssize_t _uds_sendto_dgram(int sock, const void *message, size_t length,
int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
/*
* Send a message on a socket.
*/
static ssize_t
__sendto(int fd, const void * buffer, size_t length, int flags,
const struct sockaddr * dest_addr, socklen_t dest_len)
{
message m;
memset(&m, 0, sizeof(m));
m.m_lc_vfs_sendrecv.fd = fd;
m.m_lc_vfs_sendrecv.buf = (vir_bytes)buffer;
m.m_lc_vfs_sendrecv.len = length;
m.m_lc_vfs_sendrecv.flags = flags;
m.m_lc_vfs_sendrecv.addr = (vir_bytes)dest_addr;
m.m_lc_vfs_sendrecv.addr_len = dest_len;
return _syscall(VFS_PROC_NR, VFS_SENDTO, &m);
}
ssize_t sendto(int sock, const void *message, size_t length, int flags,
const struct sockaddr *dest_addr, socklen_t dest_len)
{
@ -41,6 +62,10 @@ ssize_t sendto(int sock, const void *message, size_t length, int flags,
nwio_ipopt_t ipopt;
int uds_sotype = -1;
r = __sendto(sock, message, length, flags, dest_addr, dest_len);
if (r != -1 || errno != ENOTSOCK)
return r;
r= ioctl(sock, NWIOGTCPOPT, &tcpopt);
if (r != -1 || errno != ENOTTY)
{
@ -114,10 +139,7 @@ ssize_t sendto(int sock, const void *message, size_t length, int flags,
return retval;
}
#if DEBUG
fprintf(stderr, "sendto: not implemented for fd %d\n", sock);
#endif
errno= ENOSYS;
errno = ENOTSOCK;
return -1;
}

View File

@ -1,6 +1,8 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
@ -26,6 +28,25 @@ static int _udp_setsockopt(int sock, int level, int option_name,
static int _uds_setsockopt(int sock, int level, int option_name,
const void *option_value, socklen_t option_len);
/*
* Set socket options.
*/
static int
__setsockopt(int fd, int level, int option_name, const void * option_value,
socklen_t option_len)
{
message m;
memset(&m, 0, sizeof(m));
m.m_lc_vfs_sockopt.fd = fd;
m.m_lc_vfs_sockopt.level = level;
m.m_lc_vfs_sockopt.name = option_name;
m.m_lc_vfs_sockopt.buf = (vir_bytes)option_value;
m.m_lc_vfs_sockopt.len = option_len;
return _syscall(VFS_PROC_NR, VFS_SETSOCKOPT, &m);
}
int setsockopt(int sock, int level, int option_name,
const void *option_value, socklen_t option_len)
{
@ -34,6 +55,10 @@ int setsockopt(int sock, int level, int option_name,
nwio_udpopt_t udpopt;
struct sockaddr_un uds_addr;
r = __setsockopt(sock, level, option_name, option_value, option_len);
if (r != -1 || errno != ENOTSOCK)
return r;
r= ioctl(sock, NWIOGTCPOPT, &tcpopt);
if (r != -1 || errno != ENOTTY)
{
@ -70,11 +95,7 @@ int setsockopt(int sock, int level, int option_name,
option_value, option_len);
}
#if DEBUG
fprintf(stderr, "setsockopt: not implemented for fd %d\n", sock);
#endif
errno= ENOTSOCK;
errno = ENOTSOCK;
return -1;
}

View File

@ -1,6 +1,8 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <sys/ioctl.h>
@ -16,12 +18,31 @@
static int _tcp_shutdown(int sock, int how);
static int _uds_shutdown(int sock, int how);
/*
* Shut down socket send and receive operations.
*/
static int
__shutdown(int fd, int how)
{
message m;
memset(&m, 0, sizeof(m));
m.m_lc_vfs_shutdown.fd = fd;
m.m_lc_vfs_shutdown.how = how;
return _syscall(VFS_PROC_NR, VFS_SHUTDOWN, &m);
}
int shutdown(int sock, int how)
{
int r;
struct sockaddr_un uds_addr;
nwio_tcpconf_t tcpconf;
r = __shutdown(sock, how);
if (r != -1 || errno != ENOTSOCK)
return r;
r= ioctl(sock, NWIOGTCPCONF, &tcpconf);
if (r != -1 || errno != ENOTTY)
{
@ -44,10 +65,7 @@ int shutdown(int sock, int how)
return _uds_shutdown(sock, how);
}
#if DEBUG
fprintf(stderr, "shutdown: not implemented for fd %d\n", sock);
#endif
errno= ENOSYS;
errno = ENOTSOCK;
return -1;
}

View File

@ -1,5 +1,6 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#ifdef __weak_alias
__weak_alias(socket, __socket30)
@ -38,9 +39,29 @@ static int _uds_socket(int type, int protocol);
static int _raw_socket(int type, int protocol);
static void _socket_flags(int type, int *result);
/*
* Create a socket.
*/
static int
__socket(int domain, int type, int protocol)
{
message m;
memset(&m, 0, sizeof(m));
m.m_lc_vfs_socket.domain = domain;
m.m_lc_vfs_socket.type = type;
m.m_lc_vfs_socket.protocol = protocol;
return _syscall(VFS_PROC_NR, VFS_SOCKET, &m);
}
int socket(int domain, int type, int protocol)
{
int sock_type;
int r, sock_type;
r = __socket(domain, type, protocol);
if (r != -1 || errno != EAFNOSUPPORT)
return r;
sock_type = type & ~SOCK_FLAGS_MASK;
@ -48,37 +69,25 @@ int socket(int domain, int type, int protocol)
fprintf(stderr, "socket: domain %d, type %d, protocol %d\n",
domain, type, protocol);
#endif
if (domain != AF_INET && domain != AF_UNIX)
{
#if DEBUG
fprintf(stderr, "socket: bad domain %d\n", domain);
#endif
errno= EAFNOSUPPORT;
return -1;
}
if (domain == AF_UNIX && (sock_type == SOCK_STREAM ||
sock_type == SOCK_DGRAM ||
sock_type == SOCK_SEQPACKET))
if (domain == AF_UNIX)
return _uds_socket(type, protocol);
if (domain == AF_INET && sock_type == SOCK_STREAM)
return _tcp_socket(type, protocol);
if (domain == AF_INET) {
switch (sock_type) {
case SOCK_STREAM:
return _tcp_socket(type, protocol);
case SOCK_DGRAM:
return _udp_socket(type, protocol);
case SOCK_RAW:
return _raw_socket(type, protocol);
default:
errno = EPROTOTYPE;
return -1;
}
}
if (domain == AF_INET && sock_type == SOCK_DGRAM)
return _udp_socket(type, protocol);
if (domain == AF_INET && sock_type == SOCK_RAW && protocol == IPPROTO_ICMP)
return _raw_socket(type, protocol);
if (domain == AF_INET && sock_type == SOCK_RAW && protocol == IPPROTO_UDP)
return _raw_socket(type, protocol);
#if DEBUG
fprintf(stderr, "socket: nothing for domain %d, type %d, protocol %d\n",
domain, type, protocol);
#endif
errno= EPROTOTYPE;
errno = EAFNOSUPPORT;
return -1;
}
@ -194,6 +203,15 @@ static int _raw_socket(int type, int protocol)
static int _uds_socket(int type, int protocol)
{
int fd, r, flags = O_RDWR, sock_type;
sock_type = type & ~SOCK_FLAGS_MASK;
if (sock_type != SOCK_STREAM &&
sock_type != SOCK_DGRAM &&
sock_type != SOCK_SEQPACKET) {
errno = EPROTOTYPE;
return -1;
}
if (protocol != 0)
{
#if DEBUG
@ -212,7 +230,6 @@ static int _uds_socket(int type, int protocol)
/* set the type for the socket via ioctl (SOCK_DGRAM,
* SOCK_STREAM, SOCK_SEQPACKET, etc)
*/
sock_type = type & ~SOCK_FLAGS_MASK;
r= ioctl(fd, NWIOSUDSTYPE, &sock_type);
if (r == -1) {
int ioctl_errno;

View File

@ -1,6 +1,8 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
@ -17,32 +19,44 @@
static int _uds_socketpair(int type, int protocol, int sv[2]);
/*
* Create a pair of connected sockets
* Create a pair of connected sockets.
*/
int socketpair(int domain, int type, int protocol, int sv[2]) {
static int
__socketpair(int domain, int type, int protocol, int sv[2])
{
message m;
memset(&m, 0, sizeof(m));
m.m_lc_vfs_socket.domain = domain;
m.m_lc_vfs_socket.type = type;
m.m_lc_vfs_socket.protocol = protocol;
if (_syscall(VFS_PROC_NR, VFS_SOCKETPAIR, &m) < 0)
return -1;
sv[0] = m.m_vfs_lc_fdpair.fd0;
sv[1] = m.m_vfs_lc_fdpair.fd1;
return 0;
}
int
socketpair(int domain, int type, int protocol, int sv[2])
{
int r;
r = __socketpair(domain, type, protocol, sv);
if (r != -1 || errno != EAFNOSUPPORT)
return r;
#if DEBUG
fprintf(stderr, "socketpair: domain %d, type %d, protocol %d\n",
domain, type, protocol);
#endif
if (domain != AF_UNIX)
{
errno = EAFNOSUPPORT;
return -1;
}
if (domain == AF_UNIX &&
(type == SOCK_STREAM || type == SOCK_SEQPACKET))
if (domain == AF_UNIX)
return _uds_socketpair(type, protocol, sv);
#if DEBUG
fprintf(stderr,
"socketpair: nothing for domain %d, type %d, protocol %d\n",
domain, type, protocol);
#endif
errno= EPROTOTYPE;
errno = EAFNOSUPPORT;
return -1;
}
@ -52,6 +66,11 @@ static int _uds_socketpair(int type, int protocol, int sv[2])
int r, i;
struct stat sbuf;
if (type != SOCK_STREAM && type != SOCK_SEQPACKET) {
errno = EPROTOTYPE;
return -1;
}
if (protocol != 0)
{
#if DEBUG

View File

@ -7,7 +7,8 @@ SRCS= main.c open.c read.c write.c pipe.c dmap.c \
filedes.c stadir.c protect.c time.c \
lock.c misc.c utility.c select.c table.c \
vnode.c vmnt.c request.c \
tll.c comm.c worker.c coredump.c
tll.c comm.c worker.c coredump.c \
socket.c
.if ${MKCOVERAGE} != "no"
SRCS+= gcov.c

View File

@ -247,6 +247,27 @@ int req_utime(endpoint_t fs_e, ino_t inode_nr, struct timespec * actv,
struct timespec * modtv);
int req_newdriver(endpoint_t fs_e, dev_t dev, char *label);
/* socket.c */
int do_socket(void);
int do_socketpair(void);
int do_bind(void);
int do_connect(void);
int do_listen(void);
int do_accept(void);
void resume_accept(struct fproc *rfp, int status, dev_t dev,
unsigned int addr_len, int listen_fd);
int do_sendto(void);
int do_recvfrom(void);
void resume_recvfrom(struct fproc *rfp, int status, unsigned int addr_len);
int do_sockmsg(void);
void resume_recvmsg(struct fproc *rfp, int status, unsigned int ctl_len,
unsigned int addr_len, int flags, vir_bytes msg_buf);
int do_setsockopt(void);
int do_getsockopt(void);
int do_getsockname(void);
int do_getpeername(void);
int do_shutdown(void);
/* stadir.c */
int do_chdir(void);
int do_fchdir(void);

179
minix/servers/vfs/socket.c Normal file
View File

@ -0,0 +1,179 @@
/*
* IMPORTANT NOTICE: THIS FILE CONTAINS STUBS ONLY RIGHT NOW, TO ENABLE A
* SEAMLESS TRANSITION TO THE NEW API FOR PROGRAMS STATICALLY LINKED TO LIBC!
*
* This file implements the upper socket layer of VFS: the BSD socket system
* calls, and any associated file descriptor, file pointer, vnode, and file
* system processing. In most cases, this layer will call into the lower
* socket layer in order to send the request to a socket driver. Generic file
* calls (e.g., read, write, ioctl, and select) are not implemented here, and
* will directly call into the lower socket layer as well.
*
* The following table shows the system call numbers implemented in this file,
* along with their request and reply message types. Each request layout
* message type is prefixed with "m_lc_vfs_". Each reply layout message type
* is prefixed with "m_vfs_lc_". For requests without a specific reply layout,
* only the "m_type" message field is used in the reply message.
*
* Type Request layout Reply layout
* ---- -------------- ------------
* VFS_SOCKET socket
* VFS_SOCKETPAIR socket fdpair
* VFS_BIND sockaddr
* VFS_CONNECT sockaddr
* VFS_LISTEN listen
* VFS_ACCEPT sockaddr socklen
* VFS_SENDTO sendrecv
* VFS_RECVFROM sendrecv socklen
* VFS_SENDMSG sockmsg
* VFS_RECVMSG sockmsg
* VFS_SETSOCKOPT sockopt
* VFS_GETSOCKOPT sockopt socklen
* VFS_GETSOCKNAME sockaddr socklen
* VFS_GETPEERNAME sockaddr socklen
* VFS_SHUTDOWN shutdown
*/
#include "fs.h"
#include <sys/socket.h>
/*
* Create a socket.
*/
int
do_socket(void)
{
return EAFNOSUPPORT;
}
/*
* Create a pair of connected sockets.
*/
int
do_socketpair(void)
{
return EAFNOSUPPORT;
}
/*
* Bind a socket to a local address.
*/
int
do_bind(void)
{
return ENOTSOCK;
}
/*
* Connect a socket to a remote address.
*/
int
do_connect(void)
{
return ENOTSOCK;
}
/*
* Put a socket in listening mode.
*/
int
do_listen(void)
{
return ENOTSOCK;
}
/*
* Accept a connection on a listening socket, creating a new socket.
*/
int
do_accept(void)
{
return ENOTSOCK;
}
/*
* Send a message on a socket.
*/
int
do_sendto(void)
{
return ENOTSOCK;
}
/*
* Receive a message from a socket.
*/
int
do_recvfrom(void)
{
return ENOTSOCK;
}
/*
* Send or receive a message on a socket using a message structure.
*/
int
do_sockmsg(void)
{
return ENOTSOCK;
}
/*
* Set socket options.
*/
int
do_setsockopt(void)
{
return ENOTSOCK;
}
/*
* Get socket options.
*/
int
do_getsockopt(void)
{
return ENOTSOCK;
}
/*
* Get the local address of a socket.
*/
int
do_getsockname(void)
{
return ENOTSOCK;
}
/*
* Get the remote address of a socket.
*/
int
do_getpeername(void)
{
return ENOTSOCK;
}
/*
* Shut down socket send and receive operations.
*/
int
do_shutdown(void)
{
return ENOTSOCK;
}

View File

@ -64,4 +64,19 @@ int (* const call_vec[NR_VFS_CALLS])(void) = {
CALL(VFS_COPYFD) = do_copyfd, /* copyfd(2) */
CALL(VFS_CHECKPERMS) = do_checkperms, /* checkperms(2) */
CALL(VFS_GETSYSINFO) = do_getsysinfo, /* getsysinfo(2) */
CALL(VFS_SOCKET) = do_socket, /* socket(2) */
CALL(VFS_SOCKETPAIR) = do_socketpair, /* socketpair(2) */
CALL(VFS_BIND) = do_bind, /* bind(2) */
CALL(VFS_CONNECT) = do_connect, /* connect(2) */
CALL(VFS_LISTEN) = do_listen, /* listen(2) */
CALL(VFS_ACCEPT) = do_accept, /* accept(2) */
CALL(VFS_SENDTO) = do_sendto, /* sendto(2) */
CALL(VFS_SENDMSG) = do_sockmsg, /* sendmsg(2) */
CALL(VFS_RECVFROM) = do_recvfrom, /* recvfrom(2) */
CALL(VFS_RECVMSG) = do_sockmsg, /* recvmsg(2) */
CALL(VFS_SETSOCKOPT) = do_setsockopt, /* setsockopt(2) */
CALL(VFS_GETSOCKOPT) = do_getsockopt, /* getsockopt(2) */
CALL(VFS_GETSOCKNAME) = do_getsockname, /* getsockname(2) */
CALL(VFS_GETPEERNAME) = do_getpeername, /* getpeername(2) */
CALL(VFS_SHUTDOWN) = do_shutdown, /* shutdown(2) */
};

View File

@ -307,8 +307,9 @@ void test_shutdown(const struct socket_test_info *info)
errno = 0;
rc = shutdown(0, how[i]);
if (!(rc == -1 && errno == ENOSYS) && !info->bug_shutdown) {
test_fail("shutdown() should have failed with ENOSYS");
if (!(rc == -1 && errno == ENOTSOCK) && !info->bug_shutdown) {
test_fail("shutdown() should have failed with "
"ENOTSOCK");
}
debug("test shutdown() with a socket that is not connected");

View File

@ -317,7 +317,9 @@ static void test_bind_unix(void)
addr.sun_path[2] = 'o';
addr.sun_path[3] = '\0';
SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
rc = bind(sd, (struct sockaddr *) &addr, strlen(addr.sun_path) + 1);
rc = bind(sd, (struct sockaddr *) &addr,
offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path) +
1);
if (rc == -1) {
test_fail("bind() should have worked");
}

View File

@ -98,7 +98,7 @@ put_message(struct trace_proc * proc, const char * name, int flags,
if (flags & PF_ALT)
put_endpoint(proc, "m_source", m.m_source);
put_value(proc, "m_type", "%x", m.m_type);
put_value(proc, "m_type", "0x%x", m.m_type);
put_close_struct(proc, FALSE /*all*/);
}

View File

@ -17,6 +17,8 @@
#include <minix/endpoint.h>
#include <machine/stackframe.h>
#include <netinet/in.h>
#include "proc.h"
#include "type.h"
#include "proto.h"

View File

@ -108,13 +108,9 @@ put_ipaddr(struct trace_proc * proc, const char * name, ipaddr_t ipaddr)
{
struct in_addr in;
if (!valuesonly) {
in.s_addr = ipaddr;
in.s_addr = ipaddr;
/* Is this an acceptable encapsulation? */
put_value(proc, name, "[%s]", inet_ntoa(in));
} else
put_value(proc, name, "0x%08x", ntohl(ipaddr));
put_in_addr(proc, name, in);
}
static void
@ -193,97 +189,6 @@ static const struct flags udpopt_flags[] = {
FLAG(NWUO_DI_IPOPT),
};
static void
put_family(struct trace_proc * proc, const char * name, int family)
{
const char *text = NULL;
if (!valuesonly) {
/* TODO: add all the other protocols */
switch (family) {
TEXT(AF_UNSPEC);
TEXT(AF_LOCAL);
TEXT(AF_INET);
TEXT(AF_INET6);
}
}
if (text != NULL)
put_field(proc, name, text);
else
put_value(proc, name, "%d", family);
}
static const struct flags sock_type[] = {
FLAG_MASK(~SOCK_FLAGS_MASK, SOCK_STREAM),
FLAG_MASK(~SOCK_FLAGS_MASK, SOCK_DGRAM),
FLAG_MASK(~SOCK_FLAGS_MASK, SOCK_RAW),
FLAG_MASK(~SOCK_FLAGS_MASK, SOCK_RDM),
FLAG_MASK(~SOCK_FLAGS_MASK, SOCK_SEQPACKET),
FLAG(SOCK_CLOEXEC),
FLAG(SOCK_NONBLOCK),
FLAG(SOCK_NOSIGPIPE),
};
static void
put_shutdown_how(struct trace_proc * proc, const char * name, int how)
{
const char *text = NULL;
if (!valuesonly) {
switch (how) {
TEXT(SHUT_RD);
TEXT(SHUT_WR);
TEXT(SHUT_RDWR);
}
}
if (text != NULL)
put_field(proc, name, text);
else
put_value(proc, name, "%d", how);
}
static void
put_struct_uucred(struct trace_proc * proc, const char * name, int flags,
vir_bytes addr)
{
struct uucred cred;
if (!put_open_struct(proc, name, flags, addr, &cred, sizeof(cred)))
return;
put_value(proc, "cr_uid", "%u", cred.cr_uid);
if (verbose > 0) {
put_value(proc, "cr_gid", "%u", cred.cr_gid);
if (verbose > 1)
put_value(proc, "cr_ngroups", "%d", cred.cr_ngroups);
put_groups(proc, "cr_groups", PF_LOCADDR,
(vir_bytes)&cred.cr_groups, cred.cr_ngroups);
}
put_close_struct(proc, verbose > 0);
}
static void
put_cmsg_type(struct trace_proc * proc, const char * name, int type)
{
const char *text = NULL;
if (!valuesonly) {
switch (type) {
TEXT(SCM_RIGHTS);
TEXT(SCM_CREDS);
TEXT(SCM_TIMESTAMP);
}
}
if (text != NULL)
put_field(proc, name, text);
else
put_value(proc, name, "%d", type);
}
static void
put_msg_control(struct trace_proc * proc, struct msg_control * ptr)
{
@ -497,7 +402,7 @@ net_ioctl_arg(struct trace_proc * proc, unsigned long req, void * ptr, int dir)
if ((sun = (struct sockaddr_un *)ptr) == NULL)
return dir;
put_family(proc, "sun_family", sun->sun_family);
put_socket_family(proc, "sun_family", sun->sun_family);
/* This could be extended to a generic sockaddr printer.. */
if (sun->sun_family == AF_LOCAL) {
@ -512,8 +417,7 @@ net_ioctl_arg(struct trace_proc * proc, unsigned long req, void * ptr, int dir)
if (ptr == NULL)
return dir;
put_flags(proc, NULL, sock_type, COUNT(sock_type), "0x%x",
*(int *)ptr);
put_socket_type(proc, NULL, *(int *)ptr);
return IF_ALL;
case NWIOSUDSSHUT:

View File

@ -100,10 +100,6 @@ extern int allnames;
extern unsigned int verbose;
extern unsigned int valuesonly;
/* vfs.c */
void put_fd(struct trace_proc *proc, const char *name, int fd);
void put_dev(struct trace_proc *proc, const char *name, dev_t dev);
/* service */
const struct calls pm_calls;
const struct calls vfs_calls;
@ -112,6 +108,17 @@ const struct calls mib_calls;
const struct calls vm_calls;
const struct calls ipc_calls;
/* service/vfs.c */
void put_fd(struct trace_proc *proc, const char *name, int fd);
void put_dev(struct trace_proc *proc, const char *name, dev_t dev);
void put_in_addr(struct trace_proc *proc, const char *name, struct in_addr in);
void put_socket_type(struct trace_proc *proc, const char *name, int type);
void put_socket_family(struct trace_proc *proc, const char *name, int family);
void put_struct_uucred(struct trace_proc *proc, const char *name, int flags,
vir_bytes addr);
void put_cmsg_type(struct trace_proc *proc, const char *name, int type);
void put_shutdown_how(struct trace_proc *proc, const char *name, int how);
/* ioctl/block.c */
const char *block_ioctl_name(unsigned long req);
int block_ioctl_arg(struct trace_proc *proc, unsigned long req, void *ptr,

File diff suppressed because it is too large Load Diff