Fixed wstat fix for file permission issue

https://github.com/PowerShell/Win32-OpenSSH/issues/176


1.If there are no sufficient permissions to open a file then _wstat64() is returning file not present but it should return the accessed denied.Fixed this.


2.Code cleanup in the posix compat files to align with the openbsd coding standard.
This commit is contained in:
bagajjal 2017-02-09 11:30:40 -08:00 committed by Manoj Ampalam
parent 73180c876d
commit 4d0c1db166
14 changed files with 1202 additions and 1152 deletions

View File

@ -124,9 +124,8 @@ GetCursorPositionReport()
out = _snprintf_s(cursor_report, sizeof(cursor_report), _TRUNCATE,
CURSOR_REPORT_FORMAT_STRING, ConGetCursorY() + 1, ConGetCursorX() + 1);
if (out > 0) {
if (out > 0)
return cursor_report;
}
return NULL;
}

View File

@ -32,9 +32,10 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <io.h>
#include "w32fd.h"
#include <errno.h>
#include <stddef.h>
#include "w32fd.h"
#include "inc\utf.h"
#include "misc_internal.h"
@ -44,6 +45,14 @@
#define WRITE_BUFFER_SIZE 100*1024
#define errno_from_Win32LastError() errno_from_Win32Error(GetLastError())
struct createFile_flags {
DWORD dwDesiredAccess;
DWORD dwShareMode;
SECURITY_ATTRIBUTES securityAttributes;
DWORD dwCreationDisposition;
DWORD dwFlagsAndAttributes;
};
int termio_initiate_read(struct w32_io* pio);
int termio_initiate_write(struct w32_io* pio, DWORD num_bytes);
@ -73,7 +82,8 @@ static int pipe_counter = 0;
* to it. These handles are associated with read end and write end of the pipe
*/
int
fileio_pipe(struct w32_io* pio[2]) {
fileio_pipe(struct w32_io* pio[2])
{
HANDLE read_handle = INVALID_HANDLE_VALUE, write_handle = INVALID_HANDLE_VALUE;
struct w32_io *pio_read = NULL, *pio_write = NULL;
char pipe_name[PATH_MAX];
@ -158,18 +168,10 @@ error:
return -1;
}
struct createFile_flags {
DWORD dwDesiredAccess;
DWORD dwShareMode;
SECURITY_ATTRIBUTES securityAttributes;
DWORD dwCreationDisposition;
DWORD dwFlagsAndAttributes;
};
/* maps open() file modes and flags to ones needed by CreateFile */
static int
createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags)
{
/* check flags */
int rwflags = flags & 0x3;
int c_s_flags = flags & 0xfffffff0;
@ -185,8 +187,7 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
}
/*only following create and status flags currently supported*/
if (c_s_flags & ~(O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC
| O_EXCL | O_BINARY)) {
if (c_s_flags & ~(O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC | O_EXCL | O_BINARY)) {
debug("open - ERROR: Unsupported flags: %d", flags);
errno = ENOTSUP;
return -1;
@ -240,11 +241,12 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
/* open() implementation. Uses CreateFile to open file, console, device, etc */
struct w32_io*
fileio_open(const char *path_utf8, int flags, int mode) {
fileio_open(const char *path_utf8, int flags, int mode)
{
struct w32_io* pio = NULL;
struct createFile_flags cf_flags;
HANDLE handle;
wchar_t *path_utf16 = NULL;
wchar_t *path_utf16 = NULL;
debug2("open - pathname:%s, flags:%d, mode:%d", path_utf8, flags, mode);
/* check input params*/
@ -254,11 +256,11 @@ struct w32_io*
return NULL;
}
if ((path_utf16 = utf8_to_utf16(path_utf8)) == NULL) {
errno = ENOMEM;
debug("utf8_to_utf16 failed - ERROR:%d", GetLastError());
return NULL;
}
if ((path_utf16 = utf8_to_utf16(path_utf8)) == NULL) {
errno = ENOMEM;
debug("utf8_to_utf16 failed for file:%s error:%d", path_utf8, GetLastError());
return NULL;
}
if (createFile_flags_setup(flags, mode, &cf_flags) == -1)
return NULL;
@ -269,17 +271,17 @@ struct w32_io*
if (handle == INVALID_HANDLE_VALUE) {
errno = errno_from_Win32LastError();
debug("open - CreateFile ERROR:%d", GetLastError());
free(path_utf16);
debug("failed to open file:%s error:%d", path_utf8, GetLastError());
free(path_utf16);
return NULL;
}
free(path_utf16);
free(path_utf16);
pio = (struct w32_io*)malloc(sizeof(struct w32_io));
if (pio == NULL) {
CloseHandle(handle);
errno = ENOMEM;
debug("open - ERROR:%d", errno);
debug("fileio_open(), failed to allocate memory error:%d", errno);
return NULL;
}
@ -292,13 +294,10 @@ struct w32_io*
return pio;
}
VOID CALLBACK ReadCompletionRoutine(
_In_ DWORD dwErrorCode,
_In_ DWORD dwNumberOfBytesTransfered,
_Inout_ LPOVERLAPPED lpOverlapped
) {
struct w32_io* pio =
(struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped));
VOID CALLBACK
ReadCompletionRoutine(_In_ DWORD dwErrorCode, _In_ DWORD dwNumberOfBytesTransfered, _Inout_ LPOVERLAPPED lpOverlapped)
{
struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped));
debug2("ReadCB pio:%p, pending_state:%d, error:%d, received:%d",
pio, pio->read_details.pending, dwErrorCode, dwNumberOfBytesTransfered);
pio->read_details.error = dwErrorCode;
@ -311,7 +310,8 @@ VOID CALLBACK ReadCompletionRoutine(
/* initiate an async read */
/* TODO: make this a void func, store error in context */
int
fileio_ReadFileEx(struct w32_io* pio, unsigned int bytes_requested) {
fileio_ReadFileEx(struct w32_io* pio, unsigned int bytes_requested)
{
debug2("ReadFileEx io:%p", pio);
if (pio->read_details.buf == NULL) {
@ -342,11 +342,11 @@ fileio_ReadFileEx(struct w32_io* pio, unsigned int bytes_requested) {
/* read() implementation */
int
fileio_read(struct w32_io* pio, void *dst, unsigned int max) {
fileio_read(struct w32_io* pio, void *dst, unsigned int max)
{
int bytes_copied;
debug3("read - io:%p remaining:%d", pio, pio->read_details.remaining);
/* if read is pending */
if (pio->read_details.pending) {
if (w32_io_is_blocking(pio)) {
@ -426,11 +426,11 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max) {
return bytes_copied;
}
VOID CALLBACK WriteCompletionRoutine(
_In_ DWORD dwErrorCode,
_In_ DWORD dwNumberOfBytesTransfered,
_Inout_ LPOVERLAPPED lpOverlapped
) {
VOID CALLBACK
WriteCompletionRoutine(_In_ DWORD dwErrorCode,
_In_ DWORD dwNumberOfBytesTransfered,
_Inout_ LPOVERLAPPED lpOverlapped)
{
struct w32_io* pio =
(struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped));
debug2("WriteCB - pio:%p, pending_state:%d, error:%d, transferred:%d of remaining: %d",
@ -450,21 +450,18 @@ VOID CALLBACK WriteCompletionRoutine(
/* write() implementation */
int
fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
fileio_write(struct w32_io* pio, const void *buf, unsigned int max)
{
int bytes_copied;
debug2("write - io:%p", pio);
if (pio->write_details.pending) {
if (w32_io_is_blocking(pio))
{
if (w32_io_is_blocking(pio)) {
debug2("write - io pending, blocking call made, io:%p", pio);
while (pio->write_details.pending) {
while (pio->write_details.pending)
if (wait_for_any_event(NULL, 0, INFINITE) == -1)
return -1;
}
}
else {
} else {
errno = EAGAIN;
debug2("write - IO is already pending, io:%p", pio);
return -1;
@ -502,14 +499,12 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
}
else
return -1;
}
else {
} else {
if (WriteFileEx(WINHANDLE(pio), pio->write_details.buf, bytes_copied,
&pio->write_overlapped, &WriteCompletionRoutine)) {
pio->write_details.pending = TRUE;
pio->write_details.remaining = bytes_copied;
}
else {
} else {
errno = errno_from_Win32LastError();
/* read end of the pipe closed ? */
if ((FILETYPE(pio) == FILE_TYPE_PIPE) && (errno == ERROR_BROKEN_PIPE)) {
@ -531,6 +526,7 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
}
}
}
/* execute APC to give a chance for write to complete */
SleepEx(0, TRUE);
@ -548,8 +544,8 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
/* fstat() implemetation */
int
fileio_fstat(struct w32_io* pio, struct _stat64 *buf) {
fileio_fstat(struct w32_io* pio, struct _stat64 *buf)
{
int fd = _open_osfhandle((intptr_t)pio->handle, 0);
debug2("fstat - pio:%p", pio);
if (fd == -1) {
@ -561,12 +557,23 @@ fileio_fstat(struct w32_io* pio, struct _stat64 *buf) {
}
int
fileio_stat(const char *path, struct _stat64 *buf) {
fileio_stat(const char *path, struct _stat64 *buf)
{
wchar_t wpath[PATH_MAX];
wchar_t* wtmp = NULL;
struct w32_io* pio;
if ((wtmp = utf8_to_utf16(path)) == NULL)
fatal("failed to covert input arguments");
/* If we doesn't have sufficient permissions then _wstat4() is returning
* file not found so added fileio_open() which will set the errorno correctly (access denied)
*/
if (NULL == (pio = fileio_open(path, O_RDONLY, 0)))
return -1;
fileio_close(pio);
wcscpy(&wpath[0], wtmp);
free(wtmp);
@ -574,7 +581,8 @@ fileio_stat(const char *path, struct _stat64 *buf) {
}
long
fileio_lseek(struct w32_io* pio, long offset, int origin) {
fileio_lseek(struct w32_io* pio, long offset, int origin)
{
debug2("lseek - pio:%p", pio);
if (origin != SEEK_SET) {
debug("lseek - ERROR, origin is not supported %d", origin);
@ -589,13 +597,12 @@ fileio_lseek(struct w32_io* pio, long offset, int origin) {
/* fdopen implementation */
FILE*
fileio_fdopen(struct w32_io* pio, const char *mode) {
fileio_fdopen(struct w32_io* pio, const char *mode)
{
int fd_flags = 0;
debug2("fdopen - io:%p", pio);
/* logic below doesn't work with overlapped file HANDLES */
if (mode[1] == '\0') {
switch (*mode) {
case 'r':
@ -611,8 +618,7 @@ fileio_fdopen(struct w32_io* pio, const char *mode) {
debug("fdopen - ERROR unsupported mode %s", mode);
return NULL;
}
}
else {
} else {
errno = ENOTSUP;
debug("fdopen - ERROR unsupported mode %s", mode);
return NULL;
@ -630,8 +636,8 @@ fileio_fdopen(struct w32_io* pio, const char *mode) {
}
void
fileio_on_select(struct w32_io* pio, BOOL rd) {
fileio_on_select(struct w32_io* pio, BOOL rd)
{
if (!rd)
return;
@ -643,8 +649,7 @@ fileio_on_select(struct w32_io* pio, BOOL rd) {
errno = 0;
return;
}
}
else {
} else {
if (fileio_ReadFileEx(pio, INT_MAX) != 0) {
pio->read_details.error = errno;
errno = 0;
@ -653,16 +658,15 @@ fileio_on_select(struct w32_io* pio, BOOL rd) {
}
}
int
fileio_close(struct w32_io* pio) {
fileio_close(struct w32_io* pio)
{
debug2("fileclose - pio:%p", pio);
CancelIo(WINHANDLE(pio));
//let queued APCs (if any) drain
/* let queued APCs (if any) drain */
SleepEx(0, TRUE);
if (pio->type != STD_IO_FD) {//STD handles are never explicitly closed
if (pio->type != STD_IO_FD) { /* STD handles are never explicitly closed */
CloseHandle(WINHANDLE(pio));
if (pio->read_details.buf)
@ -677,14 +681,14 @@ fileio_close(struct w32_io* pio) {
}
BOOL
fileio_is_io_available(struct w32_io* pio, BOOL rd) {
fileio_is_io_available(struct w32_io* pio, BOOL rd)
{
if (rd) {
if (pio->read_details.remaining || pio->read_details.error)
return TRUE;
else
return FALSE;
}
else { //write
} else { /* write */
return (pio->write_details.pending == FALSE) ? TRUE : FALSE;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -31,23 +31,28 @@
#include "inc\sys\types.h"
/* uuidswap.c defs */
void temporarily_use_uid(struct passwd *pw){
return;
void
temporarily_use_uid(struct passwd *pw)
{
return;
}
void
permanently_drop_suid(uid_t uid) {
return;
permanently_drop_suid(uid_t uid)
{
return;
}
void
restore_uid(void) {
return;
restore_uid(void)
{
return;
}
void
permanently_set_uid(struct passwd *pw) {
return;
permanently_set_uid(struct passwd *pw)
{
return;
}
@ -56,74 +61,88 @@ int muxserver_sock = -1;
typedef struct Channel Channel;
unsigned int muxclient_command = 0;
void
muxserver_listen(void){
return;
muxserver_listen(void)
{
return;
}
void
mux_exit_message(Channel *c, int exitval) {
return;
mux_exit_message(Channel *c, int exitval)
{
return;
}
void
mux_tty_alloc_failed(Channel *c) {
return;
mux_tty_alloc_failed(Channel *c)
{
return;
}
void
muxclient(const char *path) {
return;
muxclient(const char *path)
{
return;
}
int
innetgr(const char *netgroup, const char *host,
const char *user, const char *domain) {
return -1;
innetgr(const char *netgroup, const char *host, const char *user, const char *domain)
{
return -1;
}
/* groupaccess.c*/
int
ga_init(const char *user, gid_t base) {
return -1;
ga_init(const char *user, gid_t base)
{
return -1;
}
int
ga_match(char * const *groups, int n) {
return -1;
ga_match(char * const *groups, int n)
{
return -1;
}
int
ga_match_pattern_list(const char *group_pattern) {
return -1;
ga_match_pattern_list(const char *group_pattern)
{
return -1;
}
void
ga_free(void) {
return;
ga_free(void)
{
return;
}
int chroot(const char *path) {
return -1;
int
chroot(const char *path)
{
return -1;
}
int initgroups(const char *user, gid_t group) {
return -1;
int
initgroups(const char *user, gid_t group)
{
return -1;
}
/* sshd.c */
int
setgroups(gid_t group, char* name) {
return 0;
setgroups(gid_t group, char* name)
{
return 0;
}
int
setsid(void) {
return 0;
}
int startup_handler(void) {
setsid(void)
{
return 0;
}
int
startup_handler(void)
{
return 0;
}

View File

@ -36,6 +36,7 @@
#include <DsGetDC.h>
#define SECURITY_WIN32
#include <security.h>
#include "inc\pwd.h"
#include "inc\grp.h"
#include "inc\utf.h"
@ -45,8 +46,10 @@ static struct passwd pw;
static char* pw_shellpath = NULL;
#define SHELL_HOST "\\ssh-shellhost.exe"
int
initialize_pw() {
initialize_pw()
{
if (pw_shellpath == NULL) {
if ((pw_shellpath = malloc(strlen(w32_programdir()) + strlen(SHELL_HOST) + 1)) == NULL)
fatal("initialize_pw - out of memory");
@ -59,6 +62,7 @@ initialize_pw() {
*head = '\0';
}
}
if (pw.pw_shell != pw_shellpath) {
memset(&pw, 0, sizeof(pw));
pw.pw_shell = pw_shellpath;
@ -71,7 +75,8 @@ initialize_pw() {
}
void
reset_pw() {
reset_pw()
{
initialize_pw();
if (pw.pw_name)
free(pw.pw_name);
@ -88,7 +93,8 @@ reset_pw() {
}
static struct passwd*
get_passwd(const char *user_utf8, LPWSTR user_sid) {
get_passwd(const char *user_utf8, LPWSTR user_sid)
{
struct passwd *ret = NULL;
wchar_t *user_utf16 = NULL, *uname_utf16, *udom_utf16, *tmp;
char *uname_utf8 = NULL, *udom_utf8 = NULL, *pw_home_utf8 = NULL, *user_sid_utf8 = NULL;
@ -102,7 +108,7 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) {
errno = 0;
reset_pw();
if ((user_utf16 = utf8_to_utf16(user_utf8) ) == NULL) {
if ((user_utf16 = utf8_to_utf16(user_utf8)) == NULL) {
errno = ENOMEM;
goto done;
}
@ -151,8 +157,8 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) {
/* if one of below fails, set profile path to Windows directory */
if (swprintf(reg_path, PATH_MAX, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", user_sid) == PATH_MAX ||
RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, &reg_key) != 0 ||
RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)profile_home, &tmp_len) != 0)
RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, &reg_key) != 0 ||
RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)profile_home, &tmp_len) != 0)
GetWindowsDirectoryW(profile_home, PATH_MAX);
if ((uname_utf8 = utf16_to_utf8(uname_utf16)) == NULL ||
@ -196,12 +202,14 @@ done:
}
struct passwd*
w32_getpwnam(const char *user_utf8) {
w32_getpwnam(const char *user_utf8)
{
return get_passwd(user_utf8, NULL);
}
struct passwd*
w32_getpwuid(uid_t uid) {
w32_getpwuid(uid_t uid)
{
wchar_t* wuser = NULL;
char* user_utf8 = NULL;
ULONG needed = 0;
@ -216,7 +224,7 @@ struct passwd*
if (GetUserNameExW(NameSamCompatible, NULL, &needed) != 0 ||
(wuser = malloc(needed * sizeof(wchar_t))) == NULL ||
GetUserNameExW(NameSamCompatible, wuser, &needed) == 0 ||
(user_utf8 = utf16_to_utf8(wuser)) == NULL ||
(user_utf8 = utf16_to_utf8(wuser)) == NULL ||
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == FALSE ||
GetTokenInformation(token, TokenUser, NULL, 0, &info_len) == TRUE ||
(info = (TOKEN_USER*)malloc(info_len)) == NULL ||
@ -243,50 +251,62 @@ done:
char *group_from_gid(gid_t gid, int nogroup) {
char *
group_from_gid(gid_t gid, int nogroup)
{
return "-";
}
char *user_from_uid(uid_t uid, int nouser) {
char *
user_from_uid(uid_t uid, int nouser)
{
return "-";
}
uid_t
getuid(void) {
getuid(void)
{
return 0;
}
gid_t
getgid(void) {
getgid(void)
{
return 0;
}
uid_t
geteuid(void) {
geteuid(void)
{
return 0;
}
gid_t
getegid(void) {
getegid(void)
{
return 0;
}
int
setuid(uid_t uid) {
setuid(uid_t uid)
{
return 0;
}
int
setgid(gid_t gid) {
setgid(gid_t gid)
{
return 0;
}
int
seteuid(uid_t uid) {
seteuid(uid_t uid)
{
return 0;
}
int
setegid(gid_t gid) {
setegid(gid_t gid)
{
return 0;
}

View File

@ -28,10 +28,11 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "w32fd.h"
#include <errno.h>
#include "w32fd.h"
#include "signal_internal.h"
#include "inc\signal.h"
#undef signal
#undef raise
#undef SIGINT
@ -48,30 +49,27 @@
/* pending signals to be processed */
sigset_t pending_signals;
/* signal handler table*/
sighandler_t sig_handlers[W32_SIGMAX];
extern struct _children children;
static VOID CALLBACK
sigint_APCProc(
_In_ ULONG_PTR dwParam
) {
sigint_APCProc(_In_ ULONG_PTR dwParam)
{
debug3("SIGINT APCProc()");
sigaddset(&pending_signals, W32_SIGINT);
}
static VOID CALLBACK
sigterm_APCProc(
_In_ ULONG_PTR dwParam
) {
sigterm_APCProc(_In_ ULONG_PTR dwParam)
{
debug3("SIGTERM APCProc()");
sigaddset(&pending_signals, W32_SIGTERM);
}
static VOID CALLBACK
sigtstp_APCProc(
_In_ ULONG_PTR dwParam
) {
sigtstp_APCProc(_In_ ULONG_PTR dwParam)
{
debug3("SIGTSTP APCProc()");
sigaddset(&pending_signals, W32_SIGTSTP);
}
@ -100,35 +98,31 @@ native_sig_handler(DWORD dwCtrlType)
}
static VOID CALLBACK
sigwinch_APCProc(
_In_ ULONG_PTR dwParam
) {
sigwinch_APCProc(_In_ ULONG_PTR dwParam)
{
debug3("SIGTERM APCProc()");
sigaddset(&pending_signals, W32_SIGWINCH);
}
void
queue_terminal_window_change_event() {
queue_terminal_window_change_event()
{
QueueUserAPC(sigwinch_APCProc, main_thread, (ULONG_PTR)NULL);
}
void
sw_init_signal_handler_table() {
int i;
sw_init_signal_handler_table()
{
SetConsoleCtrlHandler(native_sig_handler, TRUE);
sigemptyset(&pending_signals);
/* this automatically sets all to W32_SIG_DFL (0)*/
memset(sig_handlers, 0, sizeof(sig_handlers));
}
extern struct _children children;
sighandler_t
w32_signal(int signum, sighandler_t handler) {
w32_signal(int signum, sighandler_t handler)
{
sighandler_t prev;
debug2("signal() sig:%d, handler:%p", signum, handler);
if (signum >= W32_SIGMAX) {
errno = EINVAL;
@ -141,7 +135,8 @@ w32_signal(int signum, sighandler_t handler) {
}
int
w32_sigprocmask(int how, const sigset_t *set, sigset_t *oldset) {
w32_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
{
/* this is only used by sshd to block SIGCHLD while doing waitpid() */
/* our implementation of waidpid() is never interrupted, so no need to implement this for now*/
debug3("sigprocmask() how:%d");
@ -151,7 +146,8 @@ w32_sigprocmask(int how, const sigset_t *set, sigset_t *oldset) {
int
w32_raise(int sig) {
w32_raise(int sig)
{
debug("raise sig:%d", sig);
if (sig == W32_SIGSEGV)
return raise(SIGSEGV); /* raise native exception handler*/
@ -185,7 +181,8 @@ w32_raise(int sig) {
/* processes pending signals, return -1 and errno=EINTR if any are processed*/
static int
sw_process_pending_signals() {
sw_process_pending_signals()
{
sigset_t pending_tmp = pending_signals;
BOOL sig_int = FALSE; /* has any signal actually interrupted */
@ -266,55 +263,49 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
debug3("wait() on %d events and %d children", num_events, live_children);
/* TODO - implement signal catching and handling */
if (num_all_events) {
DWORD ret = WaitForMultipleObjectsEx(num_all_events, all_events, FALSE,
milli_seconds, TRUE);
DWORD ret = WaitForMultipleObjectsEx(num_all_events, all_events, FALSE, milli_seconds, TRUE);
if ((ret >= WAIT_OBJECT_0) && (ret <= WAIT_OBJECT_0 + num_all_events - 1)) {
//woken up by event signalled
/* is this due to a child process going down*/
/* woken up by event signalled
* is this due to a child process going down
*/
if (live_children && ((ret - WAIT_OBJECT_0) < live_children)) {
sigaddset(&pending_signals, W32_SIGCHLD);
sw_child_to_zombie(ret - WAIT_OBJECT_0);
}
}
else if (ret == WAIT_IO_COMPLETION) {
} else if (ret == WAIT_IO_COMPLETION) {
/* APC processed due to IO or signal*/
}
else if (ret == WAIT_TIMEOUT) {
} else if (ret == WAIT_TIMEOUT) {
/* timed out */
return 0;
}
/* some other error*/
else {
} else { /* some other error*/
errno = EOTHER;
debug("ERROR: unxpected wait end: %d", ret);
return -1;
}
}
else {
} else {
DWORD ret = SleepEx(milli_seconds, TRUE);
if (ret == WAIT_IO_COMPLETION) {
/* APC processed due to IO or signal*/
}
else if (ret == 0) {
} else if (ret == 0) {
/* timed out */
return 0;
}
else { //some other error
} else { /* some other error */
errno = EOTHER;
debug("ERROR: unxpected SleepEx error: %d", ret);
return -1;
}
}
if (pending_signals) {
if (pending_signals)
return sw_process_pending_signals();
}
return 0;
}
int
sw_initialize() {
sw_initialize()
{
memset(&children, 0, sizeof(children));
sw_init_signal_handler_table();
if (sw_init_timer() != 0)

View File

@ -35,16 +35,16 @@ struct _timer_info timer_info;
extern sigset_t pending_signals;
static VOID CALLBACK
sigalrm_APC(
_In_opt_ LPVOID lpArgToCompletionRoutine,
_In_ DWORD dwTimerLowValue,
_In_ DWORD dwTimerHighValue
) {
sigalrm_APC(_In_opt_ LPVOID lpArgToCompletionRoutine,
_In_ DWORD dwTimerLowValue,
_In_ DWORD dwTimerHighValue)
{
sigaddset(&pending_signals, W32_SIGALRM);
}
unsigned int
w32_alarm(unsigned int sec) {
w32_alarm(unsigned int sec)
{
LARGE_INTEGER due;
ULONGLONG sec_passed;
int ret = 0;
@ -59,7 +59,7 @@ w32_alarm(unsigned int sec) {
return 0;
}
due.QuadPart = -10000000LL; //1 sec in 100 nanosec intervals
due.QuadPart = -10000000LL; /* 1 sec in 100 nanosec intervals */
due.QuadPart *= sec;
/* this call resets the timer if it is already active */
if (!SetWaitableTimer(timer_info.timer, &due, 0, sigalrm_APC, NULL, FALSE)) {
@ -75,16 +75,19 @@ w32_alarm(unsigned int sec) {
}
timer_info.ticks_at_start = GetTickCount64();
timer_info.run_time_sec = sec;
return ret;
}
int
sw_init_timer() {
sw_init_timer()
{
memset(&timer_info, 0, sizeof(timer_info));
timer_info.timer = CreateWaitableTimer(NULL, TRUE, NULL);
if (timer_info.timer == NULL) {
errno = ENOMEM;
return -1;
}
return 0;
}

View File

@ -34,7 +34,8 @@
struct _children children;
int
register_child(HANDLE child, DWORD pid) {
register_child(HANDLE child, DWORD pid)
{
DWORD first_zombie_index;
debug("Register child %p pid %d, %d zombies of %d", child, pid,
@ -43,6 +44,7 @@ register_child(HANDLE child, DWORD pid) {
errno = ENOMEM;
return -1;
}
if (children.num_zombies) {
first_zombie_index = children.num_children - children.num_zombies;
children.handles[children.num_children] = children.handles[first_zombie_index];
@ -50,26 +52,23 @@ register_child(HANDLE child, DWORD pid) {
children.handles[first_zombie_index] = child;
children.process_id[first_zombie_index] = pid;
}
else {
} else {
children.handles[children.num_children] = child;
children.process_id[children.num_children] = pid;
}
children.num_children++;
return 0;
}
int
sw_remove_child_at_index(DWORD index) {
sw_remove_child_at_index(DWORD index)
{
DWORD last_non_zombie;
debug("Unregister child at index %d, %d zombies of %d", index,
children.num_zombies, children.num_children);
if ((index >= children.num_children)
|| (children.num_children == 0)) {
if ((index >= children.num_children) || (children.num_children == 0)) {
errno = EINVAL;
return -1;
}
@ -78,15 +77,13 @@ sw_remove_child_at_index(DWORD index) {
if (children.num_zombies == 0) {
children.handles[index] = children.handles[children.num_children - 1];
children.process_id[index] = children.process_id[children.num_children - 1];
}
else {
} else {
/* if its a zombie */
if (index >= (children.num_children - children.num_zombies)) {
children.handles[index] = children.handles[children.num_children - 1];
children.process_id[index] = children.process_id[children.num_children - 1];
children.num_zombies--;
}
else {
} else {
last_non_zombie = children.num_children - children.num_zombies - 1;
children.handles[index] = children.handles[last_non_zombie];
children.process_id[index] = children.process_id[last_non_zombie];
@ -101,7 +98,8 @@ sw_remove_child_at_index(DWORD index) {
}
int
sw_child_to_zombie(DWORD index) {
sw_child_to_zombie(DWORD index)
{
DWORD last_non_zombie, zombie_pid;
HANDLE zombie_handle;
@ -114,7 +112,6 @@ sw_child_to_zombie(DWORD index) {
}
last_non_zombie = children.num_children - children.num_zombies - 1;
if (last_non_zombie != index) {
/* swap */
zombie_pid = children.process_id[index];
@ -129,7 +126,8 @@ sw_child_to_zombie(DWORD index) {
}
int
w32_kill(int pid, int sig) {
w32_kill(int pid, int sig)
{
int child_index, i;
if (pid == GetCurrentProcessId())
return w32_raise(sig);
@ -148,7 +146,9 @@ w32_kill(int pid, int sig) {
}
int waitpid(int pid, int *status, int options) {
int
waitpid(int pid, int *status, int options)
{
DWORD index, ret, ret_id, exit_code, timeout = 0;
HANDLE process = NULL;
@ -230,20 +230,19 @@ int waitpid(int pid, int *status, int options) {
if (status)
*status = exit_code;
return ret_id;
}
else if (ret == WAIT_TIMEOUT) {
} else if (ret == WAIT_TIMEOUT) {
/* TODO - assert that WNOHANG was specified*/
return 0;
}
DebugBreak();//fatal
DebugBreak(); /* fatal */
return -1;
}
void
sw_cleanup_child_zombies() {
sw_cleanup_child_zombies()
{
int pid = 1;
while (pid > 0) {
while (pid > 0)
pid = waitpid(-1, NULL, WNOHANG);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -67,7 +67,8 @@ void fd_table_set(struct w32_io* pio, int index);
/* initializes mapping table*/
static int
fd_table_initialize() {
fd_table_initialize()
{
memset(&fd_table, 0, sizeof(fd_table));
memset(&w32_io_stdin, 0, sizeof(w32_io_stdin));
w32_io_stdin.std_handle = STD_INPUT_HANDLE;
@ -86,7 +87,8 @@ fd_table_initialize() {
/* get a free slot in mapping table with least index*/
static int
fd_table_get_min_index() {
fd_table_get_min_index()
{
int min_index = 0;
unsigned char* bitmap = fd_table.occupied.bitmap;
unsigned char tmp;
@ -102,9 +104,7 @@ fd_table_get_min_index() {
}
tmp = *bitmap;
while (tmp & 0x80)
{
while (tmp & 0x80) {
tmp <<= 1;
min_index++;
}
@ -114,7 +114,8 @@ fd_table_get_min_index() {
/* maps pio to fd (specified by index)*/
static void
fd_table_set(struct w32_io* pio, int index) {
fd_table_set(struct w32_io* pio, int index)
{
fd_table.w32_ios[index] = pio;
pio->table_index = index;
assert(pio->type != UNKNOWN_FD);
@ -131,19 +132,20 @@ fd_table_clear(int index)
}
void
w32posix_initialize() {
if ((fd_table_initialize() != 0)
|| (socketio_initialize() != 0))
w32posix_initialize()
{
if ((fd_table_initialize() != 0) || (socketio_initialize() != 0))
DebugBreak();
main_thread = OpenThread(THREAD_SET_CONTEXT | SYNCHRONIZE, FALSE, GetCurrentThreadId());
if ((main_thread == NULL) || (sw_initialize() != 0) || w32_programdir() == NULL) {
DebugBreak();
fatal("failed to initialize w32posix wrapper");
}
if ((main_thread == NULL) || (sw_initialize() != 0) || w32_programdir() == NULL) {
DebugBreak();
fatal("failed to initialize w32posix wrapper");
}
}
void
w32posix_done() {
w32posix_done()
{
socketio_done();
}
@ -159,7 +161,8 @@ w32_io_is_blocking(struct w32_io* pio)
* as it decides on what fds can be set.
*/
BOOL
w32_io_is_io_available(struct w32_io* pio, BOOL rd) {
w32_io_is_io_available(struct w32_io* pio, BOOL rd)
{
if (pio->type == SOCK_FD)
return socketio_is_io_available(pio, rd);
else
@ -195,7 +198,8 @@ w32_io_on_select(struct w32_io* pio, BOOL rd)
} while (0)
int
w32_socket(int domain, int type, int protocol) {
w32_socket(int domain, int type, int protocol)
{
int min_index = fd_table_get_min_index();
struct w32_io* pio = NULL;
@ -216,7 +220,6 @@ w32_socket(int domain, int type, int protocol) {
int
w32_accept(int fd, struct sockaddr* addr, int* addrlen)
{
CHECK_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
int min_index = fd_table_get_min_index();
@ -236,72 +239,72 @@ w32_accept(int fd, struct sockaddr* addr, int* addrlen)
}
int
w32_setsockopt(int fd, int level, int optname, const void* optval, int optlen) {
w32_setsockopt(int fd, int level, int optname, const void* optval, int optlen)
{
CHECK_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
return socketio_setsockopt(fd_table.w32_ios[fd], level, optname, (const char*)optval, optlen);
}
int
w32_getsockopt(int fd, int level, int optname, void* optval, int* optlen) {
w32_getsockopt(int fd, int level, int optname, void* optval, int* optlen)
{
CHECK_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
return socketio_getsockopt(fd_table.w32_ios[fd], level, optname, (char*)optval, optlen);
}
int
w32_getsockname(int fd, struct sockaddr* name, int* namelen) {
w32_getsockname(int fd, struct sockaddr* name, int* namelen)
{
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) {
w32_getpeername(int fd, struct sockaddr* name, int* namelen)
{
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) {
w32_listen(int fd, int backlog)
{
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) {
w32_bind(int fd, const struct sockaddr *name, int namelen)
{
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) {
w32_connect(int fd, const struct sockaddr* name, int namelen)
{
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) {
w32_recv(int fd, void *buf, size_t len, int flags)
{
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) {
w32_send(int fd, const void *buf, size_t len, int flags)
{
CHECK_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
return socketio_send(fd_table.w32_ios[fd], buf, len, flags);
@ -309,7 +312,8 @@ w32_send(int fd, const void *buf, size_t len, int flags) {
int
w32_shutdown(int fd, int how) {
w32_shutdown(int fd, int how)
{
debug2("shutdown - fd:%d how:%d", fd, how);
CHECK_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
@ -317,15 +321,17 @@ w32_shutdown(int fd, int how) {
}
int
w32_socketpair(int domain, int type, int protocol, int sv[2]) {
errno = ENOTSUP;
w32_socketpair(int domain, int type, int protocol, int sv[2])
{
errno = ENOTSUP;
debug("socketpair - ERROR not supported");
return -1;
}
int
w32_pipe(int *pfds) {
w32_pipe(int *pfds)
{
int read_index, write_index;
struct w32_io* pio[2];
@ -351,12 +357,14 @@ w32_pipe(int *pfds) {
pfds[0] = read_index;
pfds[1] = write_index;
debug("pipe - r-h:%d,io:%p,fd:%d w-h:%d,io:%p,fd:%d",
pio[0]->handle, pio[0], read_index, pio[1]->handle, pio[1], write_index);
pio[0]->handle, pio[0], read_index, pio[1]->handle, pio[1], write_index);
return 0;
}
int
w32_open(const char *pathname, int flags, ...) {
w32_open(const char *pathname, int flags, ...)
{
int min_index = fd_table_get_min_index();
struct w32_io* pio;
@ -376,9 +384,9 @@ w32_open(const char *pathname, int flags, ...) {
}
int
w32_read(int fd, void *dst, size_t max) {
w32_read(int fd, void *dst, size_t max)
{
CHECK_FD(fd);
if (fd_table.w32_ios[fd]->type == SOCK_FD)
return socketio_recv(fd_table.w32_ios[fd], dst, max, 0);
@ -386,7 +394,8 @@ w32_read(int fd, void *dst, size_t max) {
}
int
w32_write(int fd, const void *buf, unsigned int max) {
w32_write(int fd, const void *buf, unsigned int max)
{
CHECK_FD(fd);
if (fd_table.w32_ios[fd]->type == SOCK_FD)
@ -395,37 +404,39 @@ w32_write(int fd, const void *buf, unsigned int max) {
return fileio_write(fd_table.w32_ios[fd], buf, max);
}
int w32_writev(int fd, const struct iovec *iov, int iovcnt) {
int written = 0;
int i = 0;
int
w32_writev(int fd, const struct iovec *iov, int iovcnt)
{
int written = 0;
int i = 0;
CHECK_FD(fd);
CHECK_FD(fd);
for (i = 0; i < iovcnt; i++) {
int ret = w32_write(fd, iov[i].iov_base, iov[i].iov_len);
if (ret > 0)
written += ret;
}
for (i = 0; i < iovcnt; i++) {
int ret = w32_write(fd, iov[i].iov_base, iov[i].iov_len);
if (ret > 0) {
written += ret;
}
}
return written;
return written;
}
int
w32_fstat(int fd, struct w32_stat *buf) {
w32_fstat(int fd, struct w32_stat *buf)
{
CHECK_FD(fd);
return fileio_fstat(fd_table.w32_ios[fd], (struct _stat64*)buf);
}
long
w32_lseek(int fd, long offset, int origin) {
w32_lseek(int fd, long offset, int origin)
{
CHECK_FD(fd);
return fileio_lseek(fd_table.w32_ios[fd], offset, origin);
}
int
w32_isatty(int fd) {
w32_isatty(int fd)
{
struct w32_io* pio;
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
errno = EBADF;
@ -433,7 +444,6 @@ w32_isatty(int fd) {
}
pio = fd_table.w32_ios[fd];
if (FILETYPE(pio) == FILE_TYPE_CHAR)
return 1;
else {
@ -443,7 +453,8 @@ w32_isatty(int fd) {
}
FILE*
w32_fdopen(int fd, const char *mode) {
w32_fdopen(int fd, const char *mode)
{
errno = 0;
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
errno = EBADF;
@ -454,13 +465,13 @@ w32_fdopen(int fd, const char *mode) {
}
int
w32_close(int fd) {
w32_close(int fd)
{
struct w32_io* pio;
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
errno = EBADF;
return -1;
}
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
errno = EBADF;
return -1;
}
pio = fd_table.w32_ios[fd];
@ -480,7 +491,8 @@ w32_close(int fd) {
}
static int
w32_io_process_fd_flags(struct w32_io* pio, int flags) {
w32_io_process_fd_flags(struct w32_io* pio, int flags)
{
DWORD shi_flags;
if (flags & ~FD_CLOEXEC) {
debug("fcntl - ERROR unsupported flags %d, io:%p", flags, pio);
@ -502,42 +514,43 @@ w32_io_process_fd_flags(struct w32_io* pio, int flags) {
}
int
w32_fcntl(int fd, int cmd, ... /* arg */) {
w32_fcntl(int fd, int cmd, ... /* arg */)
{
va_list valist;
va_start(valist, cmd);
int ret = 0;
int ret = 0;
CHECK_FD(fd);
switch (cmd) {
case F_GETFL:
ret = fd_table.w32_ios[fd]->fd_status_flags;
break;
break;
case F_SETFL:
fd_table.w32_ios[fd]->fd_status_flags = va_arg(valist, int);
ret = 0;
break;
break;
case F_GETFD:
ret = fd_table.w32_ios[fd]->fd_flags;
break;
break;
case F_SETFD:
ret = w32_io_process_fd_flags(fd_table.w32_ios[fd], va_arg(valist, int));
break;
ret = w32_io_process_fd_flags(fd_table.w32_ios[fd], va_arg(valist, int));
break;
default:
errno = EINVAL;
debug("fcntl - ERROR not supported cmd:%d", cmd);
ret = -1;
break;
}
break;
}
va_end(valist);
return ret;
va_end(valist);
return ret;
}
#define SELECT_EVENT_LIMIT 32
int
w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* exceptfds,
const struct timeval *timeout) {
w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* exceptfds, const struct timeval *timeout)
{
ULONGLONG ticks_start = GetTickCount64(), ticks_spent;
w32_fd_set read_ready_fds, write_ready_fds;
HANDLE events[SELECT_EVENT_LIMIT];
@ -566,12 +579,12 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
}
/* TODO - see if this needs to be supported */
//if (exceptfds) {
// errno = EOPNOTSUPP;
// debug("select - ERROR: exceptfds not supported");
// DebugBreak();
// return -1;
//}
/* if (exceptfds) {
errno = EOPNOTSUPP;
debug("select - ERROR: exceptfds not supported");
DebugBreak();
return -1;
} */
if (readfds) {
for (i = 0; i < fds; i++)
@ -602,11 +615,10 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
* that select needs to listen on
*/
for (int i = 0; i < fds; i++) {
if (readfds && FD_ISSET(i, readfds)) {
w32_io_on_select(fd_table.w32_ios[i], TRUE);
if ((fd_table.w32_ios[i]->type == SOCK_FD)
&& (fd_table.w32_ios[i]->internal.state == SOCK_LISTENING)) {
if ((fd_table.w32_ios[i]->type == SOCK_FD) &&
(fd_table.w32_ios[i]->internal.state == SOCK_LISTENING)) {
if (num_events == SELECT_EVENT_LIMIT) {
debug("select - ERROR: max #events breach");
errno = ENOMEM;
@ -618,8 +630,8 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
if (writefds && FD_ISSET(i, writefds)) {
w32_io_on_select(fd_table.w32_ios[i], FALSE);
if ((fd_table.w32_ios[i]->type == SOCK_FD)
&& (fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)) {
if ((fd_table.w32_ios[i]->type == SOCK_FD) &&
(fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)) {
if (num_events == SELECT_EVENT_LIMIT) {
debug("select - ERROR: max #events reached for select");
errno = ENOMEM;
@ -636,7 +648,6 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
/* see if any io is ready */
for (i = 0; i < fds; i++) {
if (readfds && FD_ISSET(i, readfds)) {
if (w32_io_is_io_available(fd_table.w32_ios[i], TRUE)) {
FD_SET(i, &read_ready_fds);
@ -677,7 +688,6 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
/* check on fd status */
out_ready_fds = 0;
for (int i = 0; i < fds; i++) {
if (readfds && FD_ISSET(i, readfds)) {
if (w32_io_is_io_available(fd_table.w32_ios[i], TRUE)) {
FD_SET(i, &read_ready_fds);
@ -695,7 +705,6 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
if (out_ready_fds == 0)
debug3("select - wait ended without any IO completion, looping again");
}
/* clear out fds that are not ready yet */
@ -709,8 +718,8 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
if (FD_ISSET(i, writefds)) {
if (FD_ISSET(i, &write_ready_fds)) {
/* for connect() completed sockets finish WSA connect process*/
if ((fd_table.w32_ios[i]->type == SOCK_FD)
&& ((fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)))
if ((fd_table.w32_ios[i]->type == SOCK_FD) &&
((fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)))
if (socketio_finish_connect(fd_table.w32_ios[i]) != 0) {
/* finalizeing connect failed - recored error */
/* error gets picked up later recv and/or send*/
@ -730,7 +739,8 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
}
int
w32_dup(int oldfd) {
w32_dup(int oldfd)
{
int min_index;
struct w32_io* pio;
HANDLE src, target;
@ -773,7 +783,8 @@ w32_dup(int oldfd) {
}
int
w32_dup2(int oldfd, int newfd) {
w32_dup2(int oldfd, int newfd)
{
CHECK_FD(oldfd);
errno = EOPNOTSUPP;
debug("dup2 - ERROR: not implemented yet");
@ -781,14 +792,17 @@ w32_dup2(int oldfd, int newfd) {
}
HANDLE
w32_fd_to_handle(int fd) {
w32_fd_to_handle(int fd)
{
HANDLE h = fd_table.w32_ios[fd]->handle;
if (fd <= STDERR_FILENO)
h = GetStdHandle(fd_table.w32_ios[fd]->std_handle);
return h;
}
int w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock) {
int
w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock)
{
int min_index = fd_table_get_min_index();
struct w32_io* pio;
@ -803,7 +817,7 @@ int w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock) {
}
memset(pio, 0, sizeof(struct w32_io));
pio->type = is_sock? SOCK_FD : NONSOCK_FD;
pio->type = is_sock ? SOCK_FD : NONSOCK_FD;
pio->handle = h;
fd_table_set(pio, min_index);
return min_index;
@ -811,9 +825,9 @@ int w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock) {
int
w32_ftruncate(int fd, off_t length) {
w32_ftruncate(int fd, off_t length)
{
LARGE_INTEGER new_postion;
CHECK_FD(fd);
new_postion.QuadPart = length;
@ -826,8 +840,8 @@ w32_ftruncate(int fd, off_t length) {
}
int
w32_fsync(int fd) {
w32_fsync(int fd)
{
CHECK_FD(fd);
return FlushFileBuffers(w32_fd_to_handle(fd));
}

View File

@ -1,7 +1,33 @@
/*
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
*
* Definitions for Win32 wrapper functions with POSIX like signatures
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
*
* Definitions for Win32 wrapper functions with POSIX like signatures
*
* Copyright (c) 2015 Microsoft Corp.
* All rights reserved
*
* Microsoft openssh win32 port
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
@ -32,24 +58,18 @@ struct w32_io {
OVERLAPPED read_overlapped;
OVERLAPPED write_overlapped;
struct {
/*internal read buffer*/
char *buf;
char *buf; /*internal read buffer*/
DWORD buf_size;
/*bytes in internal buffer remaining to be read by application*/
DWORD remaining;
/*bytes in internal buffer already read by application*/
DWORD completed;
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;
char *buf; /*internal write buffer*/
DWORD buf_size;
/*bytes in internal buffer remaining to be written to network*/
DWORD remaining;
/*bytes in internal buffer already written to network*/
DWORD completed;
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;
@ -89,10 +109,8 @@ BOOL socketio_is_io_available(struct w32_io* pio, BOOL rd);
void socketio_on_select(struct w32_io* pio, BOOL rd);
struct w32_io* socketio_socket(int domain, int type, int protocol);
struct w32_io* socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen);
int socketio_setsockopt(struct w32_io* pio, int level, int optname,
const char* optval, int optlen);
int socketio_getsockopt(struct w32_io* pio, int level, int optname,
char* optval, int* optlen);
int socketio_setsockopt(struct w32_io* pio, int level, int optname, const char* optval, int optlen);
int socketio_getsockopt(struct w32_io* pio, int level, int optname, char* optval, int* optlen);
int socketio_getsockname(struct w32_io* pio, struct sockaddr* name, int* namelen);
int socketio_getpeername(struct w32_io* pio, struct sockaddr* name, int* namelen);
int socketio_listen(struct w32_io* pio, int backlog);
@ -145,16 +163,16 @@ int termio_close(struct w32_io* pio);
/* If O_CREAT and O_EXCL are set, open() shall fail if the file exists */
/* #define O_EXCL 0x400 */
/* #define O_BINARY 0x8000 //Gives raw data (while O_TEXT normalises line endings */
// open modes
/* open modes */
#ifndef S_IRUSR
#define S_IRUSR 00400 //user has read permission
#endif // ! S_IRUSR
#define S_IRUSR 00400 /* user has read permission */
#endif /* ! S_IRUSR */
#ifndef S_IWUSR
#define S_IWUSR 00200 //user has write permission
#define S_IWUSR 00200 /* user has write permission */
#endif
#ifndef S_IRGRP
#define S_IRGRP 00040 //group has read permission
#define S_IRGRP 00040 /* group has read permission */
#endif
#ifndef S_IROTH
#define S_IROTH 00004 //others have read permission
#define S_IROTH 00004 /* others have read permission */
#endif

View File

@ -27,11 +27,11 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <Windows.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "inc\syslog.h"
#include "misc_internal.h"
@ -39,14 +39,15 @@
static int logfd = -1;
void
openlog(char *ident, unsigned int option, int facility) {
openlog(char *ident, unsigned int option, int facility)
{
if (logfd != -1 || ident == NULL)
return;
wchar_t path[PATH_MAX], log_file[PATH_MAX + 12];
if (GetModuleFileNameW(NULL, path, PATH_MAX) == 0)
return;
path[PATH_MAX - 1] = '\0';
/* split path root and module */
@ -64,20 +65,20 @@ openlog(char *ident, unsigned int option, int facility) {
memcpy(p, L"log\0", 8);
}
logfd = _wopen(log_file, O_WRONLY | O_CREAT | O_APPEND,
S_IREAD | S_IWRITE);
logfd = _wopen(log_file, O_WRONLY | O_CREAT | O_APPEND, S_IREAD | S_IWRITE);
if (logfd != -1)
SetHandleInformation((HANDLE)_get_osfhandle(logfd),
HANDLE_FLAG_INHERIT, 0);
SetHandleInformation((HANDLE)_get_osfhandle(logfd), HANDLE_FLAG_INHERIT, 0);
}
void
closelog(void) {
closelog(void)
{
/*NOOP*/
}
void
syslog(int priority, const char *format, const char *formatBuffer) {
syslog(int priority, const char *format, const char *formatBuffer)
{
char msgbufTimestamp[MSGBUFSIZ];
SYSTEMTIME st;

View File

@ -1,19 +1,43 @@
// win32_dirent.c
// directory entry functions in Windows platform like Ubix/Linux
// opendir(), readdir(), closedir().
/*
* Copyright (c) 2016 Microsoft Corp.
* All rights reserved
*
* directory entry functions in Windows platform like Ubix/Linux
* opendir(), readdir(), closedir().
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "inc\utf.h"
#include "inc\utf.h"
#include "inc\dirent.h"
#include "inc\libgen.h"
#include "misc_internal.h"
struct DIR_ {
intptr_t hFile;
struct _wfinddata_t c_file;
@ -22,7 +46,8 @@ struct DIR_ {
/* Open a directory stream on NAME.
Return a DIR stream on the directory, or NULL if it could not be opened. */
DIR * opendir(const char *name)
DIR *
opendir(const char *name)
{
struct _wfinddata_t c_file;
intptr_t hFile;
@ -36,7 +61,7 @@ DIR * opendir(const char *name)
return NULL;
}
// add *.* for Windows _findfirst() search pattern
/* add *.* for Windows _findfirst() search pattern */
swprintf_s(searchstr, PATH_MAX, L"%s\\*.*", wname);
free(wname);
@ -54,28 +79,30 @@ DIR * opendir(const char *name)
memcpy(&pdir->c_file, &c_file, sizeof(c_file));
pdir->first = 1;
return pdir ;
return pdir;
}
}
/* Close the directory stream DIRP.
Return 0 if successful, -1 if not. */
int closedir(DIR *dirp)
int
closedir(DIR *dirp)
{
if ( dirp && (dirp->hFile) ) {
_findclose( dirp->hFile );
dirp->hFile = 0;
free (dirp);
}
if (dirp && (dirp->hFile)) {
_findclose(dirp->hFile);
dirp->hFile = 0;
free(dirp);
}
return 0;
return 0;
}
/* Read a directory entry from DIRP.
Return a pointer to a `struct dirent' describing the entry,
or NULL for EOF or error. The storage returned may be overwritten
by a later readdir call on the same DIR stream. */
struct dirent *readdir(void *avp)
struct dirent *
readdir(void *avp)
{
static struct dirent pdirentry;
struct _wfinddata_t c_file;
@ -86,11 +113,10 @@ struct dirent *readdir(void *avp)
if (dirp->first) {
memcpy(&c_file, &dirp->c_file, sizeof(c_file));
dirp->first = 0;
}
else if (_wfindnext(dirp->hFile, &c_file) != 0)
} else if (_wfindnext(dirp->hFile, &c_file) != 0)
return NULL;
if (wcscmp(c_file.name, L".") == 0 || wcscmp(c_file.name, L"..") == 0 )
if (wcscmp(c_file.name, L".") == 0 || wcscmp(c_file.name, L"..") == 0)
continue;
if ((tmp = utf16_to_utf8(c_file.name)) == NULL) {
@ -101,13 +127,14 @@ struct dirent *readdir(void *avp)
strncpy(pdirentry.d_name, tmp, strlen(tmp) + 1);
free(tmp);
pdirentry.d_ino = 1; // a fictious one like UNIX to say it is nonzero
return &pdirentry ;
}
pdirentry.d_ino = 1; /* a fictious one like UNIX to say it is nonzero */
return &pdirentry;
}
}
// return last part of a path. The last path being a filename.
char *basename(char *path)
/* return last part of a path. The last path being a filename */
char *
basename(char *path)
{
char *pdest;
@ -115,10 +142,10 @@ char *basename(char *path)
return ".";
pdest = strrchr(path, '/');
if (pdest)
return (pdest+1);
return (pdest + 1);
pdest = strrchr(path, '\\');
if (pdest)
return (pdest+1);
return (pdest + 1);
return path; // path does not have a slash
return path; /* path does not have a slash */
}

View File

@ -32,33 +32,38 @@
#include "inc\zlib.h"
int
deflateEnd(z_streamp strm) {
deflateEnd(z_streamp strm)
{
return Z_DATA_ERROR;
}
int
inflateEnd(z_streamp strm) {
inflateEnd(z_streamp strm)
{
return Z_DATA_ERROR;
}
int
deflateInit(z_streamp strm, int level) {
deflateInit(z_streamp strm, int level)
{
return Z_DATA_ERROR;
}
int
inflateInit(z_streamp strm) {
inflateInit(z_streamp strm)
{
return Z_DATA_ERROR;
}
int
deflate(z_streamp strm, int flush) {
deflate(z_streamp strm, int flush)
{
return Z_DATA_ERROR;
}
int
inflate(z_streamp strm, int flush) {
inflate(z_streamp strm, int flush)
{
return Z_DATA_ERROR;
}