int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
- int ret=0;
- int tmp_addrlen=0x1c;
+ int ret = 0;
+ int tmp_addrlen = 0x1c;
+ int fd, dev;
+ __handle *handle;
u32 *cmdbuf = getThreadCommandBuffer();
u8 tmpaddr[0x1c];
u32 saved_threadstorage[2];
+ sockfd = soc_get_fd(sockfd);
+ if(sockfd < 0)
+ {
+ SOCU_errno = sockfd;
+ return -1;
+ }
+
+ dev = FindDevice("soc:");
+ if(dev < 0)
+ {
+ SOCU_errno = -ENODEV;
+ return -1;
+ }
+
+ fd = __alloc_handle(sizeof(__handle) + sizeof(Handle));
+ if(fd < 0)
+ {
+ SOCU_errno = -ENOMEM;
+ return -1;
+ }
+
+ handle = __get_handle(fd);
+ handle->device = dev;
+ handle->fileStruct = ((void *)handle) + sizeof(__handle);
+
memset(tmpaddr, 0, 0x1c);
cmdbuf[0] = 0x00040082;
cmdbuf[0x100>>2] = (tmp_addrlen<<14) | 2;
cmdbuf[0x104>>2] = (u32)tmpaddr;
- if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
+ if((ret = svcSendSyncRequest(SOCU_handle)) != 0)
+ {
+ __release_handle(fd);
+ return ret;
+ }
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
- if(ret==0)ret = _net_convert_error(cmdbuf[2]);
- if(ret<0)SOCU_errno = ret;
+ if(ret == 0)
+ ret = _net_convert_error(cmdbuf[2]);
- if(ret>=0 && addr!=NULL)
+ if(ret < 0)
+ SOCU_errno = ret;
+
+ if(ret >= 0 && addr != NULL)
{
addr->sa_family = tmpaddr[1];
- if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
+ if(*addrlen > tmpaddr[0])
+ *addrlen = tmpaddr[0];
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
}
- if(ret<0)return -1;
- return ret;
+ if(ret < 0)
+ {
+ __release_handle(fd);
+ return -1;
+ }
+ else
+ *(Handle*)handle->fileStruct = ret;
+
+ return fd;
}
u32 *cmdbuf = getThreadCommandBuffer();
u8 tmpaddr[0x1c];
+ sockfd = soc_get_fd(sockfd);
+ if(sockfd < 0)
+ {
+ SOCU_errno = sockfd;
+ return -1;
+ }
+
memset(tmpaddr, 0, 0x1c);
if(addr->sa_family == AF_INET)
int closesocket(int sockfd)
{
- int ret=0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
- cmdbuf[0] = 0x000B0042;
- cmdbuf[1] = (u32)sockfd;
- cmdbuf[2] = 0x20;
-
- if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
-
- ret = (int)cmdbuf[1];
- if(ret==0)ret =_net_convert_error(cmdbuf[2]);
- SOCU_errno = ret;
-
- if(ret!=0)return -1;
- return 0;
+ int fd = soc_get_fd(sockfd);
+ if(fd < 0)
+ {
+ SOCU_errno = fd;
+ return -1;
+ }
+
+ return close(sockfd);
}
#include "soc_common.h"
#include <errno.h>
+#include <sys/iosupport.h>
Handle SOCU_handle = 0;
int SOCU_errno = 0;
#pragma once
+#include <errno.h>
#include <string.h>
+#include <sys/iosupport.h>
#include <3ds/types.h>
#include <3ds/svc.h>
#include <3ds/srv.h>
#include <3ds/services/soc.h>
+int __alloc_handle(int size);
+__handle *__get_handle(int fd);
+void __release_handle(int fd);
+
extern Handle SOCU_handle;
extern int SOCU_errno;
extern Handle socMemhandle;
+static inline int
+soc_get_fd(int fd)
+{
+ __handle *handle = __get_handle(fd);
+ if(handle == NULL)
+ return -ENODEV;
+ if(strcmp(devoptab_list[handle->device]->name, "soc") != 0)
+ return -ENOTSOCK;
+ return *(Handle*)handle->fileStruct;
+}
+
s32 _net_convert_error(s32 sock_retval);
u32 *cmdbuf = getThreadCommandBuffer();
u8 tmpaddr[0x1c];
+ sockfd = soc_get_fd(sockfd);
+ if(sockfd < 0)
+ {
+ SOCU_errno = sockfd;
+ return -1;
+ }
+
memset(tmpaddr, 0, 0x1c);
if(addr->sa_family == AF_INET)
return newflags;
}
-int fcntl(int fd, int cmd, ...)
+int fcntl(int sockfd, int cmd, ...)
{
int ret = 0;
int arg = 0;
va_list args;
+ sockfd = soc_get_fd(sockfd);
+ if(sockfd < 0)
+ {
+ SOCU_errno = sockfd;
+ return -1;
+ }
+
if(cmd != F_GETFL && cmd != F_SETFL)
{
SOCU_errno = -EINVAL;
va_end(args);
cmdbuf[0] = 0x001300C2;
- cmdbuf[1] = (u32)fd;
+ cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)cmd;
cmdbuf[3] = (u32)arg;
cmdbuf[4] = 0x20;
u32 saved_threadstorage[2];
u8 tmpaddr[0x1c];
+ sockfd = soc_get_fd(sockfd);
+ if(sockfd < 0)
+ {
+ SOCU_errno = sockfd;
+ return -1;
+ }
+
cmdbuf[0] = 0x00180082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = 0x1c;
u32 saved_threadstorage[2];
u8 tmpaddr[0x1c];
+ sockfd = soc_get_fd(sockfd);
+ if(sockfd < 0)
+ {
+ SOCU_errno = sockfd;
+ return -1;
+ }
+
cmdbuf[0] = 0x00170082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = 0x1c;
u32 *cmdbuf = getThreadCommandBuffer();
u32 saved_threadstorage[2];
+ sockfd = soc_get_fd(sockfd);
+ if(sockfd < 0)
+ {
+ SOCU_errno = sockfd;
+ return -1;
+ }
+
cmdbuf[0] = 0x00110102;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)level;
#include "soc_common.h"
+#include <sys/socket.h>
+
+static int soc_open(struct _reent *r, void *fileStruct, const char *path, int flags, int mode);
+static int soc_close(struct _reent *r, int fd);
+static ssize_t soc_write(struct _reent *r, int fd, const char *ptr, size_t len);
+static ssize_t soc_read(struct _reent *r, int fd, char *ptr, size_t len);
+
+static devoptab_t
+soc_devoptab =
+{
+ .name = "soc",
+ .structSize = sizeof(Handle),
+ .open_r = soc_open,
+ .close_r = soc_close,
+ .write_r = soc_write,
+ .read_r = soc_read,
+ .seek_r = NULL,
+ .fstat_r = NULL,
+ .stat_r = NULL,
+ .link_r = NULL,
+ .unlink_r = NULL,
+ .chdir_r = NULL,
+ .rename_r = NULL,
+ .mkdir_r = NULL,
+ .dirStateSize = 0,
+ .diropen_r = NULL,
+ .dirreset_r = NULL,
+ .dirnext_r = NULL,
+ .dirclose_r = NULL,
+ .statvfs_r = NULL,
+ .ftruncate_r = NULL,
+ .fsync_r = NULL,
+ .deviceData = NULL,
+ .chmod_r = NULL,
+ .fchmod_r = NULL,
+};
+
static Result socu_cmd1(Handle memhandle, u32 memsize)
{
{
Result ret=0;
+ /* check that the "soc" device doesn't already exist */
+ int dev = FindDevice("soc:");
+ if(dev >= 0)
+ return -1;
+
+ /* add the "soc" device */
+ dev = AddDevice(&soc_devoptab);
+ if(dev < 0)
+ return dev;
+
ret = svcCreateMemoryBlock(&socMemhandle, (u32)context_addr, context_size, 0, 3);
- if(ret!=0)return ret;
+ if(ret != 0)
+ {
+ RemoveDevice("soc");
+ return ret;
+ }
+
+ if((ret = srvGetServiceHandle(&SOCU_handle, "soc:U")) != 0)
+ {
+ RemoveDevice("soc");
+ return ret;
+ }
- if((ret = srvGetServiceHandle(&SOCU_handle, "soc:U"))!=0)return ret;
+ if((ret = socu_cmd1(socMemhandle, context_size)) != 0)
+ {
+ RemoveDevice("soc");
+ return ret;
+ }
- return socu_cmd1(socMemhandle, context_size);
+ return 0;
}
Result SOC_Shutdown(void)
{
Result ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
+ int dev;
cmdbuf[0] = 0x00190000;
svcCloseHandle(SOCU_handle);
svcCloseHandle(socMemhandle);
+ dev = FindDevice("soc:");
+ if(dev >= 0)
+ RemoveDevice("soc");
+
return cmdbuf[1];
}
+
+static int
+soc_open(struct _reent *r,
+ void *fileStruct,
+ const char *path,
+ int flags,
+ int mode)
+{
+ return -1;
+}
+
+static int
+soc_close(struct _reent *r,
+ int fd)
+{
+ Handle sockfd = *(Handle*)fd;
+
+ int ret=0;
+ u32 *cmdbuf = getThreadCommandBuffer();
+
+ cmdbuf[0] = 0x000B0042;
+ cmdbuf[1] = (u32)sockfd;
+ cmdbuf[2] = 0x20;
+
+ if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
+
+ ret = (int)cmdbuf[1];
+ if(ret==0)ret =_net_convert_error(cmdbuf[2]);
+ SOCU_errno = ret;
+
+ if(ret!=0)return -1;
+ return 0;
+}
+
+static ssize_t
+soc_write(struct _reent *r,
+ int fd,
+ const char *ptr,
+ size_t len)
+{
+ Handle sockfd = *(Handle*)fd;
+ return send(sockfd, ptr, len, 0);
+}
+
+static ssize_t
+soc_read(struct _reent *r,
+ int fd,
+ char *ptr,
+ size_t len)
+{
+ Handle sockfd = *(Handle*)fd;
+ return recv(sockfd, ptr, len, 0);
+}
#include <stdarg.h>
#include <sys/ioctl.h>
-int ioctl(int fd, int request, ...)
+int ioctl(int sockfd, int request, ...)
{
int ret;
int flags;
int *value;
va_list ap;
+ sockfd = soc_get_fd(sockfd);
+ if(sockfd < 0)
+ {
+ SOCU_errno = sockfd;
+ return -1;
+ }
+
va_start(ap, request);
switch(request) {
return -1;
}
- flags = fcntl(fd, F_GETFL, 0);
+ flags = fcntl(sockfd, F_GETFL, 0);
if(flags == -1) {
errno = SOC_GetErrno();
va_end(ap);
return -1;
}
- if(*value) ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
- else ret = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+ if(*value) ret = fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
+ else ret = fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK);
if(ret != 0)
errno = SOC_GetErrno();
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
+ sockfd = soc_get_fd(sockfd);
+ if(sockfd < 0)
+ {
+ SOCU_errno = sockfd;
+ return -1;
+ }
+
cmdbuf[0] = 0x00030082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)max_connections;
#include "soc_common.h"
#include <poll.h>
+#include <stdlib.h>
-int poll(struct pollfd *fds, nfds_t nfsd, int timeout)
+int poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
int ret = 0;
- u32 size = sizeof(struct pollfd)*nfsd;
+ nfds_t i;
+ u32 size = sizeof(struct pollfd)*nfds;
u32 *cmdbuf = getThreadCommandBuffer();
u32 saved_threadstorage[2];
+ if(nfds == 0)
+ {
+ SOCU_errno = -EINVAL;
+ return -1;
+ }
+
+ struct pollfd *tmp_fds = (struct pollfd*)malloc(sizeof(struct pollfd) * nfds);
+ if(tmp_fds == NULL)
+ {
+ SOCU_errno = -ENOMEM;
+ return -1;
+ }
+
+ memcpy(tmp_fds, fds, sizeof(struct pollfd) * nfds);
+
+ for(i = 0; i < nfds; ++i)
+ {
+ tmp_fds[i].fd = soc_get_fd(fds[i].fd);
+ if(tmp_fds[i].fd < 0)
+ {
+ SOCU_errno = tmp_fds[i].fd;
+ free(tmp_fds);
+ return -1;
+ }
+ }
+
cmdbuf[0] = 0x00140084;
- cmdbuf[1] = (u32)nfsd;
+ cmdbuf[1] = (u32)nfds;
cmdbuf[2] = (u32)timeout;
cmdbuf[3] = 0x20;
cmdbuf[5] = (size<<14) | 0x2802;
- cmdbuf[6] = (u32)fds;
+ cmdbuf[6] = (u32)tmp_fds;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = (size<<14) | 2;
cmdbuf[0x104>>2] = (u32)fds;
- if((ret = svcSendSyncRequest(SOCU_handle)) != 0)return ret;
+ if((ret = svcSendSyncRequest(SOCU_handle)) != 0)
+ {
+ free(tmp_fds);
+ return ret;
+ }
+
+ free(tmp_fds);
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
{
+ sockfd = soc_get_fd(sockfd);
+ if(sockfd < 0)
+ {
+ SOCU_errno = sockfd;
+ return -1;
+ }
+
if(len<0x2000)return socuipc_cmd8(sockfd, buf, len, flags, src_addr, addrlen);
return socuipc_cmd7(sockfd, buf, len, flags, src_addr, addrlen);
}
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
{
+ sockfd = soc_get_fd(sockfd);
+ if(sockfd < 0)
+ {
+ SOCU_errno = sockfd;
+ return -1;
+ }
+
if(len<0x2000)return socuipc_cmda(sockfd, buf, len, flags, dest_addr, addrlen);
return socuipc_cmd9(sockfd, buf, len, flags, (struct sockaddr*)dest_addr, addrlen);
}
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
+ sockfd = soc_get_fd(sockfd);
+ if(sockfd < 0)
+ {
+ SOCU_errno = sockfd;
+ return -1;
+ }
+
cmdbuf[0] = 0x000C0082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)shutdown_type;
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
+ sockfd = soc_get_fd(sockfd);
+ if(sockfd < 0)
+ {
+ SOCU_errno = sockfd;
+ return -1;
+ }
+
cmdbuf[0] = 0x00150042;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = 0x20;
#include "soc_common.h"
+#include <errno.h>
+#include <sys/iosupport.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol)
{
int ret=0;
+ int fd, dev;
+ __handle *handle;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000200C2;
cmdbuf[3] = protocol;
cmdbuf[4] = 0x20;
- if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
+ dev = FindDevice("soc:");
+ if(dev < 0)
+ {
+ SOCU_errno = -ENODEV;
+ return -1;
+ }
+
+ fd = __alloc_handle(sizeof(__handle) + sizeof(Handle));
+ if(fd < 0)
+ {
+ SOCU_errno = -ENOMEM;
+ return -1;
+ }
+
+ handle = __get_handle(fd);
+ handle->device = dev;
+ handle->fileStruct = ((void *)handle) + sizeof(__handle);
+
+ if((ret = svcSendSyncRequest(SOCU_handle)) != 0)
+ {
+ __release_handle(fd);
+ return ret;
+ }
ret = (int)cmdbuf[1];
- SOCU_errno = ret;
+ if(ret != 0)
+ {
+ SOCU_errno = _net_convert_error(cmdbuf[2]);
+ __release_handle(fd);
+ return -1;
+ }
- if(ret!=0)return -1;
- return _net_convert_error(cmdbuf[2]);
+ *(Handle*)handle->fileStruct = cmdbuf[2];
+ return fd;
}