Overhauled soc service.
This commit is contained in:
parent
919917b7ed
commit
55608adaad
@ -21,6 +21,7 @@ SOURCES := source \
|
||||
source/allocator \
|
||||
source/gpu \
|
||||
source/services \
|
||||
source/services/soc \
|
||||
source/util
|
||||
DATA := data
|
||||
INCLUDES := include
|
||||
|
@ -4,4 +4,9 @@ Result SOC_Initialize(u32 *context_addr, u32 context_size);//Example context_siz
|
||||
Result SOC_Shutdown();
|
||||
int SOC_GetErrno();
|
||||
|
||||
long gethostid();
|
||||
Result SOC_Shutdown(void);
|
||||
int SOC_GetErrno(void);
|
||||
|
||||
/* this is supposed to be in unistd.h but newlib only puts it for cygwin */
|
||||
long gethostid(void);
|
||||
|
||||
|
36
libctru/include/arpa/inet.h
Normal file
36
libctru/include/arpa/inet.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static inline uint32_t htonl(uint32_t hostlong)
|
||||
{
|
||||
return __builtin_bswap32(hostlong);
|
||||
}
|
||||
|
||||
static inline uint16_t htons(uint16_t hostshort)
|
||||
{
|
||||
return __builtin_bswap16(hostshort);
|
||||
}
|
||||
|
||||
static inline uint32_t ntohl(uint32_t netlong)
|
||||
{
|
||||
return __builtin_bswap32(netlong);
|
||||
}
|
||||
|
||||
static inline uint16_t ntohs(uint16_t netshort)
|
||||
{
|
||||
return __builtin_bswap16(netshort);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
in_addr_t inet_addr(const char *cp);
|
||||
int inet_aton(const char *cp, struct in_addr *inp);
|
||||
char* inet_ntoa(struct in_addr in);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,5 +1,12 @@
|
||||
#ifndef NETDB_H
|
||||
#define NETDB_H
|
||||
#pragma once
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define HOST_NOT_FOUND 1
|
||||
#define NO_DATA 2
|
||||
#define NO_ADDRESS NO_DATA
|
||||
#define NO_RECOVERY 3
|
||||
#define TRY_AGAIN 4
|
||||
|
||||
struct hostent {
|
||||
char *h_name;
|
||||
@ -9,16 +16,13 @@ struct hostent {
|
||||
char **h_addr_list;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int h_errno;
|
||||
struct hostent* gethostbyname(const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // NETDB_H
|
||||
|
@ -1,34 +1,28 @@
|
||||
#ifndef NETINET_IN_H
|
||||
#define NETINET_IN_H
|
||||
#pragma once
|
||||
|
||||
#include "sys/socket.h"
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#define INADDR_ANY 0x00000000
|
||||
#define INADDR_BROADCAST 0xFFFFFFFF
|
||||
#define INADDR_NONE 0xFFFFFFFF
|
||||
|
||||
#define INET_ADDRSTRLEN 16
|
||||
|
||||
//#define IPPROTO_IP ???
|
||||
//#define IPPROTO_TCP ???
|
||||
//#define IPPROTO_UDP ???
|
||||
|
||||
typedef uint16_t in_port_t;
|
||||
typedef uint32_t in_addr_t;
|
||||
|
||||
struct in_addr {
|
||||
unsigned long s_addr;
|
||||
in_addr_t s_addr;
|
||||
};
|
||||
|
||||
struct sockaddr_in {
|
||||
unsigned short sin_family;
|
||||
unsigned short sin_port;
|
||||
sa_family_t sin_family;
|
||||
in_port_t sin_port;
|
||||
struct in_addr sin_addr;
|
||||
unsigned char sin_zero[8];
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// actually from arpa/inet.h - but is included through netinet/in.h
|
||||
unsigned long inet_addr(const char *cp);
|
||||
int inet_aton(const char *cp, struct in_addr *inp);
|
||||
char *inet_ntoa(struct in_addr in);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // NETINET_IN_H
|
||||
|
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
//#define SOL_TCP ???
|
||||
|
||||
//#define TCP_NODELAY ???
|
34
libctru/include/poll.h
Normal file
34
libctru/include/poll.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
|
||||
/* only POLLIN confirmed to work so far */
|
||||
#define POLLIN 0x001
|
||||
#define POLLPRI 0x002
|
||||
#define POLLOUT 0x004
|
||||
#define POLLERR 0x008
|
||||
#define POLLHUP 0x010
|
||||
#define POLLNVAL 0x020
|
||||
#define POLLRDNORM 0x040
|
||||
#define POLLRDBAND 0x080
|
||||
#define POLLWRNORM 0x100
|
||||
#define POLLWRBAND 0x200
|
||||
|
||||
typedef u32 nfds_t;
|
||||
|
||||
struct pollfd
|
||||
{
|
||||
int fd;
|
||||
int events;
|
||||
int revents;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int poll(struct pollfd *fds, nfds_t nfsd, int timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
13
libctru/include/sys/ioctl.h
Normal file
13
libctru/include/sys/ioctl.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#define FIONBIO 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int ioctl(int fd, int request, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
13
libctru/include/sys/select.h
Normal file
13
libctru/include/sys/select.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,13 +1,9 @@
|
||||
#ifndef SYS_SOCKET_H
|
||||
#define SYS_SOCKET_H
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/*
|
||||
* Level number for (get/set)sockopt() to apply to socket itself.
|
||||
*/
|
||||
#define SOL_SOCKET 0xfff /* options for socket level */
|
||||
# define SOL_TCP 6 /* TCP level */
|
||||
#define SOL_SOCKET 0xFFFF
|
||||
|
||||
#define PF_UNSPEC 0
|
||||
#define PF_INET 2
|
||||
@ -20,100 +16,76 @@
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
|
||||
// need to sync FIO* values with commonly accepted ones sometime
|
||||
#define FIONBIO 1
|
||||
#define FIONREAD 2
|
||||
|
||||
#define SOCKET_ERROR -1
|
||||
|
||||
// send()/recv()/etc flags
|
||||
// at present, only MSG_PEEK is implemented though.
|
||||
#define MSG_WAITALL 0x40000000
|
||||
#define MSG_TRUNC 0x20000000
|
||||
#define MSG_PEEK 0x10000000
|
||||
#define MSG_OOB 0x08000000
|
||||
#define MSG_EOR 0x04000000
|
||||
#define MSG_DONTROUTE 0x02000000
|
||||
#define MSG_CTRUNC 0x01000000
|
||||
#define MSG_DONTROUTE 0x02000000
|
||||
#define MSG_EOR 0x04000000
|
||||
#define MSG_OOB 0x08000000
|
||||
#define MSG_PEEK 0x10000000
|
||||
#define MSG_TRUNC 0x20000000
|
||||
#define MSG_WAITALL 0x40000000
|
||||
|
||||
// shutdown() flags:
|
||||
#define SHUT_RD 1
|
||||
#define SHUT_WR 2
|
||||
#define SHUT_RDWR 3
|
||||
#define SHUT_RD 0
|
||||
#define SHUT_WR 1
|
||||
#define SHUT_RDWR 2
|
||||
|
||||
/*
|
||||
* Option flags per-socket.
|
||||
*/
|
||||
#define SO_DEBUG 0x0001 /* turn on debugging info recording */
|
||||
#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
|
||||
#define SO_REUSEADDR 0x0004 /* allow local address reuse */
|
||||
#define SO_KEEPALIVE 0x0008 /* keep connections alive */
|
||||
#define SO_DONTROUTE 0x0010 /* just use interface addresses */
|
||||
#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
|
||||
#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
|
||||
#define SO_LINGER 0x0080 /* linger on close if data present */
|
||||
#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
|
||||
#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */
|
||||
#define SO_DEBUG 0x0001
|
||||
#define SO_ACCEPTCONN 0x0002
|
||||
#define SO_REUSEADDR 0x0004
|
||||
#define SO_KEEPALIVE 0x0008
|
||||
#define SO_DONTROUTE 0x0010
|
||||
#define SO_BROADCAST 0x0020
|
||||
#define SO_USELOOPBACK 0x0040
|
||||
#define SO_LINGER 0x0080
|
||||
#define SO_OOBINLINE 0x0100
|
||||
#define SO_REUSEPORT 0x0200
|
||||
#define SO_SNDBUF 0x1001
|
||||
#define SO_RCVBUF 0x1002
|
||||
#define SO_SNDLOWAT 0x1003
|
||||
#define SO_RCVLOWAT 0x1004
|
||||
#define SO_SNDTIMEO 0x1005
|
||||
#define SO_RCVTIMEO 0x1006
|
||||
#define SO_ERROR 0x1007
|
||||
#define SO_TYPE 0x1008
|
||||
|
||||
#define SO_DONTLINGER (int)(~SO_LINGER)
|
||||
|
||||
/*
|
||||
* Additional options, not kept in so_options.
|
||||
*/
|
||||
#define SO_SNDBUF 0x1001 /* send buffer size */
|
||||
#define SO_RCVBUF 0x1002 /* receive buffer size */
|
||||
#define SO_SNDLOWAT 0x1003 /* send low-water mark */
|
||||
#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
|
||||
#define SO_SNDTIMEO 0x1005 /* send timeout */
|
||||
#define SO_RCVTIMEO 0x1006 /* receive timeout */
|
||||
#define SO_ERROR 0x1007 /* get error status and clear */
|
||||
#define SO_TYPE 0x1008 /* get socket type */
|
||||
typedef uint32_t socklen_t;
|
||||
typedef uint16_t sa_family_t;
|
||||
|
||||
struct sockaddr {
|
||||
unsigned short sa_family;
|
||||
char sa_data[14];
|
||||
sa_family_t sa_family;
|
||||
char sa_data[];
|
||||
};
|
||||
|
||||
#ifndef ntohs
|
||||
#define ntohs(num) htons(num)
|
||||
#define ntohl(num) htonl(num)
|
||||
#endif
|
||||
struct sockaddr_storage {
|
||||
sa_family_t ss_family;
|
||||
char __ss_padding[14];
|
||||
};
|
||||
|
||||
struct linger {
|
||||
int l_onoff;
|
||||
int l_linger;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
|
||||
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int closesocket(int sockfd);
|
||||
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
|
||||
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
|
||||
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
|
||||
int listen(int sockfd, int backlog);
|
||||
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
|
||||
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
|
||||
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
|
||||
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
|
||||
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
|
||||
int shutdown(int sockfd, int how);
|
||||
int socket(int domain, int type, int protocol);
|
||||
int bind(int socket, const struct sockaddr * addr, int addr_len);
|
||||
int connect(int socket, const struct sockaddr * addr, int addr_len);
|
||||
int send(int socket, const void * data, int sendlength, int flags);
|
||||
int recv(int socket, void * data, int recvlength, int flags);
|
||||
int sendto(int socket, const void * data, int sendlength, int flags, const struct sockaddr * addr, int addr_len);
|
||||
int recvfrom(int socket, void * data, int recvlength, int flags, struct sockaddr * addr, int * addr_len);
|
||||
int listen(int socket, int max_connections);
|
||||
int accept(int socket, struct sockaddr * addr, int * addr_len);
|
||||
int shutdown(int socket, int shutdown_type);
|
||||
int closesocket(int socket);
|
||||
|
||||
int ioctl(int socket, long cmd, void * arg);
|
||||
|
||||
int setsockopt(int socket, int level, int option_name, const void * data, int data_len);
|
||||
int getsockopt(int socket, int level, int option_name, void * data, int * data_len);
|
||||
|
||||
int getpeername(int socket, struct sockaddr *addr, int * addr_len);
|
||||
int getsockname(int socket, struct sockaddr *addr, int * addr_len);
|
||||
|
||||
int gethostname(char *name, size_t len);
|
||||
int sethostname(const char *name, size_t len);
|
||||
|
||||
unsigned short htons(unsigned short num);
|
||||
unsigned long htonl(unsigned long num);
|
||||
|
||||
extern int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);
|
||||
int sockatmark(int sockfd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // SYS_SOCKET_H
|
||||
|
@ -1,856 +0,0 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
|
||||
Handle SOCU_handle = 0;
|
||||
static int SOCU_errno = 0;
|
||||
static Handle socMemhandle = 0;
|
||||
|
||||
#define NET_UNKNOWN_ERROR_OFFSET -10000//This is from libogc network_wii.c.
|
||||
|
||||
static u8 _net_error_code_map[] = { //This is based on the array from libogc network_wii.c.
|
||||
0, // 0
|
||||
E2BIG,
|
||||
EACCES,
|
||||
EADDRINUSE,
|
||||
EADDRNOTAVAIL,
|
||||
EAFNOSUPPORT, // 5
|
||||
EAGAIN,
|
||||
EALREADY,
|
||||
EBADF,
|
||||
EBADMSG,
|
||||
EBUSY, // 10
|
||||
ECANCELED,
|
||||
ECHILD,
|
||||
ECONNABORTED,
|
||||
ECONNREFUSED,
|
||||
ECONNRESET, // 15
|
||||
EDEADLK,
|
||||
EDESTADDRREQ,
|
||||
EDOM,
|
||||
EDQUOT,
|
||||
EEXIST, // 20
|
||||
EFAULT,
|
||||
EFBIG,
|
||||
EHOSTUNREACH,
|
||||
EIDRM,
|
||||
EILSEQ, // 25
|
||||
EINPROGRESS,
|
||||
EINTR,
|
||||
EINVAL,
|
||||
EIO,
|
||||
EISCONN, // 30
|
||||
EISDIR,
|
||||
ELOOP,
|
||||
EMFILE,
|
||||
EMLINK,
|
||||
EMSGSIZE, // 35
|
||||
EMULTIHOP,
|
||||
ENAMETOOLONG,
|
||||
ENETDOWN,
|
||||
ENETRESET,
|
||||
ENETUNREACH, // 40
|
||||
ENFILE,
|
||||
ENOBUFS,
|
||||
ENODATA,
|
||||
ENODEV,
|
||||
ENOENT, // 45
|
||||
ENOEXEC,
|
||||
ENOLCK,
|
||||
ENOLINK,
|
||||
ENOMEM,
|
||||
ENOMSG, // 50
|
||||
ENOPROTOOPT,
|
||||
ENOSPC,
|
||||
ENOSR,
|
||||
ENOSTR,
|
||||
ENOSYS, // 55
|
||||
ENOTCONN,
|
||||
ENOTDIR,
|
||||
ENOTEMPTY,
|
||||
ENOTSOCK,
|
||||
ENOTSUP, // 60
|
||||
ENOTTY,
|
||||
ENXIO,
|
||||
EOPNOTSUPP,
|
||||
EOVERFLOW,
|
||||
EPERM, // 65
|
||||
EPIPE,
|
||||
EPROTO,
|
||||
EPROTONOSUPPORT,
|
||||
EPROTOTYPE,
|
||||
ERANGE, // 70
|
||||
EROFS,
|
||||
ESPIPE,
|
||||
ESRCH,
|
||||
ESTALE,
|
||||
ETIME, // 75
|
||||
ETIMEDOUT,
|
||||
};
|
||||
|
||||
static s32 _net_convert_error(s32 sock_retval)//This is based on the function from libogc network_wii.c.
|
||||
{
|
||||
if (sock_retval >= 0) return sock_retval;
|
||||
if (sock_retval < -sizeof(_net_error_code_map)
|
||||
|| !_net_error_code_map[-sock_retval])
|
||||
return NET_UNKNOWN_ERROR_OFFSET + sock_retval;
|
||||
return -_net_error_code_map[-sock_retval];
|
||||
}
|
||||
|
||||
Result socu_cmd1(Handle memhandle, u32 memsize)
|
||||
{
|
||||
Result ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00010044;
|
||||
cmdbuf[1] = memsize;
|
||||
cmdbuf[2] = 0x20;
|
||||
cmdbuf[4] = 0;
|
||||
cmdbuf[5] = memhandle;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result SOC_Shutdown()
|
||||
{
|
||||
Result ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00190000;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
svcCloseHandle(SOCU_handle);
|
||||
svcCloseHandle(socMemhandle);
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result SOC_Initialize(u32 *context_addr, u32 context_size)
|
||||
{
|
||||
Result ret=0;
|
||||
|
||||
ret = svcCreateMemoryBlock(&socMemhandle, (u32)context_addr, context_size, 0, 3);
|
||||
if(ret!=0)return ret;
|
||||
|
||||
if((ret = srvGetServiceHandle(&SOCU_handle, "soc:U"))!=0)return ret;
|
||||
|
||||
return socu_cmd1(socMemhandle, context_size);
|
||||
}
|
||||
|
||||
int SOC_GetErrno()
|
||||
{
|
||||
return SOCU_errno;
|
||||
}
|
||||
|
||||
int socket(int domain, int type, int protocol)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x000200C2;
|
||||
cmdbuf[1] = domain;
|
||||
cmdbuf[2] = type;
|
||||
cmdbuf[3] = protocol;
|
||||
cmdbuf[4] = 0x20;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
SOCU_errno = ret;
|
||||
|
||||
if(ret!=0)return -1;
|
||||
return _net_convert_error(cmdbuf[2]);
|
||||
}
|
||||
|
||||
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 shutdown(int sockfd, int shutdown_type)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x000C0082;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)shutdown_type;
|
||||
cmdbuf[3] = 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 listen(int sockfd, int max_connections)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00030082;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)max_connections;
|
||||
cmdbuf[3] = 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 accept(int sockfd, struct sockaddr *addr, int *addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
int tmp_addrlen=0x1c;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u8 tmpaddr[0x1c];
|
||||
u32 saved_threadstorage[2];
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
cmdbuf[0] = 0x00040082;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)tmp_addrlen;
|
||||
cmdbuf[3] = 0x20;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = (tmp_addrlen<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)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 && addr!=NULL)
|
||||
{
|
||||
addr->sa_family = tmpaddr[1];
|
||||
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
|
||||
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bind(int sockfd, const struct sockaddr *addr, int addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
int tmp_addrlen=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(addr->sa_family == AF_INET)
|
||||
{
|
||||
tmp_addrlen = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_addrlen = 0x1c;
|
||||
}
|
||||
|
||||
if(addrlen < tmp_addrlen)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpaddr[0] = tmp_addrlen;
|
||||
tmpaddr[1] = addr->sa_family;
|
||||
memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2);
|
||||
|
||||
cmdbuf[0] = 0x00050084;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)tmp_addrlen;
|
||||
cmdbuf[3] = 0x20;
|
||||
cmdbuf[5] = (((u32)tmp_addrlen)<<14) | 2;
|
||||
cmdbuf[6] = (u32)tmpaddr;
|
||||
|
||||
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 connect(int sockfd, const struct sockaddr *addr, int addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
int tmp_addrlen=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(addr->sa_family == AF_INET)
|
||||
{
|
||||
tmp_addrlen = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_addrlen = 0x1c;
|
||||
}
|
||||
|
||||
if(addrlen < tmp_addrlen)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpaddr[0] = tmp_addrlen;
|
||||
tmpaddr[1] = addr->sa_family;
|
||||
memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2);
|
||||
|
||||
cmdbuf[0] = 0x00060084;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)addrlen;
|
||||
cmdbuf[3] = 0x20;
|
||||
cmdbuf[5] = (((u32)tmp_addrlen)<<14) | 2;
|
||||
cmdbuf[6] = (u32)tmpaddr;
|
||||
|
||||
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 socuipc_cmd7(int sockfd, void *buf, int len, int flags, struct sockaddr *src_addr, int *addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 tmp_addrlen=0;
|
||||
u8 tmpaddr[0x1c];
|
||||
u32 saved_threadstorage[2];
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(src_addr)tmp_addrlen = 0x1c;
|
||||
|
||||
cmdbuf[0] = 0x00070104;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)len;
|
||||
cmdbuf[3] = (u32)flags;
|
||||
cmdbuf[4] = (u32)tmp_addrlen;
|
||||
cmdbuf[5] = 0x20;
|
||||
cmdbuf[7] = (((u32)len)<<4) | 12;
|
||||
cmdbuf[8] = (u32)buf;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = (tmp_addrlen<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)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 && src_addr!=NULL)
|
||||
{
|
||||
src_addr->sa_family = tmpaddr[1];
|
||||
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
|
||||
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int socuipc_cmd8(int sockfd, void *buf, int len, int flags, struct sockaddr *src_addr, int *addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 tmp_addrlen=0;
|
||||
u8 tmpaddr[0x1c];
|
||||
u32 saved_threadstorage[4];
|
||||
|
||||
if(src_addr)tmp_addrlen = 0x1c;
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
cmdbuf[0] = 0x00080102;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)len;
|
||||
cmdbuf[3] = (u32)flags;
|
||||
cmdbuf[4] = (u32)tmp_addrlen;
|
||||
cmdbuf[5] = 0x20;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
saved_threadstorage[2] = cmdbuf[0x108>>2];
|
||||
saved_threadstorage[3] = cmdbuf[0x10c>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = (((u32)len)<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)buf;
|
||||
cmdbuf[0x108>>2] = (tmp_addrlen<<14) | 2;
|
||||
cmdbuf[0x10c>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
cmdbuf[0x100>>2] = saved_threadstorage[0];
|
||||
cmdbuf[0x104>>2] = saved_threadstorage[1];
|
||||
cmdbuf[0x108>>2] = saved_threadstorage[2];
|
||||
cmdbuf[0x10c>>2] = saved_threadstorage[3];
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret>0 && src_addr!=NULL)
|
||||
{
|
||||
src_addr->sa_family = tmpaddr[1];
|
||||
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
|
||||
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int socuipc_cmd9(int sockfd, const void *buf, int len, int flags, const struct sockaddr *dest_addr, int addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 tmp_addrlen=0;
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(dest_addr)
|
||||
{
|
||||
if(dest_addr->sa_family == AF_INET)
|
||||
{
|
||||
tmp_addrlen = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_addrlen = 0x1c;
|
||||
}
|
||||
|
||||
if(addrlen < tmp_addrlen)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpaddr[0] = tmp_addrlen;
|
||||
tmpaddr[1] = dest_addr->sa_family;
|
||||
memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2);
|
||||
}
|
||||
|
||||
cmdbuf[0] = 0x00090106;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)len;
|
||||
cmdbuf[3] = (u32)flags;
|
||||
cmdbuf[4] = (u32)tmp_addrlen;
|
||||
cmdbuf[5] = 0x20;
|
||||
cmdbuf[7] = (tmp_addrlen<<14) | 0x402;
|
||||
cmdbuf[8] = (u32)tmpaddr;
|
||||
cmdbuf[9] = (((u32)len)<<4) | 10;
|
||||
cmdbuf[10] = (u32)buf;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int socuipc_cmda(int sockfd, const void *buf, int len, int flags, const struct sockaddr *dest_addr, int addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 tmp_addrlen=0;
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(dest_addr)
|
||||
{
|
||||
if(dest_addr->sa_family == AF_INET)
|
||||
{
|
||||
tmp_addrlen = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_addrlen = 0x1c;
|
||||
}
|
||||
|
||||
if(addrlen < tmp_addrlen)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpaddr[0] = tmp_addrlen;
|
||||
tmpaddr[1] = dest_addr->sa_family;
|
||||
memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2);
|
||||
}
|
||||
|
||||
cmdbuf[0] = 0x000A0106;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)len;
|
||||
cmdbuf[3] = (u32)flags;
|
||||
cmdbuf[4] = (u32)tmp_addrlen;
|
||||
cmdbuf[5] = 0x20;
|
||||
cmdbuf[7] = (((u32)len)<<14) | 0x802;
|
||||
cmdbuf[8] = (u32)buf;
|
||||
cmdbuf[9] = (tmp_addrlen<<14) | 0x402;
|
||||
cmdbuf[10] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int recvfrom(int sockfd, void *buf, int len, int flags, struct sockaddr *src_addr, int *addrlen)
|
||||
{
|
||||
if(len<0x2000)return socuipc_cmd8(sockfd, buf, len, flags, src_addr, addrlen);
|
||||
return socuipc_cmd7(sockfd, buf, len, flags, src_addr, addrlen);
|
||||
}
|
||||
|
||||
int sendto(int sockfd, const void *buf, int len, int flags, const struct sockaddr *dest_addr, int addrlen)
|
||||
{
|
||||
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 recv(int sockfd, void *buf, int len, int flags)
|
||||
{
|
||||
return recvfrom(sockfd, buf, len, flags, NULL, 0);
|
||||
}
|
||||
|
||||
int send(int sockfd, const void *buf, int len, int flags)
|
||||
{
|
||||
return sendto(sockfd, buf, len, flags, NULL, 0);
|
||||
}
|
||||
|
||||
int getsockopt(int sockfd, int level, int option_name, void * data, int * data_len)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 saved_threadstorage[2];
|
||||
|
||||
cmdbuf[0] = 0x00110102;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)level;
|
||||
cmdbuf[3] = (u32)option_name;
|
||||
cmdbuf[4] = (u32)*data_len;
|
||||
cmdbuf[5] = 0x20;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = ((*data_len)<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)data;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)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)*data_len = cmdbuf[3];
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int setsockopt(int sockfd, int level, int option_name, const void * data, int data_len)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00120104;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)level;
|
||||
cmdbuf[3] = (u32)option_name;
|
||||
cmdbuf[4] = (u32)data_len;
|
||||
cmdbuf[5] = 0x20;
|
||||
cmdbuf[7] = (data_len<<14) | 0x2402;
|
||||
cmdbuf[8] = (u32)data;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fcntl(int sockfd, int cmd, ...)
|
||||
{
|
||||
int ret=0;
|
||||
int arg=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
va_list args;
|
||||
|
||||
if(cmd!=F_GETFL && cmd!=F_SETFL)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
va_start(args, cmd);
|
||||
if(cmd==F_SETFL)
|
||||
{
|
||||
arg = va_arg(args, int);
|
||||
|
||||
if(arg && arg!=O_NONBLOCK)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
va_end(args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(arg==O_NONBLOCK)arg = 0x4;
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
cmdbuf[0] = 0x001300C2;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)cmd;
|
||||
cmdbuf[3] = (u32)arg;
|
||||
cmdbuf[4] = 0x20;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sockatmark(int sockfd)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00150042;
|
||||
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]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
long gethostid()
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00160000;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = cmdbuf[2];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int getsockname(int sockfd, struct sockaddr *addr, int * addr_len)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 saved_threadstorage[2];
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
cmdbuf[0] = 0x00170082;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = 0x1c;
|
||||
cmdbuf[3] = 0x20;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = (0x1c<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)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)
|
||||
{
|
||||
addr->sa_family = tmpaddr[1];
|
||||
if(*addr_len > tmpaddr[0])*addr_len = tmpaddr[0];
|
||||
memset(addr, 0, sizeof(struct sockaddr));
|
||||
memcpy(addr->sa_data, &tmpaddr[2], *addr_len - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int getpeername(int sockfd, struct sockaddr *addr, int * addr_len)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 saved_threadstorage[2];
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
cmdbuf[0] = 0x00180082;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = 0x1c;
|
||||
cmdbuf[3] = 0x20;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = (0x1c<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)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)
|
||||
{
|
||||
addr->sa_family = tmpaddr[1];
|
||||
if(*addr_len > tmpaddr[0])*addr_len = tmpaddr[0];
|
||||
memset(addr, 0, sizeof(struct sockaddr));
|
||||
memcpy(addr->sa_data, &tmpaddr[2], *addr_len - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define MAX_HOSTENT_RESULTS 16
|
||||
static struct hostent SOC_hostent;
|
||||
static char *SOC_hostent_results[MAX_HOSTENT_RESULTS+1];
|
||||
static char *SOC_hostent_alias = NULL;
|
||||
|
||||
struct hostent * gethostbyname(const char * name)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 saved_threadstorage[2];
|
||||
static u8 outbuf[0x1A88];
|
||||
|
||||
cmdbuf[0] = 0x000D0082;
|
||||
cmdbuf[1] = strlen(name)+1;
|
||||
cmdbuf[2] = sizeof(outbuf);
|
||||
cmdbuf[3] = ((strlen(name)+1) << 14) | 0xC02;
|
||||
cmdbuf[4] = (u32)name;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = (sizeof(outbuf) << 14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)outbuf;
|
||||
|
||||
if(( ret = svcSendSyncRequest(SOCU_handle))!=0)return NULL;
|
||||
|
||||
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)return NULL;
|
||||
|
||||
u32 num_results, i;
|
||||
memcpy(&num_results, (char*)outbuf+4, sizeof(num_results));
|
||||
if(num_results > MAX_HOSTENT_RESULTS)
|
||||
num_results = MAX_HOSTENT_RESULTS;
|
||||
|
||||
SOC_hostent.h_name = (char*)outbuf + 8;
|
||||
SOC_hostent.h_aliases = &SOC_hostent_alias;
|
||||
SOC_hostent.h_addrtype = AF_INET;
|
||||
SOC_hostent.h_length = 4;
|
||||
SOC_hostent.h_addr_list = SOC_hostent_results;
|
||||
|
||||
SOC_hostent_alias = NULL;
|
||||
|
||||
for(i = 0; i < num_results; ++i)
|
||||
SOC_hostent_results[i] = (char*)outbuf + 0x1908 + i*0x10;
|
||||
SOC_hostent_results[num_results] = NULL;
|
||||
|
||||
return &SOC_hostent;
|
||||
}
|
43
libctru/source/services/soc/soc_accept.c
Normal file
43
libctru/source/services/soc/soc_accept.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include "soc_common.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
int tmp_addrlen=0x1c;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u8 tmpaddr[0x1c];
|
||||
u32 saved_threadstorage[2];
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
cmdbuf[0] = 0x00040082;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)tmp_addrlen;
|
||||
cmdbuf[3] = 0x20;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = (tmp_addrlen<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)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 && addr!=NULL)
|
||||
{
|
||||
addr->sa_family = tmpaddr[1];
|
||||
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
|
||||
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
48
libctru/source/services/soc/soc_bind.c
Normal file
48
libctru/source/services/soc/soc_bind.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include "soc_common.h"
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
int tmp_addrlen=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(addr->sa_family == AF_INET)
|
||||
{
|
||||
tmp_addrlen = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_addrlen = 0x1c;
|
||||
}
|
||||
|
||||
if(addrlen < tmp_addrlen)
|
||||
{
|
||||
SOCU_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpaddr[0] = tmp_addrlen;
|
||||
tmpaddr[1] = addr->sa_family;
|
||||
memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2);
|
||||
|
||||
cmdbuf[0] = 0x00050084;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)tmp_addrlen;
|
||||
cmdbuf[3] = 0x20;
|
||||
cmdbuf[5] = (((u32)tmp_addrlen)<<14) | 2;
|
||||
cmdbuf[6] = (u32)tmpaddr;
|
||||
|
||||
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;
|
||||
}
|
21
libctru/source/services/soc/soc_closesocket.c
Normal file
21
libctru/source/services/soc/soc_closesocket.c
Normal file
@ -0,0 +1,21 @@
|
||||
#include "soc_common.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
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;
|
||||
}
|
104
libctru/source/services/soc/soc_common.c
Normal file
104
libctru/source/services/soc/soc_common.c
Normal file
@ -0,0 +1,104 @@
|
||||
#include "soc_common.h"
|
||||
#include <errno.h>
|
||||
|
||||
Handle SOCU_handle = 0;
|
||||
int SOCU_errno = 0;
|
||||
Handle socMemhandle = 0;
|
||||
|
||||
//This is based on the array from libogc network_wii.c.
|
||||
static u8 _net_error_code_map[] = {
|
||||
0, // 0
|
||||
E2BIG,
|
||||
EACCES,
|
||||
EADDRINUSE,
|
||||
EADDRNOTAVAIL,
|
||||
EAFNOSUPPORT, // 5
|
||||
EAGAIN,
|
||||
EALREADY,
|
||||
EBADF,
|
||||
EBADMSG,
|
||||
EBUSY, // 10
|
||||
ECANCELED,
|
||||
ECHILD,
|
||||
ECONNABORTED,
|
||||
ECONNREFUSED,
|
||||
ECONNRESET, // 15
|
||||
EDEADLK,
|
||||
EDESTADDRREQ,
|
||||
EDOM,
|
||||
EDQUOT,
|
||||
EEXIST, // 20
|
||||
EFAULT,
|
||||
EFBIG,
|
||||
EHOSTUNREACH,
|
||||
EIDRM,
|
||||
EILSEQ, // 25
|
||||
EINPROGRESS,
|
||||
EINTR,
|
||||
EINVAL,
|
||||
EIO,
|
||||
EISCONN, // 30
|
||||
EISDIR,
|
||||
ELOOP,
|
||||
EMFILE,
|
||||
EMLINK,
|
||||
EMSGSIZE, // 35
|
||||
EMULTIHOP,
|
||||
ENAMETOOLONG,
|
||||
ENETDOWN,
|
||||
ENETRESET,
|
||||
ENETUNREACH, // 40
|
||||
ENFILE,
|
||||
ENOBUFS,
|
||||
ENODATA,
|
||||
ENODEV,
|
||||
ENOENT, // 45
|
||||
ENOEXEC,
|
||||
ENOLCK,
|
||||
ENOLINK,
|
||||
ENOMEM,
|
||||
ENOMSG, // 50
|
||||
ENOPROTOOPT,
|
||||
ENOSPC,
|
||||
ENOSR,
|
||||
ENOSTR,
|
||||
ENOSYS, // 55
|
||||
ENOTCONN,
|
||||
ENOTDIR,
|
||||
ENOTEMPTY,
|
||||
ENOTSOCK,
|
||||
ENOTSUP, // 60
|
||||
ENOTTY,
|
||||
ENXIO,
|
||||
EOPNOTSUPP,
|
||||
EOVERFLOW,
|
||||
EPERM, // 65
|
||||
EPIPE,
|
||||
EPROTO,
|
||||
EPROTONOSUPPORT,
|
||||
EPROTOTYPE,
|
||||
ERANGE, // 70
|
||||
EROFS,
|
||||
ESPIPE,
|
||||
ESRCH,
|
||||
ESTALE,
|
||||
ETIME, // 75
|
||||
ETIMEDOUT,
|
||||
};
|
||||
|
||||
#define NET_UNKNOWN_ERROR_OFFSET -10000//This is from libogc network_wii.c.
|
||||
|
||||
//This is based on the function from libogc network_wii.c.
|
||||
s32 _net_convert_error(s32 sock_retval)
|
||||
{
|
||||
if (sock_retval >= 0) return sock_retval;
|
||||
if (sock_retval < -sizeof(_net_error_code_map)
|
||||
|| !_net_error_code_map[-sock_retval])
|
||||
return NET_UNKNOWN_ERROR_OFFSET + sock_retval;
|
||||
return -_net_error_code_map[-sock_retval];
|
||||
}
|
||||
|
||||
int SOC_GetErrno(void)
|
||||
{
|
||||
return SOCU_errno;
|
||||
}
|
9
libctru/source/services/soc/soc_common.h
Normal file
9
libctru/source/services/soc/soc_common.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
extern Handle SOCU_handle;
|
||||
extern int SOCU_errno;
|
||||
extern Handle socMemhandle;
|
||||
|
||||
s32 _net_convert_error(s32 sock_retval);
|
48
libctru/source/services/soc/soc_connect.c
Normal file
48
libctru/source/services/soc/soc_connect.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include "soc_common.h"
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
int tmp_addrlen=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(addr->sa_family == AF_INET)
|
||||
{
|
||||
tmp_addrlen = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_addrlen = 0x1c;
|
||||
}
|
||||
|
||||
if(addrlen < tmp_addrlen)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpaddr[0] = tmp_addrlen;
|
||||
tmpaddr[1] = addr->sa_family;
|
||||
memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2);
|
||||
|
||||
cmdbuf[0] = 0x00060084;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)addrlen;
|
||||
cmdbuf[3] = 0x20;
|
||||
cmdbuf[5] = (((u32)tmp_addrlen)<<14) | 2;
|
||||
cmdbuf[6] = (u32)tmpaddr;
|
||||
|
||||
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;
|
||||
}
|
50
libctru/source/services/soc/soc_fcntl.c
Normal file
50
libctru/source/services/soc/soc_fcntl.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include "soc_common.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
int fcntl(int fd, int cmd, ...)
|
||||
{
|
||||
int ret=0;
|
||||
int arg=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
va_list args;
|
||||
|
||||
if(cmd!=F_GETFL && cmd!=F_SETFL)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
va_start(args, cmd);
|
||||
if(cmd==F_SETFL)
|
||||
{
|
||||
arg = va_arg(args, int);
|
||||
|
||||
if(arg && arg!=O_NONBLOCK)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
va_end(args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(arg==O_NONBLOCK)arg = 0x4;
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
cmdbuf[0] = 0x001300C2;
|
||||
cmdbuf[1] = (u32)fd;
|
||||
cmdbuf[2] = (u32)cmd;
|
||||
cmdbuf[3] = (u32)arg;
|
||||
cmdbuf[4] = 0x20;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
60
libctru/source/services/soc/soc_gethostbyname.c
Normal file
60
libctru/source/services/soc/soc_gethostbyname.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include "soc_common.h"
|
||||
#include <netdb.h>
|
||||
|
||||
#define MAX_HOSTENT_RESULTS 16
|
||||
static struct hostent SOC_hostent;
|
||||
static char *SOC_hostent_results[MAX_HOSTENT_RESULTS+1];
|
||||
static char *SOC_hostent_alias = NULL;
|
||||
|
||||
int h_errno = 0;
|
||||
|
||||
struct hostent* gethostbyname(const char *name)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 saved_threadstorage[2];
|
||||
static u8 outbuf[0x1A88];
|
||||
|
||||
cmdbuf[0] = 0x000D0082;
|
||||
cmdbuf[1] = strlen(name)+1;
|
||||
cmdbuf[2] = sizeof(outbuf);
|
||||
cmdbuf[3] = ((strlen(name)+1) << 14) | 0xC02;
|
||||
cmdbuf[4] = (u32)name;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = (sizeof(outbuf) << 14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)outbuf;
|
||||
|
||||
if(( ret = svcSendSyncRequest(SOCU_handle))!=0)return NULL;
|
||||
|
||||
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;
|
||||
/* TODO: set h_errno based on SOCU_errno */
|
||||
|
||||
if(ret<0)return NULL;
|
||||
|
||||
u32 num_results, i;
|
||||
memcpy(&num_results, (char*)outbuf+4, sizeof(num_results));
|
||||
if(num_results > MAX_HOSTENT_RESULTS)
|
||||
num_results = MAX_HOSTENT_RESULTS;
|
||||
|
||||
SOC_hostent.h_name = (char*)outbuf + 8;
|
||||
SOC_hostent.h_aliases = &SOC_hostent_alias;
|
||||
SOC_hostent.h_addrtype = AF_INET;
|
||||
SOC_hostent.h_length = 4;
|
||||
SOC_hostent.h_addr_list = SOC_hostent_results;
|
||||
|
||||
SOC_hostent_alias = NULL;
|
||||
|
||||
for(i = 0; i < num_results; ++i)
|
||||
SOC_hostent_results[i] = (char*)outbuf + 0x1908 + i*0x10;
|
||||
SOC_hostent_results[num_results] = NULL;
|
||||
|
||||
return &SOC_hostent;
|
||||
}
|
16
libctru/source/services/soc/soc_gethostid.c
Normal file
16
libctru/source/services/soc/soc_gethostid.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include "soc_common.h"
|
||||
|
||||
long gethostid(void)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00160000;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = cmdbuf[2];
|
||||
|
||||
return ret;
|
||||
}
|
41
libctru/source/services/soc/soc_getpeername.c
Normal file
41
libctru/source/services/soc/soc_getpeername.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include "soc_common.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 saved_threadstorage[2];
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
cmdbuf[0] = 0x00180082;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = 0x1c;
|
||||
cmdbuf[3] = 0x20;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = (0x1c<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)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)
|
||||
{
|
||||
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
|
||||
memset(addr, 0, sizeof(struct sockaddr));
|
||||
addr->sa_family = tmpaddr[1];
|
||||
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
41
libctru/source/services/soc/soc_getsockname.c
Normal file
41
libctru/source/services/soc/soc_getsockname.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include "soc_common.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 saved_threadstorage[2];
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
cmdbuf[0] = 0x00170082;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = 0x1c;
|
||||
cmdbuf[3] = 0x20;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = (0x1c<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)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)
|
||||
{
|
||||
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
|
||||
memset(addr, 0, sizeof(struct sockaddr));
|
||||
addr->sa_family = tmpaddr[1];
|
||||
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
36
libctru/source/services/soc/soc_getsockopt.c
Normal file
36
libctru/source/services/soc/soc_getsockopt.c
Normal file
@ -0,0 +1,36 @@
|
||||
#include "soc_common.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 saved_threadstorage[2];
|
||||
|
||||
cmdbuf[0] = 0x00110102;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)level;
|
||||
cmdbuf[3] = (u32)optname;
|
||||
cmdbuf[4] = (u32)*optlen;
|
||||
cmdbuf[5] = 0x20;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = ((*optlen)<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)optval;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)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)*optlen = cmdbuf[3];
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
9
libctru/source/services/soc/soc_inet_addr.c
Normal file
9
libctru/source/services/soc/soc_inet_addr.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include "soc_common.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
in_addr_t inet_addr(const char *cp)
|
||||
{
|
||||
struct in_addr addr = { .s_addr = INADDR_BROADCAST };
|
||||
inet_aton(cp, &addr);
|
||||
return addr.s_addr;
|
||||
}
|
85
libctru/source/services/soc/soc_inet_aton.c
Normal file
85
libctru/source/services/soc/soc_inet_aton.c
Normal file
@ -0,0 +1,85 @@
|
||||
#include "soc_common.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int inet_aton(const char *cp, struct in_addr *inp)
|
||||
{
|
||||
int base;
|
||||
uint32_t val;
|
||||
int c;
|
||||
char bytes[4];
|
||||
size_t num_bytes = 0;
|
||||
|
||||
c = *cp;
|
||||
for(;;) {
|
||||
if(!isdigit(c)) return 0;
|
||||
|
||||
val = 0;
|
||||
base = 10;
|
||||
if(c == '0') {
|
||||
c = *++cp;
|
||||
if(c == 'x' || c == 'X') {
|
||||
base = 16;
|
||||
c = *++cp;
|
||||
}
|
||||
else base = 8;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
if(isdigit(c)) {
|
||||
if(base == 8 && c >= '8') return 0;
|
||||
val *= base;
|
||||
val += c - '0';
|
||||
c = *++cp;
|
||||
}
|
||||
else if(base == 16 && isxdigit(c)) {
|
||||
val *= base;
|
||||
val += c + 10 - (islower(c) ? 'a' : 'A');
|
||||
c = *++cp;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
if(c == '.') {
|
||||
if(num_bytes > 3) return 0;
|
||||
if(val > 0xFF) return 0;
|
||||
bytes[num_bytes++] = val;
|
||||
c = *++cp;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
if(c != 0) return 0;
|
||||
|
||||
switch(num_bytes) {
|
||||
case 0:
|
||||
return 0;
|
||||
|
||||
case 1:
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if(val > 0xFFFFFF) return 0;
|
||||
val |= bytes[0] << 24;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if(val > 0xFFFF) return 0;
|
||||
val |= bytes[0] << 24;
|
||||
val |= bytes[1] << 16;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if(val > 0xFF) return 0;
|
||||
val |= bytes[0] << 24;
|
||||
val |= bytes[1] << 16;
|
||||
val |= bytes[2] << 8;
|
||||
break;
|
||||
}
|
||||
|
||||
if(inp)
|
||||
inp->s_addr = htonl(val);
|
||||
|
||||
return 1;
|
||||
}
|
32
libctru/source/services/soc/soc_inet_ntoa.c
Normal file
32
libctru/source/services/soc/soc_inet_ntoa.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include "soc_common.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
static char buffer[INET_ADDRSTRLEN];
|
||||
|
||||
char* inet_ntoa(struct in_addr in)
|
||||
{
|
||||
unsigned char *addrbuf = (unsigned char*)∈
|
||||
char *p;
|
||||
size_t i;
|
||||
unsigned int n;
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
for(p = buffer, i = 0; i < 4; ++i) {
|
||||
if(i > 0) *p++ = '.';
|
||||
|
||||
n = addrbuf[i];
|
||||
if(n >= 100) {
|
||||
*p++ = n/100 + '0';
|
||||
n %= 100;
|
||||
}
|
||||
if(n >= 10 || addrbuf[i] >= 100) {
|
||||
*p++ = n/10 + '0';
|
||||
n %= 10;
|
||||
}
|
||||
*p++ = n + '0';
|
||||
}
|
||||
*p = 0;
|
||||
|
||||
return buffer;
|
||||
}
|
44
libctru/source/services/soc/soc_init.c
Normal file
44
libctru/source/services/soc/soc_init.c
Normal file
@ -0,0 +1,44 @@
|
||||
#include "soc_common.h"
|
||||
|
||||
static Result socu_cmd1(Handle memhandle, u32 memsize)
|
||||
{
|
||||
Result ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00010044;
|
||||
cmdbuf[1] = memsize;
|
||||
cmdbuf[2] = 0x20;
|
||||
cmdbuf[4] = 0;
|
||||
cmdbuf[5] = memhandle;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result SOC_Initialize(u32 *context_addr, u32 context_size)
|
||||
{
|
||||
Result ret=0;
|
||||
|
||||
ret = svcCreateMemoryBlock(&socMemhandle, (u32)context_addr, context_size, 0, 3);
|
||||
if(ret!=0)return ret;
|
||||
|
||||
if((ret = srvGetServiceHandle(&SOCU_handle, "soc:U"))!=0)return ret;
|
||||
|
||||
return socu_cmd1(socMemhandle, context_size);
|
||||
}
|
||||
|
||||
Result SOC_Shutdown(void)
|
||||
{
|
||||
Result ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00190000;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
svcCloseHandle(SOCU_handle);
|
||||
svcCloseHandle(socMemhandle);
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
37
libctru/source/services/soc/soc_ioctl.c
Normal file
37
libctru/source/services/soc/soc_ioctl.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include "soc_common.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
int ioctl(int fd, int request, ...)
|
||||
{
|
||||
int ret;
|
||||
int flags;
|
||||
int *value;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, request);
|
||||
|
||||
switch(request) {
|
||||
case FIONBIO:
|
||||
value = va_arg(ap, int*);
|
||||
if(value == NULL) ret = -1;
|
||||
else if(*value) {
|
||||
flags = fcntl(fd, F_GETFL, 0);
|
||||
ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
else {
|
||||
flags = fcntl(fd, F_GETFL, 0);
|
||||
ret = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
errno = ENOTTY;
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
22
libctru/source/services/soc/soc_listen.c
Normal file
22
libctru/source/services/soc/soc_listen.c
Normal file
@ -0,0 +1,22 @@
|
||||
#include "soc_common.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
int listen(int sockfd, int max_connections)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00030082;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)max_connections;
|
||||
cmdbuf[3] = 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;
|
||||
}
|
35
libctru/source/services/soc/soc_poll.c
Normal file
35
libctru/source/services/soc/soc_poll.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include "soc_common.h"
|
||||
#include <poll.h>
|
||||
|
||||
int poll(struct pollfd *fds, nfds_t nfsd, int timeout)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 size = sizeof(struct pollfd)*nfsd;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 saved_threadstorage[2];
|
||||
|
||||
cmdbuf[0] = 0x00140084;
|
||||
cmdbuf[1] = (u32)nfsd;
|
||||
cmdbuf[2] = (u32)timeout;
|
||||
cmdbuf[3] = 0x20;
|
||||
cmdbuf[5] = (size<<14) | 0x2802;
|
||||
cmdbuf[6] = (u32)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;
|
||||
|
||||
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)return -1;
|
||||
return ret;
|
||||
}
|
7
libctru/source/services/soc/soc_recv.c
Normal file
7
libctru/source/services/soc/soc_recv.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "soc_common.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
ssize_t recv(int sockfd, void *buf, size_t len, int flags)
|
||||
{
|
||||
return recvfrom(sockfd, buf, len, flags, NULL, 0);
|
||||
}
|
107
libctru/source/services/soc/soc_recvfrom.c
Normal file
107
libctru/source/services/soc/soc_recvfrom.c
Normal file
@ -0,0 +1,107 @@
|
||||
#include "soc_common.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
ssize_t socuipc_cmd7(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 tmp_addrlen=0;
|
||||
u8 tmpaddr[0x1c];
|
||||
u32 saved_threadstorage[2];
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(src_addr)tmp_addrlen = 0x1c;
|
||||
|
||||
cmdbuf[0] = 0x00070104;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)len;
|
||||
cmdbuf[3] = (u32)flags;
|
||||
cmdbuf[4] = (u32)tmp_addrlen;
|
||||
cmdbuf[5] = 0x20;
|
||||
cmdbuf[7] = (((u32)len)<<4) | 12;
|
||||
cmdbuf[8] = (u32)buf;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = (tmp_addrlen<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)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 && src_addr!=NULL)
|
||||
{
|
||||
src_addr->sa_family = tmpaddr[1];
|
||||
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
|
||||
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t socuipc_cmd8(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 tmp_addrlen=0;
|
||||
u8 tmpaddr[0x1c];
|
||||
u32 saved_threadstorage[4];
|
||||
|
||||
if(src_addr)tmp_addrlen = 0x1c;
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
cmdbuf[0] = 0x00080102;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)len;
|
||||
cmdbuf[3] = (u32)flags;
|
||||
cmdbuf[4] = (u32)tmp_addrlen;
|
||||
cmdbuf[5] = 0x20;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
saved_threadstorage[2] = cmdbuf[0x108>>2];
|
||||
saved_threadstorage[3] = cmdbuf[0x10c>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = (((u32)len)<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)buf;
|
||||
cmdbuf[0x108>>2] = (tmp_addrlen<<14) | 2;
|
||||
cmdbuf[0x10c>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
cmdbuf[0x100>>2] = saved_threadstorage[0];
|
||||
cmdbuf[0x104>>2] = saved_threadstorage[1];
|
||||
cmdbuf[0x108>>2] = saved_threadstorage[2];
|
||||
cmdbuf[0x10c>>2] = saved_threadstorage[3];
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret>0 && src_addr!=NULL)
|
||||
{
|
||||
src_addr->sa_family = tmpaddr[1];
|
||||
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
|
||||
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
|
||||
{
|
||||
if(len<0x2000)return socuipc_cmd8(sockfd, buf, len, flags, src_addr, addrlen);
|
||||
return socuipc_cmd7(sockfd, buf, len, flags, src_addr, addrlen);
|
||||
}
|
90
libctru/source/services/soc/soc_select.c
Normal file
90
libctru/source/services/soc/soc_select.c
Normal file
@ -0,0 +1,90 @@
|
||||
#include "soc_common.h"
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
|
||||
{
|
||||
struct pollfd *pollinfo;
|
||||
nfds_t numfds = 0;
|
||||
size_t i, j;
|
||||
int rc, found;
|
||||
|
||||
for(i = 0; i < nfds; ++i) {
|
||||
if((readfds && FD_ISSET(i, readfds))
|
||||
|| (writefds && FD_ISSET(i, writefds))
|
||||
|| (exceptfds && FD_ISSET(i, exceptfds)))
|
||||
++numfds;
|
||||
}
|
||||
|
||||
pollinfo = (struct pollfd*)calloc(numfds, sizeof(struct pollfd));
|
||||
if(pollinfo == NULL) {
|
||||
SOCU_errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i = 0, j = 0; i < nfds; ++i) {
|
||||
if((readfds && FD_ISSET(i, readfds))
|
||||
|| (writefds && FD_ISSET(i, writefds))
|
||||
|| (exceptfds && FD_ISSET(i, exceptfds))) {
|
||||
pollinfo[j].fd = i;
|
||||
pollinfo[j].events = 0;
|
||||
pollinfo[j].revents = 0;
|
||||
|
||||
if(readfds && FD_ISSET(i, readfds))
|
||||
pollinfo[j].events |= POLLIN;
|
||||
if(writefds && FD_ISSET(i, writefds))
|
||||
pollinfo[j].events |= POLLOUT;
|
||||
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
if(timeout)
|
||||
rc = poll(pollinfo, numfds, timeout->tv_sec*1000 + timeout->tv_usec/1000);
|
||||
else
|
||||
rc = poll(pollinfo, numfds, -1);
|
||||
|
||||
if(rc < 0) {
|
||||
free(pollinfo);
|
||||
return rc;
|
||||
}
|
||||
|
||||
for(i = 0, j = 0, rc = 0; i < nfds; ++i) {
|
||||
found = 0;
|
||||
|
||||
if((readfds && FD_ISSET(i, readfds))
|
||||
|| (writefds && FD_ISSET(i, writefds))
|
||||
|| (exceptfds && FD_ISSET(i, exceptfds))) {
|
||||
|
||||
if(readfds && FD_ISSET(i, readfds)) {
|
||||
if(pollinfo[j].events & (POLLIN|POLLHUP))
|
||||
found = 1;
|
||||
else
|
||||
FD_CLR(i, readfds);
|
||||
}
|
||||
|
||||
if(writefds && FD_ISSET(i, writefds)) {
|
||||
if(pollinfo[j].events & (POLLOUT|POLLHUP))
|
||||
found = 1;
|
||||
else
|
||||
FD_CLR(i, writefds);
|
||||
}
|
||||
|
||||
if(exceptfds && FD_ISSET(i, exceptfds)) {
|
||||
if(pollinfo[j].events & POLLERR)
|
||||
found = 1;
|
||||
else
|
||||
FD_CLR(i, exceptfds);
|
||||
}
|
||||
|
||||
if(found) ++rc;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
free(pollinfo);
|
||||
|
||||
return rc;
|
||||
}
|
7
libctru/source/services/soc/soc_send.c
Normal file
7
libctru/source/services/soc/soc_send.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "soc_common.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
ssize_t send(int sockfd, const void *buf, size_t len, int flags)
|
||||
{
|
||||
return sendto(sockfd, buf, len, flags, NULL, 0);
|
||||
}
|
113
libctru/source/services/soc/soc_sendto.c
Normal file
113
libctru/source/services/soc/soc_sendto.c
Normal file
@ -0,0 +1,113 @@
|
||||
#include "soc_common.h"
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
ssize_t socuipc_cmd9(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 tmp_addrlen=0;
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(dest_addr)
|
||||
{
|
||||
if(dest_addr->sa_family == AF_INET)
|
||||
{
|
||||
tmp_addrlen = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_addrlen = 0x1c;
|
||||
}
|
||||
|
||||
if(addrlen < tmp_addrlen)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpaddr[0] = tmp_addrlen;
|
||||
tmpaddr[1] = dest_addr->sa_family;
|
||||
memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2);
|
||||
}
|
||||
|
||||
cmdbuf[0] = 0x00090106;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)len;
|
||||
cmdbuf[3] = (u32)flags;
|
||||
cmdbuf[4] = (u32)tmp_addrlen;
|
||||
cmdbuf[5] = 0x20;
|
||||
cmdbuf[7] = (tmp_addrlen<<14) | 0x402;
|
||||
cmdbuf[8] = (u32)tmpaddr;
|
||||
cmdbuf[9] = (((u32)len)<<4) | 10;
|
||||
cmdbuf[10] = (u32)buf;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t socuipc_cmda(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 tmp_addrlen=0;
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(dest_addr)
|
||||
{
|
||||
if(dest_addr->sa_family == AF_INET)
|
||||
{
|
||||
tmp_addrlen = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_addrlen = 0x1c;
|
||||
}
|
||||
|
||||
if(addrlen < tmp_addrlen)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpaddr[0] = tmp_addrlen;
|
||||
tmpaddr[1] = dest_addr->sa_family;
|
||||
memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2);
|
||||
}
|
||||
|
||||
cmdbuf[0] = 0x000A0106;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)len;
|
||||
cmdbuf[3] = (u32)flags;
|
||||
cmdbuf[4] = (u32)tmp_addrlen;
|
||||
cmdbuf[5] = 0x20;
|
||||
cmdbuf[7] = (((u32)len)<<14) | 0x802;
|
||||
cmdbuf[8] = (u32)buf;
|
||||
cmdbuf[9] = (tmp_addrlen<<14) | 0x402;
|
||||
cmdbuf[10] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
|
||||
{
|
||||
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);
|
||||
}
|
26
libctru/source/services/soc/soc_setsockopt.c
Normal file
26
libctru/source/services/soc/soc_setsockopt.c
Normal file
@ -0,0 +1,26 @@
|
||||
#include "soc_common.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00120104;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)level;
|
||||
cmdbuf[3] = (u32)optname;
|
||||
cmdbuf[4] = (u32)optlen;
|
||||
cmdbuf[5] = 0x20;
|
||||
cmdbuf[7] = (optlen<<14) | 0x2402;
|
||||
cmdbuf[8] = (u32)optval;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
22
libctru/source/services/soc/soc_shutdown.c
Normal file
22
libctru/source/services/soc/soc_shutdown.c
Normal file
@ -0,0 +1,22 @@
|
||||
#include "soc_common.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
int shutdown(int sockfd, int shutdown_type)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x000C0082;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)shutdown_type;
|
||||
cmdbuf[3] = 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;
|
||||
}
|
21
libctru/source/services/soc/soc_sockatmark.c
Normal file
21
libctru/source/services/soc/soc_sockatmark.c
Normal file
@ -0,0 +1,21 @@
|
||||
#include "soc_common.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
int sockatmark(int sockfd)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00150042;
|
||||
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]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
22
libctru/source/services/soc/soc_socket.c
Normal file
22
libctru/source/services/soc/soc_socket.c
Normal file
@ -0,0 +1,22 @@
|
||||
#include "soc_common.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
int socket(int domain, int type, int protocol)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x000200C2;
|
||||
cmdbuf[1] = domain;
|
||||
cmdbuf[2] = type;
|
||||
cmdbuf[3] = protocol;
|
||||
cmdbuf[4] = 0x20;
|
||||
|
||||
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
SOCU_errno = ret;
|
||||
|
||||
if(ret!=0)return -1;
|
||||
return _net_convert_error(cmdbuf[2]);
|
||||
}
|
Loading…
Reference in New Issue
Block a user