int socket(int domain, int type, int protocol) { int ret, fd, dev; dev = FindDevice("soc:"); if(dev == -1) return -1; fd = __alloc_handle(dev); if(fd == -1) return -1; ret = _socketParseBsdResult(NULL, bsdSocket(domain, type, protocol)); if(ret == -1) { __release_handle(fd); return -1; } else { *(int *)__get_handle(fd)->fileStruct = ret; return fd; } }
int accept(int sockfd, struct sockaddr *address, socklen_t *addrlen) { int ret, fd, dev; fd = _socketGetFd(sockfd); if(fd == -1) return -1; dev = __get_handle(sockfd)->device; sockfd = fd; fd = __alloc_handle(dev); if(fd == -1) return -1; ret = _socketParseBsdResult(NULL, bsdAccept(sockfd, address, addrlen)); if(ret == -1) { __release_handle(fd); return -1; } else { *(int *)__get_handle(fd)->fileStruct = ret; return fd; } }
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { int ret = 0; int tmp_addrlen = 0x1c; int fd, dev; __handle *handle; u32 *cmdbuf = getThreadCommandBuffer(); u8 tmpaddr[0x1c]; u32 saved_threadstorage[2]; sockfd = soc_get_fd(sockfd); if(sockfd < 0) { errno = -sockfd; return -1; } dev = FindDevice("soc:"); if(dev < 0) { errno = ENODEV; return -1; } fd = __alloc_handle(sizeof(__handle) + sizeof(Handle)); if(fd < 0) { errno = ENOMEM; return -1; } handle = __get_handle(fd); handle->device = dev; handle->fileStruct = ((void *)handle) + sizeof(__handle); memset(tmpaddr, 0, 0x1c); cmdbuf[0] = IPC_MakeHeader(0x4,2,2); // 0x40082 cmdbuf[1] = (u32)sockfd; cmdbuf[2] = (u32)tmp_addrlen; cmdbuf[3] = IPC_Desc_CurProcessHandle(); u32 * staticbufs = getThreadStaticBuffers(); saved_threadstorage[0] = staticbufs[0]; saved_threadstorage[1] = staticbufs[1]; staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0); staticbufs[1] = (u32)tmpaddr; ret = svcSendSyncRequest(SOCU_handle); staticbufs[0] = saved_threadstorage[0]; staticbufs[1] = saved_threadstorage[1]; if(ret != 0) { __release_handle(fd); errno = SYNC_ERROR; return ret; } ret = (int)cmdbuf[1]; if(ret == 0) ret = _net_convert_error(cmdbuf[2]); if(ret < 0) 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) { __release_handle(fd); return -1; } else *(Handle*)handle->fileStruct = ret; return fd; }
int socket(int domain, int type, int protocol) { int ret = 0; int fd, dev; __handle *handle; u32 *cmdbuf = getThreadCommandBuffer(); // The protocol on the 3DS *must* be 0 to work // To that end, when appropriate, we will make the change for the user if (domain == AF_INET && type == SOCK_STREAM && protocol == IPPROTO_TCP) { protocol = 0; // TCP is the only option, so 0 will work as expected } if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP) { protocol = 0; // UDP is the only option, so 0 will work as expected } cmdbuf[0] = IPC_MakeHeader(0x2,3,2); // 0x200C2 cmdbuf[1] = domain; cmdbuf[2] = type; cmdbuf[3] = protocol; cmdbuf[4] = IPC_Desc_CurProcessHandle(); dev = FindDevice("soc:"); if(dev < 0) { errno = ENODEV; return -1; } fd = __alloc_handle(sizeof(__handle) + sizeof(Handle)); if(fd < 0) { errno = ENOMEM; return -1; } handle = __get_handle(fd); handle->device = dev; handle->fileStruct = ((void *)handle) + sizeof(__handle); ret = svcSendSyncRequest(SOCU_handle); if(ret != 0) { __release_handle(fd); errno = SYNC_ERROR; return ret; } ret = (int)cmdbuf[1]; if(ret == 0)ret = cmdbuf[2]; if(ret < 0) { __release_handle(fd); if(cmdbuf[1] == 0)errno = _net_convert_error(ret); if(cmdbuf[1] != 0)errno = SYNC_ERROR; return -1; } *(Handle*)handle->fileStruct = cmdbuf[2]; return fd; }