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, out = _snprintf_s(cursor_report, sizeof(cursor_report), _TRUNCATE,
CURSOR_REPORT_FORMAT_STRING, ConGetCursorY() + 1, ConGetCursorX() + 1); CURSOR_REPORT_FORMAT_STRING, ConGetCursorY() + 1, ConGetCursorX() + 1);
if (out > 0) { if (out > 0)
return cursor_report; return cursor_report;
}
return NULL; return NULL;
} }

View File

@ -32,9 +32,10 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <io.h> #include <io.h>
#include "w32fd.h"
#include <errno.h> #include <errno.h>
#include <stddef.h> #include <stddef.h>
#include "w32fd.h"
#include "inc\utf.h" #include "inc\utf.h"
#include "misc_internal.h" #include "misc_internal.h"
@ -44,6 +45,14 @@
#define WRITE_BUFFER_SIZE 100*1024 #define WRITE_BUFFER_SIZE 100*1024
#define errno_from_Win32LastError() errno_from_Win32Error(GetLastError()) #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_read(struct w32_io* pio);
int termio_initiate_write(struct w32_io* pio, DWORD num_bytes); 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 * to it. These handles are associated with read end and write end of the pipe
*/ */
int 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; HANDLE read_handle = INVALID_HANDLE_VALUE, write_handle = INVALID_HANDLE_VALUE;
struct w32_io *pio_read = NULL, *pio_write = NULL; struct w32_io *pio_read = NULL, *pio_write = NULL;
char pipe_name[PATH_MAX]; char pipe_name[PATH_MAX];
@ -158,18 +168,10 @@ error:
return -1; 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 */ /* maps open() file modes and flags to ones needed by CreateFile */
static int 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 */ /* check flags */
int rwflags = flags & 0x3; int rwflags = flags & 0x3;
int c_s_flags = flags & 0xfffffff0; 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*/ /*only following create and status flags currently supported*/
if (c_s_flags & ~(O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC if (c_s_flags & ~(O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC | O_EXCL | O_BINARY)) {
| O_EXCL | O_BINARY)) {
debug("open - ERROR: Unsupported flags: %d", flags); debug("open - ERROR: Unsupported flags: %d", flags);
errno = ENOTSUP; errno = ENOTSUP;
return -1; return -1;
@ -204,7 +205,7 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
switch (rwflags) { switch (rwflags) {
case O_RDONLY: case O_RDONLY:
cf_flags->dwDesiredAccess = GENERIC_READ; cf_flags->dwDesiredAccess = GENERIC_READ;
cf_flags->dwShareMode = FILE_SHARE_READ; cf_flags->dwShareMode = FILE_SHARE_READ;
break; break;
case O_WRONLY: case O_WRONLY:
cf_flags->dwDesiredAccess = GENERIC_WRITE; cf_flags->dwDesiredAccess = GENERIC_WRITE;
@ -226,7 +227,7 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
cf_flags->dwCreationDisposition = CREATE_NEW; cf_flags->dwCreationDisposition = CREATE_NEW;
else else
cf_flags->dwCreationDisposition = CREATE_ALWAYS; cf_flags->dwCreationDisposition = CREATE_ALWAYS;
} }
if (c_s_flags & O_APPEND) if (c_s_flags & O_APPEND)
cf_flags->dwDesiredAccess = FILE_APPEND_DATA; cf_flags->dwDesiredAccess = FILE_APPEND_DATA;
@ -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 */ /* open() implementation. Uses CreateFile to open file, console, device, etc */
struct w32_io* 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 w32_io* pio = NULL;
struct createFile_flags cf_flags; struct createFile_flags cf_flags;
HANDLE handle; HANDLE handle;
wchar_t *path_utf16 = NULL; wchar_t *path_utf16 = NULL;
debug2("open - pathname:%s, flags:%d, mode:%d", path_utf8, flags, mode); debug2("open - pathname:%s, flags:%d, mode:%d", path_utf8, flags, mode);
/* check input params*/ /* check input params*/
@ -254,12 +256,12 @@ struct w32_io*
return NULL; return NULL;
} }
if ((path_utf16 = utf8_to_utf16(path_utf8)) == NULL) { if ((path_utf16 = utf8_to_utf16(path_utf8)) == NULL) {
errno = ENOMEM; errno = ENOMEM;
debug("utf8_to_utf16 failed - ERROR:%d", GetLastError()); debug("utf8_to_utf16 failed for file:%s error:%d", path_utf8, GetLastError());
return NULL; return NULL;
} }
if (createFile_flags_setup(flags, mode, &cf_flags) == -1) if (createFile_flags_setup(flags, mode, &cf_flags) == -1)
return NULL; return NULL;
@ -269,17 +271,17 @@ struct w32_io*
if (handle == INVALID_HANDLE_VALUE) { if (handle == INVALID_HANDLE_VALUE) {
errno = errno_from_Win32LastError(); errno = errno_from_Win32LastError();
debug("open - CreateFile ERROR:%d", GetLastError()); debug("failed to open file:%s error:%d", path_utf8, GetLastError());
free(path_utf16); free(path_utf16);
return NULL; return NULL;
} }
free(path_utf16); free(path_utf16);
pio = (struct w32_io*)malloc(sizeof(struct w32_io)); pio = (struct w32_io*)malloc(sizeof(struct w32_io));
if (pio == NULL) { if (pio == NULL) {
CloseHandle(handle); CloseHandle(handle);
errno = ENOMEM; errno = ENOMEM;
debug("open - ERROR:%d", errno); debug("fileio_open(), failed to allocate memory error:%d", errno);
return NULL; return NULL;
} }
@ -292,13 +294,10 @@ struct w32_io*
return pio; return pio;
} }
VOID CALLBACK ReadCompletionRoutine( VOID CALLBACK
_In_ DWORD dwErrorCode, ReadCompletionRoutine(_In_ DWORD dwErrorCode, _In_ DWORD dwNumberOfBytesTransfered, _Inout_ LPOVERLAPPED lpOverlapped)
_In_ DWORD dwNumberOfBytesTransfered, {
_Inout_ LPOVERLAPPED lpOverlapped struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped));
) {
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", debug2("ReadCB pio:%p, pending_state:%d, error:%d, received:%d",
pio, pio->read_details.pending, dwErrorCode, dwNumberOfBytesTransfered); pio, pio->read_details.pending, dwErrorCode, dwNumberOfBytesTransfered);
pio->read_details.error = dwErrorCode; pio->read_details.error = dwErrorCode;
@ -311,7 +310,8 @@ VOID CALLBACK ReadCompletionRoutine(
/* initiate an async read */ /* initiate an async read */
/* TODO: make this a void func, store error in context */ /* TODO: make this a void func, store error in context */
int 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); debug2("ReadFileEx io:%p", pio);
if (pio->read_details.buf == NULL) { if (pio->read_details.buf == NULL) {
@ -342,11 +342,11 @@ fileio_ReadFileEx(struct w32_io* pio, unsigned int bytes_requested) {
/* read() implementation */ /* read() implementation */
int 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; int bytes_copied;
debug3("read - io:%p remaining:%d", pio, pio->read_details.remaining); debug3("read - io:%p remaining:%d", pio, pio->read_details.remaining);
/* if read is pending */ /* if read is pending */
if (pio->read_details.pending) { if (pio->read_details.pending) {
if (w32_io_is_blocking(pio)) { if (w32_io_is_blocking(pio)) {
@ -426,11 +426,11 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max) {
return bytes_copied; return bytes_copied;
} }
VOID CALLBACK WriteCompletionRoutine( VOID CALLBACK
_In_ DWORD dwErrorCode, WriteCompletionRoutine(_In_ DWORD dwErrorCode,
_In_ DWORD dwNumberOfBytesTransfered, _In_ DWORD dwNumberOfBytesTransfered,
_Inout_ LPOVERLAPPED lpOverlapped _Inout_ LPOVERLAPPED lpOverlapped)
) { {
struct w32_io* pio = struct w32_io* pio =
(struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped)); (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", debug2("WriteCB - pio:%p, pending_state:%d, error:%d, transferred:%d of remaining: %d",
@ -450,21 +450,18 @@ VOID CALLBACK WriteCompletionRoutine(
/* write() implementation */ /* write() implementation */
int 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; int bytes_copied;
debug2("write - io:%p", pio); debug2("write - io:%p", pio);
if (pio->write_details.pending) { 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); 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) if (wait_for_any_event(NULL, 0, INFINITE) == -1)
return -1; return -1;
} } else {
}
else {
errno = EAGAIN; errno = EAGAIN;
debug2("write - IO is already pending, io:%p", pio); debug2("write - IO is already pending, io:%p", pio);
return -1; return -1;
@ -502,14 +499,12 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
} }
else else
return -1; return -1;
} } else {
else {
if (WriteFileEx(WINHANDLE(pio), pio->write_details.buf, bytes_copied, if (WriteFileEx(WINHANDLE(pio), pio->write_details.buf, bytes_copied,
&pio->write_overlapped, &WriteCompletionRoutine)) { &pio->write_overlapped, &WriteCompletionRoutine)) {
pio->write_details.pending = TRUE; pio->write_details.pending = TRUE;
pio->write_details.remaining = bytes_copied; pio->write_details.remaining = bytes_copied;
} } else {
else {
errno = errno_from_Win32LastError(); errno = errno_from_Win32LastError();
/* read end of the pipe closed ? */ /* read end of the pipe closed ? */
if ((FILETYPE(pio) == FILE_TYPE_PIPE) && (errno == ERROR_BROKEN_PIPE)) { 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 */ /* execute APC to give a chance for write to complete */
SleepEx(0, TRUE); SleepEx(0, TRUE);
@ -548,8 +544,8 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
/* fstat() implemetation */ /* fstat() implemetation */
int 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); int fd = _open_osfhandle((intptr_t)pio->handle, 0);
debug2("fstat - pio:%p", pio); debug2("fstat - pio:%p", pio);
if (fd == -1) { if (fd == -1) {
@ -561,12 +557,23 @@ fileio_fstat(struct w32_io* pio, struct _stat64 *buf) {
} }
int int
fileio_stat(const char *path, struct _stat64 *buf) { fileio_stat(const char *path, struct _stat64 *buf)
{
wchar_t wpath[PATH_MAX]; wchar_t wpath[PATH_MAX];
wchar_t* wtmp = NULL; wchar_t* wtmp = NULL;
struct w32_io* pio;
if ((wtmp = utf8_to_utf16(path)) == NULL) if ((wtmp = utf8_to_utf16(path)) == NULL)
fatal("failed to covert input arguments"); 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); wcscpy(&wpath[0], wtmp);
free(wtmp); free(wtmp);
@ -574,7 +581,8 @@ fileio_stat(const char *path, struct _stat64 *buf) {
} }
long 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); debug2("lseek - pio:%p", pio);
if (origin != SEEK_SET) { if (origin != SEEK_SET) {
debug("lseek - ERROR, origin is not supported %d", origin); 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 */ /* fdopen implementation */
FILE* FILE*
fileio_fdopen(struct w32_io* pio, const char *mode) { fileio_fdopen(struct w32_io* pio, const char *mode)
{
int fd_flags = 0; int fd_flags = 0;
debug2("fdopen - io:%p", pio); debug2("fdopen - io:%p", pio);
/* logic below doesn't work with overlapped file HANDLES */ /* logic below doesn't work with overlapped file HANDLES */
if (mode[1] == '\0') { if (mode[1] == '\0') {
switch (*mode) { switch (*mode) {
case 'r': case 'r':
@ -611,8 +618,7 @@ fileio_fdopen(struct w32_io* pio, const char *mode) {
debug("fdopen - ERROR unsupported mode %s", mode); debug("fdopen - ERROR unsupported mode %s", mode);
return NULL; return NULL;
} }
} } else {
else {
errno = ENOTSUP; errno = ENOTSUP;
debug("fdopen - ERROR unsupported mode %s", mode); debug("fdopen - ERROR unsupported mode %s", mode);
return NULL; return NULL;
@ -630,8 +636,8 @@ fileio_fdopen(struct w32_io* pio, const char *mode) {
} }
void void
fileio_on_select(struct w32_io* pio, BOOL rd) { fileio_on_select(struct w32_io* pio, BOOL rd)
{
if (!rd) if (!rd)
return; return;
@ -643,8 +649,7 @@ fileio_on_select(struct w32_io* pio, BOOL rd) {
errno = 0; errno = 0;
return; return;
} }
} } else {
else {
if (fileio_ReadFileEx(pio, INT_MAX) != 0) { if (fileio_ReadFileEx(pio, INT_MAX) != 0) {
pio->read_details.error = errno; pio->read_details.error = errno;
errno = 0; errno = 0;
@ -653,16 +658,15 @@ fileio_on_select(struct w32_io* pio, BOOL rd) {
} }
} }
int int
fileio_close(struct w32_io* pio) { fileio_close(struct w32_io* pio)
{
debug2("fileclose - pio:%p", pio); debug2("fileclose - pio:%p", pio);
CancelIo(WINHANDLE(pio)); CancelIo(WINHANDLE(pio));
//let queued APCs (if any) drain /* let queued APCs (if any) drain */
SleepEx(0, TRUE); 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)); CloseHandle(WINHANDLE(pio));
if (pio->read_details.buf) if (pio->read_details.buf)
@ -677,14 +681,14 @@ fileio_close(struct w32_io* pio) {
} }
BOOL BOOL
fileio_is_io_available(struct w32_io* pio, BOOL rd) { fileio_is_io_available(struct w32_io* pio, BOOL rd)
{
if (rd) { if (rd) {
if (pio->read_details.remaining || pio->read_details.error) if (pio->read_details.remaining || pio->read_details.error)
return TRUE; return TRUE;
else else
return FALSE; return FALSE;
} } else { /* write */
else { //write
return (pio->write_details.pending == FALSE) ? TRUE : FALSE; 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" #include "inc\sys\types.h"
/* uuidswap.c defs */ /* uuidswap.c defs */
void temporarily_use_uid(struct passwd *pw){ void
return; temporarily_use_uid(struct passwd *pw)
{
return;
} }
void void
permanently_drop_suid(uid_t uid) { permanently_drop_suid(uid_t uid)
return; {
return;
} }
void void
restore_uid(void) { restore_uid(void)
return; {
return;
} }
void void
permanently_set_uid(struct passwd *pw) { permanently_set_uid(struct passwd *pw)
return; {
return;
} }
@ -56,74 +61,88 @@ int muxserver_sock = -1;
typedef struct Channel Channel; typedef struct Channel Channel;
unsigned int muxclient_command = 0; unsigned int muxclient_command = 0;
void void
muxserver_listen(void){ muxserver_listen(void)
return; {
return;
} }
void void
mux_exit_message(Channel *c, int exitval) { mux_exit_message(Channel *c, int exitval)
return; {
return;
} }
void void
mux_tty_alloc_failed(Channel *c) { mux_tty_alloc_failed(Channel *c)
return; {
return;
} }
void void
muxclient(const char *path) { muxclient(const char *path)
return; {
return;
} }
int
int innetgr(const char *netgroup, const char *host, const char *user, const char *domain)
innetgr(const char *netgroup, const char *host, {
const char *user, const char *domain) { return -1;
return -1;
} }
/* groupaccess.c*/ /* groupaccess.c*/
int int
ga_init(const char *user, gid_t base) { ga_init(const char *user, gid_t base)
return -1; {
return -1;
} }
int int
ga_match(char * const *groups, int n) { ga_match(char * const *groups, int n)
return -1; {
return -1;
} }
int int
ga_match_pattern_list(const char *group_pattern) { ga_match_pattern_list(const char *group_pattern)
return -1; {
return -1;
} }
void void
ga_free(void) { ga_free(void)
return; {
return;
} }
int chroot(const char *path) { int
return -1; chroot(const char *path)
{
return -1;
} }
int initgroups(const char *user, gid_t group) { int
return -1; initgroups(const char *user, gid_t group)
{
return -1;
} }
/* sshd.c */ /* sshd.c */
int int
setgroups(gid_t group, char* name) { setgroups(gid_t group, char* name)
return 0; {
return 0;
} }
int int
setsid(void) { setsid(void)
return 0; {
}
int startup_handler(void) {
return 0; return 0;
} }
int
startup_handler(void)
{
return 0;
}

View File

@ -36,6 +36,7 @@
#include <DsGetDC.h> #include <DsGetDC.h>
#define SECURITY_WIN32 #define SECURITY_WIN32
#include <security.h> #include <security.h>
#include "inc\pwd.h" #include "inc\pwd.h"
#include "inc\grp.h" #include "inc\grp.h"
#include "inc\utf.h" #include "inc\utf.h"
@ -45,8 +46,10 @@ static struct passwd pw;
static char* pw_shellpath = NULL; static char* pw_shellpath = NULL;
#define SHELL_HOST "\\ssh-shellhost.exe" #define SHELL_HOST "\\ssh-shellhost.exe"
int int
initialize_pw() { initialize_pw()
{
if (pw_shellpath == NULL) { if (pw_shellpath == NULL) {
if ((pw_shellpath = malloc(strlen(w32_programdir()) + strlen(SHELL_HOST) + 1)) == NULL) if ((pw_shellpath = malloc(strlen(w32_programdir()) + strlen(SHELL_HOST) + 1)) == NULL)
fatal("initialize_pw - out of memory"); fatal("initialize_pw - out of memory");
@ -59,6 +62,7 @@ initialize_pw() {
*head = '\0'; *head = '\0';
} }
} }
if (pw.pw_shell != pw_shellpath) { if (pw.pw_shell != pw_shellpath) {
memset(&pw, 0, sizeof(pw)); memset(&pw, 0, sizeof(pw));
pw.pw_shell = pw_shellpath; pw.pw_shell = pw_shellpath;
@ -71,7 +75,8 @@ initialize_pw() {
} }
void void
reset_pw() { reset_pw()
{
initialize_pw(); initialize_pw();
if (pw.pw_name) if (pw.pw_name)
free(pw.pw_name); free(pw.pw_name);
@ -88,7 +93,8 @@ reset_pw() {
} }
static struct passwd* 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; struct passwd *ret = NULL;
wchar_t *user_utf16 = NULL, *uname_utf16, *udom_utf16, *tmp; 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; 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; errno = 0;
reset_pw(); reset_pw();
if ((user_utf16 = utf8_to_utf16(user_utf8) ) == NULL) { if ((user_utf16 = utf8_to_utf16(user_utf8)) == NULL) {
errno = ENOMEM; errno = ENOMEM;
goto done; goto done;
} }
@ -126,7 +132,7 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) {
NET_API_STATUS status; NET_API_STATUS status;
if ((status = NetUserGetInfo(udom_utf16, uname_utf16, 23, &user_info)) != NERR_Success) { if ((status = NetUserGetInfo(udom_utf16, uname_utf16, 23, &user_info)) != NERR_Success) {
debug("NetUserGetInfo() failed with error: %d for user: %ls and domain: %ls \n", status, uname_utf16, udom_utf16); debug("NetUserGetInfo() failed with error: %d for user: %ls and domain: %ls \n", status, uname_utf16, udom_utf16);
if ((dsStatus = DsGetDcNameW(NULL, udom_utf16, NULL, NULL, DS_DIRECTORY_SERVICE_PREFERRED, &pdc)) != ERROR_SUCCESS) { if ((dsStatus = DsGetDcNameW(NULL, udom_utf16, NULL, NULL, DS_DIRECTORY_SERVICE_PREFERRED, &pdc)) != ERROR_SUCCESS) {
error("DsGetDcNameW() failed with error: %d \n", dsStatus); error("DsGetDcNameW() failed with error: %d \n", dsStatus);
errno = ENOENT; errno = ENOENT;
@ -137,22 +143,22 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) {
debug("NetUserGetInfo() with domainController: %ls failed with error: %d \n", pdc->DomainControllerName, status); debug("NetUserGetInfo() with domainController: %ls failed with error: %d \n", pdc->DomainControllerName, status);
errno = ENOENT; errno = ENOENT;
goto done; goto done;
} }
} }
if (ConvertSidToStringSidW(((LPUSER_INFO_23)user_info)->usri23_user_sid, &user_sid_local) == FALSE) { if (ConvertSidToStringSidW(((LPUSER_INFO_23)user_info)->usri23_user_sid, &user_sid_local) == FALSE) {
debug("NetUserGetInfo() Succeded but ConvertSidToStringSidW() failed with error: %d\n", GetLastError()); debug("NetUserGetInfo() Succeded but ConvertSidToStringSidW() failed with error: %d\n", GetLastError());
errno = ENOENT; errno = ENOENT;
goto done; goto done;
} }
user_sid = user_sid_local; user_sid = user_sid_local;
} }
/* if one of below fails, set profile path to Windows directory */ /* 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 || 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 || 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) RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)profile_home, &tmp_len) != 0)
GetWindowsDirectoryW(profile_home, PATH_MAX); GetWindowsDirectoryW(profile_home, PATH_MAX);
if ((uname_utf8 = utf16_to_utf8(uname_utf16)) == NULL || if ((uname_utf8 = utf16_to_utf8(uname_utf16)) == NULL ||
@ -196,12 +202,14 @@ done:
} }
struct passwd* struct passwd*
w32_getpwnam(const char *user_utf8) { w32_getpwnam(const char *user_utf8)
{
return get_passwd(user_utf8, NULL); return get_passwd(user_utf8, NULL);
} }
struct passwd* struct passwd*
w32_getpwuid(uid_t uid) { w32_getpwuid(uid_t uid)
{
wchar_t* wuser = NULL; wchar_t* wuser = NULL;
char* user_utf8 = NULL; char* user_utf8 = NULL;
ULONG needed = 0; ULONG needed = 0;
@ -216,7 +224,7 @@ struct passwd*
if (GetUserNameExW(NameSamCompatible, NULL, &needed) != 0 || if (GetUserNameExW(NameSamCompatible, NULL, &needed) != 0 ||
(wuser = malloc(needed * sizeof(wchar_t))) == NULL || (wuser = malloc(needed * sizeof(wchar_t))) == NULL ||
GetUserNameExW(NameSamCompatible, wuser, &needed) == 0 || 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 || OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == FALSE ||
GetTokenInformation(token, TokenUser, NULL, 0, &info_len) == TRUE || GetTokenInformation(token, TokenUser, NULL, 0, &info_len) == TRUE ||
(info = (TOKEN_USER*)malloc(info_len)) == NULL || (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 "-"; return "-";
} }
char *user_from_uid(uid_t uid, int nouser) { char *
user_from_uid(uid_t uid, int nouser)
{
return "-"; return "-";
} }
uid_t uid_t
getuid(void) { getuid(void)
{
return 0; return 0;
} }
gid_t gid_t
getgid(void) { getgid(void)
{
return 0; return 0;
} }
uid_t uid_t
geteuid(void) { geteuid(void)
{
return 0; return 0;
} }
gid_t gid_t
getegid(void) { getegid(void)
{
return 0; return 0;
} }
int int
setuid(uid_t uid) { setuid(uid_t uid)
{
return 0; return 0;
} }
int int
setgid(gid_t gid) { setgid(gid_t gid)
{
return 0; return 0;
} }
int int
seteuid(uid_t uid) { seteuid(uid_t uid)
{
return 0; return 0;
} }
int int
setegid(gid_t gid) { setegid(gid_t gid)
{
return 0; return 0;
} }

View File

@ -28,10 +28,11 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "w32fd.h"
#include <errno.h> #include <errno.h>
#include "w32fd.h"
#include "signal_internal.h" #include "signal_internal.h"
#include "inc\signal.h" #include "inc\signal.h"
#undef signal #undef signal
#undef raise #undef raise
#undef SIGINT #undef SIGINT
@ -48,30 +49,27 @@
/* pending signals to be processed */ /* pending signals to be processed */
sigset_t pending_signals; sigset_t pending_signals;
/* signal handler table*/ /* signal handler table*/
sighandler_t sig_handlers[W32_SIGMAX]; sighandler_t sig_handlers[W32_SIGMAX];
extern struct _children children;
static VOID CALLBACK static VOID CALLBACK
sigint_APCProc( sigint_APCProc(_In_ ULONG_PTR dwParam)
_In_ ULONG_PTR dwParam {
) {
debug3("SIGINT APCProc()"); debug3("SIGINT APCProc()");
sigaddset(&pending_signals, W32_SIGINT); sigaddset(&pending_signals, W32_SIGINT);
} }
static VOID CALLBACK static VOID CALLBACK
sigterm_APCProc( sigterm_APCProc(_In_ ULONG_PTR dwParam)
_In_ ULONG_PTR dwParam {
) {
debug3("SIGTERM APCProc()"); debug3("SIGTERM APCProc()");
sigaddset(&pending_signals, W32_SIGTERM); sigaddset(&pending_signals, W32_SIGTERM);
} }
static VOID CALLBACK static VOID CALLBACK
sigtstp_APCProc( sigtstp_APCProc(_In_ ULONG_PTR dwParam)
_In_ ULONG_PTR dwParam {
) {
debug3("SIGTSTP APCProc()"); debug3("SIGTSTP APCProc()");
sigaddset(&pending_signals, W32_SIGTSTP); sigaddset(&pending_signals, W32_SIGTSTP);
} }
@ -100,48 +98,45 @@ native_sig_handler(DWORD dwCtrlType)
} }
static VOID CALLBACK static VOID CALLBACK
sigwinch_APCProc( sigwinch_APCProc(_In_ ULONG_PTR dwParam)
_In_ ULONG_PTR dwParam {
) {
debug3("SIGTERM APCProc()"); debug3("SIGTERM APCProc()");
sigaddset(&pending_signals, W32_SIGWINCH); sigaddset(&pending_signals, W32_SIGWINCH);
} }
void void
queue_terminal_window_change_event() { queue_terminal_window_change_event()
{
QueueUserAPC(sigwinch_APCProc, main_thread, (ULONG_PTR)NULL); QueueUserAPC(sigwinch_APCProc, main_thread, (ULONG_PTR)NULL);
} }
void void
sw_init_signal_handler_table() { sw_init_signal_handler_table()
int i; {
SetConsoleCtrlHandler(native_sig_handler, TRUE); SetConsoleCtrlHandler(native_sig_handler, TRUE);
sigemptyset(&pending_signals); sigemptyset(&pending_signals);
/* this automatically sets all to W32_SIG_DFL (0)*/ /* this automatically sets all to W32_SIG_DFL (0)*/
memset(sig_handlers, 0, sizeof(sig_handlers)); memset(sig_handlers, 0, sizeof(sig_handlers));
} }
extern struct _children children; sighandler_t
w32_signal(int signum, sighandler_t handler)
sighandler_t {
w32_signal(int signum, sighandler_t handler) {
sighandler_t prev; sighandler_t prev;
debug2("signal() sig:%d, handler:%p", signum, handler); debug2("signal() sig:%d, handler:%p", signum, handler);
if (signum >= W32_SIGMAX) { if (signum >= W32_SIGMAX) {
errno = EINVAL; errno = EINVAL;
return W32_SIG_ERR; return W32_SIG_ERR;
} }
prev = sig_handlers[signum]; prev = sig_handlers[signum];
sig_handlers[signum] = handler; sig_handlers[signum] = handler;
return prev; return prev;
} }
int 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() */ /* 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*/ /* our implementation of waidpid() is never interrupted, so no need to implement this for now*/
debug3("sigprocmask() how:%d"); debug3("sigprocmask() how:%d");
@ -150,8 +145,9 @@ w32_sigprocmask(int how, const sigset_t *set, sigset_t *oldset) {
int int
w32_raise(int sig) { w32_raise(int sig)
{
debug("raise sig:%d", sig); debug("raise sig:%d", sig);
if (sig == W32_SIGSEGV) if (sig == W32_SIGSEGV)
return raise(SIGSEGV); /* raise native exception handler*/ return raise(SIGSEGV); /* raise native exception handler*/
@ -170,7 +166,7 @@ w32_raise(int sig) {
/* if set to ignore, nothing to do */ /* if set to ignore, nothing to do */
if (sig_handlers[sig] == W32_SIG_IGN) if (sig_handlers[sig] == W32_SIG_IGN)
return 0; return 0;
/* execute any default handlers */ /* execute any default handlers */
switch (sig) { switch (sig) {
case W32_SIGCHLD: case W32_SIGCHLD:
@ -184,8 +180,9 @@ w32_raise(int sig) {
} }
/* processes pending signals, return -1 and errno=EINTR if any are processed*/ /* processes pending signals, return -1 and errno=EINTR if any are processed*/
static int static int
sw_process_pending_signals() { sw_process_pending_signals()
{
sigset_t pending_tmp = pending_signals; sigset_t pending_tmp = pending_signals;
BOOL sig_int = FALSE; /* has any signal actually interrupted */ BOOL sig_int = FALSE; /* has any signal actually interrupted */
@ -195,7 +192,7 @@ sw_process_pending_signals() {
/* check for expected signals*/ /* check for expected signals*/
for (i = 0; i < (sizeof(exp) / sizeof(exp[0])); i++) for (i = 0; i < (sizeof(exp) / sizeof(exp[0])); i++)
sigdelset(&pending_tmp, exp[i]); sigdelset(&pending_tmp, exp[i]);
if (pending_tmp) { if (pending_tmp) {
/* unexpected signals queued up */ /* unexpected signals queued up */
debug("process_signals() - ERROR unexpected signals in queue: %d", pending_tmp); debug("process_signals() - ERROR unexpected signals in queue: %d", pending_tmp);
errno = ENOTSUP; errno = ENOTSUP;
@ -219,7 +216,7 @@ sw_process_pending_signals() {
sigdelset(&pending_tmp, exp[i]); sigdelset(&pending_tmp, exp[i]);
} }
} }
/* by now all pending signals should have been taken care of*/ /* by now all pending signals should have been taken care of*/
if (pending_tmp) if (pending_tmp)
@ -235,17 +232,17 @@ sw_process_pending_signals() {
} }
/* /*
* Main wait routine used by all blocking calls. * Main wait routine used by all blocking calls.
* It wakes up on * It wakes up on
* - any signals (errno = EINTR ) * - any signals (errno = EINTR )
* - any of the supplied events set * - any of the supplied events set
* - any APCs caused by IO completions * - any APCs caused by IO completions
* - time out * - time out
* - Returns 0 on IO completion and timeout, -1 on rest * - Returns 0 on IO completion and timeout, -1 on rest
* if milli_seconds is 0, this function returns 0, its called with 0 * if milli_seconds is 0, this function returns 0, its called with 0
* to execute any scheduled APCs * to execute any scheduled APCs
*/ */
int int
wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds) wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
{ {
HANDLE all_events[MAXIMUM_WAIT_OBJECTS]; HANDLE all_events[MAXIMUM_WAIT_OBJECTS];
@ -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); debug3("wait() on %d events and %d children", num_events, live_children);
/* TODO - implement signal catching and handling */ /* TODO - implement signal catching and handling */
if (num_all_events) { if (num_all_events) {
DWORD ret = WaitForMultipleObjectsEx(num_all_events, all_events, FALSE, DWORD ret = WaitForMultipleObjectsEx(num_all_events, all_events, FALSE, milli_seconds, TRUE);
milli_seconds, TRUE);
if ((ret >= WAIT_OBJECT_0) && (ret <= WAIT_OBJECT_0 + num_all_events - 1)) { if ((ret >= WAIT_OBJECT_0) && (ret <= WAIT_OBJECT_0 + num_all_events - 1)) {
//woken up by event signalled /* woken up by event signalled
/* is this due to a child process going down*/ * is this due to a child process going down
*/
if (live_children && ((ret - WAIT_OBJECT_0) < live_children)) { if (live_children && ((ret - WAIT_OBJECT_0) < live_children)) {
sigaddset(&pending_signals, W32_SIGCHLD); sigaddset(&pending_signals, W32_SIGCHLD);
sw_child_to_zombie(ret - WAIT_OBJECT_0); 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*/ /* APC processed due to IO or signal*/
} } else if (ret == WAIT_TIMEOUT) {
else if (ret == WAIT_TIMEOUT) {
/* timed out */ /* timed out */
return 0; return 0;
} } else { /* some other error*/
/* some other error*/
else {
errno = EOTHER; errno = EOTHER;
debug("ERROR: unxpected wait end: %d", ret); debug("ERROR: unxpected wait end: %d", ret);
return -1; return -1;
} }
} } else {
else {
DWORD ret = SleepEx(milli_seconds, TRUE); DWORD ret = SleepEx(milli_seconds, TRUE);
if (ret == WAIT_IO_COMPLETION) { if (ret == WAIT_IO_COMPLETION) {
/* APC processed due to IO or signal*/ /* APC processed due to IO or signal*/
} } else if (ret == 0) {
else if (ret == 0) {
/* timed out */ /* timed out */
return 0; return 0;
} } else { /* some other error */
else { //some other error
errno = EOTHER; errno = EOTHER;
debug("ERROR: unxpected SleepEx error: %d", ret); debug("ERROR: unxpected SleepEx error: %d", ret);
return -1; return -1;
} }
} }
if (pending_signals) { if (pending_signals)
return sw_process_pending_signals(); return sw_process_pending_signals();
}
return 0; return 0;
} }
int int
sw_initialize() { sw_initialize()
{
memset(&children, 0, sizeof(children)); memset(&children, 0, sizeof(children));
sw_init_signal_handler_table(); sw_init_signal_handler_table();
if (sw_init_timer() != 0) if (sw_init_timer() != 0)

View File

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

View File

@ -34,7 +34,8 @@
struct _children children; struct _children children;
int int
register_child(HANDLE child, DWORD pid) { register_child(HANDLE child, DWORD pid)
{
DWORD first_zombie_index; DWORD first_zombie_index;
debug("Register child %p pid %d, %d zombies of %d", child, pid, debug("Register child %p pid %d, %d zombies of %d", child, pid,
@ -43,6 +44,7 @@ register_child(HANDLE child, DWORD pid) {
errno = ENOMEM; errno = ENOMEM;
return -1; return -1;
} }
if (children.num_zombies) { if (children.num_zombies) {
first_zombie_index = children.num_children - children.num_zombies; first_zombie_index = children.num_children - children.num_zombies;
children.handles[children.num_children] = children.handles[first_zombie_index]; 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.handles[first_zombie_index] = child;
children.process_id[first_zombie_index] = pid; children.process_id[first_zombie_index] = pid;
} } else {
else {
children.handles[children.num_children] = child; children.handles[children.num_children] = child;
children.process_id[children.num_children] = pid; children.process_id[children.num_children] = pid;
} }
children.num_children++; children.num_children++;
return 0; return 0;
} }
int int
sw_remove_child_at_index(DWORD index) { sw_remove_child_at_index(DWORD index)
{
DWORD last_non_zombie; DWORD last_non_zombie;
debug("Unregister child at index %d, %d zombies of %d", index, debug("Unregister child at index %d, %d zombies of %d", index,
children.num_zombies, children.num_children); children.num_zombies, children.num_children);
if ((index >= children.num_children) if ((index >= children.num_children) || (children.num_children == 0)) {
|| (children.num_children == 0)) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
@ -78,15 +77,13 @@ sw_remove_child_at_index(DWORD index) {
if (children.num_zombies == 0) { if (children.num_zombies == 0) {
children.handles[index] = children.handles[children.num_children - 1]; children.handles[index] = children.handles[children.num_children - 1];
children.process_id[index] = children.process_id[children.num_children - 1]; children.process_id[index] = children.process_id[children.num_children - 1];
} } else {
else {
/* if its a zombie */ /* if its a zombie */
if (index >= (children.num_children - children.num_zombies)) { if (index >= (children.num_children - children.num_zombies)) {
children.handles[index] = children.handles[children.num_children - 1]; children.handles[index] = children.handles[children.num_children - 1];
children.process_id[index] = children.process_id[children.num_children - 1]; children.process_id[index] = children.process_id[children.num_children - 1];
children.num_zombies--; children.num_zombies--;
} } else {
else {
last_non_zombie = children.num_children - children.num_zombies - 1; last_non_zombie = children.num_children - children.num_zombies - 1;
children.handles[index] = children.handles[last_non_zombie]; children.handles[index] = children.handles[last_non_zombie];
children.process_id[index] = children.process_id[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 int
sw_child_to_zombie(DWORD index) { sw_child_to_zombie(DWORD index)
{
DWORD last_non_zombie, zombie_pid; DWORD last_non_zombie, zombie_pid;
HANDLE zombie_handle; HANDLE zombie_handle;
@ -114,7 +112,6 @@ sw_child_to_zombie(DWORD index) {
} }
last_non_zombie = children.num_children - children.num_zombies - 1; last_non_zombie = children.num_children - children.num_zombies - 1;
if (last_non_zombie != index) { if (last_non_zombie != index) {
/* swap */ /* swap */
zombie_pid = children.process_id[index]; zombie_pid = children.process_id[index];
@ -129,7 +126,8 @@ sw_child_to_zombie(DWORD index) {
} }
int int
w32_kill(int pid, int sig) { w32_kill(int pid, int sig)
{
int child_index, i; int child_index, i;
if (pid == GetCurrentProcessId()) if (pid == GetCurrentProcessId())
return w32_raise(sig); 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; DWORD index, ret, ret_id, exit_code, timeout = 0;
HANDLE process = NULL; HANDLE process = NULL;
@ -214,7 +214,7 @@ int waitpid(int pid, int *status, int options) {
sw_remove_child_at_index(children.num_children - 1); sw_remove_child_at_index(children.num_children - 1);
return ret_id; return ret_id;
} }
/* all children are alive. wait for one of them to exit */ /* all children are alive. wait for one of them to exit */
timeout = INFINITE; timeout = INFINITE;
if (options & WNOHANG) if (options & WNOHANG)
@ -230,20 +230,19 @@ int waitpid(int pid, int *status, int options) {
if (status) if (status)
*status = exit_code; *status = exit_code;
return ret_id; return ret_id;
} } else if (ret == WAIT_TIMEOUT) {
else if (ret == WAIT_TIMEOUT) {
/* TODO - assert that WNOHANG was specified*/ /* TODO - assert that WNOHANG was specified*/
return 0; return 0;
} }
DebugBreak();//fatal DebugBreak(); /* fatal */
return -1; return -1;
} }
void void
sw_cleanup_child_zombies() { sw_cleanup_child_zombies()
{
int pid = 1; int pid = 1;
while (pid > 0) { while (pid > 0)
pid = waitpid(-1, NULL, WNOHANG); 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*/ /* initializes mapping table*/
static int static int
fd_table_initialize() { fd_table_initialize()
{
memset(&fd_table, 0, sizeof(fd_table)); memset(&fd_table, 0, sizeof(fd_table));
memset(&w32_io_stdin, 0, sizeof(w32_io_stdin)); memset(&w32_io_stdin, 0, sizeof(w32_io_stdin));
w32_io_stdin.std_handle = STD_INPUT_HANDLE; 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*/ /* get a free slot in mapping table with least index*/
static int static int
fd_table_get_min_index() { fd_table_get_min_index()
{
int min_index = 0; int min_index = 0;
unsigned char* bitmap = fd_table.occupied.bitmap; unsigned char* bitmap = fd_table.occupied.bitmap;
unsigned char tmp; unsigned char tmp;
@ -102,9 +104,7 @@ fd_table_get_min_index() {
} }
tmp = *bitmap; tmp = *bitmap;
while (tmp & 0x80) {
while (tmp & 0x80)
{
tmp <<= 1; tmp <<= 1;
min_index++; min_index++;
} }
@ -114,7 +114,8 @@ fd_table_get_min_index() {
/* maps pio to fd (specified by index)*/ /* maps pio to fd (specified by index)*/
static void 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; fd_table.w32_ios[index] = pio;
pio->table_index = index; pio->table_index = index;
assert(pio->type != UNKNOWN_FD); assert(pio->type != UNKNOWN_FD);
@ -131,19 +132,20 @@ fd_table_clear(int index)
} }
void void
w32posix_initialize() { w32posix_initialize()
if ((fd_table_initialize() != 0) {
|| (socketio_initialize() != 0)) if ((fd_table_initialize() != 0) || (socketio_initialize() != 0))
DebugBreak(); DebugBreak();
main_thread = OpenThread(THREAD_SET_CONTEXT | SYNCHRONIZE, FALSE, GetCurrentThreadId()); main_thread = OpenThread(THREAD_SET_CONTEXT | SYNCHRONIZE, FALSE, GetCurrentThreadId());
if ((main_thread == NULL) || (sw_initialize() != 0) || w32_programdir() == NULL) { if ((main_thread == NULL) || (sw_initialize() != 0) || w32_programdir() == NULL) {
DebugBreak(); DebugBreak();
fatal("failed to initialize w32posix wrapper"); fatal("failed to initialize w32posix wrapper");
} }
} }
void void
w32posix_done() { w32posix_done()
{
socketio_done(); socketio_done();
} }
@ -159,7 +161,8 @@ w32_io_is_blocking(struct w32_io* pio)
* as it decides on what fds can be set. * as it decides on what fds can be set.
*/ */
BOOL 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) if (pio->type == SOCK_FD)
return socketio_is_io_available(pio, rd); return socketio_is_io_available(pio, rd);
else else
@ -171,7 +174,7 @@ w32_io_on_select(struct w32_io* pio, BOOL rd)
{ {
if ((pio->type == SOCK_FD)) if ((pio->type == SOCK_FD))
socketio_on_select(pio, rd); socketio_on_select(pio, rd);
else else
fileio_on_select(pio, rd); fileio_on_select(pio, rd);
} }
@ -195,7 +198,8 @@ w32_io_on_select(struct w32_io* pio, BOOL rd)
} while (0) } while (0)
int 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(); int min_index = fd_table_get_min_index();
struct w32_io* pio = NULL; struct w32_io* pio = NULL;
@ -216,7 +220,6 @@ w32_socket(int domain, int type, int protocol) {
int int
w32_accept(int fd, struct sockaddr* addr, int* addrlen) w32_accept(int fd, struct sockaddr* addr, int* addrlen)
{ {
CHECK_FD(fd); CHECK_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]); CHECK_SOCK_IO(fd_table.w32_ios[fd]);
int min_index = fd_table_get_min_index(); int min_index = fd_table_get_min_index();
@ -236,72 +239,72 @@ w32_accept(int fd, struct sockaddr* addr, int* addrlen)
} }
int 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_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]); CHECK_SOCK_IO(fd_table.w32_ios[fd]);
return socketio_setsockopt(fd_table.w32_ios[fd], level, optname, (const char*)optval, optlen); return socketio_setsockopt(fd_table.w32_ios[fd], level, optname, (const char*)optval, optlen);
} }
int 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_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]); CHECK_SOCK_IO(fd_table.w32_ios[fd]);
return socketio_getsockopt(fd_table.w32_ios[fd], level, optname, (char*)optval, optlen); return socketio_getsockopt(fd_table.w32_ios[fd], level, optname, (char*)optval, optlen);
} }
int int
w32_getsockname(int fd, struct sockaddr* name, int* namelen) { w32_getsockname(int fd, struct sockaddr* name, int* namelen)
{
CHECK_FD(fd); CHECK_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]); CHECK_SOCK_IO(fd_table.w32_ios[fd]);
return socketio_getsockname(fd_table.w32_ios[fd], name, namelen); return socketio_getsockname(fd_table.w32_ios[fd], name, namelen);
} }
int int
w32_getpeername(int fd, struct sockaddr* name, int* namelen) { w32_getpeername(int fd, struct sockaddr* name, int* namelen)
{
CHECK_FD(fd); CHECK_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]); CHECK_SOCK_IO(fd_table.w32_ios[fd]);
return socketio_getpeername(fd_table.w32_ios[fd], name, namelen); return socketio_getpeername(fd_table.w32_ios[fd], name, namelen);
} }
int int
w32_listen(int fd, int backlog) { w32_listen(int fd, int backlog)
{
CHECK_FD(fd); CHECK_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]); CHECK_SOCK_IO(fd_table.w32_ios[fd]);
return socketio_listen(fd_table.w32_ios[fd], backlog); return socketio_listen(fd_table.w32_ios[fd], backlog);
} }
int 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_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]); CHECK_SOCK_IO(fd_table.w32_ios[fd]);
return socketio_bind(fd_table.w32_ios[fd], name, namelen); return socketio_bind(fd_table.w32_ios[fd], name, namelen);
} }
int 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_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]); CHECK_SOCK_IO(fd_table.w32_ios[fd]);
return socketio_connect(fd_table.w32_ios[fd], name, namelen); return socketio_connect(fd_table.w32_ios[fd], name, namelen);
} }
int 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_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]); CHECK_SOCK_IO(fd_table.w32_ios[fd]);
return socketio_recv(fd_table.w32_ios[fd], buf, len, flags); return socketio_recv(fd_table.w32_ios[fd], buf, len, flags);
} }
int 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_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]); CHECK_SOCK_IO(fd_table.w32_ios[fd]);
return socketio_send(fd_table.w32_ios[fd], buf, len, flags); 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 int
w32_shutdown(int fd, int how) { w32_shutdown(int fd, int how)
{
debug2("shutdown - fd:%d how:%d", fd, how); debug2("shutdown - fd:%d how:%d", fd, how);
CHECK_FD(fd); CHECK_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]); CHECK_SOCK_IO(fd_table.w32_ios[fd]);
@ -317,15 +321,17 @@ w32_shutdown(int fd, int how) {
} }
int int
w32_socketpair(int domain, int type, int protocol, int sv[2]) { w32_socketpair(int domain, int type, int protocol, int sv[2])
errno = ENOTSUP; {
errno = ENOTSUP;
debug("socketpair - ERROR not supported"); debug("socketpair - ERROR not supported");
return -1; return -1;
} }
int int
w32_pipe(int *pfds) { w32_pipe(int *pfds)
{
int read_index, write_index; int read_index, write_index;
struct w32_io* pio[2]; struct w32_io* pio[2];
@ -350,13 +356,15 @@ w32_pipe(int *pfds) {
fd_table_set(pio[1], write_index); fd_table_set(pio[1], write_index);
pfds[0] = read_index; pfds[0] = read_index;
pfds[1] = write_index; pfds[1] = write_index;
debug("pipe - r-h:%d,io:%p,fd:%d w-h:%d,io:%p,fd:%d", 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; return 0;
} }
int int
w32_open(const char *pathname, int flags, ...) { w32_open(const char *pathname, int flags, ...)
{
int min_index = fd_table_get_min_index(); int min_index = fd_table_get_min_index();
struct w32_io* pio; struct w32_io* pio;
@ -376,64 +384,66 @@ w32_open(const char *pathname, int flags, ...) {
} }
int int
w32_read(int fd, void *dst, size_t max) { w32_read(int fd, void *dst, size_t max)
{
CHECK_FD(fd); CHECK_FD(fd);
if (fd_table.w32_ios[fd]->type == SOCK_FD) if (fd_table.w32_ios[fd]->type == SOCK_FD)
return socketio_recv(fd_table.w32_ios[fd], dst, max, 0); return socketio_recv(fd_table.w32_ios[fd], dst, max, 0);
return fileio_read(fd_table.w32_ios[fd], dst, max); return fileio_read(fd_table.w32_ios[fd], dst, max);
} }
int int
w32_write(int fd, const void *buf, unsigned int max) { w32_write(int fd, const void *buf, unsigned int max)
{
CHECK_FD(fd); CHECK_FD(fd);
if (fd_table.w32_ios[fd]->type == SOCK_FD) if (fd_table.w32_ios[fd]->type == SOCK_FD)
return socketio_send(fd_table.w32_ios[fd], buf, max, 0); return socketio_send(fd_table.w32_ios[fd], buf, max, 0);
return fileio_write(fd_table.w32_ios[fd], buf, max); return fileio_write(fd_table.w32_ios[fd], buf, max);
} }
int w32_writev(int fd, const struct iovec *iov, int iovcnt) { int
int written = 0; w32_writev(int fd, const struct iovec *iov, int iovcnt)
int i = 0; {
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++) { return written;
int ret = w32_write(fd, iov[i].iov_base, iov[i].iov_len);
if (ret > 0) {
written += ret;
}
}
return written;
} }
int int
w32_fstat(int fd, struct w32_stat *buf) { w32_fstat(int fd, struct w32_stat *buf)
{
CHECK_FD(fd); CHECK_FD(fd);
return fileio_fstat(fd_table.w32_ios[fd], (struct _stat64*)buf); return fileio_fstat(fd_table.w32_ios[fd], (struct _stat64*)buf);
} }
long long
w32_lseek(int fd, long offset, int origin) { w32_lseek(int fd, long offset, int origin)
{
CHECK_FD(fd); CHECK_FD(fd);
return fileio_lseek(fd_table.w32_ios[fd], offset, origin); return fileio_lseek(fd_table.w32_ios[fd], offset, origin);
} }
int int
w32_isatty(int fd) { w32_isatty(int fd)
{
struct w32_io* pio; struct w32_io* pio;
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) { if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
errno = EBADF; errno = EBADF;
return 0; return 0;
} }
pio = fd_table.w32_ios[fd];
pio = fd_table.w32_ios[fd];
if (FILETYPE(pio) == FILE_TYPE_CHAR) if (FILETYPE(pio) == FILE_TYPE_CHAR)
return 1; return 1;
else { else {
@ -443,7 +453,8 @@ w32_isatty(int fd) {
} }
FILE* FILE*
w32_fdopen(int fd, const char *mode) { w32_fdopen(int fd, const char *mode)
{
errno = 0; errno = 0;
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) { if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
errno = EBADF; errno = EBADF;
@ -454,13 +465,13 @@ w32_fdopen(int fd, const char *mode) {
} }
int int
w32_close(int fd) { w32_close(int fd)
{
struct w32_io* pio; struct w32_io* pio;
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) { errno = EBADF;
errno = EBADF; return -1;
return -1; }
}
pio = fd_table.w32_ios[fd]; pio = fd_table.w32_ios[fd];
@ -480,7 +491,8 @@ w32_close(int fd) {
} }
static int 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; DWORD shi_flags;
if (flags & ~FD_CLOEXEC) { if (flags & ~FD_CLOEXEC) {
debug("fcntl - ERROR unsupported flags %d, io:%p", flags, pio); debug("fcntl - ERROR unsupported flags %d, io:%p", flags, pio);
@ -491,7 +503,7 @@ w32_io_process_fd_flags(struct w32_io* pio, int flags) {
shi_flags = (flags & FD_CLOEXEC) ? 0 : HANDLE_FLAG_INHERIT; shi_flags = (flags & FD_CLOEXEC) ? 0 : HANDLE_FLAG_INHERIT;
if (SetHandleInformation(WINHANDLE(pio), HANDLE_FLAG_INHERIT, shi_flags) == FALSE) { if (SetHandleInformation(WINHANDLE(pio), HANDLE_FLAG_INHERIT, shi_flags) == FALSE) {
debug("fcntl - SetHandleInformation failed %d, io:%p", debug("fcntl - SetHandleInformation failed %d, io:%p",
GetLastError(), pio); GetLastError(), pio);
errno = EOTHER; errno = EOTHER;
return -1; return -1;
@ -502,42 +514,43 @@ w32_io_process_fd_flags(struct w32_io* pio, int flags) {
} }
int int
w32_fcntl(int fd, int cmd, ... /* arg */) { w32_fcntl(int fd, int cmd, ... /* arg */)
{
va_list valist; va_list valist;
va_start(valist, cmd); va_start(valist, cmd);
int ret = 0; int ret = 0;
CHECK_FD(fd); CHECK_FD(fd);
switch (cmd) { switch (cmd) {
case F_GETFL: case F_GETFL:
ret = fd_table.w32_ios[fd]->fd_status_flags; ret = fd_table.w32_ios[fd]->fd_status_flags;
break; break;
case F_SETFL: case F_SETFL:
fd_table.w32_ios[fd]->fd_status_flags = va_arg(valist, int); fd_table.w32_ios[fd]->fd_status_flags = va_arg(valist, int);
ret = 0; ret = 0;
break; break;
case F_GETFD: case F_GETFD:
ret = fd_table.w32_ios[fd]->fd_flags; ret = fd_table.w32_ios[fd]->fd_flags;
break; break;
case F_SETFD: case F_SETFD:
ret = w32_io_process_fd_flags(fd_table.w32_ios[fd], va_arg(valist, int)); ret = w32_io_process_fd_flags(fd_table.w32_ios[fd], va_arg(valist, int));
break; break;
default: default:
errno = EINVAL; errno = EINVAL;
debug("fcntl - ERROR not supported cmd:%d", cmd); debug("fcntl - ERROR not supported cmd:%d", cmd);
ret = -1; ret = -1;
break; break;
} }
va_end(valist); va_end(valist);
return ret; return ret;
} }
#define SELECT_EVENT_LIMIT 32 #define SELECT_EVENT_LIMIT 32
int int
w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* exceptfds, w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* exceptfds, const struct timeval *timeout)
const struct timeval *timeout) { {
ULONGLONG ticks_start = GetTickCount64(), ticks_spent; ULONGLONG ticks_start = GetTickCount64(), ticks_spent;
w32_fd_set read_ready_fds, write_ready_fds; w32_fd_set read_ready_fds, write_ready_fds;
HANDLE events[SELECT_EVENT_LIMIT]; 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 */ /* TODO - see if this needs to be supported */
//if (exceptfds) { /* if (exceptfds) {
// errno = EOPNOTSUPP; errno = EOPNOTSUPP;
// debug("select - ERROR: exceptfds not supported"); debug("select - ERROR: exceptfds not supported");
// DebugBreak(); DebugBreak();
// return -1; return -1;
//} } */
if (readfds) { if (readfds) {
for (i = 0; i < fds; i++) 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 * that select needs to listen on
*/ */
for (int i = 0; i < fds; i++) { for (int i = 0; i < fds; i++) {
if (readfds && FD_ISSET(i, readfds)) { if (readfds && FD_ISSET(i, readfds)) {
w32_io_on_select(fd_table.w32_ios[i], TRUE); w32_io_on_select(fd_table.w32_ios[i], TRUE);
if ((fd_table.w32_ios[i]->type == SOCK_FD) if ((fd_table.w32_ios[i]->type == SOCK_FD) &&
&& (fd_table.w32_ios[i]->internal.state == SOCK_LISTENING)) { (fd_table.w32_ios[i]->internal.state == SOCK_LISTENING)) {
if (num_events == SELECT_EVENT_LIMIT) { if (num_events == SELECT_EVENT_LIMIT) {
debug("select - ERROR: max #events breach"); debug("select - ERROR: max #events breach");
errno = ENOMEM; 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)) { if (writefds && FD_ISSET(i, writefds)) {
w32_io_on_select(fd_table.w32_ios[i], FALSE); w32_io_on_select(fd_table.w32_ios[i], FALSE);
if ((fd_table.w32_ios[i]->type == SOCK_FD) if ((fd_table.w32_ios[i]->type == SOCK_FD) &&
&& (fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)) { (fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)) {
if (num_events == SELECT_EVENT_LIMIT) { if (num_events == SELECT_EVENT_LIMIT) {
debug("select - ERROR: max #events reached for select"); debug("select - ERROR: max #events reached for select");
errno = ENOMEM; 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 */ /* see if any io is ready */
for (i = 0; i < fds; i++) { for (i = 0; i < fds; i++) {
if (readfds && FD_ISSET(i, readfds)) { if (readfds && FD_ISSET(i, readfds)) {
if (w32_io_is_io_available(fd_table.w32_ios[i], TRUE)) { if (w32_io_is_io_available(fd_table.w32_ios[i], TRUE)) {
FD_SET(i, &read_ready_fds); 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 */ /* check on fd status */
out_ready_fds = 0; out_ready_fds = 0;
for (int i = 0; i < fds; i++) { for (int i = 0; i < fds; i++) {
if (readfds && FD_ISSET(i, readfds)) { if (readfds && FD_ISSET(i, readfds)) {
if (w32_io_is_io_available(fd_table.w32_ios[i], TRUE)) { if (w32_io_is_io_available(fd_table.w32_ios[i], TRUE)) {
FD_SET(i, &read_ready_fds); FD_SET(i, &read_ready_fds);
@ -693,9 +703,8 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
} }
} }
if (out_ready_fds == 0) if (out_ready_fds == 0)
debug3("select - wait ended without any IO completion, looping again"); debug3("select - wait ended without any IO completion, looping again");
} }
/* clear out fds that are not ready yet */ /* 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, writefds)) {
if (FD_ISSET(i, &write_ready_fds)) { if (FD_ISSET(i, &write_ready_fds)) {
/* for connect() completed sockets finish WSA connect process*/ /* for connect() completed sockets finish WSA connect process*/
if ((fd_table.w32_ios[i]->type == SOCK_FD) if ((fd_table.w32_ios[i]->type == SOCK_FD) &&
&& ((fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING))) ((fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)))
if (socketio_finish_connect(fd_table.w32_ios[i]) != 0) { if (socketio_finish_connect(fd_table.w32_ios[i]) != 0) {
/* finalizeing connect failed - recored error */ /* finalizeing connect failed - recored error */
/* error gets picked up later recv and/or send*/ /* 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 int
w32_dup(int oldfd) { w32_dup(int oldfd)
{
int min_index; int min_index;
struct w32_io* pio; struct w32_io* pio;
HANDLE src, target; HANDLE src, target;
@ -773,7 +783,8 @@ w32_dup(int oldfd) {
} }
int int
w32_dup2(int oldfd, int newfd) { w32_dup2(int oldfd, int newfd)
{
CHECK_FD(oldfd); CHECK_FD(oldfd);
errno = EOPNOTSUPP; errno = EOPNOTSUPP;
debug("dup2 - ERROR: not implemented yet"); debug("dup2 - ERROR: not implemented yet");
@ -781,14 +792,17 @@ w32_dup2(int oldfd, int newfd) {
} }
HANDLE HANDLE
w32_fd_to_handle(int fd) { w32_fd_to_handle(int fd)
{
HANDLE h = fd_table.w32_ios[fd]->handle; HANDLE h = fd_table.w32_ios[fd]->handle;
if (fd <= STDERR_FILENO) if (fd <= STDERR_FILENO)
h = GetStdHandle(fd_table.w32_ios[fd]->std_handle); h = GetStdHandle(fd_table.w32_ios[fd]->std_handle);
return h; 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(); int min_index = fd_table_get_min_index();
struct w32_io* pio; struct w32_io* pio;
@ -803,17 +817,17 @@ int w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock) {
} }
memset(pio, 0, sizeof(struct w32_io)); 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; pio->handle = h;
fd_table_set(pio, min_index); fd_table_set(pio, min_index);
return min_index; return min_index;
} }
int int
w32_ftruncate(int fd, off_t length) { w32_ftruncate(int fd, off_t length)
{
LARGE_INTEGER new_postion; LARGE_INTEGER new_postion;
CHECK_FD(fd); CHECK_FD(fd);
new_postion.QuadPart = length; new_postion.QuadPart = length;
@ -825,9 +839,9 @@ w32_ftruncate(int fd, off_t length) {
return 0; return 0;
} }
int int
w32_fsync(int fd) { w32_fsync(int fd)
{
CHECK_FD(fd); CHECK_FD(fd);
return FlushFileBuffers(w32_fd_to_handle(fd)); return FlushFileBuffers(w32_fd_to_handle(fd));
} }

View File

@ -1,7 +1,33 @@
/* /*
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com> * Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
* *
* Definitions for Win32 wrapper functions with POSIX like signatures * 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 #pragma once
@ -17,7 +43,7 @@ enum w32_io_type {
}; };
enum w32_io_sock_state { enum w32_io_sock_state {
SOCK_INITIALIZED = 0, SOCK_INITIALIZED = 0,
SOCK_LISTENING = 1, /*listen called on socket*/ SOCK_LISTENING = 1, /*listen called on socket*/
SOCK_ACCEPTED = 2, /*socket returned from accept()*/ SOCK_ACCEPTED = 2, /*socket returned from accept()*/
SOCK_CONNECTING = 3, /*connect called on socket, connect is in progress*/ SOCK_CONNECTING = 3, /*connect called on socket, connect is in progress*/
@ -25,41 +51,35 @@ enum w32_io_sock_state {
}; };
/* /*
* This structure encapsulates the state info needed to map a File Descriptor * This structure encapsulates the state info needed to map a File Descriptor
* to Win32 Handle * to Win32 Handle
*/ */
struct w32_io { struct w32_io {
OVERLAPPED read_overlapped; OVERLAPPED read_overlapped;
OVERLAPPED write_overlapped; OVERLAPPED write_overlapped;
struct { struct {
/*internal read buffer*/ char *buf; /*internal read buffer*/
char *buf;
DWORD buf_size; DWORD buf_size;
/*bytes in internal buffer remaining to be read by application*/ DWORD remaining; /*bytes in internal buffer remaining to be read by application*/
DWORD remaining; DWORD completed; /*bytes in internal buffer already read by application*/
/*bytes in internal buffer already read by application*/
DWORD completed;
BOOL pending; /*waiting on a read operation to complete*/ BOOL pending; /*waiting on a read operation to complete*/
DWORD error; /*error reported on async read or accept completion*/ DWORD error; /*error reported on async read or accept completion*/
}read_details; }read_details;
struct { struct {
/*internal write buffer*/ char *buf; /*internal write buffer*/
char *buf;
DWORD buf_size; DWORD buf_size;
/*bytes in internal buffer remaining to be written to network*/ DWORD remaining; /*bytes in internal buffer remaining to be written to network*/
DWORD remaining; DWORD completed; /*bytes in internal buffer already written to network*/
/*bytes in internal buffer already written to network*/
DWORD completed;
BOOL pending; /*waiting on a write operation to complete*/ BOOL pending; /*waiting on a write operation to complete*/
DWORD error; /*error reported on async write or connect completion*/ DWORD error; /*error reported on async write or connect completion*/
}write_details; }write_details;
/*index at which this object is stored in fd_table*/ /*index at which this object is stored in fd_table*/
int table_index; int table_index;
enum w32_io_type type; /*hanldle type*/ enum w32_io_type type; /*hanldle type*/
DWORD fd_flags; /*fd flags from POSIX*/ DWORD fd_flags; /*fd flags from POSIX*/
DWORD fd_status_flags; /*fd status flags from POSIX*/ DWORD fd_status_flags; /*fd status flags from POSIX*/
/*underlying w32 handle*/ /*underlying w32 handle*/
union { union {
SOCKET sock; SOCKET sock;
@ -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); 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_socket(int domain, int type, int protocol);
struct w32_io* socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen); 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, int socketio_setsockopt(struct w32_io* pio, int level, int optname, const char* optval, int optlen);
const char* optval, int optlen); int socketio_getsockopt(struct w32_io* pio, int level, int optname, 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_getsockname(struct w32_io* pio, struct sockaddr* name, int* namelen);
int socketio_getpeername(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); 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 */ /* If O_CREAT and O_EXCL are set, open() shall fail if the file exists */
/* #define O_EXCL 0x400 */ /* #define O_EXCL 0x400 */
/* #define O_BINARY 0x8000 //Gives raw data (while O_TEXT normalises line endings */ /* #define O_BINARY 0x8000 //Gives raw data (while O_TEXT normalises line endings */
// open modes /* open modes */
#ifndef S_IRUSR #ifndef S_IRUSR
#define S_IRUSR 00400 //user has read permission #define S_IRUSR 00400 /* user has read permission */
#endif // ! S_IRUSR #endif /* ! S_IRUSR */
#ifndef S_IWUSR #ifndef S_IWUSR
#define S_IWUSR 00200 //user has write permission #define S_IWUSR 00200 /* user has write permission */
#endif #endif
#ifndef S_IRGRP #ifndef S_IRGRP
#define S_IRGRP 00040 //group has read permission #define S_IRGRP 00040 /* group has read permission */
#endif #endif
#ifndef S_IROTH #ifndef S_IROTH
#define S_IROTH 00004 //others have read permission #define S_IROTH 00004 /* others have read permission */
#endif #endif

View File

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

View File

@ -1,19 +1,43 @@
// win32_dirent.c /*
// directory entry functions in Windows platform like Ubix/Linux * Copyright (c) 2016 Microsoft Corp.
// opendir(), readdir(), closedir(). * 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 <windows.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include "inc\utf.h"
#include "inc\utf.h"
#include "inc\dirent.h" #include "inc\dirent.h"
#include "inc\libgen.h" #include "inc\libgen.h"
#include "misc_internal.h" #include "misc_internal.h"
struct DIR_ { struct DIR_ {
intptr_t hFile; intptr_t hFile;
struct _wfinddata_t c_file; struct _wfinddata_t c_file;
@ -22,7 +46,8 @@ struct DIR_ {
/* Open a directory stream on NAME. /* Open a directory stream on NAME.
Return a DIR stream on the directory, or NULL if it could not be opened. */ 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; struct _wfinddata_t c_file;
intptr_t hFile; intptr_t hFile;
@ -30,17 +55,17 @@ DIR * opendir(const char *name)
wchar_t searchstr[PATH_MAX]; wchar_t searchstr[PATH_MAX];
wchar_t* wname = NULL; wchar_t* wname = NULL;
int needed; int needed;
if ((wname = utf8_to_utf16(sanitized_path(name))) == NULL) { if ((wname = utf8_to_utf16(sanitized_path(name))) == NULL) {
errno = ENOMEM; errno = ENOMEM;
return NULL; return NULL;
} }
// add *.* for Windows _findfirst() search pattern /* add *.* for Windows _findfirst() search pattern */
swprintf_s(searchstr, PATH_MAX, L"%s\\*.*", wname); swprintf_s(searchstr, PATH_MAX, L"%s\\*.*", wname);
free(wname); free(wname);
if ((hFile = _wfindfirst(searchstr, &c_file)) == -1L) if ((hFile = _wfindfirst(searchstr, &c_file)) == -1L)
return NULL; /* errno is set by _wfindfirst */ return NULL; /* errno is set by _wfindfirst */
else { else {
if ((pdir = malloc(sizeof(DIR))) == NULL) { if ((pdir = malloc(sizeof(DIR))) == NULL) {
@ -48,34 +73,36 @@ DIR * opendir(const char *name)
errno = ENOMEM; errno = ENOMEM;
return NULL; return NULL;
} }
memset(pdir, 0, sizeof(DIR)); memset(pdir, 0, sizeof(DIR));
pdir->hFile = hFile; pdir->hFile = hFile;
memcpy(&pdir->c_file, &c_file, sizeof(c_file)); memcpy(&pdir->c_file, &c_file, sizeof(c_file));
pdir->first = 1; pdir->first = 1;
return pdir ; return pdir;
} }
} }
/* Close the directory stream DIRP. /* Close the directory stream DIRP.
Return 0 if successful, -1 if not. */ Return 0 if successful, -1 if not. */
int closedir(DIR *dirp) int
closedir(DIR *dirp)
{ {
if ( dirp && (dirp->hFile) ) { if (dirp && (dirp->hFile)) {
_findclose( dirp->hFile ); _findclose(dirp->hFile);
dirp->hFile = 0; dirp->hFile = 0;
free (dirp); free(dirp);
} }
return 0; return 0;
} }
/* Read a directory entry from DIRP. /* Read a directory entry from DIRP.
Return a pointer to a `struct dirent' describing the entry, Return a pointer to a `struct dirent' describing the entry,
or NULL for EOF or error. The storage returned may be overwritten or NULL for EOF or error. The storage returned may be overwritten
by a later readdir call on the same DIR stream. */ by a later readdir call on the same DIR stream. */
struct dirent *readdir(void *avp) struct dirent *
readdir(void *avp)
{ {
static struct dirent pdirentry; static struct dirent pdirentry;
struct _wfinddata_t c_file; struct _wfinddata_t c_file;
@ -86,11 +113,10 @@ struct dirent *readdir(void *avp)
if (dirp->first) { if (dirp->first) {
memcpy(&c_file, &dirp->c_file, sizeof(c_file)); memcpy(&c_file, &dirp->c_file, sizeof(c_file));
dirp->first = 0; dirp->first = 0;
} } else if (_wfindnext(dirp->hFile, &c_file) != 0)
else if (_wfindnext(dirp->hFile, &c_file) != 0)
return NULL; 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; continue;
if ((tmp = utf16_to_utf8(c_file.name)) == NULL) { 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); strncpy(pdirentry.d_name, tmp, strlen(tmp) + 1);
free(tmp); free(tmp);
pdirentry.d_ino = 1; // a fictious one like UNIX to say it is nonzero pdirentry.d_ino = 1; /* a fictious one like UNIX to say it is nonzero */
return &pdirentry ; return &pdirentry;
} }
} }
// return last part of a path. The last path being a filename. /* return last part of a path. The last path being a filename */
char *basename(char *path) char *
basename(char *path)
{ {
char *pdest; char *pdest;
@ -115,10 +142,10 @@ char *basename(char *path)
return "."; return ".";
pdest = strrchr(path, '/'); pdest = strrchr(path, '/');
if (pdest) if (pdest)
return (pdest+1); return (pdest + 1);
pdest = strrchr(path, '\\'); pdest = strrchr(path, '\\');
if (pdest) 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" #include "inc\zlib.h"
int int
deflateEnd(z_streamp strm) { deflateEnd(z_streamp strm)
{
return Z_DATA_ERROR; return Z_DATA_ERROR;
} }
int int
inflateEnd(z_streamp strm) { inflateEnd(z_streamp strm)
{
return Z_DATA_ERROR; return Z_DATA_ERROR;
} }
int int
deflateInit(z_streamp strm, int level) { deflateInit(z_streamp strm, int level)
{
return Z_DATA_ERROR; return Z_DATA_ERROR;
} }
int int
inflateInit(z_streamp strm) { inflateInit(z_streamp strm)
{
return Z_DATA_ERROR; return Z_DATA_ERROR;
} }
int int
deflate(z_streamp strm, int flush) { deflate(z_streamp strm, int flush)
{
return Z_DATA_ERROR; return Z_DATA_ERROR;
} }
int int
inflate(z_streamp strm, int flush) { inflate(z_streamp strm, int flush)
{
return Z_DATA_ERROR; return Z_DATA_ERROR;
} }