Simple POSIX I/O emulation layer to work around Windows's defective
Unix I/O: [_WIN32] (socklen_t, accept, posix_accept, bind. posix_bind, listen) (posix_listen, setsockopt, posix_setsockopt, shutdown, posix_shutdown) (socket, posix_socket, close, posix_close, creat, fstat, posix_fstat) (lseek, posix_lseek, open, posix_open, read, posix_read, write) (posix_write, fileno, posix_fileno, fcntl, O_NONBLOCK, F_RDLCK) (F_WRLCK, F_GETFL, F_SETFL, F_SETLK, EWOULDBLOCK, ENOTSOCK) (flock, fsync, posix_fsync): New. (ef_open, io_close, io_input, io_output, io_shutdown, io_noblocking) (player_accept): Use them to simplify. [_WIN32] (posix_fd2socket): New. (empth_select): Use it. (gen_power): Use it.
This commit is contained in:
parent
e7b04123a9
commit
4bbc3f4286
17 changed files with 669 additions and 109 deletions
|
@ -34,11 +34,7 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#if defined(_WIN32)
|
|
||||||
#include <io.h>
|
|
||||||
#else
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
|
|
|
@ -34,13 +34,8 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#if defined(_WIN32)
|
|
||||||
#include <io.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#if !defined(_WIN32)
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "land.h"
|
#include "land.h"
|
||||||
#include "optlist.h"
|
#include "optlist.h"
|
||||||
|
|
|
@ -35,11 +35,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#ifdef _WIN32
|
|
||||||
#include <io.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
|
@ -317,14 +314,13 @@ gen_power(struct powstr *powbuf, int save)
|
||||||
return;
|
return;
|
||||||
for (i = 0; i < MAXNOC; i++)
|
for (i = 0; i < MAXNOC; i++)
|
||||||
putpower(i, &powbuf[i]);
|
putpower(i, &powbuf[i]);
|
||||||
#ifdef _WIN32
|
|
||||||
/*
|
/*
|
||||||
* At least some versions of Windows fail to update mtime on
|
* At least some versions of Windows fail to update st_mtime on
|
||||||
* write(). Bad, because `power' displays that time. Attempt to
|
* write(), the st_mtime is not until the file is written to the
|
||||||
* force an update.
|
* disk. Bad, because `power' displays that time.
|
||||||
|
* Force a sync to ensure the st_time is correct.
|
||||||
*/
|
*/
|
||||||
_commit(empfile[EF_POWER].fd);
|
fsync(empfile[EF_POWER].fd);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -34,11 +34,7 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#if !defined(_WIN32)
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#elif defined(__GNUC__)
|
|
||||||
#include <io.h>
|
|
||||||
#endif
|
|
||||||
#include "tel.h"
|
#include "tel.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "optlist.h"
|
#include "optlist.h"
|
||||||
|
|
|
@ -36,17 +36,11 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#if defined(_WIN32)
|
|
||||||
#include <io.h>
|
|
||||||
#include <share.h>
|
|
||||||
#endif
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#if !defined(_WIN32)
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "match.h"
|
#include "match.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
@ -68,9 +62,7 @@ int
|
||||||
ef_open(int type, int how)
|
ef_open(int type, int how)
|
||||||
{
|
{
|
||||||
struct empfile *ep;
|
struct empfile *ep;
|
||||||
#if !defined(_WIN32)
|
|
||||||
struct flock lock;
|
struct flock lock;
|
||||||
#endif
|
|
||||||
int oflags, fd, fsiz, size;
|
int oflags, fd, fsiz, size;
|
||||||
|
|
||||||
if (ef_check(type) < 0)
|
if (ef_check(type) < 0)
|
||||||
|
@ -89,13 +81,7 @@ ef_open(int type, int how)
|
||||||
oflags |= O_CREAT | O_TRUNC;
|
oflags |= O_CREAT | O_TRUNC;
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
oflags |= O_BINARY;
|
oflags |= O_BINARY;
|
||||||
if ((fd = sopen(ep->file, oflags,
|
#endif
|
||||||
how & EFF_RDONLY ? SH_DENYNO : SH_DENYWR,
|
|
||||||
S_IRWUG)) < 0) {
|
|
||||||
logerror("Can't open %s (%s)", ep->file, strerror(errno));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if ((fd = open(ep->file, oflags, S_IRWUG)) < 0) {
|
if ((fd = open(ep->file, oflags, S_IRWUG)) < 0) {
|
||||||
logerror("Can't open %s (%s)", ep->file, strerror(errno));
|
logerror("Can't open %s (%s)", ep->file, strerror(errno));
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -109,7 +95,6 @@ ef_open(int type, int how)
|
||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* get file size */
|
/* get file size */
|
||||||
fsiz = fsize(fd);
|
fsiz = fsize(fd);
|
||||||
|
|
|
@ -37,9 +37,7 @@
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#if !defined(_WIN32)
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
|
|
||||||
|
|
|
@ -33,12 +33,7 @@
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#include <io.h>
|
|
||||||
#endif
|
|
||||||
#if !defined(_WIN32)
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
|
@ -35,13 +35,8 @@
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#if defined(_WIN32)
|
|
||||||
#include <io.h>
|
|
||||||
#endif
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#if !defined(_WIN32)
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
|
@ -55,6 +55,10 @@
|
||||||
#undef NS_ALL
|
#undef NS_ALL
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
/* Note: unistd.h(posixio.c) is not thread-safe.
|
||||||
|
* It may be used *only* while holding hThreadMutex.
|
||||||
|
*/
|
||||||
|
#include "unistd.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "empthread.h"
|
#include "empthread.h"
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
|
@ -313,6 +317,9 @@ loc_Exit_Handler(DWORD fdwCtrlType)
|
||||||
*
|
*
|
||||||
* This is the main line of each thread.
|
* This is the main line of each thread.
|
||||||
* This is really a static local func....
|
* This is really a static local func....
|
||||||
|
* Note: As the POSIX compatibility layer is not thread safe
|
||||||
|
* this function can not open or create any files or sockets until
|
||||||
|
* loc_RunThisThread() is called
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
empth_threadMain(void *pvData)
|
empth_threadMain(void *pvData)
|
||||||
|
@ -535,6 +542,7 @@ empth_terminate(empth_t *pThread)
|
||||||
void
|
void
|
||||||
empth_select(int fd, int flags)
|
empth_select(int fd, int flags)
|
||||||
{
|
{
|
||||||
|
int handle;
|
||||||
WSAEVENT hEventObject[2];
|
WSAEVENT hEventObject[2];
|
||||||
empth_t *pThread = TlsGetValue(dwTLSIndex);
|
empth_t *pThread = TlsGetValue(dwTLSIndex);
|
||||||
|
|
||||||
|
@ -545,10 +553,13 @@ empth_select(int fd, int flags)
|
||||||
hEventObject[0] = WSACreateEvent();
|
hEventObject[0] = WSACreateEvent();
|
||||||
hEventObject[1] = pThread->hThreadEvent;
|
hEventObject[1] = pThread->hThreadEvent;
|
||||||
|
|
||||||
|
handle = posix_fd2socket(fd);
|
||||||
|
CANT_HAPPEN(handle < 0);
|
||||||
|
|
||||||
if (flags == EMPTH_FD_READ)
|
if (flags == EMPTH_FD_READ)
|
||||||
WSAEventSelect(fd, hEventObject[0], FD_READ | FD_ACCEPT | FD_CLOSE);
|
WSAEventSelect(handle, hEventObject[0], FD_READ | FD_ACCEPT | FD_CLOSE);
|
||||||
else if (flags == EMPTH_FD_WRITE)
|
else if (flags == EMPTH_FD_WRITE)
|
||||||
WSAEventSelect(fd, hEventObject[0], FD_WRITE | FD_CLOSE);
|
WSAEventSelect(handle, hEventObject[0], FD_WRITE | FD_CLOSE);
|
||||||
else {
|
else {
|
||||||
logerror("bad flag %d passed to empth_select", flags);
|
logerror("bad flag %d passed to empth_select", flags);
|
||||||
empth_exit();
|
empth_exit();
|
||||||
|
@ -556,7 +567,7 @@ empth_select(int fd, int flags)
|
||||||
|
|
||||||
WSAWaitForMultipleEvents(2, hEventObject, FALSE, WSA_INFINITE, FALSE);
|
WSAWaitForMultipleEvents(2, hEventObject, FALSE, WSA_INFINITE, FALSE);
|
||||||
|
|
||||||
WSAEventSelect(fd, hEventObject[0], 0);
|
WSAEventSelect(handle, hEventObject[0], 0);
|
||||||
|
|
||||||
WSACloseEvent(hEventObject[0]);
|
WSACloseEvent(hEventObject[0]);
|
||||||
|
|
||||||
|
|
|
@ -48,11 +48,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef _WIN32
|
|
||||||
#include <direct.h>
|
|
||||||
#else
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
|
@ -47,13 +47,12 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#undef NS_ALL
|
|
||||||
#else
|
#else
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "empio.h"
|
#include "empio.h"
|
||||||
|
@ -111,11 +110,7 @@ io_close(struct iop *iop)
|
||||||
ioq_destroy(iop->input);
|
ioq_destroy(iop->input);
|
||||||
if (iop->output != 0)
|
if (iop->output != 0)
|
||||||
ioq_destroy(iop->output);
|
ioq_destroy(iop->output);
|
||||||
#if !defined(_WIN32)
|
|
||||||
(void)close(iop->fd);
|
(void)close(iop->fd);
|
||||||
#else
|
|
||||||
closesocket(iop->fd);
|
|
||||||
#endif
|
|
||||||
free(iop);
|
free(iop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +130,6 @@ io_input(struct iop *iop, int waitforinput)
|
||||||
if (waitforinput) {
|
if (waitforinput) {
|
||||||
empth_select(iop->fd, EMPTH_FD_READ);
|
empth_select(iop->fd, EMPTH_FD_READ);
|
||||||
}
|
}
|
||||||
#if !defined(_WIN32)
|
|
||||||
/* Do the actual read. */
|
/* Do the actual read. */
|
||||||
cc = read(iop->fd, buf, sizeof(buf));
|
cc = read(iop->fd, buf, sizeof(buf));
|
||||||
if (cc < 0) {
|
if (cc < 0) {
|
||||||
|
@ -147,19 +141,6 @@ io_input(struct iop *iop, int waitforinput)
|
||||||
iop->flags |= IO_ERROR;
|
iop->flags |= IO_ERROR;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
cc = recv(iop->fd, buf, sizeof(buf), 0);
|
|
||||||
if (cc == SOCKET_ERROR) {
|
|
||||||
int err = WSAGetLastError();
|
|
||||||
/* Hmm, it would block. file is opened noblock, soooooo.. */
|
|
||||||
if (err == WSAEWOULDBLOCK)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Some form of file error occurred... */
|
|
||||||
iop->flags |= IO_ERROR;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* We eof'd */
|
/* We eof'd */
|
||||||
if (cc == 0) {
|
if (cc == 0) {
|
||||||
|
@ -232,6 +213,9 @@ io_output(struct iop *iop, int waitforoutput)
|
||||||
/* Do the actual write. */
|
/* Do the actual write. */
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
cc = writev(iop->fd, iov, n);
|
cc = writev(iop->fd, iov, n);
|
||||||
|
#else
|
||||||
|
cc = write(iop->fd, buf, n);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* if it failed.... */
|
/* if it failed.... */
|
||||||
if (cc < 0) {
|
if (cc < 0) {
|
||||||
|
@ -244,22 +228,6 @@ io_output(struct iop *iop, int waitforoutput)
|
||||||
iop->flags |= IO_ERROR;
|
iop->flags |= IO_ERROR;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
cc = send(iop->fd, buf, n, 0);
|
|
||||||
|
|
||||||
/* if it failed.... */
|
|
||||||
if (cc == SOCKET_ERROR) {
|
|
||||||
int err = WSAGetLastError();
|
|
||||||
/* Hmm, it would block. file is opened noblock, soooooo.. */
|
|
||||||
if (err == WSAEWOULDBLOCK) {
|
|
||||||
/* If there are remaining bytes, set the IO as remaining.. */
|
|
||||||
remain = ioq_qsize(iop->output);
|
|
||||||
return remain;
|
|
||||||
}
|
|
||||||
iop->flags |= IO_ERROR;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If no bytes were written, something happened.. Like an EOF. */
|
/* If no bytes were written, something happened.. Like an EOF. */
|
||||||
if (cc == 0) {
|
if (cc == 0) {
|
||||||
|
@ -366,7 +334,6 @@ io_shutdown(struct iop *iop, int flags)
|
||||||
int
|
int
|
||||||
io_noblocking(struct iop *iop, int value)
|
io_noblocking(struct iop *iop, int value)
|
||||||
{
|
{
|
||||||
#if !defined(_WIN32)
|
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
flags = fcntl(iop->fd, F_GETFL, 0);
|
flags = fcntl(iop->fd, F_GETFL, 0);
|
||||||
|
@ -378,10 +345,6 @@ io_noblocking(struct iop *iop, int value)
|
||||||
flags |= O_NONBLOCK;
|
flags |= O_NONBLOCK;
|
||||||
if (fcntl(iop->fd, F_SETFL, flags) < 0)
|
if (fcntl(iop->fd, F_SETFL, flags) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
#else
|
|
||||||
u_long arg = value;
|
|
||||||
ioctlsocket(iop->fd, FIONBIO, &arg);
|
|
||||||
#endif
|
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
iop->flags &= ~IO_NBLOCK;
|
iop->flags &= ~IO_NBLOCK;
|
||||||
else
|
else
|
||||||
|
|
|
@ -47,8 +47,8 @@
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -170,7 +170,7 @@ player_accept(void *unused)
|
||||||
void *inaddr;
|
void *inaddr;
|
||||||
int s = player_socket;
|
int s = player_socket;
|
||||||
struct player *np;
|
struct player *np;
|
||||||
int len;
|
socklen_t len;
|
||||||
int ns;
|
int ns;
|
||||||
int set = 1;
|
int set = 1;
|
||||||
int stacksize;
|
int stacksize;
|
||||||
|
|
|
@ -38,9 +38,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#if !defined(_WIN32)
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include "com.h"
|
#include "com.h"
|
||||||
|
|
|
@ -32,9 +32,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#if !defined(_WIN32)
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
|
@ -33,14 +33,11 @@
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#include <io.h>
|
|
||||||
#endif
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#if !defined(_WIN32)
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#if !defined(_WIN32)
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#endif
|
#endif
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
|
565
src/lib/w32/posixio.c
Normal file
565
src/lib/w32/posixio.c
Normal file
|
@ -0,0 +1,565 @@
|
||||||
|
/*
|
||||||
|
* Empire - A multi-player, client/server Internet based war game.
|
||||||
|
* Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
|
||||||
|
* Ken Stevens, Steve McClure
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* ---
|
||||||
|
*
|
||||||
|
* See files README, COPYING and CREDITS in the root of the source
|
||||||
|
* tree for related information and legal notices. It is expected
|
||||||
|
* that future projects/authors will amend these files as needed.
|
||||||
|
*
|
||||||
|
* ---
|
||||||
|
*
|
||||||
|
* posixio.c: POSIX IO emulation layer for WIN32
|
||||||
|
*
|
||||||
|
* Known contributors to this file:
|
||||||
|
* Ron Koenderink, 2007
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX has just one kind of file descriptors, while Windows has (at
|
||||||
|
* least) two: one for sockets and one for files, with separate
|
||||||
|
* functions to operate on them. To present a more POSIX-like
|
||||||
|
* interface to our application code, we provide a compatibility layer
|
||||||
|
* that maps POSIX file descriptors to sockets and file handles behind
|
||||||
|
* the scenes. This actual mapping is done by the fdmap. It doesn't
|
||||||
|
* implement the finer points of POSIX correctly. In particular, the
|
||||||
|
* actual values of the file descriptors usually differ.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#undef NS_ALL
|
||||||
|
#include <io.h>
|
||||||
|
#include <direct.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <share.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "unistd.h"
|
||||||
|
#include "empio.h"
|
||||||
|
#include "prototypes.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FD_SETSIZE is the size for the maximum number of sockets.
|
||||||
|
* The number of file descriptors is in a variable _nhandle
|
||||||
|
* based on the assertion output. In order the simplify the
|
||||||
|
* code and skip dynamic allocation, used double the socket size.
|
||||||
|
*/
|
||||||
|
#define MAX_FDS (FD_SETSIZE * 2)
|
||||||
|
|
||||||
|
enum fdmap_io_type {
|
||||||
|
FDMAP_IO_NOTUSED = 0,
|
||||||
|
FDMAP_IO_FILE,
|
||||||
|
FDMAP_IO_SOCKET,
|
||||||
|
FDMAP_IO_ANY /* used for searching only (lookup_handle) */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fdmap {
|
||||||
|
int handle;
|
||||||
|
enum fdmap_io_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct fdmap fdmap[MAX_FDS] = {
|
||||||
|
{0, FDMAP_IO_FILE},
|
||||||
|
{1, FDMAP_IO_FILE},
|
||||||
|
{2, FDMAP_IO_FILE}
|
||||||
|
};
|
||||||
|
static int nfd = 3;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate a POSIX equivalent file descriptor.
|
||||||
|
* Note once get_fd() is called either free_fd() or set_fd()
|
||||||
|
* must be called before thread mutex is released as the
|
||||||
|
* allocation/deallocation code is not thread safe.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
get_fd(void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
for (fd = 0; fd < nfd && fdmap[fd].type != FDMAP_IO_NOTUSED; fd++) ;
|
||||||
|
if (fd == MAX_FDS) {
|
||||||
|
errno = EMFILE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (fd == nfd) {
|
||||||
|
fdmap[fd].type = FDMAP_IO_NOTUSED;
|
||||||
|
nfd++;
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deallocate a POSIX equivalent file descriptor.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
free_fd(int fd)
|
||||||
|
{
|
||||||
|
fdmap[fd].type = FDMAP_IO_NOTUSED;
|
||||||
|
for(; fdmap[nfd - 1].type == FDMAP_IO_NOTUSED; nfd--) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Complete the allocation of the file descriptor.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
set_fd(int fd, enum fdmap_io_type type, int handle)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
fdmap[fd].handle = handle;
|
||||||
|
fdmap[fd].type = type;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Garbage collection for posix_fileno(), currently not
|
||||||
|
* replacing fclose() and fcloseall() so do not know when
|
||||||
|
* a stream is closed.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < nfd; i++) {
|
||||||
|
if (i != fd && type == fdmap[i].type && handle == fdmap[i].handle)
|
||||||
|
free_fd(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the windows handle (file or socket) for file descriptor.
|
||||||
|
* Return windows handle and type of handle.
|
||||||
|
* You can search for a specific type (FDMAP_IO_FILE or FDMAP_IO_SOCKET)
|
||||||
|
* or for both search by using FDMAP_IO_ANY.
|
||||||
|
* FDMAP_IO_NOTUSED is not valid type to search with.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
lookup_handle(int fd, enum fdmap_io_type d_type, int error,
|
||||||
|
enum fdmap_io_type *type_ptr, int *handle_ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (fd < 0 || fd >= MAX_FDS) {
|
||||||
|
if (error != 0)
|
||||||
|
errno = error;
|
||||||
|
return 0;
|
||||||
|
} else if ((fdmap[fd].type != d_type && d_type != FDMAP_IO_ANY) ||
|
||||||
|
(fdmap[fd].type == FDMAP_IO_NOTUSED && d_type == FDMAP_IO_ANY)) {
|
||||||
|
if (error != 0)
|
||||||
|
errno = error;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (type_ptr != NULL)
|
||||||
|
*type_ptr = fdmap[fd].type;
|
||||||
|
if (handle_ptr != NULL)
|
||||||
|
*handle_ptr = fdmap[fd].handle;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find and return the file descriptor associated with windows handle.
|
||||||
|
* You can search for FDMAP_IO_FILE or FDMAP_IO_SOCKET.
|
||||||
|
* FDMAP_IO_ANY or FDMAP_IO_NOTUSED is not considered valid search
|
||||||
|
* criteria.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
lookup_fd(int handle, enum fdmap_io_type d_type)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < nfd; i++)
|
||||||
|
if (fdmap[i].handle == handle && fdmap[i].type == d_type)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the window socket handle for POSIX file descriptor.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
posix_fd2socket(int fd)
|
||||||
|
{
|
||||||
|
int handle;
|
||||||
|
enum dmap_io_type type;
|
||||||
|
|
||||||
|
if (!lookup_handle(fd, FDMAP_IO_SOCKET, WSAENOTSOCK,
|
||||||
|
&type, &handle))
|
||||||
|
return INVALID_SOCKET;
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SOCKET_FUNCTION(expr) \
|
||||||
|
int result; \
|
||||||
|
int handle; \
|
||||||
|
\
|
||||||
|
if (!lookup_handle(fd, FDMAP_IO_SOCKET, \
|
||||||
|
ENOTSOCK, NULL, &handle)) \
|
||||||
|
return -1; \
|
||||||
|
\
|
||||||
|
result = (expr); \
|
||||||
|
if (result == SOCKET_ERROR) { \
|
||||||
|
errno = WSAGetLastError(); \
|
||||||
|
return -1; \
|
||||||
|
} \
|
||||||
|
return result;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX equivalent for accept().
|
||||||
|
*/
|
||||||
|
#undef accept
|
||||||
|
int
|
||||||
|
posix_accept(int fd, struct sockaddr *addr, socklen_t *addrlen)
|
||||||
|
{
|
||||||
|
int new_fd;
|
||||||
|
int handle, new_handle;
|
||||||
|
|
||||||
|
if (!lookup_handle(fd, FDMAP_IO_SOCKET, ENOTSOCK, NULL, &handle))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
new_fd = get_fd();
|
||||||
|
if (new_fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
new_handle = accept(handle, addr, addrlen);
|
||||||
|
if (new_handle == INVALID_SOCKET) {
|
||||||
|
free_fd(new_fd);
|
||||||
|
errno = WSAGetLastError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
set_fd(new_fd, FDMAP_IO_SOCKET, new_handle);
|
||||||
|
return new_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX equivalent for bind().
|
||||||
|
*/
|
||||||
|
#undef bind
|
||||||
|
int
|
||||||
|
posix_bind(int fd, const struct sockaddr *name, int namelen)
|
||||||
|
{
|
||||||
|
SOCKET_FUNCTION(bind(handle, name, namelen))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX equivalent for listen().
|
||||||
|
*/
|
||||||
|
#undef listen
|
||||||
|
int
|
||||||
|
posix_listen(int fd, int backlog)
|
||||||
|
{
|
||||||
|
SOCKET_FUNCTION(listen(handle, backlog))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX equivalent for setsockopt().
|
||||||
|
*/
|
||||||
|
#undef setsockopt
|
||||||
|
int
|
||||||
|
posix_setsockopt(int fd, int level, int optname,
|
||||||
|
const char *optval, int optlen)
|
||||||
|
{
|
||||||
|
SOCKET_FUNCTION(setsockopt(handle, level, optname,
|
||||||
|
optval, optlen))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX equivalent for shutdown().
|
||||||
|
*/
|
||||||
|
#undef shutdown
|
||||||
|
int
|
||||||
|
posix_shutdown(int fd, int how)
|
||||||
|
{
|
||||||
|
SOCKET_FUNCTION(shutdown(handle, how))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX equivalent for socket().
|
||||||
|
*/
|
||||||
|
#undef socket
|
||||||
|
int
|
||||||
|
posix_socket(int domain, int type, int protocol)
|
||||||
|
{
|
||||||
|
int handle;
|
||||||
|
int new_fd;
|
||||||
|
|
||||||
|
if ((new_fd = get_fd()) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
handle = socket(domain, type, protocol);
|
||||||
|
if (handle == INVALID_SOCKET) {
|
||||||
|
free_fd(new_fd);
|
||||||
|
errno = WSAGetLastError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
set_fd(new_fd, FDMAP_IO_SOCKET, handle);
|
||||||
|
return new_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FILE_FUNCTION(type, expr) \
|
||||||
|
int handle; \
|
||||||
|
\
|
||||||
|
if (!lookup_handle(fd, (type), EBADF, NULL, &handle)) \
|
||||||
|
return -1; \
|
||||||
|
\
|
||||||
|
return (expr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX equivalent for close().
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
posix_close(int fd)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
int handle;
|
||||||
|
enum fdmap_io_type type;
|
||||||
|
|
||||||
|
if (!lookup_handle(fd, FDMAP_IO_ANY, EBADF, &type, &handle))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
free_fd(fd);
|
||||||
|
switch (type) {
|
||||||
|
case FDMAP_IO_SOCKET:
|
||||||
|
result = closesocket(handle);
|
||||||
|
if (result == SOCKET_ERROR) {
|
||||||
|
errno = WSAGetLastError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
case FDMAP_IO_FILE:
|
||||||
|
return _close(handle);
|
||||||
|
}
|
||||||
|
CANT_REACH();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* posix_fsync forces file sync with the disk.
|
||||||
|
* In order for the power report report to accurate timestamp,
|
||||||
|
* the _commit() is to force a sync with disk and therefore
|
||||||
|
* an update for file time.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
posix_fsync(int fd)
|
||||||
|
{
|
||||||
|
FILE_FUNCTION(FDMAP_IO_FILE, _commit(handle))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX equivalent for fstat().
|
||||||
|
* fstat() is used instead of _fstat(),
|
||||||
|
* otherwise problems with the 32/64 time definitions
|
||||||
|
* in WIN32.
|
||||||
|
*/
|
||||||
|
#undef fstat
|
||||||
|
int
|
||||||
|
posix_fstat(int fd, struct stat *buffer)
|
||||||
|
{
|
||||||
|
FILE_FUNCTION(FDMAP_IO_ANY, fstat(handle, buffer))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX equivalent for lseek().
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
posix_lseek(int fd, long offset, int origin)
|
||||||
|
{
|
||||||
|
FILE_FUNCTION(FDMAP_IO_FILE, _lseek(handle, offset, origin))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX equivalent for open().
|
||||||
|
* Implements file locks when opening files to provide equivalent
|
||||||
|
* F_GETLK/F_SETLK.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
posix_open(const char *fname, int oflag, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int pmode = 0, new_fd;
|
||||||
|
int handle;
|
||||||
|
|
||||||
|
if (oflag & O_CREAT) {
|
||||||
|
va_start(ap, oflag);
|
||||||
|
pmode = va_arg(ap, int);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((new_fd = get_fd()) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't implement fcntl() for F_SETLK. Instead, we lock *all*
|
||||||
|
* files we open. Not ideal, but it works for Empire.
|
||||||
|
*/
|
||||||
|
_sopen_s(&handle, fname, oflag,
|
||||||
|
oflag & O_RDONLY ? SH_DENYNO : SH_DENYWR, pmode);
|
||||||
|
if (handle == -1) {
|
||||||
|
free_fd(new_fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
set_fd(new_fd, FDMAP_IO_FILE, handle);
|
||||||
|
return new_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SHARED_FUNCTION(socket_expr, file_expr) \
|
||||||
|
int result; \
|
||||||
|
int handle; \
|
||||||
|
enum fdmap_io_type type; \
|
||||||
|
\
|
||||||
|
if (!lookup_handle(fd, FDMAP_IO_ANY, EBADF, &type, &handle)) \
|
||||||
|
return -1; \
|
||||||
|
\
|
||||||
|
switch (type) { \
|
||||||
|
case FDMAP_IO_SOCKET: \
|
||||||
|
result = (socket_expr); \
|
||||||
|
if (result == SOCKET_ERROR) { \
|
||||||
|
errno = WSAGetLastError(); \
|
||||||
|
return -1; \
|
||||||
|
} \
|
||||||
|
return result; \
|
||||||
|
case FDMAP_IO_FILE: \
|
||||||
|
return (file_expr); \
|
||||||
|
} \
|
||||||
|
CANT_REACH(); \
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX equivalent for read().
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
posix_read(int fd, void *buffer, unsigned int count)
|
||||||
|
{
|
||||||
|
SHARED_FUNCTION(recv(handle, buffer, count, 0),
|
||||||
|
_read(handle, buffer, count))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX equivalent for write().
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
posix_write(int fd, const void *buffer, unsigned int count)
|
||||||
|
{
|
||||||
|
SHARED_FUNCTION(send(handle, buffer, count, 0),
|
||||||
|
_write(handle, buffer, count))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX equivalent for fileno().
|
||||||
|
* As fopen/fclose/fcloseall are not implemented as POSIX
|
||||||
|
* equivalent functions, the mapping is done when required
|
||||||
|
* by a call to fileno(). The garbage collection of the
|
||||||
|
* file descriptors allocated is done in set_fd() when the
|
||||||
|
* handle is reused.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
posix_fileno(FILE *stream)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int handle;
|
||||||
|
|
||||||
|
if (stream == NULL) {
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle = _fileno(stream);
|
||||||
|
|
||||||
|
fd = lookup_fd(handle, FDMAP_IO_FILE);
|
||||||
|
if (fd >= 0)
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
if ((fd = get_fd()) < 0) {
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_fd(fd, FDMAP_IO_FILE, handle);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX equivalent for fcntl().
|
||||||
|
* Currently supports only the F_GETFL/F_SETFL/O_NONBLOCK
|
||||||
|
* Currently ignores F_GETLK/F_SETLK as the file locks are
|
||||||
|
* implement in open()
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
fcntl(int fd, int cmd, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int value;
|
||||||
|
unsigned int nonblocking;
|
||||||
|
int result;
|
||||||
|
long bytes_returned;
|
||||||
|
int handle;
|
||||||
|
enum fdmap_io_type type;
|
||||||
|
|
||||||
|
if (!lookup_handle(fd, FDMAP_IO_ANY, EBADF, &type, &handle))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case F_GETFL:
|
||||||
|
/*
|
||||||
|
* F_GETFL and F_SETFL only support O_NONBLOCK
|
||||||
|
* for sockets currently
|
||||||
|
*/
|
||||||
|
if (type == FDMAP_IO_SOCKET) {
|
||||||
|
result = WSAIoctl(handle, FIONBIO, NULL, 0,&nonblocking,
|
||||||
|
sizeof (nonblocking), &bytes_returned, NULL, NULL);
|
||||||
|
|
||||||
|
if(result < 0) {
|
||||||
|
errno = WSAGetLastError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nonblocking)
|
||||||
|
return O_NONBLOCK;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case F_SETFL:
|
||||||
|
if (type == FDMAP_IO_SOCKET) {
|
||||||
|
va_start(ap, cmd);
|
||||||
|
value = va_arg(ap, int);
|
||||||
|
va_end(ap);
|
||||||
|
if (value & O_NONBLOCK)
|
||||||
|
nonblocking = 1;
|
||||||
|
else
|
||||||
|
nonblocking = 0;
|
||||||
|
|
||||||
|
result = WSAIoctl(handle, FIONBIO, &nonblocking,
|
||||||
|
sizeof (nonblocking), NULL, 0, &bytes_returned,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
if(result < 0) {
|
||||||
|
errno = WSAGetLastError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case F_SETLK:
|
||||||
|
/*
|
||||||
|
* The POSIX equivalent is not available in WIN32
|
||||||
|
* That implement the file locking in the file open
|
||||||
|
* by using sopen instead of open.
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
|
@ -34,7 +34,9 @@
|
||||||
#ifndef UNISTD_H
|
#ifndef UNISTD_H
|
||||||
#define UNISTD_H
|
#define UNISTD_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* posixfile.c
|
* posixfile.c
|
||||||
|
@ -43,4 +45,78 @@
|
||||||
|
|
||||||
extern int posix_mkdir(const char *dirname, int perm);
|
extern int posix_mkdir(const char *dirname, int perm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* posixio.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef int socklen_t;
|
||||||
|
|
||||||
|
#define accept(fd, addr, addrlen) \
|
||||||
|
posix_accept((fd), (addr), (addrlen))
|
||||||
|
#define bind(fd, name, namelen) \
|
||||||
|
posix_bind((fd), (name), (namelen))
|
||||||
|
#define listen(fd, backlog) \
|
||||||
|
posix_listen((fd), (backlog))
|
||||||
|
#define setsockopt(fd, level, optname, optval, optlen) \
|
||||||
|
posix_setsockopt((fd), (level), (optname), (optval), (optlen))
|
||||||
|
#define shutdown(fd, how) \
|
||||||
|
posix_shutdown((fd), (how))
|
||||||
|
#define socket(domain, type, protocol) \
|
||||||
|
posix_socket((domain), (type), (protocol))
|
||||||
|
|
||||||
|
#define close(fd) \
|
||||||
|
posix_close((fd))
|
||||||
|
#define creat(fname, pmode) \
|
||||||
|
posix_open((fname), _O_WRONLY | _O_CREAT |_O_TRUNC, (pmode))
|
||||||
|
#define fstat(fd, buffer) \
|
||||||
|
posix_fstat((fd), (buffer))
|
||||||
|
#define lseek(fd, offset, origin) \
|
||||||
|
posix_lseek((fd), (offset), (origin))
|
||||||
|
#define open(fname, oflag, ...) \
|
||||||
|
posix_open((fname), (oflag), __VA_ARGS__)
|
||||||
|
#define read posix_read
|
||||||
|
#define write(fd, buffer, count) \
|
||||||
|
posix_write((fd), (buffer), (count))
|
||||||
|
#define fileno(stream) \
|
||||||
|
posix_fileno((stream))
|
||||||
|
#define fsync(fd) \
|
||||||
|
posix_fsync((fd))
|
||||||
|
|
||||||
|
#define O_NONBLOCK 1
|
||||||
|
#define F_RDLCK 0
|
||||||
|
#define F_WRLCK 1
|
||||||
|
#define F_GETFL 1
|
||||||
|
#define F_SETFL 2
|
||||||
|
#define F_SETLK 3
|
||||||
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
|
#define ENOTSOCK WSAENOTSOCK
|
||||||
|
|
||||||
|
struct flock
|
||||||
|
{
|
||||||
|
int l_type;
|
||||||
|
int l_whence;
|
||||||
|
int l_start;
|
||||||
|
int l_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int posix_fd2socket(int fd);
|
||||||
|
|
||||||
|
extern int posix_accept(int fd, struct sockaddr *addr, socklen_t *addrlen);
|
||||||
|
extern int posix_bind(int fd, const struct sockaddr *name, int namelen);
|
||||||
|
extern int posix_listen(int fd, int backlog);
|
||||||
|
extern int posix_setsockopt(int fd, int level, int optname,
|
||||||
|
const char *optval, int optlen);
|
||||||
|
extern int posix_shutdown(int fd, int how);
|
||||||
|
extern int posix_socket(int domain, int type, int protocol);
|
||||||
|
|
||||||
|
extern int posix_close(int fd);
|
||||||
|
extern int posix_fstat(int fd, struct stat *buffer);
|
||||||
|
extern int posix_lseek(int fd, long offset, int origin);
|
||||||
|
extern int posix_open(const char *fname, int oflag, ...);
|
||||||
|
extern int posix_read(int fd, void *buffer, unsigned int count);
|
||||||
|
extern int posix_write(int fd, const void *buffer, unsigned int count);
|
||||||
|
|
||||||
|
extern int posix_fileno(FILE *stream);
|
||||||
|
extern int posix_fsync(int fd);
|
||||||
|
extern int fcntl(int fd, int cmd, ...);
|
||||||
#endif /* UNISTD_H */
|
#endif /* UNISTD_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue