upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/compat.h
blob: 68f78e0153adde703454ddfe45e924e27e8b64b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// Copyright (c) 2026 Bitflash developers
// Distributed under the MIT/X11 software license.
//
// POSIX/Linux compatibility shim. Lets the Windows-flavored core (Winsock,
// _beginthread, CRITICAL_SECTION, Sleep, ...) compile largely unchanged on
// Linux for the headless node/miner `bitflash-node`. Included by headers.h on
// non-Windows platforms only; the Windows build never sees this file.

#ifndef BITFLASH_COMPAT_H
#define BITFLASH_COMPAT_H
#ifndef _WIN32

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <time.h>
#include <stdint.h>
#include <stdarg.h>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <string>

// ---- Windows integer/type aliases used across the core ----
typedef unsigned int   DWORD;
typedef void*          HANDLE;
typedef int64_t        LARGE_INTEGER;
#ifndef TRUE
#define TRUE  1
#define FALSE 0
#endif
#ifndef _I64_MAX
#define _I64_MAX  0x7fffffffffffffffLL
#define _I64_MIN  (-0x7fffffffffffffffLL - 1)
#endif
#ifndef _UI64_MAX
#define _UI64_MAX 0xffffffffffffffffULL
#endif

// High-resolution counter (used only for optional timing in the core).
inline void QueryPerformanceCounter(LARGE_INTEGER* p)
{
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    *p = (int64_t)ts.tv_sec * 1000000000LL + ts.tv_nsec;
}

// ---- socket layer (Winsock -> BSD sockets) ----
typedef int SOCKET;
#ifndef INVALID_SOCKET
#define INVALID_SOCKET (-1)
#endif
#ifndef SOCKET_ERROR
#define SOCKET_ERROR (-1)
#endif
#ifndef NO_ERROR
#define NO_ERROR 0
#endif
#define closesocket(s) ::close(s)
inline int WSAGetLastError() { return errno; }

// Winsock error codes mapped to POSIX errno values
#define WSAEWOULDBLOCK  EWOULDBLOCK
#define WSAEMSGSIZE     EMSGSIZE
#define WSAEINTR        EINTR
#define WSAEINPROGRESS  EINPROGRESS
#define WSAEADDRINUSE   EADDRINUSE
#define WSAEALREADY     EALREADY
#define WSAECONNREFUSED ECONNREFUSED
#define WSAENOTSOCK     EBADF

// Only FIONBIO (non-blocking toggle) is used; implement it robustly via fcntl.
inline int ioctlsocket(SOCKET s, long cmd, u_long* argp)
{
    if (cmd == (long)FIONBIO)
    {
        int flags = fcntl(s, F_GETFL, 0);
        if (flags < 0) return -1;
        if (*argp) flags |= O_NONBLOCK; else flags &= ~O_NONBLOCK;
        return fcntl(s, F_SETFL, flags);
    }
    return ioctl(s, cmd, argp);
}

// WSAStartup/WSACleanup are no-ops outside Windows.
typedef int WSADATA;
inline int WSAStartup(unsigned short, WSADATA*) { return 0; }
inline int WSACleanup() { return 0; }
#ifndef MAKEWORD
#define MAKEWORD(a, b) 0
#endif

// ---- Sleep(ms) ----
inline void Sleep(unsigned int ms)
{
    struct timespec ts;
    ts.tv_sec  = ms / 1000;
    ts.tv_nsec = (long)(ms % 1000) * 1000000L;
    nanosleep(&ts, NULL);
}

// ---- threads: _beginthread / _endthread over pthreads ----
struct _bf_thread_ctx { void (*fn)(void*); void* arg; };
inline void* _bf_thread_trampoline(void* p)
{
    _bf_thread_ctx* c = (_bf_thread_ctx*)p;
    void (*fn)(void*) = c->fn;
    void* arg = c->arg;
    delete c;
    fn(arg);
    return NULL;
}
inline uintptr_t _beginthread(void (*start)(void*), unsigned, void* arg)
{
    _bf_thread_ctx* c = new _bf_thread_ctx;
    c->fn = start; c->arg = arg;
    pthread_t th;
    if (pthread_create(&th, NULL, _bf_thread_trampoline, c) != 0)
    {
        delete c;
        return (uintptr_t)-1;
    }
    pthread_detach(th);
    return (uintptr_t)th;
}
inline void _endthread() { pthread_exit(NULL); }

// ---- CRITICAL_SECTION over a recursive mutex (util.h's CCriticalSection
//      compiles unchanged on top of these) ----
typedef pthread_mutex_t CRITICAL_SECTION;
inline void InitializeCriticalSection(CRITICAL_SECTION* cs)
{
    pthread_mutexattr_t a;
    pthread_mutexattr_init(&a);
    pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(cs, &a);
    pthread_mutexattr_destroy(&a);
}
inline void DeleteCriticalSection(CRITICAL_SECTION* cs) { pthread_mutex_destroy(cs); }
inline void EnterCriticalSection(CRITICAL_SECTION* cs)  { pthread_mutex_lock(cs); }
inline void LeaveCriticalSection(CRITICAL_SECTION* cs)  { pthread_mutex_unlock(cs); }
inline bool TryEnterCriticalSection(CRITICAL_SECTION* cs) { return pthread_mutex_trylock(cs) == 0; }

// ---- misc Windows CRT/debug helpers ----
inline void OutputDebugStringA(const char*) {}
inline void DebugBreak() {}
#ifndef _HEAPOK
#define _HEAPOK 0
#endif
inline int _heapchk() { return _HEAPOK; }
#define _vsnprintf vsnprintf
inline char* strlwr(char* s) { for (char* p = s; *p; ++p) *p = (char)tolower((unsigned char)*p); return s; }
#define _strlwr strlwr
inline int _mkdir(const char* p) { return ::mkdir(p, 0755); }

// Thread priority is a Windows nicety; on Linux the message-handler thread just
// runs at normal priority (harmless no-op).
inline void* GetCurrentThread() { return (void*)0; }
inline void SetThreadPriority(void*, int) {}
#ifndef THREAD_PRIORITY_BELOW_NORMAL
#define THREAD_PRIORITY_BELOW_NORMAL 0
#define THREAD_PRIORITY_LOWEST 0
#define THREAD_PRIORITY_NORMAL 0
#endif

// wx is always available (wx/wx.h included via headers.h); no shims needed.

#endif // !_WIN32
#endif // BITFLASH_COMPAT_H