Complete rewrite of bsd IClient (#460)

This should provide accurate behaviours.
This implementation has been tested with ftpd and libtransistor bsd tests.

This implementation lacks OOB support.
This commit is contained in:
Thomas Guillemard 2018-10-21 00:08:58 +02:00 committed by Ac_K
parent 2cb8541462
commit b5f7d8106b
8 changed files with 1304 additions and 302 deletions

View file

@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Bsd
{
//bsd_errno == (SocketException.ErrorCode - 10000)
enum BsdError
{
Timeout = 60
}
}

View file

@ -0,0 +1,7 @@
namespace Ryujinx.HLE.HOS.Services.Bsd
{
enum BsdIoctl
{
AtMark = 0x40047307,
}
}

View file

@ -1,4 +1,3 @@
using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
namespace Ryujinx.HLE.HOS.Services.Bsd namespace Ryujinx.HLE.HOS.Services.Bsd
@ -9,10 +8,6 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
public int Type; public int Type;
public int Protocol; public int Protocol;
public IPAddress IpAddress;
public IPEndPoint RemoteEP;
public Socket Handle; public Socket Handle;
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,28 @@
namespace Ryujinx.HLE.HOS.Services.Bsd
{
class PollEvent
{
public enum EventTypeMask
{
Input = 1,
UrgentInput = 2,
Output = 4,
Error = 8,
Disconnected = 0x10,
Invalid = 0x20,
}
public int SocketFd { get; private set; }
public BsdSocket Socket { get; private set; }
public EventTypeMask InputEvents { get; private set; }
public EventTypeMask OutputEvents { get; private set; }
public PollEvent(int SocketFd, BsdSocket Socket, EventTypeMask InputEvents, EventTypeMask OutputEvents)
{
this.SocketFd = SocketFd;
this.Socket = Socket;
this.InputEvents = InputEvents;
this.OutputEvents = OutputEvents;
}
}
}

View file

@ -72,10 +72,10 @@ namespace Ryujinx.HLE.HOS.Services
return new Bcat.IServiceCreator(); return new Bcat.IServiceCreator();
case "bsd:s": case "bsd:s":
return new IClient(); return new IClient(true);
case "bsd:u": case "bsd:u":
return new IClient(); return new IClient(false);
case "caps:a": case "caps:a":
return new IAlbumAccessorService(); return new IAlbumAccessorService();

View file

@ -0,0 +1,152 @@
namespace Ryujinx.HLE.Utilities
{
enum LinuxError
{
SUCCESS = 0,
EPERM = 1 /* Operation not permitted */,
ENOENT = 2 /* No such file or directory */,
ESRCH = 3 /* No such process */,
EINTR = 4 /* Interrupted system call */,
EIO = 5 /* I/O error */,
ENXIO = 6 /* No such device or address */,
E2BIG = 7 /* Argument list too long */,
ENOEXEC = 8 /* Exec format error */,
EBADF = 9 /* Bad file number */,
ECHILD = 10 /* No child processes */,
EAGAIN = 11 /* Try again */,
ENOMEM = 12 /* Out of memory */,
EACCES = 13 /* Permission denied */,
EFAULT = 14 /* Bad address */,
ENOTBLK = 15 /* Block device required */,
EBUSY = 16 /* Device or resource busy */,
EEXIST = 17 /* File exists */,
EXDEV = 18 /* Cross-device link */,
ENODEV = 19 /* No such device */,
ENOTDIR = 20 /* Not a directory */,
EISDIR = 21 /* Is a directory */,
EINVAL = 22 /* Invalid argument */,
ENFILE = 23 /* File table overflow */,
EMFILE = 24 /* Too many open files */,
ENOTTY = 25 /* Not a typewriter */,
ETXTBSY = 26 /* Text file busy */,
EFBIG = 27 /* File too large */,
ENOSPC = 28 /* No space left on device */,
ESPIPE = 29 /* Illegal seek */,
EROFS = 30 /* Read-only file system */,
EMLINK = 31 /* Too many links */,
EPIPE = 32 /* Broken pipe */,
EDOM = 33 /* Math argument out of domain of func */,
ERANGE = 34 /* Math result not representable */,
EDEADLK = 35 /* Resource deadlock would occur */,
ENAMETOOLONG = 36 /* File name too long */,
ENOLCK = 37 /* No record locks available */,
/*
* This error code is special: arch syscall entry code will return
* -ENOSYS if users try to call a syscall that doesn't exist. To keep
* failures of syscalls that really do exist distinguishable from
* failures due to attempts to use a nonexistent syscall, syscall
* implementations should refrain from returning -ENOSYS.
*/
ENOSYS = 38 /* Invalid system call number */,
ENOTEMPTY = 39 /* Directory not empty */,
ELOOP = 40 /* Too many symbolic links encountered */,
EWOULDBLOCK = EAGAIN /* Operation would block */,
ENOMSG = 42 /* No message of desired type */,
EIDRM = 43 /* Identifier removed */,
ECHRNG = 44 /* Channel number out of range */,
EL2NSYNC = 45 /* Level 2 not synchronized */,
EL3HLT = 46 /* Level 3 halted */,
EL3RST = 47 /* Level 3 reset */,
ELNRNG = 48 /* Link number out of range */,
EUNATCH = 49 /* Protocol driver not attached */,
ENOCSI = 50 /* No CSI structure available */,
EL2HLT = 51 /* Level 2 halted */,
EBADE = 52 /* Invalid exchange */,
EBADR = 53 /* Invalid request descriptor */,
EXFULL = 54 /* Exchange full */,
ENOANO = 55 /* No anode */,
EBADRQC = 56 /* Invalid request code */,
EBADSLT = 57 /* Invalid slot */,
EDEADLOCK = EDEADLK,
EBFONT = 59 /* Bad font file format */,
ENOSTR = 60 /* Device not a stream */,
ENODATA = 61 /* No data available */,
ETIME = 62 /* Timer expired */,
ENOSR = 63 /* Out of streams resources */,
ENONET = 64 /* Machine is not on the network */,
ENOPKG = 65 /* Package not installed */,
EREMOTE = 66 /* Object is remote */,
ENOLINK = 67 /* Link has been severed */,
EADV = 68 /* Advertise error */,
ESRMNT = 69 /* Srmount error */,
ECOMM = 70 /* Communication error on send */,
EPROTO = 71 /* Protocol error */,
EMULTIHOP = 72 /* Multihop attempted */,
EDOTDOT = 73 /* RFS specific error */,
EBADMSG = 74 /* Not a data message */,
EOVERFLOW = 75 /* Value too large for defined data type */,
ENOTUNIQ = 76 /* Name not unique on network */,
EBADFD = 77 /* File descriptor in bad state */,
EREMCHG = 78 /* Remote address changed */,
ELIBACC = 79 /* Can not access a needed shared library */,
ELIBBAD = 80 /* Accessing a corrupted shared library */,
ELIBSCN = 81 /* .lib section in a.out corrupted */,
ELIBMAX = 82 /* Attempting to link in too many shared libraries */,
ELIBEXEC = 83 /* Cannot exec a shared library directly */,
EILSEQ = 84 /* Illegal byte sequence */,
ERESTART = 85 /* Interrupted system call should be restarted */,
ESTRPIPE = 86 /* Streams pipe error */,
EUSERS = 87 /* Too many users */,
ENOTSOCK = 88 /* Socket operation on non-socket */,
EDESTADDRREQ = 89 /* Destination address required */,
EMSGSIZE = 90 /* Message too long */,
EPROTOTYPE = 91 /* Protocol wrong type for socket */,
ENOPROTOOPT = 92 /* Protocol not available */,
EPROTONOSUPPORT = 93 /* Protocol not supported */,
ESOCKTNOSUPPORT = 94 /* Socket type not supported */,
EOPNOTSUPP = 95 /* Operation not supported on transport endpoint */,
EPFNOSUPPORT = 96 /* Protocol family not supported */,
EAFNOSUPPORT = 97 /* Address family not supported by protocol */,
EADDRINUSE = 98 /* Address already in use */,
EADDRNOTAVAIL = 99 /* Cannot assign requested address */,
ENETDOWN = 100 /* Network is down */,
ENETUNREACH = 101 /* Network is unreachable */,
ENETRESET = 102 /* Network dropped connection because of reset */,
ECONNABORTED = 103 /* Software caused connection abort */,
ECONNRESET = 104 /* Connection reset by peer */,
ENOBUFS = 105 /* No buffer space available */,
EISCONN = 106 /* Transport endpoint is already connected */,
ENOTCONN = 107 /* Transport endpoint is not connected */,
ESHUTDOWN = 108 /* Cannot send after transport endpoint shutdown */,
ETOOMANYREFS = 109 /* Too many references: cannot splice */,
ETIMEDOUT = 110 /* Connection timed out */,
ECONNREFUSED = 111 /* Connection refused */,
EHOSTDOWN = 112 /* Host is down */,
EHOSTUNREACH = 113 /* No route to host */,
EALREADY = 114 /* Operation already in progress */,
EINPROGRESS = 115 /* Operation now in progress */,
ESTALE = 116 /* Stale file handle */,
EUCLEAN = 117 /* Structure needs cleaning */,
ENOTNAM = 118 /* Not a XENIX named type file */,
ENAVAIL = 119 /* No XENIX semaphores available */,
EISNAM = 120 /* Is a named type file */,
EREMOTEIO = 121 /* Remote I/O error */,
EDQUOT = 122 /* Quota exceeded */,
ENOMEDIUM = 123 /* No medium found */,
EMEDIUMTYPE = 124 /* Wrong medium type */,
ECANCELED = 125 /* Operation Canceled */,
ENOKEY = 126 /* Required key not available */,
EKEYEXPIRED = 127 /* Key has expired */,
EKEYREVOKED = 128 /* Key has been revoked */,
EKEYREJECTED = 129 /* Key was rejected by service */,
/* for robust mutexes */
EOWNERDEAD = 130 /* Owner died */,
ENOTRECOVERABLE = 131 /* State not recoverable */,
ERFKILL = 132 /* Operation not possible due to RF-kill */,
EHWPOISON = 133 /* Memory page has hardware error */,
}
}

View file

@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Ryujinx.HLE.Utilities
{
public enum WSAError
{
/*
* All Windows Sockets error constants are biased by WSABASEERR from
* the "normal"
*/
WSABASEERR = 10000,
/*
* Windows Sockets definitions of regular Microsoft C error constants
*/
WSAEINTR = (WSABASEERR + 4),
WSAEBADF = (WSABASEERR + 9),
WSAEACCES = (WSABASEERR + 13),
WSAEFAULT = (WSABASEERR + 14),
WSAEINVAL = (WSABASEERR + 22),
WSAEMFILE = (WSABASEERR + 24),
/*
* Windows Sockets definitions of regular Berkeley error constants
*/
WSAEWOULDBLOCK = (WSABASEERR + 35),
WSAEINPROGRESS = (WSABASEERR + 36),
WSAEALREADY = (WSABASEERR + 37),
WSAENOTSOCK = (WSABASEERR + 38),
WSAEDESTADDRREQ = (WSABASEERR + 39),
WSAEMSGSIZE = (WSABASEERR + 40),
WSAEPROTOTYPE = (WSABASEERR + 41),
WSAENOPROTOOPT = (WSABASEERR + 42),
WSAEPROTONOSUPPORT = (WSABASEERR + 43),
WSAESOCKTNOSUPPORT = (WSABASEERR + 44),
WSAEOPNOTSUPP = (WSABASEERR + 45),
WSAEPFNOSUPPORT = (WSABASEERR + 46),
WSAEAFNOSUPPORT = (WSABASEERR + 47),
WSAEADDRINUSE = (WSABASEERR + 48),
WSAEADDRNOTAVAIL = (WSABASEERR + 49),
WSAENETDOWN = (WSABASEERR + 50),
WSAENETUNREACH = (WSABASEERR + 51),
WSAENETRESET = (WSABASEERR + 52),
WSAECONNABORTED = (WSABASEERR + 53),
WSAECONNRESET = (WSABASEERR + 54),
WSAENOBUFS = (WSABASEERR + 55),
WSAEISCONN = (WSABASEERR + 56),
WSAENOTCONN = (WSABASEERR + 57),
WSAESHUTDOWN = (WSABASEERR + 58),
WSAETOOMANYREFS = (WSABASEERR + 59),
WSAETIMEDOUT = (WSABASEERR + 60),
WSAECONNREFUSED = (WSABASEERR + 61),
WSAELOOP = (WSABASEERR + 62),
WSAENAMETOOLONG = (WSABASEERR + 63),
WSAEHOSTDOWN = (WSABASEERR + 64),
WSAEHOSTUNREACH = (WSABASEERR + 65),
WSAENOTEMPTY = (WSABASEERR + 66),
WSAEPROCLIM = (WSABASEERR + 67),
WSAEUSERS = (WSABASEERR + 68),
WSAEDQUOT = (WSABASEERR + 69),
WSAESTALE = (WSABASEERR + 70),
WSAEREMOTE = (WSABASEERR + 71),
/*
* Extended Windows Sockets error constant definitions
*/
WSASYSNOTREADY = (WSABASEERR + 91),
WSAVERNOTSUPPORTED = (WSABASEERR + 92),
WSANOTINITIALISED = (WSABASEERR + 93),
WSAEDISCON = (WSABASEERR + 101),
WSAENOMORE = (WSABASEERR + 102),
WSAECANCELLED = (WSABASEERR + 103),
WSAEINVALIDPROCTABLE = (WSABASEERR + 104),
WSAEINVALIDPROVIDER = (WSABASEERR + 105),
WSAEPROVIDERFAILEDINIT = (WSABASEERR + 106),
WSASYSCALLFAILURE = (WSABASEERR + 107),
WSASERVICE_NOT_FOUND = (WSABASEERR + 108),
WSATYPE_NOT_FOUND = (WSABASEERR + 109),
WSA_E_NO_MORE = (WSABASEERR + 110),
WSA_E_CANCELLED = (WSABASEERR + 111),
WSAEREFUSED = (WSABASEERR + 112),
/*
* Error return codes from gethostbyname() and gethostbyaddr()
* (when using the resolver). Note that these errors are
* retrieved via WSAGetLastError() and must therefore follow
* the rules for avoiding clashes with error numbers from
* specific implementations or language run-time systems.
* For this reason the codes are based at WSABASEERR+1001.
* Note also that [WSA]NO_ADDRESS is defined only for
* compatibility purposes.
*/
/* Authoritative Answer: Host not found */
WSAHOST_NOT_FOUND = (WSABASEERR + 1001),
/* Non-Authoritative: Host not found, or SERVERFAIL */
WSATRY_AGAIN = (WSABASEERR + 1002),
/* Non-recoverable errors, FORMERR, REFUSED, NOTIMP */
WSANO_RECOVERY = (WSABASEERR + 1003),
/* Valid name, no data record of requested type */
WSANO_DATA = (WSABASEERR + 1004),
/*
* Define QOS related error return codes
*
*/
WSA_QOS_RECEIVERS = (WSABASEERR + 1005),
/* at least one Reserve has arrived */
WSA_QOS_SENDERS = (WSABASEERR + 1006),
/* at least one Path has arrived */
WSA_QOS_NO_SENDERS = (WSABASEERR + 1007),
/* there are no senders */
WSA_QOS_NO_RECEIVERS = (WSABASEERR + 1008),
/* there are no receivers */
WSA_QOS_REQUEST_CONFIRMED = (WSABASEERR + 1009),
/* Reserve has been confirmed */
WSA_QOS_ADMISSION_FAILURE = (WSABASEERR + 1010),
/* error due to lack of resources */
WSA_QOS_POLICY_FAILURE = (WSABASEERR + 1011),
/* rejected for administrative reasons - bad credentials */
WSA_QOS_BAD_STYLE = (WSABASEERR + 1012),
/* unknown or conflicting style */
WSA_QOS_BAD_OBJECT = (WSABASEERR + 1013),
/* problem with some part of the filterspec or providerspecific
* buffer in general */
WSA_QOS_TRAFFIC_CTRL_ERROR = (WSABASEERR + 1014),
/* problem with some part of the flowspec */
WSA_QOS_GENERIC_ERROR = (WSABASEERR + 1015),
}
}