3-3 c2
This commit is contained in:
parent
bc122a7472
commit
18bd5676ce
|
@ -1,3 +1,8 @@
|
|||
/*
|
||||
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
|
||||
*
|
||||
* Redefined and missing POSIX macros
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <memory.h>
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
/*
|
||||
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
|
||||
*
|
||||
* POSIX header and needed function definitions
|
||||
*/
|
||||
#include "w32posix.h"
|
||||
|
||||
#define fcntl w32_fcntl
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
/*
|
||||
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
|
||||
*
|
||||
* POSIX header and needed function definitions
|
||||
*/
|
||||
#include "..\w32posix.h"
|
||||
|
||||
#define select w32_select
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
|
||||
*
|
||||
* POSIX header and needed function definitions
|
||||
*/
|
||||
|
||||
#include "..\w32posix.h"
|
||||
|
||||
#define socket w32_socket
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
|
||||
*
|
||||
* POSIX header and needed function definitions
|
||||
*/
|
||||
|
||||
#include "..\w32posix.h"
|
||||
|
||||
#define fstat w32_fstat
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
|
||||
*
|
||||
* POSIX header and needed function definitions
|
||||
*/
|
||||
|
||||
#include "w32posix.h"
|
||||
|
||||
#define pipe w32_pipe
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
/*
|
||||
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
|
||||
*
|
||||
* Win32 renamed POSIX APIs
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <WinSock2.h>
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
/*
|
||||
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
|
||||
*
|
||||
* Implementation of POSIX APIs
|
||||
*/
|
||||
#include "inc\w32posix.h"
|
||||
#include "w32fd.h"
|
||||
#include <stdarg.h>
|
||||
|
@ -5,404 +10,430 @@
|
|||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* internal table that stores the fd to w32_io mapping*/
|
||||
struct w32fd_table {
|
||||
w32_fd_set occupied;
|
||||
struct w32_io* w32_ios[MAX_FDS];
|
||||
w32_fd_set occupied; /*bit map for tracking occipied table entries*/
|
||||
struct w32_io* w32_ios[MAX_FDS];/*array of references to mapped w32_io objects*/
|
||||
};
|
||||
|
||||
struct w32fd_table fd_table;
|
||||
struct w32_io w32_io_stdin, w32_io_stdout, w32_io_stderr;
|
||||
/* mapping table*/
|
||||
static struct w32fd_table fd_table;
|
||||
|
||||
/* static table entries representing std in, out and error*/
|
||||
static struct w32_io w32_io_stdin, w32_io_stdout, w32_io_stderr;
|
||||
|
||||
/* maps pio to fd (specified by index)*/
|
||||
void fd_table_set(struct w32_io* pio, int index);
|
||||
|
||||
#pragma warning(disable:4312)
|
||||
int fd_table_initialize() {
|
||||
memset(&fd_table, 0, sizeof(fd_table));
|
||||
memset(&w32_io_stdin, 0, sizeof(w32_io_stdin));
|
||||
w32_io_stdin.handle = (HANDLE)STD_INPUT_HANDLE;
|
||||
w32_io_stdin.type = STD_IO_FD;
|
||||
fd_table_set(&w32_io_stdin, STDIN_FILENO);
|
||||
memset(&w32_io_stdout, 0, sizeof(w32_io_stdout));
|
||||
w32_io_stdout.handle = (HANDLE)STD_OUTPUT_HANDLE;
|
||||
w32_io_stdout.type = STD_IO_FD;
|
||||
fd_table_set(&w32_io_stdout, STDOUT_FILENO);
|
||||
memset(&w32_io_stderr, 0, sizeof(w32_io_stderr));
|
||||
w32_io_stderr.handle = (HANDLE)STD_ERROR_HANDLE;
|
||||
w32_io_stderr.type = STD_IO_FD;
|
||||
fd_table_set(&w32_io_stderr, STDERR_FILENO);
|
||||
return 0;
|
||||
/* initializes mapping table*/
|
||||
static int
|
||||
fd_table_initialize() {
|
||||
memset(&fd_table, 0, sizeof(fd_table));
|
||||
memset(&w32_io_stdin, 0, sizeof(w32_io_stdin));
|
||||
w32_io_stdin.handle = (HANDLE)STD_INPUT_HANDLE;
|
||||
w32_io_stdin.type = STD_IO_FD;
|
||||
fd_table_set(&w32_io_stdin, STDIN_FILENO);
|
||||
memset(&w32_io_stdout, 0, sizeof(w32_io_stdout));
|
||||
w32_io_stdout.handle = (HANDLE)STD_OUTPUT_HANDLE;
|
||||
w32_io_stdout.type = STD_IO_FD;
|
||||
fd_table_set(&w32_io_stdout, STDOUT_FILENO);
|
||||
memset(&w32_io_stderr, 0, sizeof(w32_io_stderr));
|
||||
w32_io_stderr.handle = (HANDLE)STD_ERROR_HANDLE;
|
||||
w32_io_stderr.type = STD_IO_FD;
|
||||
fd_table_set(&w32_io_stderr, STDERR_FILENO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fd_table_get_min_index() {
|
||||
int min_index = 0;
|
||||
unsigned char* bitmap = fd_table.occupied.bitmap;
|
||||
unsigned char tmp;
|
||||
/* get a free slot in mapping table with least index*/
|
||||
static int
|
||||
fd_table_get_min_index() {
|
||||
int min_index = 0;
|
||||
unsigned char* bitmap = fd_table.occupied.bitmap;
|
||||
unsigned char tmp;
|
||||
|
||||
while (*bitmap == 0xff)
|
||||
{
|
||||
bitmap++;
|
||||
min_index += 8;
|
||||
if (min_index >= MAX_FDS) {
|
||||
errno = EMFILE;
|
||||
debug("ERROR: MAX_FDS limit reached");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
while (*bitmap == 0xff) {
|
||||
bitmap++;
|
||||
min_index += 8;
|
||||
if (min_index >= MAX_FDS) {
|
||||
errno = EMFILE;
|
||||
debug("ERROR: MAX_FDS limit reached");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = *bitmap;
|
||||
tmp = *bitmap;
|
||||
|
||||
while (tmp & 0x80)
|
||||
{
|
||||
tmp <<= 1;
|
||||
min_index++;
|
||||
}
|
||||
while (tmp & 0x80)
|
||||
{
|
||||
tmp <<= 1;
|
||||
min_index++;
|
||||
}
|
||||
|
||||
return min_index;
|
||||
return min_index;
|
||||
}
|
||||
|
||||
static void fd_table_set(struct w32_io* pio, int index) {
|
||||
fd_table.w32_ios[index] = pio;
|
||||
pio->table_index = index;
|
||||
assert(pio->type != UNKNOWN_FD);
|
||||
FD_SET(index, &(fd_table.occupied));
|
||||
static void
|
||||
fd_table_set(struct w32_io* pio, int index) {
|
||||
fd_table.w32_ios[index] = pio;
|
||||
pio->table_index = index;
|
||||
assert(pio->type != UNKNOWN_FD);
|
||||
FD_SET(index, &(fd_table.occupied));
|
||||
}
|
||||
|
||||
static void fd_table_clear(int index)
|
||||
static void
|
||||
fd_table_clear(int index)
|
||||
{
|
||||
fd_table.w32_ios[index]->table_index = -1;
|
||||
fd_table.w32_ios[index] = NULL;
|
||||
FD_CLR(index, &(fd_table.occupied));
|
||||
fd_table.w32_ios[index]->table_index = -1;
|
||||
fd_table.w32_ios[index] = NULL;
|
||||
FD_CLR(index, &(fd_table.occupied));
|
||||
}
|
||||
|
||||
void w32posix_initialize() {
|
||||
if ((debug_initialize() != 0)
|
||||
|| (fd_table_initialize() != 0)
|
||||
|| (socketio_initialize() != 0))
|
||||
abort();
|
||||
void
|
||||
w32posix_initialize() {
|
||||
if ((debug_initialize() != 0)
|
||||
|| (fd_table_initialize() != 0)
|
||||
|| (socketio_initialize() != 0))
|
||||
abort();
|
||||
}
|
||||
|
||||
void w32posix_done() {
|
||||
debug_done();
|
||||
socketio_done();
|
||||
void
|
||||
w32posix_done() {
|
||||
debug_done();
|
||||
socketio_done();
|
||||
}
|
||||
|
||||
BOOL w32_io_is_blocking(struct w32_io* pio)
|
||||
BOOL
|
||||
w32_io_is_blocking(struct w32_io* pio)
|
||||
{
|
||||
return (pio->fd_status_flags & O_NONBLOCK) ? FALSE : TRUE;
|
||||
return (pio->fd_status_flags & O_NONBLOCK) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
BOOL w32_io_is_io_available(struct w32_io* pio, BOOL rd) {
|
||||
if (pio->type == SOCK_FD) {
|
||||
return socketio_is_io_available(pio, rd);
|
||||
}
|
||||
else {
|
||||
return fileio_is_io_available(pio, rd);
|
||||
}
|
||||
|
||||
BOOL
|
||||
w32_io_is_io_available(struct w32_io* pio, BOOL rd) {
|
||||
if (pio->type == SOCK_FD)
|
||||
return socketio_is_io_available(pio, rd);
|
||||
else
|
||||
return fileio_is_io_available(pio, rd);
|
||||
}
|
||||
|
||||
int w32_io_on_select(struct w32_io* pio, BOOL rd)
|
||||
int
|
||||
w32_io_on_select(struct w32_io* pio, BOOL rd)
|
||||
{
|
||||
if ((pio->type == SOCK_FD)) {
|
||||
return socketio_on_select(pio, rd);
|
||||
}
|
||||
else {
|
||||
return fileio_on_select(pio, rd);
|
||||
}
|
||||
|
||||
if ((pio->type == SOCK_FD))
|
||||
return socketio_on_select(pio, rd);
|
||||
else
|
||||
return fileio_on_select(pio, rd);
|
||||
}
|
||||
|
||||
#define CHECK_FD(fd) do { \
|
||||
errno = 0; \
|
||||
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) { \
|
||||
errno = EBADF; \
|
||||
debug("ERROR: bad fd: %d", fd); \
|
||||
return -1; \
|
||||
} \
|
||||
#define CHECK_FD(fd) do { \
|
||||
errno = 0; \
|
||||
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) { \
|
||||
errno = EBADF; \
|
||||
debug("ERROR: bad fd: %d", fd); \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_SOCK_IO(pio) do { \
|
||||
errno = 0; \
|
||||
if (pio->type != SOCK_FD) { \
|
||||
errno = ENOTSOCK; \
|
||||
debug("ERROR: non sock fd type:%d", pio->type); \
|
||||
return -1; \
|
||||
} \
|
||||
errno = 0; \
|
||||
if (pio->type != SOCK_FD) { \
|
||||
errno = ENOTSOCK; \
|
||||
debug("ERROR: non sock fd type:%d", pio->type); \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int w32_socket(int domain, int type, int protocol) {
|
||||
int min_index = fd_table_get_min_index();
|
||||
struct w32_io* pio = NULL;
|
||||
int
|
||||
w32_socket(int domain, int type, int protocol) {
|
||||
int min_index = fd_table_get_min_index();
|
||||
struct w32_io* pio = NULL;
|
||||
|
||||
errno = 0;
|
||||
if (min_index == -1)
|
||||
return -1;
|
||||
errno = 0;
|
||||
if (min_index == -1)
|
||||
return -1;
|
||||
|
||||
pio = socketio_socket(domain, type, protocol);
|
||||
if (!pio) {
|
||||
return -1;
|
||||
}
|
||||
pio = socketio_socket(domain, type, protocol);
|
||||
if (pio == NULL)
|
||||
return -1;
|
||||
|
||||
pio->type = SOCK_FD;
|
||||
fd_table_set(pio, min_index);
|
||||
debug("socket:%d, io:%p, fd:%d ", pio->sock, pio, min_index);
|
||||
return min_index;
|
||||
pio->type = SOCK_FD;
|
||||
fd_table_set(pio, min_index);
|
||||
debug("socket:%d, io:%p, fd:%d ", pio->sock, pio, min_index);
|
||||
return min_index;
|
||||
}
|
||||
|
||||
int w32_accept(int fd, struct sockaddr* addr, int* addrlen)
|
||||
int
|
||||
w32_accept(int fd, struct sockaddr* addr, int* addrlen)
|
||||
{
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
int min_index = fd_table_get_min_index();
|
||||
struct w32_io* pio = NULL;
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
int min_index = fd_table_get_min_index();
|
||||
struct w32_io* pio = NULL;
|
||||
|
||||
if (min_index == -1)
|
||||
return -1;
|
||||
if (min_index == -1)
|
||||
return -1;
|
||||
|
||||
pio = socketio_accept(fd_table.w32_ios[fd], addr, addrlen);
|
||||
if (!pio) {
|
||||
return -1;
|
||||
}
|
||||
pio = socketio_accept(fd_table.w32_ios[fd], addr, addrlen);
|
||||
if (!pio)
|
||||
return -1;
|
||||
|
||||
pio->type = SOCK_FD;
|
||||
fd_table_set(pio, min_index);
|
||||
debug("socket:%d, io:%p, fd:%d ", pio->sock, pio, min_index);
|
||||
return min_index;
|
||||
pio->type = SOCK_FD;
|
||||
fd_table_set(pio, min_index);
|
||||
debug("socket:%d, io:%p, fd:%d ", pio->sock, pio, min_index);
|
||||
return min_index;
|
||||
}
|
||||
|
||||
int w32_setsockopt(int fd, int level, int optname, const char* optval, int optlen) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_setsockopt(fd_table.w32_ios[fd], level, optname, optval, optlen);
|
||||
int
|
||||
w32_setsockopt(int fd, int level, int optname, const char* optval, int optlen) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_setsockopt(fd_table.w32_ios[fd], level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
int w32_getsockopt(int fd, int level, int optname, char* optval, int* optlen) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_getsockopt(fd_table.w32_ios[fd], level, optname, optval, optlen);
|
||||
int
|
||||
w32_getsockopt(int fd, int level, int optname, char* optval, int* optlen) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_getsockopt(fd_table.w32_ios[fd], level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
int w32_getsockname(int fd, struct sockaddr* name, int* namelen) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_getsockname(fd_table.w32_ios[fd], name, namelen);
|
||||
int
|
||||
w32_getsockname(int fd, struct sockaddr* name, int* namelen) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_getsockname(fd_table.w32_ios[fd], name, namelen);
|
||||
}
|
||||
|
||||
int w32_getpeername(int fd, struct sockaddr* name, int* namelen) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_getpeername(fd_table.w32_ios[fd], name, namelen);
|
||||
int
|
||||
w32_getpeername(int fd, struct sockaddr* name, int* namelen) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_getpeername(fd_table.w32_ios[fd], name, namelen);
|
||||
}
|
||||
|
||||
int w32_listen(int fd, int backlog) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_listen(fd_table.w32_ios[fd], backlog);
|
||||
int
|
||||
w32_listen(int fd, int backlog) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_listen(fd_table.w32_ios[fd], backlog);
|
||||
}
|
||||
|
||||
int w32_bind(int fd, const struct sockaddr *name, int namelen) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_bind(fd_table.w32_ios[fd], name, namelen);
|
||||
int
|
||||
w32_bind(int fd, const struct sockaddr *name, int namelen) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_bind(fd_table.w32_ios[fd], name, namelen);
|
||||
}
|
||||
|
||||
int w32_connect(int fd, const struct sockaddr* name, int namelen) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_connect(fd_table.w32_ios[fd], name, namelen);
|
||||
int
|
||||
w32_connect(int fd, const struct sockaddr* name, int namelen) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_connect(fd_table.w32_ios[fd], name, namelen);
|
||||
}
|
||||
|
||||
int w32_recv(int fd, void *buf, size_t len, int flags) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_recv(fd_table.w32_ios[fd], buf, len, flags);
|
||||
int
|
||||
w32_recv(int fd, void *buf, size_t len, int flags) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_recv(fd_table.w32_ios[fd], buf, len, flags);
|
||||
}
|
||||
|
||||
int w32_send(int fd, const void *buf, size_t len, int flags) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
return socketio_send(fd_table.w32_ios[fd], buf, len, flags);
|
||||
int
|
||||
w32_send(int fd, const void *buf, size_t len, int flags) {
|
||||
debug3("fd:%d", fd);
|
||||
CHECK_FD(fd);
|
||||
return socketio_send(fd_table.w32_ios[fd], buf, len, flags);
|
||||
}
|
||||
|
||||
|
||||
int w32_shutdown(int fd, int how) {
|
||||
debug3("fd:%d how:%d", fd, how);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_shutdown(fd_table.w32_ios[fd], how);
|
||||
int
|
||||
w32_shutdown(int fd, int how) {
|
||||
debug3("fd:%d how:%d", fd, how);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_shutdown(fd_table.w32_ios[fd], how);
|
||||
}
|
||||
|
||||
|
||||
//file io
|
||||
int w32_pipe(int *pfds){
|
||||
int read_index, write_index;
|
||||
struct w32_io* pio[2];
|
||||
int
|
||||
w32_pipe(int *pfds){
|
||||
int read_index, write_index;
|
||||
struct w32_io* pio[2];
|
||||
|
||||
errno = 0;
|
||||
read_index = fd_table_get_min_index();
|
||||
if (read_index == -1)
|
||||
return -1;
|
||||
errno = 0;
|
||||
read_index = fd_table_get_min_index();
|
||||
if (read_index == -1)
|
||||
return -1;
|
||||
|
||||
//temporarily set occupied bit
|
||||
FD_SET(read_index, &fd_table.occupied);
|
||||
write_index = fd_table_get_min_index();
|
||||
FD_CLR(read_index, &fd_table.occupied);
|
||||
if (write_index == -1)
|
||||
return -1;
|
||||
/*temporarily set occupied bit*/
|
||||
FD_SET(read_index, &fd_table.occupied);
|
||||
write_index = fd_table_get_min_index();
|
||||
FD_CLR(read_index, &fd_table.occupied);
|
||||
if (write_index == -1)
|
||||
return -1;
|
||||
|
||||
if (-1 == fileio_pipe(pio))
|
||||
return -1;
|
||||
if (-1 == fileio_pipe(pio))
|
||||
return -1;
|
||||
|
||||
pio[0]->type = PIPE_FD;
|
||||
pio[1]->type = PIPE_FD;
|
||||
fd_table_set(pio[0], read_index);
|
||||
fd_table_set(pio[1], write_index);
|
||||
pfds[0] = read_index;
|
||||
pfds[1] = write_index;
|
||||
debug("read end: handle:%p, io:%p, fd:%d", pio[0]->handle, pio[0], read_index);
|
||||
debug("write end: handle:%p, io:%p, fd:%d", pio[1]->handle, pio[1], write_index);
|
||||
return 0;
|
||||
pio[0]->type = PIPE_FD;
|
||||
pio[1]->type = PIPE_FD;
|
||||
fd_table_set(pio[0], read_index);
|
||||
fd_table_set(pio[1], write_index);
|
||||
pfds[0] = read_index;
|
||||
pfds[1] = write_index;
|
||||
debug("read end: handle:%p, io:%p, fd:%d", pio[0]->handle, pio[0], read_index);
|
||||
debug("write end: handle:%p, io:%p, fd:%d", pio[1]->handle, pio[1], write_index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w32_open(const char *pathname, int flags, ...) {
|
||||
int min_index = fd_table_get_min_index();
|
||||
struct w32_io* pio;
|
||||
int
|
||||
w32_open(const char *pathname, int flags, ...) {
|
||||
int min_index = fd_table_get_min_index();
|
||||
struct w32_io* pio;
|
||||
|
||||
errno = 0;
|
||||
if (min_index == -1)
|
||||
return -1;
|
||||
errno = 0;
|
||||
if (min_index == -1)
|
||||
return -1;
|
||||
|
||||
pio = fileio_open(pathname, flags, 0);
|
||||
if (pio == NULL)
|
||||
return -1;
|
||||
pio = fileio_open(pathname, flags, 0);
|
||||
if (pio == NULL)
|
||||
return -1;
|
||||
|
||||
pio->type = FILE_FD;
|
||||
fd_table_set(pio, min_index);
|
||||
debug("handle:%p, io:%p, fd:%d", pio->handle, pio, min_index);
|
||||
return min_index;
|
||||
pio->type = FILE_FD;
|
||||
fd_table_set(pio, min_index);
|
||||
debug("handle:%p, io:%p, fd:%d", pio->handle, pio, min_index);
|
||||
return min_index;
|
||||
}
|
||||
|
||||
int w32_read(int fd, void *dst, unsigned int max) {
|
||||
CHECK_FD(fd);
|
||||
if (fd_table.w32_ios[fd]->type == SOCK_FD)
|
||||
return socketio_recv(fd_table.w32_ios[fd], dst, max, 0);
|
||||
return fileio_read(fd_table.w32_ios[fd], dst, max);
|
||||
int
|
||||
w32_read(int fd, void *dst, unsigned int max) {
|
||||
CHECK_FD(fd);
|
||||
if (fd_table.w32_ios[fd]->type == SOCK_FD)
|
||||
return socketio_recv(fd_table.w32_ios[fd], dst, max, 0);
|
||||
return fileio_read(fd_table.w32_ios[fd], dst, max);
|
||||
}
|
||||
|
||||
int w32_write(int fd, const void *buf, unsigned int max) {
|
||||
CHECK_FD(fd);
|
||||
if (fd_table.w32_ios[fd]->type == SOCK_FD)
|
||||
return socketio_send(fd_table.w32_ios[fd], buf, max, 0);
|
||||
return fileio_write(fd_table.w32_ios[fd], buf, max);
|
||||
int
|
||||
w32_write(int fd, const void *buf, unsigned int max) {
|
||||
CHECK_FD(fd);
|
||||
if (fd_table.w32_ios[fd]->type == SOCK_FD)
|
||||
return socketio_send(fd_table.w32_ios[fd], buf, max, 0);
|
||||
return fileio_write(fd_table.w32_ios[fd], buf, max);
|
||||
}
|
||||
|
||||
int w32_fstat(int fd, struct stat *buf) {
|
||||
CHECK_FD(fd);
|
||||
return fileio_fstat(fd_table.w32_ios[fd], buf);
|
||||
int
|
||||
w32_fstat(int fd, struct stat *buf) {
|
||||
CHECK_FD(fd);
|
||||
return fileio_fstat(fd_table.w32_ios[fd], buf);
|
||||
}
|
||||
|
||||
int w32_isatty(int fd) {
|
||||
CHECK_FD(fd);
|
||||
return fileio_isatty(fd_table.w32_ios[fd]);
|
||||
int
|
||||
w32_isatty(int fd) {
|
||||
CHECK_FD(fd);
|
||||
return fileio_isatty(fd_table.w32_ios[fd]);
|
||||
}
|
||||
|
||||
FILE* w32_fdopen(int fd, const char *mode) {
|
||||
errno = 0;
|
||||
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
|
||||
errno = EBADF;
|
||||
debug("bad fd: %d", fd);
|
||||
return NULL;
|
||||
}
|
||||
return fileio_fdopen(fd_table.w32_ios[fd], mode);
|
||||
FILE*
|
||||
w32_fdopen(int fd, const char *mode) {
|
||||
errno = 0;
|
||||
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
|
||||
errno = EBADF;
|
||||
debug("bad fd: %d", fd);
|
||||
return NULL;
|
||||
}
|
||||
return fileio_fdopen(fd_table.w32_ios[fd], mode);
|
||||
}
|
||||
|
||||
//Common IO
|
||||
int w32_close(int fd) {
|
||||
int
|
||||
w32_close(int fd) {
|
||||
struct w32_io* pio;
|
||||
|
||||
struct w32_io* pio;
|
||||
|
||||
CHECK_FD(fd);
|
||||
pio = fd_table.w32_ios[fd];
|
||||
CHECK_FD(fd);
|
||||
pio = fd_table.w32_ios[fd];
|
||||
|
||||
debug("io:%p, type:%d, fd:%d, table_index:%d", pio, pio->type, fd, pio->table_index);
|
||||
fd_table_clear(pio->table_index);
|
||||
if ((pio->type == SOCK_FD)) {
|
||||
return socketio_close(pio);
|
||||
}
|
||||
else
|
||||
return fileio_close(pio);
|
||||
debug("io:%p, type:%d, fd:%d, table_index:%d", pio, pio->type, fd, pio->table_index);
|
||||
fd_table_clear(pio->table_index);
|
||||
if ((pio->type == SOCK_FD))
|
||||
return socketio_close(pio);
|
||||
else
|
||||
return fileio_close(pio);
|
||||
}
|
||||
|
||||
int w32_fcntl(int fd, int cmd, ... /* arg */) {
|
||||
va_list valist;
|
||||
va_start(valist, cmd);
|
||||
int
|
||||
w32_fcntl(int fd, int cmd, ... /* arg */) {
|
||||
va_list valist;
|
||||
va_start(valist, cmd);
|
||||
|
||||
CHECK_FD(fd);
|
||||
CHECK_FD(fd);
|
||||
|
||||
switch (cmd){
|
||||
case F_GETFL:
|
||||
return fd_table.w32_ios[fd]->fd_status_flags;
|
||||
case F_SETFL:
|
||||
fd_table.w32_ios[fd]->fd_status_flags = va_arg(valist, int);
|
||||
return 0;
|
||||
case F_GETFD:
|
||||
return fd_table.w32_ios[fd]->fd_flags;
|
||||
return 0;
|
||||
case F_SETFD:
|
||||
fd_table.w32_ios[fd]->fd_flags = va_arg(valist, int);
|
||||
return 0;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
debug("ERROR: cmd:%d", cmd);
|
||||
return -1;
|
||||
switch (cmd){
|
||||
case F_GETFL:
|
||||
return fd_table.w32_ios[fd]->fd_status_flags;
|
||||
case F_SETFL:
|
||||
fd_table.w32_ios[fd]->fd_status_flags = va_arg(valist, int);
|
||||
return 0;
|
||||
case F_GETFD:
|
||||
return fd_table.w32_ios[fd]->fd_flags;
|
||||
return 0;
|
||||
case F_SETFD:
|
||||
fd_table.w32_ios[fd]->fd_flags = va_arg(valist, int);
|
||||
return 0;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
debug("ERROR: cmd:%d", cmd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int w32_select(int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const struct timeval *timeout) {
|
||||
int in_set_fds = 0, out_ready_fds = 0, i;
|
||||
fd_set read_ready_fds, write_ready_fds;
|
||||
HANDLE events[32];
|
||||
int num_events = 0;
|
||||
unsigned int time_milliseconds = timeout->tv_sec * 100 + timeout->tv_usec / 1000;
|
||||
ULONGLONG ticks_start = GetTickCount64(), ticks_now;
|
||||
int
|
||||
w32_select(int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const struct timeval *timeout) {
|
||||
ULONGLONG ticks_start = GetTickCount64(), ticks_now;
|
||||
fd_set read_ready_fds, write_ready_fds;
|
||||
HANDLE events[32];
|
||||
int num_events = 0;
|
||||
int in_set_fds = 0, out_ready_fds = 0, i;
|
||||
unsigned int time_milliseconds = timeout->tv_sec * 100 + timeout->tv_usec / 1000;
|
||||
|
||||
errno = 0;
|
||||
memset(&read_ready_fds, 0, sizeof(fd_set));
|
||||
memset(&write_ready_fds, 0, sizeof(fd_set));
|
||||
errno = 0;
|
||||
memset(&read_ready_fds, 0, sizeof(fd_set));
|
||||
memset(&write_ready_fds, 0, sizeof(fd_set));
|
||||
|
||||
if (fds > MAX_FDS ) {
|
||||
errno = EINVAL;
|
||||
debug("ERROR: fds: %d", fds);
|
||||
return -1;
|
||||
}
|
||||
if (fds > MAX_FDS ) {
|
||||
errno = EINVAL;
|
||||
debug("ERROR: fds: %d", fds);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!readfds && !writefds) {
|
||||
errno = EINVAL;
|
||||
debug("ERROR: null fd_sets");
|
||||
return -1;
|
||||
}
|
||||
if (!readfds && !writefds) {
|
||||
errno = EINVAL;
|
||||
debug("ERROR: null fd_sets");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (exceptfds) {
|
||||
errno = EOPNOTSUPP;
|
||||
debug("ERROR: exceptfds not supported");
|
||||
return -1;
|
||||
}
|
||||
if (exceptfds) {
|
||||
errno = EOPNOTSUPP;
|
||||
debug("ERROR: exceptfds not supported");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (readfds) {
|
||||
for (i = 0; i < fds; i++)
|
||||
if (FD_ISSET(i, readfds)) {
|
||||
CHECK_FD(i);
|
||||
in_set_fds++;
|
||||
}
|
||||
}
|
||||
if (readfds) {
|
||||
for (i = 0; i < fds; i++)
|
||||
if (FD_ISSET(i, readfds)) {
|
||||
CHECK_FD(i);
|
||||
in_set_fds++;
|
||||
}
|
||||
}
|
||||
|
||||
if (writefds) {
|
||||
for (i = 0; i < fds; i++)
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
|
||||
*
|
||||
* Definitions for Win32 wrapper functions with POSIX like signatures
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
|
@ -5,80 +11,82 @@
|
|||
#include "debug.h"
|
||||
|
||||
enum w32_io_type {
|
||||
UNKNOWN_FD = 0,
|
||||
SOCK_FD = 1,
|
||||
FILE_FD = 2,
|
||||
PIPE_FD = 3,
|
||||
CONSOLE_FD = 4,
|
||||
STD_IO_FD = 5
|
||||
UNKNOWN_FD = 0,
|
||||
SOCK_FD = 1, /*maps a socket fd*/
|
||||
FILE_FD = 2, /*maps a file fd*/
|
||||
PIPE_FD = 3, /*maps a pipe fd*/
|
||||
STD_IO_FD = 5 /*maps a std fd*/
|
||||
};
|
||||
|
||||
enum w32_io_sock_state {
|
||||
SOCK_INITIALIZED = 0,
|
||||
SOCK_LISTENING = 1,
|
||||
SOCK_ACCEPTED = 2,
|
||||
SOCK_CONNECTING = 3,
|
||||
SOCK_CONNECTED = 4
|
||||
SOCK_INITIALIZED = 0,
|
||||
SOCK_LISTENING = 1, /*listen called on socket*/
|
||||
SOCK_ACCEPTED = 2, /*socket retruned from accept()*/
|
||||
SOCK_CONNECTING = 3, /*connect called on socket, connect is in progress*/
|
||||
SOCK_CONNECTED = 4 /*connect completed on socket*/
|
||||
};
|
||||
|
||||
enum w32_io_pipe_state {
|
||||
PIPE_READ_END = 1,
|
||||
PIPE_WRITE_END = 2
|
||||
PIPE_READ_END = 1, /*read end of a pipe()*/
|
||||
PIPE_WRITE_END = 2 /*write end of a pipe()*/
|
||||
};
|
||||
|
||||
/*
|
||||
* This sturcture encapsulates the state info needed to map a File Descriptor to Win32 Handle
|
||||
*/
|
||||
struct w32_io {
|
||||
OVERLAPPED read_overlapped;
|
||||
OVERLAPPED write_overlapped;
|
||||
struct {
|
||||
//internal buffer details
|
||||
char *buf;
|
||||
DWORD buf_size;
|
||||
OVERLAPPED write_overlapped;
|
||||
struct {
|
||||
/*internal read buffer*/
|
||||
char *buf;
|
||||
DWORD buf_size;
|
||||
DWORD remaining; /*bytes in internal buffer remaining to be read by application*/
|
||||
DWORD completed; /*bytes in internal buffer already read by application*/
|
||||
BOOL pending; /*waiting on a read operation to complete*/
|
||||
DWORD error; /*error reported on async read or accept completion*/
|
||||
}read_details;
|
||||
struct {
|
||||
/*internal write buffer*/
|
||||
char *buf;
|
||||
DWORD buf_size;
|
||||
DWORD remaining; /*bytes in internal buffer remaining to be written to network*/
|
||||
DWORD completed; /*bytes in internal buffer already written to network*/
|
||||
BOOL pending; /*waiting on a write operation to complete*/
|
||||
DWORD error; /*error reported on async write or connect completion*/
|
||||
}write_details;
|
||||
|
||||
//async io details
|
||||
DWORD error; //error reported on async read completion
|
||||
DWORD remaining; //bytes in internal buffer remaining to be read by application
|
||||
DWORD completed; //bytes in internal buffer already read by application
|
||||
BOOL pending; //waiting on async io to complete
|
||||
}read_details;
|
||||
struct {
|
||||
//internal buffer details
|
||||
char* buf;
|
||||
DWORD buf_size;
|
||||
|
||||
//async io details
|
||||
DWORD error; //error reported on async write completion
|
||||
DWORD remaining; //bytes in internal buffer that are not yet successfully written on i/o
|
||||
DWORD completed; //bytes in internal buffer that have been successfully written on i/o
|
||||
BOOL pending; //waiting on async io to complete
|
||||
}write_details;
|
||||
|
||||
//-1 if not indexed
|
||||
int table_index;
|
||||
//handle type
|
||||
enum w32_io_type type;
|
||||
DWORD fd_flags;
|
||||
DWORD fd_status_flags;
|
||||
int table_index; /*index at which this object is stored in fd_table*/
|
||||
enum w32_io_type type; /*hanldle type*/
|
||||
DWORD fd_flags; /*fd flags from POSIX*/
|
||||
DWORD fd_status_flags; /*fd status flags from POSIX*/
|
||||
|
||||
//underlying w32 handle
|
||||
/*underlying w32 handle*/
|
||||
union {
|
||||
SOCKET sock;
|
||||
HANDLE handle;
|
||||
};
|
||||
|
||||
//handle specific internal state context, currently used by sockets
|
||||
struct {
|
||||
enum w32_io_sock_state state;
|
||||
void* context;
|
||||
}internal;
|
||||
/*handle specific internal state context, used by sockets and pipes*/
|
||||
struct {
|
||||
enum w32_io_sock_state state;
|
||||
void* context;
|
||||
}internal;
|
||||
};
|
||||
|
||||
/* Check if the corresponding fd is set blocking */
|
||||
BOOL w32_io_is_blocking(struct w32_io*);
|
||||
/*
|
||||
* Check if io is ready/available. This function is primarily used by select() as it decides on what fds can be set.
|
||||
*/
|
||||
BOOL w32_io_is_io_available(struct w32_io* pio, BOOL rd);
|
||||
|
||||
//signal
|
||||
/*
|
||||
* Main wait routine used by all blocking calls. It wakes up on IO completions, timers, timeouts and signals.
|
||||
*/
|
||||
int wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds);
|
||||
|
||||
//socket io
|
||||
/*POSIX mimic'ing socket API*/
|
||||
int socketio_initialize();
|
||||
int socketio_done();
|
||||
BOOL socketio_is_io_available(struct w32_io* pio, BOOL rd);
|
||||
|
@ -98,7 +106,7 @@ int socketio_shutdown(struct w32_io* pio, int how);
|
|||
int socketio_close(struct w32_io* pio);
|
||||
|
||||
|
||||
//fileio
|
||||
/*POSIX mimic'ing file API*/
|
||||
BOOL fileio_is_io_available(struct w32_io* pio, BOOL rd);
|
||||
int fileio_on_select(struct w32_io* pio, BOOL rd);
|
||||
int fileio_close(struct w32_io* pio);
|
||||
|
|
Loading…
Reference in New Issue