Skip to content

Commit

Permalink
Simplify & shorten additional posixlib socket code paths
Browse files Browse the repository at this point in the history
  • Loading branch information
LeeTibbert committed Jul 20, 2022
1 parent 607c813 commit 24e004e
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 349 deletions.
41 changes: 8 additions & 33 deletions posixlib/src/main/resources/scala-native/netdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,20 @@
#ifdef _WIN32
#include <Winerror.h>
#else // not _WIN32
// FreeBSD wants AF_INET, which is in <sys/socket.h> but not in the local
// "sys/socket.h".
// FreeBSD wants AF_INET, which is in <sys/socket.h>
//
// Windows can not find the <> form, and suggests the "" form. However,
// the later is a local copy which does not define AF_INET.
// Including that file prevents the system copy with AF_INET from
// being included.
// Windows can not find the <> form, and suggests the "" form.
//
// On linux, macOS, etc. the include should provide AF_INET if it has
// On linux, macOS, etc. This include should provide AF_INET if it has
// not been previously defined.

#include <sys/socket.h>
#endif

#include "sys/socket_conversions.h"
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

int scalanative_getnameinfo(struct scalanative_sockaddr *addr,
socklen_t addrlen, char *host, socklen_t hostlen,
char *serv, socklen_t servlen, int flags) {
struct sockaddr *converted_addr;
scalanative_convert_sockaddr(addr, &converted_addr, &addrlen);
int status = getnameinfo(converted_addr, addrlen, host, hostlen, serv,
servlen, flags);
free(converted_addr);
return status;
}

void scalanative_convert_scalanative_addrinfo(struct scalanative_addrinfo *in,
struct addrinfo *out) {
// ai_addr and ai_next fields are set to NULL because this function is only
Expand Down Expand Up @@ -68,20 +52,11 @@ void scalanative_convert_addrinfo(struct addrinfo *in,
out->ai_addr = NULL;
out->ai_addrlen = in->ai_addrlen;
} else {
socklen_t size;
if (in->ai_addr->sa_family == AF_INET) {
struct scalanative_sockaddr_in *addr =
malloc(sizeof(struct scalanative_sockaddr_in));
scalanative_convert_scalanative_sockaddr_in(
(struct sockaddr_in *)in->ai_addr, addr, &size);
out->ai_addr = (struct scalanative_sockaddr *)addr;
} else {
struct scalanative_sockaddr_in6 *addr =
malloc(sizeof(struct scalanative_sockaddr_in6));
scalanative_convert_scalanative_sockaddr_in6(
(struct sockaddr_in6 *)in->ai_addr, addr, &size);
out->ai_addr = (struct scalanative_sockaddr *)addr;
}
socklen_t size = (in->ai_addr->sa_family == AF_INET)
? sizeof(struct sockaddr_in)
: sizeof(struct sockaddr_in6);
struct scalanative_sockaddr *addr = malloc(size);
out->ai_addr = memcpy(addr, in->ai_addr, size);
out->ai_addrlen = size;
}
if (in->ai_canonname == NULL) {
Expand Down
5 changes: 0 additions & 5 deletions posixlib/src/main/resources/scala-native/netdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@
#else
#include <netdb.h>
#endif
#include "sys/socket_conversions.h"

#ifndef __SYS_SOCKET_H
#include "sys/socket.h"
#endif

struct scalanative_addrinfo {
int ai_flags; /* Input flags. */
Expand Down
4 changes: 3 additions & 1 deletion posixlib/src/main/resources/scala-native/netinet/in.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#define __NETINET_IN_H

#include <inttypes.h>
#include "../sys/socket.h"

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
Expand All @@ -16,6 +15,9 @@ typedef uint16_t in_port_t;
#include <netinet/in.h>
#endif

// See comment on this type in sys/socket.c. Keep in sync.
typedef unsigned short scalanative_sa_family_t;

struct scalanative_in_addr {
in_addr_t so_addr;
};
Expand Down
138 changes: 38 additions & 100 deletions posixlib/src/main/resources/scala-native/sys/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "socket_conversions.h"

#ifdef _WIN32
#include <WinSock2.h>
Expand All @@ -17,14 +16,44 @@ typedef SSIZE_T ssize_t;
#warning "Size and order of C structures are not checked when -std < c11."
#endif
#else
// Posix defines the name and type of required fields. Size of fields
// and any internal or tail padding are left unspecified. This section
// verifies that the C and Scala Native definitions match in each compilation
// environment.
//
// The first sockaddr field in C has had size 2 and no padding after it
// since time immemorial. Verify that the Scala Native field has the same.

/* POSIX defines the name and type of required fields. Size of fields
* and any internal or tail padding are left unspecified. This section
* verifies that the C and Scala Native definitions match in each compilation
* environment.
*
* With such assurance, Scala Native code can call directly into C or
* C like code without an expensive conversion layer.
*
* The first sockaddr field in C has had size 2 and no padding after it
* since time immemorial.
*
* BSD operating systems changed. macOS & FreeBSD kept the two byte prologue
* by shortening sa_family to one byte and adding a one byte
* sin_len/sin6_len field (editorial snark deleted).
*
* Here the traditional 2 bytes are declared. On BSD systems, code in
* Socket.scala handles reading and writing the "short" sa_family and
* synthesizes the sin*_len fields.
*
* If scalanative_sa_family_t _ever_ changes here, keep in sync with
* netinet/in.h.
*/

typedef unsigned short scalanative_sa_family_t;

struct scalanative_sockaddr {
scalanative_sa_family_t sa_family;
char sa_data[14];
};

struct scalanative_sockaddr_storage {
scalanative_sa_family_t ss_family;
unsigned short __opaquePadTo32;
unsigned int __opaquePadTo64;
unsigned long long __opaqueAlignStructure[15];
};

// Also verifies that Scala Native sa_family field has the traditional size.
_Static_assert(offsetof(struct scalanative_sockaddr, sa_data) == 2,
"Unexpected size: scalanative_sockaddr sa_family");

Expand Down Expand Up @@ -124,94 +153,3 @@ int scalanative_af_inet6() { return AF_INET6; }
int scalanative_af_unix() { return AF_UNIX; }

int scalanative_af_unspec() { return AF_UNSPEC; }

int scalanative_getsockname(int socket, struct scalanative_sockaddr *address,
socklen_t *address_len) {
struct sockaddr *converted_address = NULL;
int convert_result =
scalanative_convert_sockaddr(address, &converted_address, address_len);

int result;

if (convert_result == 0) {
result = getsockname(socket, converted_address, address_len);
convert_result = scalanative_convert_scalanative_sockaddr(
converted_address, address, address_len);

if (convert_result != 0) {
errno = convert_result;
result = -1;
}
} else {
errno = convert_result;
result = -1;
}

if (converted_address != NULL)
free(converted_address);

return result;
}

int scalanative_bind(int socket, struct scalanative_sockaddr *address,
socklen_t address_len) {
struct sockaddr *converted_address;
int convert_result =
scalanative_convert_sockaddr(address, &converted_address, &address_len);

int result;

if (convert_result == 0) {
result = bind(socket, converted_address, address_len);
} else {
errno = convert_result;
result = -1;
}

free(converted_address);
return result;
}

int scalanative_connect(int socket, struct scalanative_sockaddr *address,
socklen_t address_len) {
struct sockaddr *converted_address;
int convert_result =
scalanative_convert_sockaddr(address, &converted_address, &address_len);

int result;

if (convert_result == 0) {
result = connect(socket, converted_address, address_len);
} else {
errno = convert_result;
result = -1;
}
free(converted_address);
return result;
}

int scalanative_accept(int socket, struct scalanative_sockaddr *address,
socklen_t *address_len) {
struct sockaddr *converted_address;
int convert_result =
scalanative_convert_sockaddr(address, &converted_address, address_len);

int result;

if (convert_result == 0) {
result = accept(socket, converted_address, address_len);
convert_result = scalanative_convert_scalanative_sockaddr(
converted_address, address, address_len);

if (convert_result != 0) {
errno = convert_result;
result = -1;
}
} else {
errno = convert_result;
result = -1;
}

free(converted_address);
return result;
}
6 changes: 0 additions & 6 deletions posixlib/src/main/resources/scala-native/sys/socket.h

This file was deleted.

0 comments on commit 24e004e

Please sign in to comment.