Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify & shorten additional posixlib socket code paths #2742

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
22 changes: 9 additions & 13 deletions posixlib/src/main/resources/scala-native/netdb.h
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
#ifdef _WIN32
#include <WinSock2.h>
#include <ws2tcpip.h> // socklen_t
#define strdup(arg1) _strdup(arg1);
#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. */
int ai_family; /* Protocol family for socket. */
int ai_socktype; /* Socket type. */
int ai_protocol; /* Protocol for socket. */
socklen_t ai_addrlen; /* Length of socket address. */
struct scalanative_sockaddr *ai_addr; /* Socket address for socket. */
char *ai_canonname; /* Canonical name for service location. */
void *ai_next; /* Pointer to next in list. */
int ai_flags; /* Input flags. */
int ai_family; /* Protocol family for socket. */
int ai_socktype; /* Socket type. */
int ai_protocol; /* Protocol for socket. */
socklen_t ai_addrlen; /* Length of socket address. */
void *ai_addr; /* Socket address for socket. */
char *ai_canonname; /* Canonical name for service location. */
void *ai_next; /* Pointer to next in list. */
};
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.