Skip to content

Commit 4d59611

Browse files
committed
[NX] replace unistd sockets with bsd, reduce static size by 24mb, disable heap for sysmod
1 parent 3388959 commit 4d59611

File tree

5 files changed

+220
-12
lines changed

5 files changed

+220
-12
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ else()
252252

253253
target_compile_definitions(ftpsrv PUBLIC
254254
FTP_VFS_HEADER="${CMAKE_CURRENT_SOURCE_DIR}/src/platform/nx/vfs_nx.h"
255-
FTP_SOCKET_HEADER="${CMAKE_CURRENT_SOURCE_DIR}/src/platform/unistd/socket_unistd.h"
255+
FTP_SOCKET_HEADER="${CMAKE_CURRENT_SOURCE_DIR}/src/platform/nx/socket_nx.h"
256256
VFS_NX_BUFFER_WRITES=1
257257
)
258258

@@ -365,7 +365,7 @@ else()
365365

366366
target_compile_definitions(ftpsrv_sysmod PUBLIC
367367
FTP_VFS_HEADER="${CMAKE_CURRENT_SOURCE_DIR}/src/platform/nx/vfs_nx.h"
368-
FTP_SOCKET_HEADER="${CMAKE_CURRENT_SOURCE_DIR}/src/platform/unistd/socket_unistd.h"
368+
FTP_SOCKET_HEADER="${CMAKE_CURRENT_SOURCE_DIR}/src/platform/nx/socket_nx.h"
369369
VFS_NX_BUFFER_WRITES=0
370370
)
371371

CMakePresets.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@
4444
"name": "switch",
4545
"displayName": "switch",
4646
"inherits": [ "core" ],
47-
"toolchainFile": "$env{DEVKITPRO}/cmake/Switch.cmake"
47+
"toolchainFile": "$env{DEVKITPRO}/cmake/Switch.cmake",
48+
"cacheVariables": {
49+
"CMAKE_BUILD_TYPE": "MinSizeRel"
50+
}
4851
},
4952
{
5053
"name": "ps4",

src/platform/nx/main.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,6 @@ void userAppInit(void) {
320320
diagAbortWithResult(rc);
321321
if (R_FAILED(rc = bsdInitialize(&bsd_config, socket_config.num_bsd_sessions, socket_config.bsd_service_type)))
322322
diagAbortWithResult(rc);
323-
if (R_FAILED(rc = socketInitialize(&socket_config)))
324-
diagAbortWithResult(rc);
325323
if (R_FAILED(rc = nifmInitialize(NifmServiceType_User)))
326324
diagAbortWithResult(rc);
327325
if (R_FAILED(rc = accountInitialize(IsApplication() ? AccountServiceType_Application : AccountServiceType_System)))
@@ -348,7 +346,6 @@ void userAppExit(void) {
348346
setExit();
349347
ncmExit();
350348
accountExit();
351-
socketExit();
352349
bsdExit();
353350
nifmExit();
354351
fsdev_wrapUnmountAll();

src/platform/nx/main_sysmod.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,12 @@ void __libnx_init_time(void);
141141

142142
// Newlib heap configuration function (makes malloc/free work).
143143
void __libnx_initheap(void) {
144-
alignas(0x1000) static char inner_heap[0x1000];
145144
extern char* fake_heap_start;
146145
extern char* fake_heap_end;
147146

148147
// Configure the newlib heap.
149-
fake_heap_start = inner_heap;
150-
fake_heap_end = inner_heap + sizeof(inner_heap);
148+
fake_heap_start = NULL;
149+
fake_heap_end = NULL;
151150
}
152151

153152
void __appInit(void) {
@@ -202,8 +201,6 @@ void __appInit(void) {
202201
diagAbortWithResult(rc);
203202
if (R_FAILED(rc = bsdInitialize(&bsd_config, socket_config.num_bsd_sessions, socket_config.bsd_service_type)))
204203
diagAbortWithResult(rc);
205-
if (R_FAILED(rc = socketInitialize(&socket_config)))
206-
diagAbortWithResult(rc);
207204
if (R_FAILED(rc = accountInitialize(AccountServiceType_System)))
208205
diagAbortWithResult(rc);
209206
if (R_FAILED(rc = ncmInitialize()))
@@ -223,7 +220,6 @@ void __appExit(void) {
223220
setExit();
224221
ncmExit();
225222
accountExit();
226-
socketExit();
227223
bsdExit();
228224
fsdev_wrapUnmountAll();
229225
fsExit();

src/platform/nx/socket_nx.h

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
#pragma once
2+
3+
#ifdef __cplusplus
4+
extern "C" {
5+
#endif
6+
7+
#include <switch/services/bsd.h>
8+
#include <arpa/inet.h>
9+
#include <netinet/tcp.h>
10+
#include <fcntl.h>
11+
#include <errno.h>
12+
#include <assert.h>
13+
#include <stddef.h>
14+
15+
#if defined(HAVE_IPTOS_THROUGHPUT) && HAVE_IPTOS_THROUGHPUT
16+
#include <netinet/ip.h>
17+
#endif
18+
19+
#include <poll.h>
20+
21+
struct FtpSocketPollFd {
22+
struct pollfd s;
23+
};
24+
25+
struct FtpSocket {
26+
int s;
27+
};
28+
29+
int _convert_errno(int bsdErrno);
30+
31+
// taken from libnx socket.c
32+
static inline int bsd_errno(int ret) {
33+
int errno_;
34+
if(ret != -1)
35+
return ret; // Nothing to do
36+
else {
37+
if(g_bsdErrno == -1) {
38+
// We're using -1 to signal Switch error codes.
39+
// Note: all of the bsd:u/s handlers return 0.
40+
switch(g_bsdResult) {
41+
case 0xD201:
42+
errno_ = ENFILE;
43+
break;
44+
case 0xD401:
45+
errno_ = EFAULT;
46+
break;
47+
case 0x10601:
48+
errno_ = EBUSY;
49+
break;
50+
default:
51+
errno_ = EPIPE;
52+
break;
53+
}
54+
}
55+
else
56+
errno_ = _convert_errno(g_bsdErrno); /* Nintendo actually used the Linux errno definitions for their FreeBSD build :)
57+
but we still need to convert to newlib errno */
58+
}
59+
60+
errno = errno_;
61+
return -1;
62+
}
63+
64+
static inline int ftp_socket_open_nx(struct FtpSocket* sock, int domain, int type, int protocol) {
65+
return sock->s = bsdSocket(domain, type, protocol);
66+
}
67+
68+
static inline int ftp_socket_recv_nx(struct FtpSocket* sock, void* buf, size_t size, int flags) {
69+
return bsd_errno(bsdRecv(sock->s, buf, size, flags));
70+
}
71+
72+
static inline int ftp_socket_send_nx(struct FtpSocket* sock, const void* buf, size_t size, int flags) {
73+
return bsd_errno(bsdSend(sock->s, buf, size, flags));
74+
}
75+
76+
static inline int ftp_socket_close_nx(struct FtpSocket* sock) {
77+
if (sock->s) {
78+
bsdShutdown(sock->s, SHUT_RDWR);
79+
bsdClose(sock->s);
80+
sock->s = 0;
81+
}
82+
return 0;
83+
}
84+
85+
static inline int ftp_socket_accept_nx(struct FtpSocket* sock_out, struct FtpSocket* listen_sock, struct sockaddr* addr, size_t* addrlen) {
86+
socklen_t len = *addrlen;
87+
const int rc = bsd_errno(sock_out->s = bsdAccept(listen_sock->s, addr, &len));
88+
*addrlen = len;
89+
return rc;
90+
}
91+
92+
static inline int ftp_socket_bind_nx(struct FtpSocket* sock, struct sockaddr* addr, size_t addrlen) {
93+
return bsd_errno(bsdBind(sock->s, addr, addrlen));
94+
}
95+
96+
static inline int ftp_socket_connect_nx(struct FtpSocket* sock, struct sockaddr* addr, size_t addrlen) {
97+
return bsd_errno(bsdConnect(sock->s, addr, addrlen));
98+
}
99+
100+
static inline int ftp_socket_listen_nx(struct FtpSocket* sock, int backlog) {
101+
return bsd_errno(bsdListen(sock->s, backlog));
102+
}
103+
104+
static inline int ftp_socket_getsockname_nx(struct FtpSocket* sock, struct sockaddr* addr, size_t* addrlen) {
105+
socklen_t len = *addrlen;
106+
const int rc = bsd_errno(bsdGetSockName(sock->s, addr, &len));
107+
*addrlen = len;
108+
return rc;
109+
}
110+
111+
static inline int ftp_socket_set_reuseaddr_enable_nx(struct FtpSocket* sock, int enable) {
112+
#if defined(HAVE_SO_REUSEADDR) && HAVE_SO_REUSEADDR
113+
const int option = 1;
114+
return bsd_errno(bsdSetSockOpt(sock->s, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)));
115+
#else
116+
return 0;
117+
#endif
118+
}
119+
120+
static inline int ftp_socket_set_nodelay_enable_nx(struct FtpSocket* sock, int enable) {
121+
#if defined(HAVE_TCP_NODELAY) && HAVE_TCP_NODELAY
122+
const int option = 1;
123+
return bsd_errno(bsdSetSockOpt(sock->s, IPPROTO_TCP, TCP_NODELAY, &option, sizeof(option)));
124+
#else
125+
return 0;
126+
#endif
127+
}
128+
129+
static inline int ftp_socket_set_keepalive_enable_nx(struct FtpSocket* sock, int enable) {
130+
#if defined(HAVE_SO_KEEPALIVE) && HAVE_SO_KEEPALIVE
131+
const int option = 1;
132+
return bsd_errno(bsdSetSockOpt(sock->s, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof(option)));
133+
#else
134+
return 0;
135+
#endif
136+
}
137+
138+
static inline int ftp_socket_set_throughput_enable_nx(struct FtpSocket* sock, int enable) {
139+
#if defined(HAVE_IPTOS_THROUGHPUT) && HAVE_IPTOS_THROUGHPUT
140+
const int option = IPTOS_THROUGHPUT;
141+
return bsd_errno(bsdSetSockOpt(sock->s, IPPROTO_IP, IP_TOS, &option, sizeof(option)));
142+
#else
143+
return 0;
144+
#endif
145+
}
146+
147+
#define O_NONBLOCK_NX 0x800
148+
149+
static inline int ftp_socket_set_nonblocking_enable_nx(struct FtpSocket* sock, int enable) {
150+
return bsd_errno(bsdFcntl(sock->s, F_SETFL, O_NONBLOCK_NX));
151+
}
152+
153+
static inline int ftp_socket_poll_nx(struct FtpSocketPollEntry* entries, struct FtpSocketPollFd* _fds, size_t nfds, int timeout) {
154+
struct pollfd* fds = (struct pollfd*)_fds;
155+
156+
for (size_t i = 0; i < nfds; i++) {
157+
if (entries[i].fd) {
158+
fds[i].fd = entries[i].fd->s;
159+
fds[i].events = 0;
160+
if (entries[i].events & FtpSocketPollType_IN) {
161+
fds[i].events |= POLLIN;
162+
}
163+
if (entries[i].events & FtpSocketPollType_OUT) {
164+
fds[i].events |= POLLOUT;
165+
}
166+
} else {
167+
fds[i].fd = -1;
168+
}
169+
}
170+
171+
int rc = bsd_errno(bsdPoll(fds, nfds, timeout));
172+
if (rc < 0) {
173+
return rc;
174+
}
175+
176+
for (size_t i = 0; i < nfds; i++) {
177+
if (entries[i].fd) {
178+
entries[i].revents = 0;
179+
if (fds[i].revents & POLLIN) {
180+
entries[i].revents |= FtpSocketPollType_IN;
181+
}
182+
if (fds[i].revents & POLLOUT) {
183+
entries[i].revents |= FtpSocketPollType_OUT;
184+
}
185+
if (fds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) {
186+
entries[i].revents |= FtpSocketPollType_ERROR;
187+
}
188+
}
189+
}
190+
191+
return rc;
192+
}
193+
194+
#define ftp_socket_open ftp_socket_open_nx
195+
#define ftp_socket_recv ftp_socket_recv_nx
196+
#define ftp_socket_send ftp_socket_send_nx
197+
#define ftp_socket_close ftp_socket_close_nx
198+
#define ftp_socket_accept ftp_socket_accept_nx
199+
#define ftp_socket_bind ftp_socket_bind_nx
200+
#define ftp_socket_connect ftp_socket_connect_nx
201+
#define ftp_socket_listen ftp_socket_listen_nx
202+
#define ftp_socket_getsockname ftp_socket_getsockname_nx
203+
#define ftp_socket_set_reuseaddr_enable ftp_socket_set_reuseaddr_enable_nx
204+
#define ftp_socket_set_nodelay_enable ftp_socket_set_nodelay_enable_nx
205+
#define ftp_socket_set_keepalive_enable ftp_socket_set_keepalive_enable_nx
206+
#define ftp_socket_set_throughput_enable ftp_socket_set_throughput_enable_nx
207+
#define ftp_socket_set_nonblocking_enable ftp_socket_set_nonblocking_enable_nx
208+
#define ftp_socket_poll ftp_socket_poll_nx
209+
210+
#ifdef __cplusplus
211+
}
212+
#endif

0 commit comments

Comments
 (0)