Added SOC error conversion, and implemented getsockopt, setsockopt, fcntl, sockatmark, gethostid, getsockname, and getpeername.
This commit is contained in:
parent
e0cde91e0f
commit
7a5d01108a
@ -1,3 +1,4 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@ -9,10 +10,104 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
|
||||
Handle SOCU_handle = 0;
|
||||
static int SOCU_errno = 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;
|
||||
@ -78,7 +173,7 @@ int socket(int domain, int type, int protocol)
|
||||
SOCU_errno = ret;
|
||||
|
||||
if(ret!=0)return -1;
|
||||
return (int)cmdbuf[2];
|
||||
return _net_convert_error(cmdbuf[2]);
|
||||
}
|
||||
|
||||
int closesocket(int sockfd)
|
||||
@ -93,7 +188,7 @@ int closesocket(int sockfd)
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret==0)ret =_net_convert_error(cmdbuf[2]);
|
||||
SOCU_errno = ret;
|
||||
|
||||
if(ret!=0)return -1;
|
||||
@ -113,7 +208,7 @@ int shutdown(int sockfd, int shutdown_type)
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
SOCU_errno = ret;
|
||||
|
||||
if(ret!=0)return -1;
|
||||
@ -133,7 +228,7 @@ int listen(int sockfd, int max_connections)
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
SOCU_errno = ret;
|
||||
|
||||
if(ret!=0)return -1;
|
||||
@ -167,7 +262,7 @@ int accept(int sockfd, struct sockaddr *addr, int *addrlen)
|
||||
cmdbuf[0x104>>2] = saved_threadstorage[1];
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret>=0 && addr!=NULL)
|
||||
@ -204,7 +299,7 @@ int bind(int sockfd, const struct sockaddr *addr, int addrlen)
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
@ -233,7 +328,7 @@ int connect(int sockfd, const struct sockaddr *addr, int addrlen)
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
@ -271,7 +366,7 @@ int socuipc_cmd7(int sockfd, void *buf, int len, int flags, struct sockaddr *src
|
||||
cmdbuf[0x104>>2] = saved_threadstorage[1];
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
@ -313,7 +408,7 @@ int socuipc_cmd8(int sockfd, void *buf, int len, int flags, struct sockaddr *src
|
||||
cmdbuf[0x10c>>2] = saved_threadstorage[3];
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
@ -343,7 +438,7 @@ int socuipc_cmd9(int sockfd, const void *buf, int len, int flags, const struct s
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
@ -373,7 +468,7 @@ int socuipc_cmda(int sockfd, const void *buf, int len, int flags, const struct s
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
@ -402,3 +497,215 @@ 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 = svc_sendSyncRequest(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 = svc_sendSyncRequest(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;
|
||||
va_start(args, cmd);
|
||||
|
||||
if(cmd!=F_GETFL && cmd!=F_SETFL)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(cmd==F_SETFL)
|
||||
{
|
||||
arg = va_arg(args, int);
|
||||
|
||||
if(arg && arg!=O_NONBLOCK)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(arg==O_NONBLOCK)arg = 0x4;
|
||||
}
|
||||
|
||||
cmdbuf[0] = 0x001300C2;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)cmd;
|
||||
cmdbuf[3] = (u32)arg;
|
||||
cmdbuf[4] = 0x20;
|
||||
|
||||
if((ret = svc_sendSyncRequest(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 = svc_sendSyncRequest(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 = svc_sendSyncRequest(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 = svc_sendSyncRequest(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];
|
||||
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 = svc_sendSyncRequest(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];
|
||||
memcpy(addr->sa_data, &tmpaddr[2], *addr_len - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user