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 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
|
/* $Header: /home/jcb/MahJong/newmj/RCS/sysdep.h,v 12.3 2025/09/06 12:12:39 jcb Exp $
* sysdep.h
* Miscellaneous system stuff that may require attention
* by configuration procedures.
*/
/****************** COPYRIGHT STATEMENT **********************
* This file is Copyright (c) 2000 by J. C. Bradfield. *
* Distribution and use is governed by the LICENCE file that *
* accompanies this file. *
* The moral rights of the author are asserted. *
* *
***************** DISCLAIMER OF WARRANTY ********************
* This code is not warranted fit for any purpose. See the *
* LICENCE file for further information. *
* *
*************************************************************/
/* network conversion utilities */
#ifndef SYSDEP_H_INCLUDED
#define SYSDEP_H_INCLUDED
#include <unistd.h>
/* The following define prevents HP-UX from using the antiquated
version of select() with ints instead of fd_sets */
#define _XOPEN_SOURCE_EXTENDED 1
#include <time.h>
#ifdef WIN32
// these may be missing
#ifndef SHUT_RDWR
#define SHUT_RD 0x00
#define SHUT_WR 0x01
#define SHUT_RDWR 0x02
#endif
#include <winsock.h>
typedef int socklen_t;
/* following functions don't exist in Windows, so we need to emulate them */
/* Windows doesn't define the struct timezone, so just use void * */
int gettimeofday(struct timeval *tv, void *tz);
char *getlogin(void);
unsigned int sleep(unsigned int t);
// provided on modern mingw
#ifndef XCOMPILE
unsigned int usleep(unsigned int t);
#endif
int getpid(void);
int unlink(const char *f);
#else
#include <netinet/in.h>
/* need this for gettimeofday */
#include <sys/time.h>
#endif /* WIN32 */
#include <stdlib.h>
#include <stdio.h>
/* In the mingw I use, these functions are missing from the headers */
#ifdef WIN32
#ifndef XCOMPILE
int _snprintf(char *str, size_t n, const char *format, ...);
int _vsnprintf(char *buffer,size_t count,const char *format,va_list argptr);
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#endif
#endif
/* for memset and friends */
#include <string.h>
/* This is missing in my windows mingw */
#ifdef WIN32
char * index(const char *s, int c);
#endif
#include <assert.h>
#include <ctype.h>
/* define SOCKET types so we can also work with windows */
#ifndef WIN32
typedef intptr_t SOCKET;
#define INVALID_SOCKET -1
#define closesocket close
#endif
/* If we're using GNU CC, we can suppress warnings for unused variables
with this.
*/
#if defined( __GNUC__) && !defined(__GNUG__)
# define UNUSED __attribute ((unused))
#else
# define UNUSED
#endif
/* functions in sysdep.c */
/* warn is fprintf(stderr,...) .
*/
typedef enum { LogInfo = 1, LogWarning = 2, LogError = 3 } LogLevel;
/* If the global variable log_msg_add_note_hook is non-null,
it is called with the level, and returns a (char *) which
will be appended to the log message. The returned value should
be static, or at least long-lived enough.
*/
extern char *(*log_msg_add_note_hook)(LogLevel l);
/* If the global variable log_msg_hook is non-null, it should
be a pointer to a function which will be passed the formatted
warning. If the hook returns non-zero, the warning will not
be printed to stderr.
*/
extern int (*log_msg_hook)(LogLevel l,char *);
/* log_msg is a generalized version with a syslog like warning
level. */
int log_msg(LogLevel l, char *format,...);
/* and here are abbreviations for the levels */
int info(char *format,...);
int warn(char *format,...);
/* The error function is called log_error, because on error we
almost certainly want to add CPP information, which we pass in via
a macro */
int log_error(const char *function, const char *file, const int line, const char *format,...);
/* like this: */
#define error(format, args...) log_error(__FUNCTION__,__FILE__,__LINE__,format,## args)
/* ignore the SIGPIPE signal. Return 0 on success
, -1 on error */
int ignore_sigpipe(void);
/* Initialize the socket library functions. This is only needed
under Windows. It need not be called explicitly, as the library
functions will call it (with null arguments) if necessary.
The arguments, if non-NULL, are used by programs that need to do strange
things to the sockets, such as gtk applications under windows.
open_transform is a function which is applied to all sockets created,
and had better return something that fits in
a (void *); all functions that return or store SOCKET, will instead
return or store the result of open_transform, cast to a SOCKET.
(So SOCKET had better fit a void*; this is true on all systems
I know of.)
closer is a function to close the resulting object;
reader is a function to read from it; it should have the same
type as the system read function, mutatis mutandis;
writer is a function to write. */
int initialize_sockets(void *(*open_transform)(SOCKET),
int (*closer)(void *),
int (*reader)(void *, void *, size_t),
int (*writer)(void *, const void *,size_t));
/* In the following function, a socket address is a string.
If it contains a colon, then it is assumed to be a TCP
address host:port (if host is omitted, it is localhost).
Otherwise, it is assumed to be a Unix filename, and
Unix domain sockets are used.
*/
/* set_up_listening_socket:
Set up a socket, listening on the given address.
Return its system level SOCKET.
*/
SOCKET set_up_listening_socket(const char *address);
/* accept_new_connection:
A connection has arrived on the socket fd.
Accept the connection, and return the new fd,
or INVALID_SOCKET on error.
*/
SOCKET accept_new_connection(SOCKET fd);
/* connect_to_host:
Establish a connection to the given address.
Return the file descriptor or INVALID_SOCKET on error.
The file descriptor is marked close-on-exec.
*/
SOCKET connect_to_host(const char *address);
/* same as above, but ignores the socket transformers */
SOCKET plain_connect_to_host(const char *address);
/* close a network connection with or without transforms */
int close_socket(SOCKET s);
int plain_close_socket(SOCKET s);
/* read a line, up to lf/crlf terminator, from the socket,
and return it.
If there is an error or end of file before seeing a terminator,
NULL is returned. At present, error includes reading a partial line.
The returned string is valid until the next call of get_line.
As a special hack, if fd is STDOUT_FILENO, then read from
STDIN_FILENO as an fd.
*/
char *get_line(SOCKET fd);
/* write a line (which should include any terminator) to a socket.
Return -1 on error, length of line on success.
If fd is equal to STDOUT_FILENO, then print to it as an fd.
*/
int put_line(SOCKET fd,char *line);
/* These are the same, but they take a file descriptor
rather than a socket. (I hate Windows) */
char *fd_get_line(int fd);
int fd_put_line(int fd, char *line);
/* stuff arbitrary data down a socket. If len is zero, send EOF */
int put_data(SOCKET fd, char *data, int len);
/* and read it - data must be preallocated */
int get_data(SOCKET fd, char *data, int len);
/* rand_index: return a random integer from 0 to arg (inclusive).
*/
unsigned int rand_index(int top);
/* rand_seed: if the random number generation has a seed value,
use this argument, if non-zero; if zero, seed with a system
dependent variable value (actually time(), but needn't be).
If this function is not called explicitly, it will be called
with arg 0 on first use of rand_index.
*/
void rand_seed(int seed);
/* utility function: this is just like strncpy, except that it
guarantees that the target is null-terminated.
The m parameter is the length of the target field INCLUDING
the terminating null.
*/
/* Since we're overwriting the last char, no need to copy it.
Doing this apparently squashes some warnings.
*/
#define strmcpy(dest,src,m) { strncpy(dest,src,m-1) ; dest[m-1] = '\000' ; }
/* similarly */
#define strmcat(dest,src,m) { strncat(dest,src,m-1) ; dest[m-1] = '\000' ; }
/* This is like strmcat, but it also quotes the string (in a system
dependent way) for adding it to a shell command line.
*/
char *qstrmcat(char *dest, const char *src, int len);
/* another utility function: return arg, or "NULL" if it's null */
char *nullprotect(char *s);
/* feed a command to the system to be started in background.
No fancy argument processing, just pass to shell or equiv
Return 1 on success, 0 on failure */
int start_background_program(const char *cmd);
/* unfortunately we need a slightly more sophisticated one where
we can get at the output. This passes out a write handle for the
new process's stdin, and a read handle for its stdout */
/* Under Windows, this is fiddled to return "file descriptors" */
int start_background_program_with_io(const char *cmd,int *childin,
int *childout);
/* return a path for the home directory, or equivalent concept.
Returns NULL if no sensible homedir is available
(i.e. HOME is unset on Unix, or HOMEPATH is unset on Windows) */
char *get_homedir(void);
#endif /* SYSDEP_H_INCLUDED */
|