*
* swift: PROTOCOL is IPPROTO_SWIFT. Ignore TYPE.
*/
-int sw_socket (int __domain, int __type, int __protocol)
+int sw_socket(int __domain, int __type, int __protocol)
{
int s;
struct sock_list *list;
- s = socket(__domain, SOCK_RAW, IPPROTO_SWIFT);
- if (s < 0)
+ if (__domain != PF_INET || __type != SOCK_RAW || __protocol != IPPROTO_SWIFT) {
+ errno = EINVAL;
goto sock_err;
+ }
+
+ s = socket(PF_INET, SOCK_RAW, IPPROTO_SWIFT);
+ if (s < 0) {
+ goto sock_err;
+ }
list = list_add_socket(s);
- if (list == NULL)
+ if (list == NULL) {
+ errno = ENOMEM;
goto list_add_err;
+ }
/* Socket is fully open. */
list->rw_state = STATE_NO_SHUT;
*
* swift: ADDR is of type struct sockaddr_sw.
*/
-int sw_bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
+int sw_bind(int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
{
struct sock_list *list;
errno = EADDRINUSE;
goto list_elem_err;
}
+
/* Update __fd entry in socket management list. */
list = list_update_socket_address(__fd, __addr);
if (list == NULL) {
}
/* Put the local address of FD into *ADDR and its length in *LEN. */
-int sw_getsockname (int __fd, __SOCKADDR_ARG __addr,
+int sw_getsockname(int __fd, __SOCKADDR_ARG __addr,
socklen_t *__restrict __len)
{
/* TODO */
* This function is a cancellation point and therefore not marked with
* __THROW.
*/
-ssize_t sw_sendto (int __fd, __const void *__buf, size_t __n,
+ssize_t sw_sendto(int __fd, __const void *__buf, size_t __n,
int __flags, __CONST_SOCKADDR_ARG __addr,
socklen_t __addr_len)
{
ssize_t bytes_sent;
+ struct sock_list *list;
+ struct iovec __iov[1];
+ struct msghdr __msgh;
+
+ list = list_elem_from_socket(__fd);
+ if (list == NULL) {
+ errno = EBADF;
+ goto sock_err;
+ }
- /* TODO */
+ if (list->rw_state == STATE_SHUT_WR || list->rw_state == STATE_SHUT_RDWR) {
+ errno = ENOTCONN;
+ goto sock_err;
+ }
+/*
+ if (list->state == STATE_NOBOUND) {
+ errno = EDESTADDRREQ;
+ goto sock_err;
+ }
+ */
+
+ /* Specify the components of the message in an "iovec". */
+ __iov[0].iov_base = __buf;
+ __iov[0].iov_len = __n;
+
+ /* The message header contains parameters for sendmsg. */
+ __msgh.msg_name = (caddr_t) __addr;
+ __msgh.msg_namelen = sizeof(__addr);
+ __msgh.msg_iov = __iov;
+ __msgh.msg_iovlen = 1;
+ __msgh.msg_control = NULL; /* irrelevant to AF_INET */
+ __msgh.msg_controllen = 0; /* irrelevant to AF_INET */
+
+ return sendmsg(__fd, &__msgh, 0);
- return bytes_sent;
+sock_err:
+ return -1;
}
/*
* This function is a cancellation point and therefore not marked with
* __THROW.
*/
-ssize_t sw_recvfrom (int __fd, void *__restrict __buf, size_t __n,
+ssize_t sw_recvfrom(int __fd, void *__restrict __buf, size_t __n,
int __flags, __SOCKADDR_ARG __addr,
socklen_t *__restrict __addr_len)
{
* This function is a cancellation point and therefore not marked with
* __THROW.
*/
-ssize_t sw_sendmsg (int __fd, __const struct msghdr *__message,
+ssize_t sw_sendmsg(int __fd, __const struct msghdr *__message,
int __flags)
{
ssize_t bytes_sent;
- /* TODO */
-
- return bytes_sent;
+ return sendmsg(__fd, __message, __flags);
}
/*
* This function is a cancellation point and therefore not marked with
* __THROW.
*/
-ssize_t sw_recvmsg (int __fd, struct msghdr *__message, int __flags)
+ssize_t sw_recvmsg(int __fd, struct msghdr *__message, int __flags)
{
ssize_t bytes_recv;
* LEVEL into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the
* value's actual length. Returns 0 on success, -1 for errors.
*/
-int sw_getsockopt (int __fd, int __level, int __optname,
+int sw_getsockopt(int __fd, int __level, int __optname,
void *__restrict __optval,
socklen_t *__restrict __optlen)
{
* Returns 0 on success, -1 for errors.
*/
-int sw_setsockopt (int __fd, int __level, int __optname,
+int sw_setsockopt(int __fd, int __level, int __optname,
__const void *__optval, socklen_t __optlen)
{
/* Call classical interface of setsockopt(2). */
* SHUT_RDWR = No more receptions or transmissions.
* Returns 0 on success, -1 for errors.
*/
-int sw_shutdown (int __fd, int __how)
+int sw_shutdown(int __fd, int __how)
{
struct sock_list *list;
list_unlink_err:
return -1;
}
+
+/*
+ * Close file descriptor for socket FD.
+ * Returns 0 on success, -1 for errors.
+ */
+int sw_close(int __fd)
+{
+ struct sock_list *list;
+
+ /* Remove socket from socket management structure. */
+ list = list_unlink_socket(__fd);
+ if (list == NULL) {
+ errno = EBADF;
+ goto list_unlink_err;
+ }
+
+ /* Call classical interface of close(2). */
+ return close(__fd);
+
+list_unlink_err:
+ return -1;
+}