fix issues and warnings when compiling with glibc < 2.32 (#57, #58)

This also fixes some inconsistencies such as mixing both strerror
and strerrordesc_np, and possible formatting issues.
This commit is contained in:
fusion32 2026-05-28 23:56:29 -03:00
parent d1c4dce3be
commit e2ba7cd296
15 changed files with 95 additions and 45 deletions

View File

@ -4,13 +4,13 @@ OUTPUTEXE = game
CC = g++
CFLAGS = -m64 -fno-strict-aliasing -pedantic -Wall -Wextra -Wno-deprecated-declarations -Wno-unused-parameter -Wno-format-truncation -std=c++11 -pthread -DOS_LINUX=1 -DARCH_X64=1
LFLAGS = -Wl,-t -lcrypto
LFLAGS = -Wl,-t -lrt -lcrypto
DEBUG ?= 0
ifneq ($(DEBUG), 0)
CFLAGS += -g -Og -DENABLE_ASSERTIONS=1
CFLAGS += -g -Og -DENABLE_ASSERTIONS=1
else
CFLAGS += -O2
CFLAGS += -O2
endif
HEADERS = $(SRCDIR)/common.hh $(SRCDIR)/communication.hh $(SRCDIR)/config.hh $(SRCDIR)/connections.hh $(SRCDIR)/containers.hh $(SRCDIR)/cr.hh $(SRCDIR)/crypto.hh $(SRCDIR)/enums.hh $(SRCDIR)/houses.hh $(SRCDIR)/info.hh $(SRCDIR)/magic.hh $(SRCDIR)/map.hh $(SRCDIR)/moveuse.hh $(SRCDIR)/objects.hh $(SRCDIR)/operate.hh $(SRCDIR)/query.hh $(SRCDIR)/reader.hh $(SRCDIR)/script.hh $(SRCDIR)/threads.hh $(SRCDIR)/writer.hh

View File

@ -182,6 +182,8 @@ void error(const char *Text, ...) ATTR_PRINTF(1, 2);
void print(int Level, const char *Text, ...) ATTR_PRINTF(2, 3);
int random(int Min, int Max);
bool FileExists(const char *FileName);
const char *GetSignalDescription(int SigNr);
const char *GetErrorDescription(int SigNr);
bool isSpace(int c);
bool isAlpha(int c);

View File

@ -652,7 +652,7 @@ bool CallGameThread(TConnection *Connection){
Connection->WaitingForACK = true;
if(tgkill(GetGameProcessID(), GetGameThreadID(), SIGUSR1) == -1){
error("CallGameThread: Can't send SIGUSR1 to thread %d/%d: (%d) %s\n",
GetGameProcessID(), GetGameThreadID(), errno, strerrordesc_np(errno));
GetGameProcessID(), GetGameThreadID(), errno, GetErrorDescription(errno));
SendLoginMessage(Connection, LOGIN_MESSAGE_ERROR,
"The server is not online.\nPlease try again later.", -1);
return false;
@ -1489,21 +1489,21 @@ bool OpenSocket(void){
Linger.l_linger = 0;
if(setsockopt(TCPSocket, SOL_SOCKET, SO_LINGER, &Linger, sizeof(Linger)) == -1){
error("LaunchServer: Failed to set SO_LINGER=(0, 0): (%d) %s.\n",
errno, strerrordesc_np(errno));
errno, GetErrorDescription(errno));
return false;
}
int ReuseAddr = 1;
if(setsockopt(TCPSocket, SOL_SOCKET, SO_REUSEADDR, &ReuseAddr, sizeof(ReuseAddr)) == -1){
error("LaunchServer: Failed to set SO_REUSEADDR=1: (%d) %s.\n",
errno, strerrordesc_np(errno));
errno, GetErrorDescription(errno));
return false;
}
int NoDelay = 1;
if(setsockopt(TCPSocket, IPPROTO_TCP, TCP_NODELAY, &NoDelay, sizeof(NoDelay)) == -1){
error("LaunchServer: Failed to set TCP_NODELAY=1: (%d) %s.\n",
errno, strerrordesc_np(errno));
errno, GetErrorDescription(errno));
return false;
}
@ -1517,7 +1517,7 @@ bool OpenSocket(void){
#endif
if(bind(TCPSocket, (struct sockaddr*)&ServerAddress, sizeof(ServerAddress)) == -1){
error("LaunchServer: Failed to bind to acceptor to %s:%d: (%d) %s.\n",
inet_ntoa(ServerAddress.sin_addr), GamePort, errno, strerrordesc_np(errno));
inet_ntoa(ServerAddress.sin_addr), GamePort, errno, GetErrorDescription(errno));
return false;
}

View File

@ -105,7 +105,7 @@ bool TConnection::SetLoginTimer(int Timeout){
SigEvent.sigev_notify_thread_id = this->ThreadID;
if(timer_create(CLOCK_MONOTONIC, &SigEvent, &this->LoginTimer) == -1){
error("TConnection::SetLoginTimer: Failed to create timer: (%d) %s\n",
errno, strerrordesc_np(errno));
errno, GetErrorDescription(errno));
return false;
}
@ -113,7 +113,7 @@ bool TConnection::SetLoginTimer(int Timeout){
TimerSpec.it_value.tv_sec = Timeout;
if(timer_settime(this->LoginTimer, 0, &TimerSpec, NULL) == -1){
error("TConnection::SetLoginTimer: Failed to start timer: (%d) %s\n",
errno, strerrordesc_np(errno));
errno, GetErrorDescription(errno));
return false;
}
@ -133,7 +133,7 @@ void TConnection::StopLoginTimer(void){
if(timer_delete(this->LoginTimer) == -1){
error("TConnection::StopLoginTimer: Failed to delete timer: (%d) %s\n",
errno, strerrordesc_np(errno));
errno, GetErrorDescription(errno));
}
this->LoginTimer = 0;

View File

@ -53,7 +53,8 @@ static void SigBlock(int SigNr){
sigaddset(&Set, SigNr);
if(sigprocmask(SIG_BLOCK, &Set, NULL) == -1){
error("SigBlock: Failed to block signal %d (%s): (%d) %s\n",
SigNr, sigdescr_np(SigNr), errno, strerrordesc_np(errno));
SigNr, GetSignalDescription(SigNr),
errno, GetErrorDescription(errno));
}
}
@ -63,18 +64,18 @@ static void SigWaitAny(void){
sigsuspend(&Set);
}
static void SigHupHandler(int signr){
static void SigHupHandler(int SigNr){
// no-op (?)
}
static void SigAbortHandler(int signr){
static void SigAbortHandler(int SigNr){
print(1, "SigAbortHandler: schalte Writer-Thread ab.\n");
AbortWriter();
}
static void DefaultHandler(int signr){
static void DefaultHandler(int SigNr){
print(1, "DefaultHandler: Beende Game-Server (SigNr. %d: %s).\n",
signr, sigdescr_np(signr));
SigNr, GetSignalDescription(SigNr));
SigHandler(SIGINT, SIG_IGN);
SigHandler(SIGQUIT, SIG_IGN);
@ -83,8 +84,8 @@ static void DefaultHandler(int signr){
SigHandler(SIGXFSZ, SIG_IGN);
SigHandler(SIGPWR, SIG_IGN);
SaveMapOn = (signr == SIGQUIT) || (signr == SIGTERM) || (signr == SIGPWR);
if(signr == SIGTERM){
SaveMapOn = (SigNr == SIGQUIT) || (SigNr == SIGTERM) || (SigNr == SIGPWR);
if(SigNr == SIGTERM){
int Hour, Minute;
GetRealTime(&Hour, &Minute);
RebootTime = (Hour * 60 + Minute + 6) % 1440;
@ -98,8 +99,8 @@ static void DefaultHandler(int signr){
#if 0
// TODO(fusion): This function was exported in the binary but not referenced anywhere.
static void ErrorHandler(int signr){
error("ErrorHandler: SigNr. %d: %s\n", signr, sigdescr_np(signr));
static void ErrorHandler(int SigNr){
error("ErrorHandler: SigNr. %d: %s\n", SigNr, GetSignalDescription(SigNr));
EndGame();
LogoutAllPlayers();
exit(EXIT_FAILURE);
@ -151,7 +152,7 @@ static void InitTime(void){
SigEvent.sigev_notify_thread_id = gettid();
if(timer_create(CLOCK_MONOTONIC, &SigEvent, &BeatTimer) == -1){
error("InitTime: Failed to create beat timer: (%d) %s\n",
errno, strerrordesc_np(errno));
errno, GetErrorDescription(errno));
throw "cannot create beat timer";
}
@ -161,7 +162,7 @@ static void InitTime(void){
TimerSpec.it_value = TimerSpec.it_interval;
if(timer_settime(BeatTimer, 0, &TimerSpec, NULL) == -1){
error("InitTime: Failed to start beat timer: (%d) %s\n",
errno, strerrordesc_np(errno));
errno, GetErrorDescription(errno));
throw "cannot start beat timer";
}
}
@ -169,7 +170,7 @@ static void InitTime(void){
static void ExitTime(void){
if(timer_delete(BeatTimer) == -1){
error("ExitTime: Failed to delete beat timer: (%d) %s\n",
errno, strerrordesc_np(errno));
errno, GetErrorDescription(errno));
}
SigHandler(SIGALRM, SIG_IGN);
@ -448,7 +449,7 @@ static void AdvanceGame(int Delay){
SendAll();
}
static void SigUsr1Handler(int signr){
static void SigUsr1Handler(int SigNr){
SigUsr1Counter += 1;
}
@ -508,7 +509,12 @@ static bool DaemonInit(bool NoFork){
}
umask(0177);
chdir(SAVEPATH);
// NOTE(fusion): The original binary would change directories to `SAVEPATH`
// here, but because this function is called very early at startup, no config
// values would have been loaded, leaving `SAVEPATH` empty and causing this
// next call to `chdir` to always fail with ENOENT.
//chdir(SAVEPATH);
int OpenMax = sysconf(_SC_OPEN_MAX);
if(OpenMax < 0){

View File

@ -1713,7 +1713,7 @@ void PatchSector(int SectorX, int SectorY, int SectorZ, bool FullSector,
if(rename(FileNameBak, FileName) != 0){
int ErrCode = errno;
error("PatchSector: Fehler %d beim Umbenennen von %s.\n", ErrCode, FileNameBak);
error("# Fehler %d: %s.\n", ErrCode, strerror(ErrCode));
error("# Fehler %d: %s.\n", ErrCode, GetErrorDescription(ErrCode));
throw "cannot patch ORIGMAP";
}
}

View File

@ -2406,7 +2406,7 @@ void Talk(uint32 CreatureID, int Mode, const char *Addressee, const char *Text,
TConnection *Connection = GetFirstConnection();
while(Connection != NULL){
if(Connection->Live()){
SendMessage(Connection, TALK_ADMIN_MESSAGE, Text);
SendMessage(Connection, TALK_ADMIN_MESSAGE, "%s", Text);
}
Connection = GetNextConnection();

View File

@ -95,7 +95,7 @@ void TQueryManagerConnection::connect(void){
int SocketFlags = fcntl(this->Socket, F_GETFL);
if(SocketFlags == -1 || fcntl(this->Socket, F_SETFL, (SocketFlags | O_NONBLOCK)) == -1){
error("TQueryManagerConnection::connect: Failed to set socket as non-blocking: (%d) %s\n",
errno, strerrordesc_np(errno));
errno, GetErrorDescription(errno));
this->disconnect();
continue;
}

View File

@ -115,7 +115,7 @@ void TReadScriptFile::open(const char *FileName){
if(this->File[Depth] == NULL){
int ErrCode = errno;
::error("TReadScriptFile::open: Kann Datei %s nicht öffnen.\n", this->Filename[Depth]);
::error("Fehler %d: %s.\n", ErrCode, strerror(ErrCode));
::error("Fehler %d: %s.\n", ErrCode, GetErrorDescription(ErrCode));
throw "Cannot open script-file";
}
@ -582,7 +582,7 @@ void TWriteScriptFile::open(const char *FileName){
if(this->File == NULL){
int ErrCode = errno;
::error("TWriteScriptFile: Kann Datei %s nicht anlegen.\n", FileName);
::error("Fehler %d: %s.\n", ErrCode, strerror(ErrCode));
::error("Fehler %d: %s.\n", ErrCode, GetErrorDescription(ErrCode));
throw "Cannot create script-file";
}
@ -751,7 +751,7 @@ void TReadBinaryFile::close(void){
int ErrCode = errno;
::error("TReadBinaryFile::close: Fehler beim Schließen der Datei.\n");
::error("# Datei: %s, Fehlercode: %d (%s)\n",
this->Filename, ErrCode, strerror(ErrCode));
this->Filename, ErrCode, GetErrorDescription(ErrCode));
}
this->File = NULL;
}
@ -811,7 +811,7 @@ uint8 TReadBinaryFile::readByte(void){
int Position = this->getPosition();
::error("TReadBinaryFile::readByte: Fehler beim Lesen eines Bytes\n");
::error("# Datei: %s, Position: %d, Rückgabewert: %d, Fehlercode: %d (%s)\n",
this->Filename, Position, Result, ErrCode, strerror(ErrCode));
this->Filename, Position, Result, ErrCode, GetErrorDescription(ErrCode));
// NOTE(fusion): Close file and make a backup, possibly for further inspection.
if(fclose(this->File) != 0){
@ -832,7 +832,7 @@ void TReadBinaryFile::readBytes(uint8 *Buffer, int Count){
int Position = this->getPosition();
::error("TReadBinaryFile::readBytes: Fehler beim Lesen von %d Bytes\n", Count);
::error("# Datei: %s, Position %d, Rückgabewert: %d, Fehlercode: %d (%s)\n",
this->Filename, Position, Result, ErrCode, strerror(ErrCode));
this->Filename, Position, Result, ErrCode, GetErrorDescription(ErrCode));
// NOTE(fusion): Close file and make a backup, possibly for further inspection.
if(fclose(this->File) != 0){
@ -885,7 +885,7 @@ void TWriteBinaryFile::open(const char *FileName){
if(this->File == NULL){
int ErrCode = errno;
::error("TWriteBinaryFile::open: Kann Datei %s nicht anlegen.\n", FileName);
::error("Fehler %d: %s.\n", ErrCode, strerror(ErrCode));
::error("Fehler %d: %s.\n", ErrCode, GetErrorDescription(ErrCode));
snprintf(ErrorString, sizeof(ErrorString),
"Cannot create file %s.", FileName);
@ -902,7 +902,7 @@ void TWriteBinaryFile::close(void){
int ErrCode = errno;
::error("TWriteBinaryFile::close: Fehler beim Schließen der Datei.\n");
::error("# Datei: %s, Fehlercode: %d (%s)\n",
this->Filename, ErrCode, strerror(ErrCode));
this->Filename, ErrCode, GetErrorDescription(ErrCode));
}
this->File = NULL;
}
@ -928,7 +928,7 @@ void TWriteBinaryFile::writeByte(uint8 Byte){
int ErrCode = errno;
::error("TWriteBinaryFile::writeByte: Fehler beim Schreiben eines Bytes\n");
::error("# Datei: %s, Rückgabewert: %d, Fehlercode: %d (%s)\n",
this->Filename, Result, ErrCode, strerror(ErrCode));
this->Filename, Result, ErrCode, GetErrorDescription(ErrCode));
// NOTE(fusion): Close file and make a backup, possibly for further inspection.
if(fclose(this->File) != 0){
@ -947,7 +947,7 @@ void TWriteBinaryFile::writeBytes(const uint8 *Buffer, int Count){
int ErrCode = errno;
::error("TWriteBinaryFile::writeBytes: Fehler beim Schreiben von %d Bytes\n", Count);
::error("# Datei: %s, Rückgabewert: %d, Fehlercode: %d (%s)\n",
this->Filename, Result, ErrCode, strerror(ErrCode));
this->Filename, Result, ErrCode, GetErrorDescription(ErrCode));
// NOTE(fusion): Close file and make a backup, possibly for further inspection.
if(fclose(this->File) != 0){

View File

@ -349,7 +349,7 @@ void SendResult(TConnection *Connection, RESULT r){
}
if(Message != NULL){
SendMessage(Connection, TALK_FAILURE_MESSAGE, Message);
SendMessage(Connection, TALK_FAILURE_MESSAGE, "%s", Message);
if(r == ENTERPROTECTIONZONE || r == NOTINVITED || r == MOVENOTPOSSIBLE){
SendSnapback(Connection);
}
@ -1721,7 +1721,7 @@ void BroadcastMessage(int Mode, const char *Text, ...){
TConnection *Connection = GetFirstConnection();
while(Connection != NULL){
if(Connection->Live()){
SendMessage(Connection, Mode, Message);
SendMessage(Connection, Mode, "%s", Message);
}
Connection = GetNextConnection();
}

View File

@ -126,7 +126,7 @@ static void ErrorHandler(const char *Text){
if(SHM != NULL){
SHM->Errors += 1;
if(SHM->Errors <= 0x8000){
Log("error", Text);
Log("error", "%s", Text);
if(SHM->Errors == 0x8000){
Log("error", "Zu viele Fehler. Keine weitere Protokollierung.\n");
}

View File

@ -146,10 +146,10 @@ Semaphore::~Semaphore(void){
int ErrorCode;
if((ErrorCode = pthread_mutex_destroy(&this->mutex)) != 0){
error("Semaphore::~Semaphore: Kann Mutex nicht freigeben: (%d) %s.\n",
ErrorCode, strerrordesc_np(ErrorCode));
ErrorCode, GetErrorDescription(ErrorCode));
}else if((ErrorCode = pthread_cond_destroy(&this->condition)) != 0){
error("Semaphore::~Semaphore: Kann Wartebedingung nicht freigeben: (%d) %s.\n",
ErrorCode, strerrordesc_np(ErrorCode));
ErrorCode, GetErrorDescription(ErrorCode));
}
}

View File

@ -1,5 +1,6 @@
#include "common.hh"
#include <signal.h>
#include <sys/stat.h>
static TErrorFunction *ErrorFunction;
@ -95,6 +96,46 @@ bool FileExists(const char *FileName){
return Result;
}
#if !defined(_GNU_SOURCE) || (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 32))
# if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
static const char *sigdescr_np(int SigNr){
const char *Description = NULL;
if(SigNr >= 0 && SigNr < NSIG){
Description = sys_siglist[SigNr];
}
return Description;
}
static const char *strerrordesc_np(int ErrCode){
const char *Description = NULL;
if(ErrCode >= 0 && ErrCode < sys_nerr){
Description = sys_errlist[ErrCode];
}
return Description;
}
# else // defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
#warning "Current LIBC/GLIBC version doesn't expose error/signal description tables."
static const char *sigdescr_np(int SigNr){ return "No signal description"; }
static const char *strerrordesc_np(int ErrCode){ return "No error description"; }
# endif // defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
#endif //!defined(_GNU_SOURCE) || (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 32))
const char *GetSignalDescription(int SigNr){
const char *Description = sigdescr_np(SigNr);
if(Description == NULL){
Description = "Invalid signal";
}
return Description;
}
const char *GetErrorDescription(int ErrCode){
const char *Description = strerrordesc_np(ErrCode);
if(Description == NULL){
Description = "Invalid error";
}
return Description;
}
// String Utility
// =============================================================================
bool isSpace(int c){

View File

@ -921,7 +921,7 @@ void ProcessBroadcastReply(TBroadcastReplyData *Data){
return;
}
BroadcastMessage(TALK_STATUS_MESSAGE, Data->Message);
BroadcastMessage(TALK_STATUS_MESSAGE, "%s", Data->Message);
delete Data;
}

View File

@ -30,6 +30,7 @@ var (
releaseOptions = []string{"-O2"}
linkerOptions = []string{
"-Wl,-t",
"-lrt",
"-lcrypto",
}
)
@ -80,9 +81,9 @@ func main() {
// DEBUG SWITCH
fmt.Fprint(&output, "DEBUG ?= 0\n")
fmt.Fprint(&output, "ifneq ($(DEBUG), 0)\n")
fmt.Fprintf(&output, "\tCFLAGS += %v\n", strings.Join(debugOptions, " "))
fmt.Fprintf(&output, " CFLAGS += %v\n", strings.Join(debugOptions, " "))
fmt.Fprint(&output, "else\n")
fmt.Fprintf(&output, "\tCFLAGS += %v\n", strings.Join(releaseOptions, " "))
fmt.Fprintf(&output, " CFLAGS += %v\n", strings.Join(releaseOptions, " "))
fmt.Fprint(&output, "endif\n\n")
// HEADERS