0ad/source/lib/sysdep/win/wposix.h

604 lines
14 KiB
C
Executable File

// misc. POSIX routines for Win32
//
// Copyright (c) 2003 Jan Wassenberg
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// Contact info:
// Jan.Wassenberg@stud.uni-karlsruhe.de
// http://www.stud.uni-karlsruhe.de/~urkt/
// note: try to avoid redefining CRT functions - if building against the
// DLL CRT, the declarations will be incompatible. adding _CRTIMP to the decl
// is a last resort (e.g. if the regular CRT headers would conflict).
#ifndef __WPOSIX_H__
#define __WPOSIX_H__
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#define IMP(ret, name, param) extern "C" __declspec(dllimport) ret __stdcall name param;
//
// <inttypes.h>
//
typedef unsigned short u16_t;
//
// <sys/types.h>
//
typedef unsigned long useconds_t;
typedef long suseconds_t;
typedef long ssize_t;
//
// <limits.h>
//
#define PATH_MAX 260
//
// <errno.h>
//
#define EINPROGRESS 100000
#include <errno.h>
/*
enum
{
EINPROGRESS = 1000, // Operation in progress.
ENOMEM // Not enough space.
EACCES, // Permission denied.
EADDRINUSE, // Address in use.
EADDRNOTAVAIL, // Address not available.
EAGAIN, // Resource unavailable, try again (may be the same value as EWOULDBLOCK]).
EALREADY, // Connection already in progress.
EBADF, // Bad file descriptor.
ECANCELED, // Operation canceled.
ECONNABORTED, // Connection aborted.
ECONNREFUSED, // Connection refused.
ECONNRESET, // Connection reset.
EDOM, // Mathematics argument out of domain of function.
EEXIST, // File exists.
EFAULT, // Bad address.
EHOSTUNREACH, // Host is unreachable.
EINTR, // Interrupted function.
EINVAL, // Invalid argument.
EISCONN, // Socket is connected.
EISDIR, // Is a directory.
ENAMETOOLONG, // Filename too long.
ENETDOWN, // Network is down.
ENETRESET, // Connection aborted by network.
ENETUNREACH, // Network unreachable.
ENOENT, // No such file or directory.
ENOEXEC, // Executable file format error.
ENOSPC, // No space left on device.
ENOSYS, // Function not supported.
ENOTCONN, // The socket is not connected.
ENOTDIR, // Not a directory.
ENOTEMPTY, // Directory not empty.
ENOTSOCK, // Not a socket.
ENOTSUP, // Not supported.
EOVERFLOW, // Value too large to be stored in data type.
EPERM, // Operation not permitted.
EPIPE, // Broken pipe.
EPROTO, // Protocol error.
ERANGE, // Result too large.
ETIMEDOUT, // Connection timed out.
EWOULDBLOCK // Operation would block (may be the same value as EAGAIN]).
};
*/
//
// sys/stat.h
//
typedef unsigned int mode_t;
// VC libc includes stat, but it's quite slow.
// we implement our own, but use the CRT struct definition.
#include <sys/stat.h>
extern int mkdir(const char*, mode_t);
// currently only sets st_mode (file or dir) and st_size.
extern int stat(const char*, struct stat*);
//
// dirent.h
//
typedef void DIR;
struct dirent
{
ino_t d_ino;
char* d_name;
};
extern DIR* opendir(const char* name);
extern struct dirent* readdir(DIR*);
extern int closedir(DIR*);
//
// <sys/mman.h>
//
#define PROT_READ 0x01 // page can be read
#define PROT_WRITE 0x02 // page can be written
#define MAP_SHARED 0x01 // share changes across processes
#define MAP_PRIVATE 0x02 // private copy on write mapping
#define MAP_FIXED 0x04
#define MAP_FAILED 0
extern void* mmap(void* start, unsigned int len, int prot, int flags, int fd, long offset);
extern int munmap(void* start, unsigned int len);
//
// <fcntl.h>
//
// values from MS _open - do not change!
#define O_RDONLY 0x0000 // open for reading only
#define O_WRONLY 0x0001 // open for writing only
#define O_RDWR 0x0002 // open for reading and writing
#define O_APPEND 0x0008 // writes done at eof
#define O_CREAT 0x0100 // create and open file
#define O_TRUNC 0x0200 // open and truncate
#define O_EXCL 0x0400 // open only if file doesn't already exist
#define O_BINARY 0x8000 // file mode is binary (untranslated)
#define O_NONBLOCK 0x1000000
extern int open(const char* fn, int mode, ...);
//
// <unistd.h>
//
#define F_OK 0
#define R_OK 1
#define W_OK 2
#define X_OK 4
#define read _read
#define write _write
extern int close(int);
extern int access(const char*, int);
extern int chdir(const char*);
extern unsigned int sleep(unsigned int sec);
extern int usleep(useconds_t us);
// user tests if available via #ifdef; can't use enum.
#define _SC_PAGESIZE 1
#define _SC_PAGE_SIZE 1
#define _SC_PHYS_PAGES 2
#define _SC_AVPHYS_PAGES 3
extern long sysconf(int name);
#ifndef _WINSOCKAPI_
IMP(int, gethostname, (char* name, size_t namelen))
#endif
//
// <stdlib.h>
//
extern char* realpath(const char*, char*);
//
// <signal.h>
//
union sigval
{
int sival_int; // Integer signal value.
void* sival_ptr; // Pointer signal value.
};
struct sigevent
{
int sigev_notify; // notification mode
int sigev_signo; // signal number
union sigval sigev_value; // signal value
void(*sigev_notify_function)(union sigval);
};
//
// <termios.h>
//
#define TCSANOW 0
struct termios
{
long c_lflag;
};
#define ICANON 2 // do not change - correspond to ENABLE_LINE_INPUT / ENABLE_ECHO_INPUT
#define ECHO 4
extern int tcgetattr(int fd, struct termios* termios_p);
extern int tcsetattr(int fd, int optional_actions, const struct termios* termios_p);
//
// <sched.h>
//
struct sched_param
{
int sched_priority;
};
enum
{
SCHED_RR,
SCHED_FIFO,
SCHED_OTHER
};
#define sched_get_priority_max(policy) 15 // TIME_CRITICAL
#define sched_get_priority_min(policy) -15 // IDLE
//
// <pthread.h>
//
typedef unsigned int pthread_t;
extern pthread_t pthread_self();
extern int pthread_getschedparam(pthread_t thread, int* policy, struct sched_param* param);
extern int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param* param);
extern int pthread_create(pthread_t* thread, const void* attr, void*(*func)(void*), void* arg);
typedef void* pthread_mutex_t;
typedef void pthread_mutexattr_t;
extern pthread_mutex_t pthread_mutex_initializer();
#define PTHREAD_MUTEX_INITIALIZER pthread_mutex_initializer()
extern int pthread_mutex_init(pthread_mutex_t*, const pthread_mutexattr_t*);
extern int pthread_mutex_destroy(pthread_mutex_t*);
extern int pthread_mutex_lock(pthread_mutex_t*);
extern int pthread_mutex_trylock(pthread_mutex_t*);
extern int pthread_mutex_unlock(pthread_mutex_t*);
extern int pthread_mutex_timedlock(pthread_mutex_t*, const struct timespec*);
//
// <time.h>
//
typedef enum
{
CLOCK_REALTIME
}
clockid_t;
// BSD gettimeofday
struct timeval
{
time_t tv_sec;
suseconds_t tv_usec;
};
// POSIX realtime clock_*
struct timespec
{
time_t tv_sec;
long tv_nsec;
};
extern int gettimeofday(struct timeval* tv, void* tzp);
extern int nanosleep(const struct timespec* rqtp, struct timespec* rmtp);
extern int clock_gettime(clockid_t clock, struct timespec* ts);
extern int clock_getres(clockid_t clock, struct timespec* res);
//
// <sys/socket.h>
//
typedef unsigned long socklen_t;
typedef unsigned short sa_family_t;
// Win32 values - do not change
#ifndef _WINSOCKAPI_
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define AF_INET 2
#define PF_INET AF_INET
#define AF_INET6 23
#define PF_INET6 AF_INET6
#define SOL_SOCKET 0xffff /* options for socket level */
#define TCP_NODELAY 0x0001
/* This is the slightly unreadable encoded form of the windows ioctl that sets
non-blocking mode for a socket */
#define FIONBIO 0x8004667E
enum {
SHUT_RD=0,
SHUT_WR=1,
SHUT_RDWR=2
};
struct sockaddr;
IMP(int, socket, (int, int, int))
IMP(int, setsockopt, (int, int, int, const void*, socklen_t))
IMP(int, getsockopt, (int, int, int, void*, socklen_t*))
IMP(int, ioctlsocket, (int, int, const void *))
IMP(int, shutdown, (int, int))
IMP(int, closesocket, (int))
//
// <netinet/in.h>
//
typedef unsigned long in_addr_t;
typedef unsigned short in_port_t;
struct in_addr
{
in_addr_t s_addr;
};
struct sockaddr_in
{
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
#define INET_ADDRSTRLEN 16
#define INADDR_ANY 0
#define INADDR_NONE ((in_addr_t)-1)
#define IPPROTO_IP 0
#define IP_ADD_MEMBERSHIP 5
#define IP_DROP_MEMBERSHIP 6
struct ip_mreq
{
struct in_addr imr_multiaddr; /* multicast group to join */
struct in_addr imr_interface; /* interface to join on */
};
// ==== IPv6 ====
extern const struct in6_addr in6addr_any; /* :: */
extern const struct in6_addr in6addr_loopback; /* ::1 */
#define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }
#define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } }
// struct of array => 2 braces.
struct in6_addr
{
unsigned char s6_addr[16];
};
struct sockaddr_in6 {
sa_family_t sin6_family; /* AF_INET6 */
in_port_t sin6_port; /* Transport level port number */
unsigned long sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 address */
unsigned long sin6_scope_id; /* set of interfaces for a scope */
};
//
// <netdb.h>
//
struct hostent
{
char* h_name; // Official name of the host.
char** h_aliases; // A pointer to an array of pointers to
// alternative host names, terminated by a
// null pointer.
short h_addrtype; // Address type.
short h_length; // The length, in bytes, of the address.
char** h_addr_list; // A pointer to an array of pointers to network
// addresses (in network byte order) for the host,
// terminated by a null pointer.
};
IMP(struct hostent*, gethostbyname, (const char *name))
#define h_error WSAGetLastError()
#define HOST_NOT_FOUND 11001
#define TRY_AGAIN 11002
// addrinfo struct */
struct addrinfo
{
int ai_flags; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST
int ai_family; // PF_xxx
int ai_socktype; // SOCK_xxx
int ai_protocol; // 0 or IPPROTO_xxx for IPv4 and IPv6
size_t ai_addrlen; // Length of ai_addr
char *ai_canonname; // Canonical name for nodename
struct sockaddr *ai_addr; // Binary address
struct addrinfo *ai_next; // Next structure in linked list
};
// Hint flags for getaddrinfo
#define AI_PASSIVE 0x1 // Socket address will be used in bind() call
// Flags for getnameinfo()
#define NI_NUMERICHOST 0x02 // Return numeric form of the host's address
#define NI_MAXHOST 1025
#define NI_MAXSERV 32
/* Note that these are function pointers. They will be initialized by the
entry point function in posix.cpp */
typedef int (*fp_getnameinfo_t)(const struct sockaddr *sa, socklen_t salen, char *node,
socklen_t nodelen, char *serv, socklen_t servlen, unsigned int flags);
typedef int (*fp_getaddrinfo_t)(const char *nodename, const char *servname,
const struct addrinfo *hints, struct addrinfo **res);
typedef void (*fp_freeaddrinfo_t)(struct addrinfo *ai);
extern fp_getnameinfo_t p_getnameinfo;
extern fp_getaddrinfo_t p_getaddrinfo;
extern fp_freeaddrinfo_t p_freeaddrinfo;
#define getnameinfo p_getnameinfo
#define getaddrinfo p_getaddrinfo
#define freeaddrinfo p_freeaddrinfo
// getaddr/nameinfo error codes
#define EAI_NONAME HOST_NOT_FOUND
//
// <arpa/inet.h>
//
extern u16_t htons(u16_t hostshort);
#define ntohs htons
IMP(unsigned long, htonl, (unsigned long hostlong))
IMP(in_addr_t, inet_addr, (const char*))
IMP(char*, inet_ntoa, (in_addr))
IMP(int, accept, (int, struct sockaddr*, socklen_t*))
IMP(int, bind, (int, const struct sockaddr*, socklen_t))
IMP(int, connect, (int, const struct sockaddr*, socklen_t))
IMP(int, listen, (int, int))
IMP(ssize_t, recv, (int, void*, size_t, int))
IMP(ssize_t, send, (int, const void*, size_t, int))
IMP(ssize_t, sendto, (int, const void*, size_t, int, const struct sockaddr*, socklen_t))
IMP(ssize_t, recvfrom, (int, void*, size_t, int, struct sockaddr*, socklen_t*))
#endif /* _WINSOCKAPI_ */
//
// <poll.h>
//
struct pollfd
{
int fd;
short int events, revents;
};
#define POLLIN 1
extern int poll(struct pollfd[], int, int);
//
// <sys/utsname.h>
//
struct utsname
{
char sysname[9]; // Name of this implementation of the operating system.
char nodename[16]; // Name of this node within an implementation-defined
// communications network.
// Win9x requires this minimum buffer size.
char release[9]; // Current release level of this implementation.
char version[16]; // Current version level of this release.
char machine[9]; // Name of the hardware type on which the system is running.
};
extern int uname(struct utsname*);
//
// serial port IOCTL
//
// use with TIOCMBIS
#define TIOCM_RTS 1
// use with TIOCMGET or TIOCMIWAIT
#define TIOCM_CD 0x80 // MS_RLSD_ON
#define TIOCM_CTS 0x10 // MS_CTS_ON
enum
{
TIOCMBIS, // set control line
TIOCMGET, // get line state
TIOCMIWAIT // wait for status change
};
extern int ioctl(int fd, int op, int* data);
#ifndef _WINSOCKAPI_
#define FIONREAD 0
#endif
extern void _get_console();
extern void _hide_console();
// split out of this module
#include "waio.h"
#ifdef __cplusplus
}
#endif
#endif // #ifndef __WPOSIX_H__