diff --git a/arch/sim/src/sim/posix/sim_hostfs.c b/arch/sim/src/sim/posix/sim_hostfs.c index 8716e9fe5123f..67380d14038f8 100644 --- a/arch/sim/src/sim/posix/sim_hostfs.c +++ b/arch/sim/src/sim/posix/sim_hostfs.c @@ -39,10 +39,191 @@ #include "hostfs.h" #include "sim_internal.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define HOSTFS_RETRY_DELAY_US 10000 + /**************************************************************************** * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: host_oflags_convert + ****************************************************************************/ + +static int host_oflags_convert(int flags) +{ + int mapflags = 0; + + switch (flags & NUTTX_O_ACCMODE) + { + case NUTTX_O_RDONLY: + mapflags = O_RDONLY; + break; + + case NUTTX_O_WRONLY: + mapflags = O_WRONLY; + break; + + case NUTTX_O_RDWR: + mapflags = O_RDWR; + break; + } + + if (flags & NUTTX_O_APPEND) + { + mapflags |= O_APPEND; + } + + if (flags & NUTTX_O_CREAT) + { + mapflags |= O_CREAT; + } + + if (flags & NUTTX_O_EXCL) + { + mapflags |= O_EXCL; + } + + if (flags & NUTTX_O_TRUNC) + { + mapflags |= O_TRUNC; + } + + if (flags & NUTTX_O_NONBLOCK) + { + mapflags |= O_NONBLOCK; + } + + if (flags & NUTTX_O_SYNC) + { + mapflags |= O_SYNC; + } + +#ifdef O_DIRECT + if (flags & NUTTX_O_DIRECT) + { + mapflags |= O_DIRECT; + } +#endif + + if (flags & NUTTX_O_CLOEXEC) + { + mapflags |= O_CLOEXEC; + } + + if (flags & NUTTX_O_DIRECTORY) + { + mapflags |= O_DIRECTORY; + } + + return mapflags; +} + +/**************************************************************************** + * Name: host_flock_type_convert + ****************************************************************************/ + +static int host_flock_type_convert(int type) +{ + switch (type) + { + case NUTTX_F_RDLCK: + return F_RDLCK; + + case NUTTX_F_WRLCK: + return F_WRLCK; + + case NUTTX_F_UNLCK: + return F_UNLCK; + + default: + return -EINVAL; + } +} + +/**************************************************************************** + * Name: host_flock_type_revert + ****************************************************************************/ + +static int host_flock_type_revert(int type) +{ + switch (type) + { + case F_RDLCK: + return NUTTX_F_RDLCK; + + case F_WRLCK: + return NUTTX_F_WRLCK; + + case F_UNLCK: + return NUTTX_F_UNLCK; + + default: + return -EINVAL; + } +} + +/**************************************************************************** + * Name: host_ioctl_fcntl + ****************************************************************************/ + +static int host_ioctl_fcntl(int fd, int request, unsigned long arg) +{ + struct nuttx_flock_s *lock = (struct nuttx_flock_s *)(uintptr_t)arg; + struct flock hostlock; + int ret; + + if (lock == NULL) + { + return -EINVAL; + } + + hostlock.l_type = host_flock_type_convert(lock->l_type); + if (hostlock.l_type < 0) + { + return hostlock.l_type; + } + + hostlock.l_whence = lock->l_whence; + hostlock.l_start = lock->l_start; + hostlock.l_len = lock->l_len; + hostlock.l_pid = lock->l_pid; + + for (; ; ) + { + ret = fcntl(fd, request == NUTTX_FIOC_GETLK ? F_GETLK : F_SETLK, + &hostlock); + if (ret >= 0 || request != NUTTX_FIOC_SETLKW || + (errno != EAGAIN && errno != EACCES)) + { + break; + } + + usleep(HOSTFS_RETRY_DELAY_US); + } + + if (ret < 0) + { + return host_errno_convert(-errno); + } + + lock->l_type = host_flock_type_revert(hostlock.l_type); + if (lock->l_type < 0) + { + return lock->l_type; + } + + lock->l_whence = hostlock.l_whence; + lock->l_start = hostlock.l_start; + lock->l_len = hostlock.l_len; + lock->l_pid = hostlock.l_pid; + + return ret; +} + /**************************************************************************** * Name: host_stat_convert ****************************************************************************/ @@ -130,71 +311,7 @@ static void host_stat_convert(struct stat *hostbuf, struct nuttx_stat_s *buf) int host_open(const char *pathname, int flags, int mode) { - int mapflags = 0; - - /* Perform flag mapping */ - - switch (flags & NUTTX_O_ACCMODE) - { - case NUTTX_O_RDONLY: - mapflags = O_RDONLY; - break; - - case NUTTX_O_WRONLY: - mapflags = O_WRONLY; - break; - - case NUTTX_O_RDWR: - mapflags = O_RDWR; - break; - } - - if (flags & NUTTX_O_APPEND) - { - mapflags |= O_APPEND; - } - - if (flags & NUTTX_O_CREAT) - { - mapflags |= O_CREAT; - } - - if (flags & NUTTX_O_EXCL) - { - mapflags |= O_EXCL; - } - - if (flags & NUTTX_O_TRUNC) - { - mapflags |= O_TRUNC; - } - - if (flags & NUTTX_O_NONBLOCK) - { - mapflags |= O_NONBLOCK; - } - - if (flags & NUTTX_O_SYNC) - { - mapflags |= O_SYNC; - } - -#ifdef O_DIRECT - if (flags & NUTTX_O_DIRECT) - { - mapflags |= O_DIRECT; - } -#endif - - if (flags & NUTTX_O_CLOEXEC) - { - mapflags |= O_CLOEXEC; - } - - if (flags & NUTTX_O_DIRECTORY) - { - mapflags |= O_DIRECTORY; - } + int mapflags = host_oflags_convert(flags); int ret = open(pathname, mapflags, mode); if (ret == -1) @@ -280,9 +397,22 @@ nuttx_off_t host_lseek(int fd, nuttx_off_t pos, nuttx_off_t offset, int host_ioctl(int fd, int request, unsigned long arg) { + int ret; + + switch (request) + { + case NUTTX_FIOC_GETLK: + case NUTTX_FIOC_SETLK: + case NUTTX_FIOC_SETLKW: + return host_ioctl_fcntl(fd, request, arg); + + default: + break; + } + /* Just call the ioctl routine */ - int ret = ioctl(fd, request, arg); + ret = ioctl(fd, request, arg); if (ret < 0) { ret = host_errno_convert(-errno); diff --git a/arch/sim/src/sim/posix/sim_hostusrsock.c b/arch/sim/src/sim/posix/sim_hostusrsock.c index 4ba0fb0dafa54..52cd495ecadbf 100644 --- a/arch/sim/src/sim/posix/sim_hostusrsock.c +++ b/arch/sim/src/sim/posix/sim_hostusrsock.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -39,6 +40,7 @@ #include #include +#include #include "sim_internal.h" #include "sim_hostusrsock.h" @@ -92,26 +94,93 @@ static void host_usrsock_set_fd(int fd, fd_set *fds) } } -static void sockaddr_to_native(const struct nuttx_sockaddr *addr, - const nuttx_socklen_t addrlen, - struct sockaddr *naddr, - socklen_t *naddrlen) +static int sockaddr_to_native(const struct nuttx_sockaddr *addr, + nuttx_socklen_t addrlen, + struct sockaddr_storage *naddr, + socklen_t *naddrlen) { - naddr->sa_family = addr->sa_family; - memcpy(naddr->sa_data, addr->sa_data, sizeof(naddr->sa_data)); + if (addr == NULL || naddr == NULL || naddrlen == NULL) + { + return -EINVAL; + } + + memset(naddr, 0, sizeof(*naddr)); + + if (addr->sa_family == NUTTX_AF_LOCAL) + { + const struct nuttx_sockaddr_un *un = + (const struct nuttx_sockaddr_un *)addr; + struct sockaddr_un *native = (struct sockaddr_un *)naddr; + size_t pathlen; + + if (addrlen < offsetof(struct nuttx_sockaddr_un, sun_path) + 1) + { + return -EINVAL; + } + + pathlen = strnlen(un->sun_path, sizeof(un->sun_path)); + if (pathlen >= sizeof(native->sun_path)) + { + return -ENAMETOOLONG; + } + native->sun_family = AF_UNIX; + memcpy(native->sun_path, un->sun_path, pathlen + 1); + *naddrlen = offsetof(struct sockaddr_un, sun_path) + pathlen + 1; + + return 0; + } + + if (addrlen > sizeof(*naddr)) + { + return -ENOSPC; + } + + memcpy(naddr, addr, addrlen); *naddrlen = addrlen; + + return 0; } -static void sockaddr_to_nuttx(const struct sockaddr *naddr, - const socklen_t naddrlen, - struct nuttx_sockaddr *addr, - nuttx_socklen_t *addrlen) +static int sockaddr_to_nuttx(const struct sockaddr_storage *naddr, + socklen_t naddrlen, + struct nuttx_sockaddr *addr, + nuttx_socklen_t *addrlen) { - addr->sa_family = naddr->sa_family; - memcpy(addr->sa_data, naddr->sa_data, sizeof(addr->sa_data)); + if (naddr == NULL || addr == NULL || addrlen == NULL) + { + return -EINVAL; + } + + if (naddr->ss_family == AF_UNIX) + { + const struct sockaddr_un *native = (const struct sockaddr_un *)naddr; + struct nuttx_sockaddr_un *un = (struct nuttx_sockaddr_un *)addr; + size_t pathlen; + + if (*addrlen < sizeof(*un)) + { + return -ENOSPC; + } + + memset(un, 0, sizeof(*un)); + pathlen = strnlen(native->sun_path, sizeof(native->sun_path)); + un->sun_family = NUTTX_AF_LOCAL; + memcpy(un->sun_path, native->sun_path, pathlen); + *addrlen = offsetof(struct nuttx_sockaddr_un, sun_path) + pathlen + 1; + + return 0; + } + if (*addrlen < naddrlen) + { + return -ENOSPC; + } + + memcpy(addr, naddr, naddrlen); *addrlen = naddrlen; + + return 0; } static void sock_nonblock(int socket, int enable) @@ -248,33 +317,68 @@ static int host_usrsock_sockopt(int sockfd, int level, int optname, int host_usrsock_socket(int domain, int type, int protocol) { int opt = 1; + int sockflags = 0; int ret; - if (domain == NUTTX_PF_INET) + switch (domain) { - domain = PF_INET; - } - else - { - return -EINVAL; - } + case NUTTX_PF_INET: + domain = PF_INET; + break; - if (type == NUTTX_SOCK_STREAM) - { - type = SOCK_STREAM; +#ifdef CONFIG_NET_IPv6 + case NUTTX_PF_INET6: + domain = PF_INET6; + break; +#endif + + case NUTTX_PF_LOCAL: + domain = PF_UNIX; + break; + + default: + return -EINVAL; } - else if (type == NUTTX_SOCK_DGRAM) + + switch (type & NUTTX_SOCK_TYPE_MASK) { - type = SOCK_DGRAM; + case NUTTX_SOCK_STREAM: + sockflags = SOCK_STREAM; + break; + + case NUTTX_SOCK_DGRAM: + sockflags = SOCK_DGRAM; + break; + + case NUTTX_SOCK_RAW: + sockflags = SOCK_RAW; + break; + + case NUTTX_SOCK_SEQPACKET: +#ifdef SOCK_SEQPACKET + sockflags = SOCK_SEQPACKET; + break; +#else + return -EPROTONOSUPPORT; +#endif + + default: + return -EINVAL; } - else if (type == NUTTX_SOCK_RAW) + +#ifdef SOCK_CLOEXEC + if ((type & NUTTX_SOCK_CLOEXEC) != 0) { - type = SOCK_RAW; + sockflags |= SOCK_CLOEXEC; } - else +#endif + +#ifdef SOCK_NONBLOCK + if ((type & NUTTX_SOCK_NONBLOCK) != 0) { - return -EINVAL; + sockflags |= SOCK_NONBLOCK; } +#endif if (protocol == NUTTX_IPPROTO_IP) { @@ -297,7 +401,7 @@ int host_usrsock_socket(int domain, int type, int protocol) return -EINVAL; } - ret = socket(domain, type, protocol); + ret = socket(domain, sockflags, protocol); if (ret < 0) { return -errno; @@ -327,17 +431,26 @@ int host_usrsock_connect(int sockfd, const struct nuttx_sockaddr *addr, nuttx_socklen_t addrlen) { - struct sockaddr naddr; + struct sockaddr_storage naddr; socklen_t naddrlen; int ret; - sockaddr_to_native(addr, addrlen, &naddr, &naddrlen); + ret = sockaddr_to_native(addr, addrlen, &naddr, &naddrlen); + if (ret < 0) + { + return ret; + } - sock_nonblock(sockfd, false); - ret = connect(sockfd, &naddr, naddrlen); - sock_nonblock(sockfd, true); + ret = connect(sockfd, (struct sockaddr *)&naddr, naddrlen); if (ret < 0) { + if (errno == EINPROGRESS || errno == EALREADY || errno == EWOULDBLOCK) + { + host_usrsock_set_fd(sockfd, &g_active_write_fds); + host_usrsock_set_fd(sockfd, &g_active_read_fds); + return -EINPROGRESS; + } + return -errno; } @@ -351,14 +464,20 @@ ssize_t host_usrsock_sendto(int sockfd, const void *buf, const struct nuttx_sockaddr *dest_addr, nuttx_socklen_t addrlen) { - struct sockaddr naddr; + struct sockaddr_storage naddr; socklen_t naddrlen; int ret; if (dest_addr && addrlen >= sizeof(*dest_addr)) { - sockaddr_to_native(dest_addr, addrlen, &naddr, &naddrlen); - ret = sendto(sockfd, buf, len, flags, &naddr, naddrlen); + ret = sockaddr_to_native(dest_addr, addrlen, &naddr, &naddrlen); + if (ret < 0) + { + return ret; + } + + ret = sendto(sockfd, buf, len, flags, + (struct sockaddr *)&naddr, naddrlen); } else { @@ -384,14 +503,14 @@ ssize_t host_usrsock_recvfrom(int sockfd, void *buf, size_t len, int flags, struct nuttx_sockaddr *src_addr, nuttx_socklen_t *addrlen) { - struct sockaddr naddr; - socklen_t naddrlen; + struct sockaddr_storage naddr; + socklen_t naddrlen = sizeof(naddr); int ret; - if (src_addr && addrlen && *addrlen >= sizeof(*src_addr)) + if (src_addr && addrlen) { - sockaddr_to_native(src_addr, *addrlen, &naddr, &naddrlen); - ret = recvfrom(sockfd, buf, len, flags, &naddr, &naddrlen); + ret = recvfrom(sockfd, buf, len, flags, + (struct sockaddr *)&naddr, &naddrlen); } else { @@ -408,7 +527,7 @@ ssize_t host_usrsock_recvfrom(int sockfd, void *buf, size_t len, int flags, return -errno; } - if (src_addr && addrlen && *addrlen >= sizeof(*src_addr)) + if (src_addr && addrlen) { sockaddr_to_nuttx(&naddr, naddrlen, src_addr, addrlen); } @@ -436,19 +555,19 @@ int host_usrsock_getsockname(int sockfd, struct nuttx_sockaddr *addr, nuttx_socklen_t *addrlen) { - socklen_t naddrlen = sizeof(struct sockaddr); - struct sockaddr naddr; + socklen_t naddrlen = sizeof(struct sockaddr_storage); + struct sockaddr_storage naddr; int ret; - ret = getsockname(sockfd, &naddr, &naddrlen); + ret = getsockname(sockfd, (struct sockaddr *)&naddr, &naddrlen); if (ret < 0) { return -errno; } - if (addr && addrlen && *addrlen >= sizeof(*addr)) + if (addr && addrlen) { - sockaddr_to_nuttx(&naddr, naddrlen, addr, addrlen); + ret = sockaddr_to_nuttx(&naddr, naddrlen, addr, addrlen); } return ret; @@ -458,19 +577,19 @@ int host_usrsock_getpeername(int sockfd, struct nuttx_sockaddr *addr, nuttx_socklen_t *addrlen) { - socklen_t naddrlen = sizeof(struct sockaddr); - struct sockaddr naddr; + socklen_t naddrlen = sizeof(struct sockaddr_storage); + struct sockaddr_storage naddr; int ret; - ret = getpeername(sockfd, &naddr, &naddrlen); + ret = getpeername(sockfd, (struct sockaddr *)&naddr, &naddrlen); if (ret < 0) { return -errno; } - if (addr && addrlen && *addrlen >= sizeof(*addr)) + if (addr && addrlen) { - sockaddr_to_nuttx(&naddr, naddrlen, addr, addrlen); + ret = sockaddr_to_nuttx(&naddr, naddrlen, addr, addrlen); } return ret; @@ -480,12 +599,17 @@ int host_usrsock_bind(int sockfd, const struct nuttx_sockaddr *addr, nuttx_socklen_t addrlen) { - struct sockaddr naddr; + struct sockaddr_storage naddr; socklen_t naddrlen; + int ret; - sockaddr_to_native(addr, addrlen, &naddr, &naddrlen); + ret = sockaddr_to_native(addr, addrlen, &naddr, &naddrlen); + if (ret < 0) + { + return ret; + } - return bind(sockfd, &naddr, naddrlen) < 0 ? -errno : 0; + return bind(sockfd, (struct sockaddr *)&naddr, naddrlen) < 0 ? -errno : 0; } int host_usrsock_listen(int sockfd, int backlog) @@ -506,17 +630,17 @@ int host_usrsock_listen(int sockfd, int backlog) int host_usrsock_accept(int sockfd, struct nuttx_sockaddr *addr, nuttx_socklen_t *addrlen) { - socklen_t naddrlen = sizeof(socklen_t); - struct sockaddr naddr; + socklen_t naddrlen = sizeof(struct sockaddr_storage); + struct sockaddr_storage naddr; int ret; - ret = accept(sockfd, &naddr, &naddrlen); - if (ret <= 0) + ret = accept(sockfd, (struct sockaddr *)&naddr, &naddrlen); + if (ret < 0) { return -errno; } - if (addr && addrlen && *addrlen >= sizeof(*addr)) + if (addr && addrlen) { sockaddr_to_nuttx(&naddr, naddrlen, addr, addrlen); } @@ -562,7 +686,7 @@ void host_usrsock_loop(void) int ret; int i; - if (g_active_maxfd <= 0) + if (g_active_maxfd < 0) { return; } diff --git a/arch/sim/src/sim/sim_hostusrsock.h b/arch/sim/src/sim/sim_hostusrsock.h index e5fb2f10d3d31..34a2ce243b563 100644 --- a/arch/sim/src/sim/sim_hostusrsock.h +++ b/arch/sim/src/sim/sim_hostusrsock.h @@ -83,6 +83,8 @@ #define NUTTX_PF_PKTRADIO 64 #define NUTTX_PF_RPMSG 65 +#define NUTTX_UNIX_PATH_MAX 108 + #define NUTTX_AF_UNSPEC NUTTX_PF_UNSPEC #define NUTTX_AF_UNIX NUTTX_PF_UNIX #define NUTTX_AF_LOCAL NUTTX_PF_LOCAL @@ -219,6 +221,12 @@ struct nuttx_sockaddr char sa_data[14]; /* 14-bytes data (actually variable length) */ }; +struct nuttx_sockaddr_un +{ + sa_family_t sun_family; /* Address family: AF_LOCAL */ + char sun_path[NUTTX_UNIX_PATH_MAX]; +}; + struct nuttx_linger { int l_onoff; /* Indicates whether linger option is enabled. */ diff --git a/arch/sim/src/sim/sim_usrsock.c b/arch/sim/src/sim/sim_usrsock.c index c8210d0336149..ae41fc663b089 100644 --- a/arch/sim/src/sim/sim_usrsock.c +++ b/arch/sim/src/sim/sim_usrsock.c @@ -415,6 +415,7 @@ static const usrsock_handler_t g_usrsock_handler[] = static void sim_usrsock_work(void *arg) { + host_usrsock_loop(); work_queue_next_wq(g_work_queue, &g_usrsock.work, sim_usrsock_work, NULL, SIM_USRSOCK_PERIOD); } diff --git a/fs/hostfs/hostfs.c b/fs/hostfs/hostfs.c index 092655ef609ae..697a121548611 100644 --- a/fs/hostfs/hostfs.c +++ b/fs/hostfs/hostfs.c @@ -49,12 +49,6 @@ #include "hostfs.h" #include "fs_heap.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define HOSTFS_RETRY_DELAY_MS 10 - /**************************************************************************** * Private Types ****************************************************************************/ @@ -236,7 +230,7 @@ static void hostfs_mkpath(FAR struct hostfs_mountpt_s *fs, if (depth >= 0) { - strlcat(path, &relpath[first], pathlen - strlen(path)); + strlcat(path, &relpath[first], pathlen); } } diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h index 096be6ae75ae6..05486aed7cf32 100644 --- a/fs/hostfs/hostfs.h +++ b/fs/hostfs/hostfs.h @@ -29,6 +29,7 @@ #include +#include #include #include #include @@ -37,7 +38,7 @@ * Pre-processor Definitions ****************************************************************************/ -#define HOSTFS_MAX_PATH 256 +#define HOSTFS_MAX_PATH PATH_MAX /**************************************************************************** * Public Types diff --git a/include/nuttx/fs/hostfs.h b/include/nuttx/fs/hostfs.h index 694efe10c45fe..601b210db5aa5 100644 --- a/include/nuttx/fs/hostfs.h +++ b/include/nuttx/fs/hostfs.h @@ -113,6 +113,18 @@ #define NUTTX_CH_STAT_ATIME (1 << 3) #define NUTTX_CH_STAT_MTIME (1 << 4) +/* These must exactly match the definitions from include/nuttx/fs/ioctl.h: */ + +#define NUTTX_FIOC_SETLK 0x0312 +#define NUTTX_FIOC_GETLK 0x0313 +#define NUTTX_FIOC_SETLKW 0x0314 + +/* These must exactly match the definitions from include/fcntl.h: */ + +#define NUTTX_F_RDLCK 0 +#define NUTTX_F_WRLCK 1 +#define NUTTX_F_UNLCK 2 + #endif /* __SIM__ */ /**************************************************************************** @@ -203,6 +215,15 @@ struct nuttx_stat_s nuttx_blkcnt_t st_blocks; /* Number of blocks allocated */ }; +struct nuttx_flock_s +{ + int16_t l_type; + int16_t l_whence; + nuttx_off_t l_start; + nuttx_off_t l_len; + int32_t l_pid; +}; + #endif /* __SIM__ */ /**************************************************************************** diff --git a/libs/libc/netdb/lib_getservbynamer.c b/libs/libc/netdb/lib_getservbynamer.c index a1fe9fee71ce2..eaf3a26e7db45 100644 --- a/libs/libc/netdb/lib_getservbynamer.c +++ b/libs/libc/netdb/lib_getservbynamer.c @@ -46,6 +46,10 @@ const struct services_db_s g_services_db[] = { + { "http", 80, IP_PROTO_TCP }, + { "http", 80, IP_PROTO_UDP }, + { "https", 443, IP_PROTO_TCP }, + { "https", 443, IP_PROTO_UDP }, { "ntp", 123, IP_PROTO_TCP }, { "ntp", 123, IP_PROTO_UDP }, { NULL, 0, 0 } diff --git a/net/usrsock/usrsock_sockif.c b/net/usrsock/usrsock_sockif.c index 28079dfd38cf0..2e796a2b7dba9 100644 --- a/net/usrsock/usrsock_sockif.c +++ b/net/usrsock/usrsock_sockif.c @@ -103,10 +103,14 @@ static int usrsock_sockif_setup(FAR struct socket *psock) int ret; if (psock->s_domain != PF_INET && psock->s_domain != PF_INET6 && - psock->s_domain != PF_NETLINK) + psock->s_domain != PF_NETLINK +#ifndef CONFIG_NET_LOCAL + && psock->s_domain != PF_LOCAL +#endif + ) { - return -ENOTSUP; /* Only ipv4, ipv6 and netlink support the offload */ - }; + return -ENOTSUP; /* Only supported families can use usrsock offload */ + } /* Let the user socket logic handle the setup... *