Replace ioctl with fcntl, fix ioctlsocket calls (64-bit fix)

`ioctl` and `ioctlsocket` take two different types of arguments but worked in the past due to
long being 32-bit. However, ioctl functionality is non-standard and should not be used in
code written after **1997** in order to make sockets non-blocking. This functionality was
standardized as part of fcntl.

* Using the new function `make_nonblocking` to make socket nonblocking
This commit is contained in:
GravisZro 2024-05-22 17:41:31 -04:00
parent 8485cb0c4d
commit 4ac9b9c22f
9 changed files with 39 additions and 81 deletions

View File

@ -140,6 +140,7 @@ typedef int socklen_t;
#include "init.h"
#include "ship.h"
#include "hud.h"
#include "networking.h"
bool Dedicated_server = false;
@ -809,7 +810,9 @@ void PrintDedicatedMessage(const char *fmt, ...) {
#define WSAEINVAL EINVAL
#define WSAENOPROTOOPT ENOPROTOOPT
#define WSAGetLastError(a) errno
#ifndef WSAGetLastError
#define WSAGetLastError() errno
#endif
#define SOCKET_ERROR -1
@ -854,15 +857,7 @@ void InitDedicatedSocket(uint16_t port) {
mprintf((0, "Unable to listen on dedicated server socket!\n"));
return;
}
// Make the socket non-blocking
#if defined(WIN32)
u_long argp = 1;
ioctlsocket(dedicated_listen_socket, FIONBIO, &argp);
#elif defined(__LINUX__)
int argp = 1;
ioctl(dedicated_listen_socket, FIONBIO, &argp);
#endif
make_nonblocking(dedicated_listen_socket);
}
void ListenDedicatedSocket(void) {
@ -874,13 +869,8 @@ void ListenDedicatedSocket(void) {
if (INVALID_SOCKET != incoming_socket) {
// Make the socket non-blocking
#if defined(WIN32)
u_long argp = 1;
ioctlsocket(incoming_socket, FIONBIO, &argp);
#elif defined(__LINUX__)
int argp = 1;
ioctl(incoming_socket, FIONBIO, &argp);
#endif
make_nonblocking(incoming_socket);
if (!Dedicated_allow_remote) {
// Check to see if this came in from the local address
uint32_t localhost = inet_addr("127.0.0.1");

View File

@ -64,7 +64,6 @@
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/ioctl.h>
#define MAX_TCPLOG_LEN 2000
#define SOCKET int

View File

@ -201,15 +201,9 @@ void ChttpGet::PrepSocket(char *URL)
{
m_State = HTTP_STATE_SOCKET_ERROR;
return;
}
unsigned long arg;
}
arg = true;
#if defined(WIN32)
ioctlsocket( m_DataSock, FIONBIO, &arg );
#elif defined(__LINUX__)
ioctl( m_DataSock, FIONBIO, &arg );
#endif
make_nonblocking(m_DataSock);
char *pURL = URL;
if(strnicmp(URL,"http:",5)==0)
@ -759,16 +753,6 @@ uint32_t ChttpGet::ReadDataChannel()
}
}
typedef struct _async_dns_lookup
{
uint32_t ip; //resolved host. Write only to worker thread.
char * host;//host name to resolve. read only to worker thread
bool done; //write only to the worker thread. Signals that the operation is complete
bool error; //write only to worker thread. Thread sets this if the name doesn't resolve
bool abort; //read only to worker thread. If this is set, don't fill in the struct.
}async_dns_lookup;
async_dns_lookup httpaslu;
async_dns_lookup *http_lastaslu = NULL;

View File

@ -30,9 +30,9 @@
#include "game.h"
#include "pilot.h"
#include "ddio_common.h"
#include "networking.h"
#ifdef __LINUX__
#include "networking.h"
#include <sys/time.h>
#include <unistd.h>
#endif
@ -133,8 +133,7 @@ int ConnectToChatServer(char *serveraddr,char *nickname,char *trackerid)
{
int16_t chat_port;
char chat_server[50];
char *p;
unsigned long argp = 1;
char *p;
char signon_str[100];
//if(Socket_connected && ) return -2;
@ -186,12 +185,7 @@ int ConnectToChatServer(char *serveraddr,char *nickname,char *trackerid)
return -1;
}
#ifdef WIN32
ioctlsocket( Chatsock, FIONBIO, &argp );
#elif defined(__LINUX__)
ioctl(Chatsock,FIONBIO,&argp);
#endif
make_nonblocking(Chatsock);
/*
HOSTENT *he;

View File

@ -237,7 +237,10 @@ static inline void INADDR_GET_SUN_SUNB(struct in_addr *st, uint8_t *s_b1, uint8_
#define WSAEINVAL EINVAL
#define WSAENOPROTOOPT ENOPROTOOPT
static inline int WSAGetLastError() { return errno; }
#ifndef WSAGetLastError
#define WSAGetLastError() errno
#endif
extern bool Use_DirectPlay;
// helper macros for working with SOCKADDR_IN to make it look nicer between windows and Linux
@ -343,6 +346,10 @@ typedef struct {
extern BOOL DP_active;
extern BOOL TCP_active;
extern BOOL IPX_active;
// create a new non-blocking socket
int make_nonblocking(SOCKET sock);
// Get the info from RAS
uint32_t psnet_ras_status();

View File

@ -65,6 +65,7 @@
#define _CHTTPGET_HEADER_
#include <cstdint>
#include "networking.h"
#define HTTP_STATE_INTERNAL_ERROR 0
#define HTTP_STATE_SOCKET_ERROR 1

View File

@ -93,7 +93,6 @@
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netdb.h>
#include <sys/time.h>
#include <unistd.h>
@ -126,8 +125,8 @@
#define WSAEISCONN EISCONN
#define SOCKET_ERROR -1
#ifndef NETWORKING_H
static inline int WSAGetLastError() { return errno; }
#ifndef WSAGetLastError
#define WSAGetLastError() errno
#endif

View File

@ -210,14 +210,8 @@ void ChttpGet::PrepSocket(char *URL) {
m_State = HTTP_STATE_SOCKET_ERROR;
return;
}
uint32_t arg = 1;
#ifdef WIN32
u_long argWin = static_cast<u_long>(arg);
ioctlsocket(m_DataSock, FIONBIO, &argWin);
#elif defined(__linux__)
ioctl(m_DataSock, FIONBIO, &arg);
#endif
make_nonblocking(m_DataSock);
char *pURL = URL;
if (strnicmp(URL, "http:", 5) == 0) {
@ -669,18 +663,6 @@ uint32_t ChttpGet::ReadDataChannel() {
}
}
typedef struct _async_dns_lookup {
uint32_t ip; // resolved host. Write only to worker thread.
char *host; // host name to resolve. read only to worker thread
bool done; // write only to the worker thread. Signals that the operation is complete
bool error; // write only to worker thread. Thread sets this if the name doesn't resolve
bool abort; // read only to worker thread. If this is set, don't fill in the struct.
#ifdef __LINUX__
SDL_Thread *threadId;
#endif
} async_dns_lookup;
static async_dns_lookup httpaslu;
static async_dns_lookup *http_lastaslu = NULL;

View File

@ -519,10 +519,20 @@ typedef struct {
static reliable_socket reliable_sockets[MAXRELIABLESOCKETS];
//*******************************
#ifdef __LINUX__
#include <fcntl.h>
#endif
static void CloseNetworking();
static void nw_SetSocketOptions(SOCKET sock);
static void nw_LoadThreadLibrary(void);
int make_nonblocking(SOCKET sock)
{
SOCKET rval;
#ifdef WIN32
unsigned long arg = 1;
return ioctlsocket(sock, FIONBIO, &arg);
#else // WIN32
return fcntl(sock, F_SETFL, fcntl(rval, F_GETFL, 0) | O_NONBLOCK);
#endif
}
void CloseNetworking() {
if (Sockets_initted != 1)
@ -671,15 +681,7 @@ void nw_SetSocketOptions(SOCKET sock) {
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (LPSTR)&broadcast, sizeof(broadcast));
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (LPSTR)&broadcast, sizeof(broadcast));
int error;
unsigned long arg;
arg = TRUE;
#ifdef WIN32
error = ioctlsocket(sock, FIONBIO, &arg);
#elif defined(__LINUX__)
error = ioctl(sock, FIONBIO, &arg);
#endif
int error = make_nonblocking(sock);
if (error == SOCKET_ERROR) {
mprintf((0, "Unable to make socket non-blocking -- %d", WSAGetLastError()));
}