diff --git a/contrib/win32/win32compat/ansiprsr.c b/contrib/win32/win32compat/ansiprsr.c index 9f9bf03b7..f2e99bc66 100644 --- a/contrib/win32/win32compat/ansiprsr.c +++ b/contrib/win32/win32compat/ansiprsr.c @@ -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; } diff --git a/contrib/win32/win32compat/fileio.c b/contrib/win32/win32compat/fileio.c index f8ab73c40..06745d16c 100644 --- a/contrib/win32/win32compat/fileio.c +++ b/contrib/win32/win32compat/fileio.c @@ -32,9 +32,10 @@ #include #include #include -#include "w32fd.h" #include #include + +#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; @@ -204,7 +205,7 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) { switch (rwflags) { case O_RDONLY: cf_flags->dwDesiredAccess = GENERIC_READ; - cf_flags->dwShareMode = FILE_SHARE_READ; + cf_flags->dwShareMode = FILE_SHARE_READ; break; case O_WRONLY: 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; else cf_flags->dwCreationDisposition = CREATE_ALWAYS; - } + } if (c_s_flags & O_APPEND) 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 */ 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,12 +256,12 @@ 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; } } \ No newline at end of file diff --git a/contrib/win32/win32compat/misc.c b/contrib/win32/win32compat/misc.c index efabfef35..4a58b83df 100644 --- a/contrib/win32/win32compat/misc.c +++ b/contrib/win32/win32compat/misc.c @@ -30,11 +30,12 @@ #include #include +#include +#include + #include "inc\sys\stat.h" #include "inc\sys\statvfs.h" #include "inc\sys\time.h" -#include -#include #include "misc_internal.h" #include "inc\dlfcn.h" #include "inc\dirent.h" @@ -43,92 +44,187 @@ #include "inc\fcntl.h" #include "signal_internal.h" -int usleep(unsigned int useconds) +static char* s_programdir = NULL; + +/* Maximum reparse buffer info size. The max user defined reparse + * data is 16KB, plus there's a header. + */ +#define MAX_REPARSE_SIZE 17000 +#define IO_REPARSE_TAG_SYMBOLIC_LINK IO_REPARSE_TAG_RESERVED_ZERO +#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) /* winnt ntifs */ +#define IO_REPARSE_TAG_HSM (0xC0000004L) /* winnt ntifs */ +#define IO_REPARSE_TAG_SIS (0x80000007L) /* winnt ntifs */ +#define REPARSE_MOUNTPOINT_HEADER_SIZE 8 + +typedef struct _REPARSE_DATA_BUFFER { + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union { + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + + struct { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + }; +} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; + +/* Windows CRT defines error string messages only till 43 in errno.h + * This is an extended list that defines messages for EADDRINUSE through EWOULDBLOCK + */ +char* _sys_errlist_ext[] = { + "Address already in use", /* EADDRINUSE 100 */ + "Address not available", /* EADDRNOTAVAIL 101 */ + "Address family not supported", /* EAFNOSUPPORT 102 */ + "Connection already in progress", /* EALREADY 103 */ + "Bad message", /* EBADMSG 104 */ + "Operation canceled", /* ECANCELED 105 */ + "Connection aborted", /* ECONNABORTED 106 */ + "Connection refused", /* ECONNREFUSED 107 */ + "Connection reset", /* ECONNRESET 108 */ + "Destination address required", /* EDESTADDRREQ 109 */ + "Host is unreachable", /* EHOSTUNREACH 110 */ + "Identifier removed", /* EIDRM 111 */ + "Operation in progress", /* EINPROGRESS 112 */ + "Socket is connected", /* EISCONN 113 */ + "Too many levels of symbolic links", /* ELOOP 114 */ + "Message too long", /* EMSGSIZE 115 */ + "Network is down", /* ENETDOWN 116 */ + "Connection aborted by network", /* ENETRESET 117 */ + "Network unreachable", /* ENETUNREACH 118 */ + "No buffer space available", /* ENOBUFS 119 */ + "No message is available on the STREAM head read queue",/* ENODATA 120 */ + "Link has been severed", /* ENOLINK 121 */ + "No message of the desired type", /* ENOMSG 122 */ + "Protocol not available", /* ENOPROTOOPT 123 */ + "No STREAM resources", /* ENOSR 124 */ + "Not a STREAM", /* ENOSTR 125 */ + "The socket is not connected", /* ENOTCONN 126 */ + "enotecoverable", /* ENOTRECOVERABLE 127 */ + "Not a socket", /* ENOTSOCK 128 */ + "Operation not supported", /* ENOTSUP 129 */ + "Operation not supported on socket", /* EOPNOTSUPP 130 */ + "eother", /* EOTHER 131 */ + "Value too large to be stored in data type", /* EOVERFLOW 132 */ + "eownerdead", /* EOWNERDEAD 133 */ + "Protocol error", /* EPROTO 134 */ + "Protocol not supported", /* EPROTONOSUPPORT 135 */ + "Protocol wrong type for socket", /* EPROTOTYPE 136 */ + "Timer expired", /* ETIME 137 */ + "Connection timed out", /* ETIMEDOUT 138 */ + "Text file busy", /* ETXTBSY 139 */ + "Operation would block" /* EWOULDBLOCK 140 */ +}; + +int +usleep(unsigned int useconds) { Sleep(useconds / 1000); return 1; } -int nanosleep(const struct timespec *req, struct timespec *rem) { - HANDLE timer; - LARGE_INTEGER li; +int +nanosleep(const struct timespec *req, struct timespec *rem) +{ + HANDLE timer; + LARGE_INTEGER li; - if (req->tv_sec < 0 || req->tv_nsec < 0 || req->tv_nsec > 999999999) { - errno = EINVAL; - return -1; - } + if (req->tv_sec < 0 || req->tv_nsec < 0 || req->tv_nsec > 999999999) { + errno = EINVAL; + return -1; + } - if ((timer = CreateWaitableTimerW(NULL, TRUE, NULL)) == NULL) { - errno = EFAULT; - return -1; - } + if ((timer = CreateWaitableTimerW(NULL, TRUE, NULL)) == NULL) { + errno = EFAULT; + return -1; + } - li.QuadPart = -req->tv_nsec; - if (!SetWaitableTimer(timer, &li, 0, NULL, NULL, FALSE)) { - CloseHandle(timer); - errno = EFAULT; - return -1; - } - - /* TODO - use wait_for_any_event, since we want to wake up on interrupts*/ - switch (WaitForSingleObject(timer, INFINITE)) { - case WAIT_OBJECT_0: - CloseHandle(timer); - return 0; - default: - errno = EFAULT; - return -1; - } + li.QuadPart = -req->tv_nsec; + if (!SetWaitableTimer(timer, &li, 0, NULL, NULL, FALSE)) { + CloseHandle(timer); + errno = EFAULT; + return -1; + } + + /* TODO - use wait_for_any_event, since we want to wake up on interrupts*/ + switch (WaitForSingleObject(timer, INFINITE)) { + case WAIT_OBJECT_0: + CloseHandle(timer); + return 0; + default: + errno = EFAULT; + return -1; + } } /* Difference in us between UNIX Epoch and Win32 Epoch */ #define EPOCH_DELTA_US 11644473600000000ULL /* This routine is contributed by * Author: NoMachine -* Copyright (c) 2009, 2010 NoMachine -* All rights reserved -*/ + * Copyright (c) 2009, 2010 NoMachine + * All rights reserved + */ int gettimeofday(struct timeval *tv, void *tz) { - union - { - FILETIME ft; - unsigned long long ns; - } timehelper; - unsigned long long us; + union { + FILETIME ft; + unsigned long long ns; + } timehelper; + unsigned long long us; - /* Fetch time since Jan 1, 1601 in 100ns increments */ - GetSystemTimeAsFileTime(&timehelper.ft); + /* Fetch time since Jan 1, 1601 in 100ns increments */ + GetSystemTimeAsFileTime(&timehelper.ft); - /* Convert to microseconds from 100 ns units */ - us = timehelper.ns / 10; + /* Convert to microseconds from 100 ns units */ + us = timehelper.ns / 10; - /* Remove the epoch difference */ - us -= EPOCH_DELTA_US; + /* Remove the epoch difference */ + us -= EPOCH_DELTA_US; - /* Stuff result into the timeval */ - tv->tv_sec = (long)(us / 1000000ULL); - tv->tv_usec = (long)(us % 1000000ULL); + /* Stuff result into the timeval */ + tv->tv_sec = (long)(us / 1000000ULL); + tv->tv_usec = (long)(us % 1000000ULL); - return 0; + return 0; } void -explicit_bzero(void *b, size_t len) { +explicit_bzero(void *b, size_t len) +{ SecureZeroMemory(b, len); } -HMODULE dlopen(const char *filename, int flags) { +HMODULE +dlopen(const char *filename, int flags) +{ return LoadLibraryA(filename); } -int dlclose(HMODULE handle) { +int +dlclose(HMODULE handle) +{ FreeLibrary(handle); return 0; } -FARPROC dlsym(HMODULE handle, const char *symbol) { +FARPROC +dlsym(HMODULE handle, const char *symbol) +{ return GetProcAddress(handle, symbol); } @@ -136,8 +232,9 @@ FARPROC dlsym(HMODULE handle, const char *symbol) { /*fopen on Windows to mimic https://linux.die.net/man/3/fopen * only r, w, a are supported for now */ -FILE* -w32_fopen_utf8(const char *path, const char *mode) { +FILE * +w32_fopen_utf8(const char *path, const char *mode) +{ wchar_t wpath[PATH_MAX], wmode[5]; FILE* f; char utf8_bom[] = { 0xEF,0xBB,0xBF }; @@ -149,7 +246,7 @@ w32_fopen_utf8(const char *path, const char *mode) { } if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, PATH_MAX) == 0 || - MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, 5) == 0) { + MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, 5) == 0) { errno = EFAULT; debug("WideCharToMultiByte failed for %c - ERROR:%d", path, GetLastError()); return NULL; @@ -166,11 +263,10 @@ w32_fopen_utf8(const char *path, const char *mode) { return NULL; }*/ - } - else if (mode[0] == 'r' && fseek(f, 0, SEEK_SET) != EBADF) { + } else if (mode[0] == 'r' && fseek(f, 0, SEEK_SET) != EBADF) { /* read out UTF-8 BOM if present*/ if (fread(first3_bytes, 3, 1, f) != 1 || - memcmp(first3_bytes, utf8_bom, 3) != 0) { + memcmp(first3_bytes, utf8_bom, 3) != 0) { fseek(f, 0, SEEK_SET); } } @@ -180,85 +276,90 @@ w32_fopen_utf8(const char *path, const char *mode) { } -wchar_t* -utf8_to_utf16(const char *utf8) { - int needed = 0; - wchar_t* utf16 = NULL; - if ((needed = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0)) == 0 || - (utf16 = malloc(needed * sizeof(wchar_t))) == NULL || - MultiByteToWideChar(CP_UTF8, 0, utf8, -1, utf16, needed) == 0) - return NULL; - return utf16; +wchar_t * +utf8_to_utf16(const char *utf8) +{ + int needed = 0; + wchar_t* utf16 = NULL; + if ((needed = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0)) == 0 || + (utf16 = malloc(needed * sizeof(wchar_t))) == NULL || + MultiByteToWideChar(CP_UTF8, 0, utf8, -1, utf16, needed) == 0) + return NULL; + + return utf16; } -char* -utf16_to_utf8(const wchar_t* utf16) { - int needed = 0; - char* utf8 = NULL; - if ((needed = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, NULL, NULL)) == 0 || - (utf8 = malloc(needed)) == NULL || - WideCharToMultiByte(CP_UTF8, 0, utf16, -1, utf8, needed, NULL, NULL) == 0) - return NULL; - return utf8; +char * +utf16_to_utf8(const wchar_t* utf16) +{ + int needed = 0; + char* utf8 = NULL; + if ((needed = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, NULL, NULL)) == 0 || + (utf8 = malloc(needed)) == NULL || + WideCharToMultiByte(CP_UTF8, 0, utf16, -1, utf8, needed, NULL, NULL) == 0) + return NULL; + + return utf8; } -static char* s_programdir = NULL; -char* w32_programdir() { - if (s_programdir != NULL) - return s_programdir; +char * +w32_programdir() +{ + if (s_programdir != NULL) + return s_programdir; - if ((s_programdir = utf16_to_utf8(_wpgmptr)) == NULL) - return NULL; + if ((s_programdir = utf16_to_utf8(_wpgmptr)) == NULL) + return NULL; - /* null terminate after directory path */ - { - char* tail = s_programdir + strlen(s_programdir); - while (tail > s_programdir && *tail != '\\' && *tail != '/') - tail--; + /* null terminate after directory path */ + char* tail = s_programdir + strlen(s_programdir); + while (tail > s_programdir && *tail != '\\' && *tail != '/') + tail--; - if (tail > s_programdir) - *tail = '\0'; - else - *tail = '.'; /* current directory */ - } - - return s_programdir; + if (tail > s_programdir) + *tail = '\0'; + else + *tail = '.'; /* current directory */ + return s_programdir; } -int +int daemon(int nochdir, int noclose) { - FreeConsole(); - return 0; + FreeConsole(); + return 0; } -int w32_ioctl(int d, int request, ...) { - va_list valist; - va_start(valist, request); +int +w32_ioctl(int d, int request, ...) +{ + va_list valist; + va_start(valist, request); - switch (request){ - case TIOCGWINSZ: { - struct winsize* wsize = va_arg(valist, struct winsize*); - CONSOLE_SCREEN_BUFFER_INFO c_info; - if (wsize == NULL || !GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &c_info)) { - errno = EINVAL; - return -1; - } - wsize->ws_col = c_info.dwSize.X - 5; - wsize->ws_row = c_info.dwSize.Y; - wsize->ws_xpixel = 640; - wsize->ws_ypixel = 480; - return 0; - } - default: - errno = ENOTSUP; - return -1; - } + switch (request) { + case TIOCGWINSZ: { + struct winsize* wsize = va_arg(valist, struct winsize*); + CONSOLE_SCREEN_BUFFER_INFO c_info; + if (wsize == NULL || !GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &c_info)) { + errno = EINVAL; + return -1; + } + wsize->ws_col = c_info.dwSize.X - 5; + wsize->ws_row = c_info.dwSize.Y; + wsize->ws_xpixel = 640; + wsize->ws_ypixel = 480; + return 0; + } + default: + errno = ENOTSUP; + return -1; + } } -int -spawn_child(char* cmd, int in, int out, int err, DWORD flags) { +int +spawn_child(char* cmd, int in, int out, int err, DWORD flags) +{ PROCESS_INFORMATION pi; STARTUPINFOW si; BOOL b; @@ -267,8 +368,8 @@ spawn_child(char* cmd, int in, int out, int err, DWORD flags) { int add_module_path = 0; /* should module path be added */ - do{ - if(!cmd) + do { + if (!cmd) break; t = cmd; if (*t == '\"') @@ -276,7 +377,6 @@ spawn_child(char* cmd, int in, int out, int err, DWORD flags) { if (t[0] == '\0' || t[0] == '\\' || t[0] == '.' || t[1] == ':') break; add_module_path = 1; - } while (0); /* add current module path to start if needed */ @@ -292,10 +392,9 @@ spawn_child(char* cmd, int in, int out, int err, DWORD flags) { ctr += strlen(w32_programdir()); *ctr++ = '\\'; memcpy(ctr, cmd, strlen(cmd) + 1); - } - else + } else abs_cmd = cmd; - + debug("spawning %s", abs_cmd); if ((cmd_utf16 = utf8_to_utf16(abs_cmd)) == NULL) { @@ -303,7 +402,7 @@ spawn_child(char* cmd, int in, int out, int err, DWORD flags) { return -1; } - if(abs_cmd != cmd) + if (abs_cmd != cmd) free(abs_cmd); memset(&si, 0, sizeof(STARTUPINFOW)); @@ -322,8 +421,7 @@ spawn_child(char* cmd, int in, int out, int err, DWORD flags) { pi.dwProcessId = -1; } CloseHandle(pi.hThread); - } - else { + } else { errno = GetLastError(); pi.dwProcessId = -1; } @@ -343,15 +441,9 @@ strmode(mode_t mode, char *p) case S_IFCHR: /* character special */ *p++ = 'c'; break; - //case S_IFBLK: /* block special */ - // *p++ = 'b'; - // break; case S_IFREG: /* regular */ *p++ = '-'; break; - //case S_IFLNK: /* symbolic link */ - // *p++ = 'l'; - // break; #ifdef S_IFSOCK case S_IFSOCK: /* socket */ *p++ = 's'; @@ -364,82 +456,84 @@ strmode(mode_t mode, char *p) *p++ = '?'; break; } - - // The below code is commented as the group, other is not applicable on the windows. - // This will be properly fixed in next releases. - // As of now we are keeping "*" for everything. + + /* The below code is commented as the group, other is not applicable on the windows. + * This will be properly fixed in next releases. + * As of now we are keeping "*" for everything. + */ const char *permissions = "********* "; strncpy(p, permissions, strlen(permissions) + 1); p = p + strlen(p); - ///* usr */ - //if (mode & S_IRUSR) - // *p++ = 'r'; - //else - // *p++ = '-'; - //if (mode & S_IWUSR) - // *p++ = 'w'; - //else - // *p++ = '-'; - //switch (mode & (S_IXUSR)) { - //case 0: - // *p++ = '-'; - // break; - //case S_IXUSR: - // *p++ = 'x'; - // break; - // //case S_ISUID: - // // *p++ = 'S'; - // // break; - // //case S_IXUSR | S_ISUID: - // // *p++ = 's'; - // // break; - //} - ///* group */ - //if (mode & S_IRGRP) - // *p++ = 'r'; - //else - // *p++ = '-'; - //if (mode & S_IWGRP) - // *p++ = 'w'; - //else - // *p++ = '-'; - //switch (mode & (S_IXGRP)) { - //case 0: - // *p++ = '-'; - // break; - //case S_IXGRP: - // *p++ = 'x'; - // break; - // //case S_ISGID: - // // *p++ = 'S'; - // // break; - // //case S_IXGRP | S_ISGID: - // // *p++ = 's'; - // // break; - //} - ///* other */ - //if (mode & S_IROTH) - // *p++ = 'r'; - //else - // *p++ = '-'; - //if (mode & S_IWOTH) - // *p++ = 'w'; - //else - // *p++ = '-'; - //switch (mode & (S_IXOTH)) { - //case 0: - // *p++ = '-'; - // break; - //case S_IXOTH: - // *p++ = 'x'; - // break; - //} - //*p++ = ' '; /* will be a '+' if ACL's implemented */ + /* //usr + if (mode & S_IRUSR) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWUSR) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXUSR)) { + case 0: + *p++ = '-'; + break; + case S_IXUSR: + *p++ = 'x'; + break; + //case S_ISUID: + // *p++ = 'S'; + // break; + //case S_IXUSR | S_ISUID: + // *p++ = 's'; + // break; + } + // group + if (mode & S_IRGRP) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWGRP) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXGRP)) { + case 0: + *p++ = '-'; + break; + case S_IXGRP: + *p++ = 'x'; + break; + //case S_ISGID: + // *p++ = 'S'; + // break; + //case S_IXGRP | S_ISGID: + // *p++ = 's'; + // break; + } + // other + if (mode & S_IROTH) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWOTH) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXOTH)) { + case 0: + *p++ = '-'; + break; + case S_IXOTH: + *p++ = 'x'; + break; + } + *p++ = ' '; // will be a '+' if ACL's implemented */ *p = '\0'; } -int -w32_chmod(const char *pathname, mode_t mode) { +int +w32_chmod(const char *pathname, mode_t mode) +{ int ret; wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(pathname)); if (resolvedPathName_utf16 == NULL) { @@ -451,16 +545,17 @@ w32_chmod(const char *pathname, mode_t mode) { return ret; } -int -w32_chown(const char *pathname, unsigned int owner, unsigned int group) { +int +w32_chown(const char *pathname, unsigned int owner, unsigned int group) +{ /* TODO - implement this */ errno = EOPNOTSUPP; return -1; } static void -unix_time_to_file_time(ULONG t, LPFILETIME pft) { - +unix_time_to_file_time(ULONG t, LPFILETIME pft) +{ ULONGLONG ull; ull = UInt32x32To64(t, 10000000) + 116444736000000000; @@ -469,7 +564,8 @@ unix_time_to_file_time(ULONG t, LPFILETIME pft) { } static int -settimes(wchar_t * path, FILETIME *cretime, FILETIME *acttime, FILETIME *modtime) { +settimes(wchar_t * path, FILETIME *cretime, FILETIME *acttime, FILETIME *modtime) +{ HANDLE handle; handle = CreateFileW(path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); @@ -493,7 +589,8 @@ settimes(wchar_t * path, FILETIME *cretime, FILETIME *acttime, FILETIME *modtime } int -w32_utimes(const char *filename, struct timeval *tvp) { +w32_utimes(const char *filename, struct timeval *tvp) +{ int ret; FILETIME acttime, modtime; wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(filename)); @@ -511,25 +608,28 @@ w32_utimes(const char *filename, struct timeval *tvp) { return ret; } -int -w32_symlink(const char *target, const char *linkpath) { - // Not supported in windows - errno = EOPNOTSUPP; - return -1; -} - -int -link(const char *oldpath, const char *newpath) { - // Not supported in windows +int +w32_symlink(const char *target, const char *linkpath) +{ + /* Not supported in windows */ errno = EOPNOTSUPP; return -1; } int -w32_rename(const char *old_name, const char *new_name) { +link(const char *oldpath, const char *newpath) +{ + /* Not supported in windows */ + errno = EOPNOTSUPP; + return -1; +} + +int +w32_rename(const char *old_name, const char *new_name) +{ wchar_t *resolvedOldPathName_utf16 = utf8_to_utf16(sanitized_path(old_name)); wchar_t *resolvedNewPathName_utf16 = utf8_to_utf16(sanitized_path(new_name)); - + if (NULL == resolvedOldPathName_utf16 || NULL == resolvedNewPathName_utf16) { errno = ENOMEM; return -1; @@ -542,17 +642,16 @@ w32_rename(const char *old_name, const char *new_name) { */ struct _stat64 st; if (fileio_stat(sanitized_path(new_name), &st) != -1) { - if(((st.st_mode & _S_IFMT) == _S_IFREG)) { + if (((st.st_mode & _S_IFMT) == _S_IFREG)) w32_unlink(new_name); - } else { + else { DIR *dirp = opendir(new_name); if (NULL != dirp) { struct dirent *dp = readdir(dirp); closedir(dirp); - if (dp == NULL) { + if (dp == NULL) w32_rmdir(new_name); - } } } } @@ -565,8 +664,8 @@ w32_rename(const char *old_name, const char *new_name) { } int -w32_unlink(const char *path) { - +w32_unlink(const char *path) +{ wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(path)); if (NULL == resolvedPathName_utf16) { errno = ENOMEM; @@ -580,7 +679,8 @@ w32_unlink(const char *path) { } int -w32_rmdir(const char *path) { +w32_rmdir(const char *path) +{ wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(path)); if (NULL == resolvedPathName_utf16) { errno = ENOMEM; @@ -593,8 +693,9 @@ w32_rmdir(const char *path) { return returnStatus; } -int -w32_chdir(const char *dirname_utf8) { +int +w32_chdir(const char *dirname_utf8) +{ wchar_t *dirname_utf16 = utf8_to_utf16(dirname_utf8); if (dirname_utf16 == NULL) { errno = ENOMEM; @@ -608,7 +709,8 @@ w32_chdir(const char *dirname_utf8) { } char * -w32_getcwd(char *buffer, int maxlen) { +w32_getcwd(char *buffer, int maxlen) +{ wchar_t wdirname[PATH_MAX]; char* putf8 = NULL; @@ -623,8 +725,8 @@ w32_getcwd(char *buffer, int maxlen) { } int -w32_mkdir(const char *path_utf8, unsigned short mode) { - +w32_mkdir(const char *path_utf8, unsigned short mode) +{ wchar_t *path_utf16 = utf8_to_utf16(sanitized_path(path_utf8)); if (path_utf16 == NULL) { errno = ENOMEM; @@ -635,32 +737,34 @@ w32_mkdir(const char *path_utf8, unsigned short mode) { free(path_utf16); return -1; } - + mode_t curmask = _umask(0); _umask(curmask); - + returnStatus = _wchmod(path_utf16, mode & ~curmask & (_S_IREAD | _S_IWRITE)); free(path_utf16); - + return returnStatus; } int -w32_stat(const char *path, struct w32_stat *buf) { +w32_stat(const char *path, struct w32_stat *buf) +{ return fileio_stat(sanitized_path(path), (struct _stat64*)buf); } -// if file is symbolic link, copy its link into "link" . -int +/* if file is symbolic link, copy its link into "link" */ +int readlink(const char *path, char *link, int linklen) { strcpy_s(link, linklen, sanitized_path(path)); return 0; } -// convert forward slash to back slash +/* convert forward slash to back slash */ void -convertToBackslash(char *str) { +convertToBackslash(char *str) +{ while (*str) { if (*str == '/') *str = '\\'; @@ -668,9 +772,10 @@ convertToBackslash(char *str) { } } -// convert back slash to forward slash -void -convertToForwardslash(char *str) { +/* convert back slash to forward slash */ +void +convertToForwardslash(char *str) +{ while (*str) { if (*str == '\\') *str = '/'; @@ -683,131 +788,90 @@ convertToForwardslash(char *str) { * path to produce a canonicalized absolute pathname. */ char * -realpath(const char *path, char resolved[PATH_MAX]) { +realpath(const char *path, char resolved[PATH_MAX]) +{ char tempPath[PATH_MAX]; - - if ((path[0] == '/') && path[1] && (path[2] == ':')) { - strncpy(resolved, path + 1, strlen(path)); // skip the first '/' - } else { - strncpy(resolved, path, strlen(path) + 1); - } - if ((resolved[0]) && (resolved[1] == ':') && (resolved[2] == '\0')) { // make "x:" as "x:\\" + if ((path[0] == '/') && path[1] && (path[2] == ':')) + strncpy(resolved, path + 1, strlen(path)); /* skip the first '/' */ + else + strncpy(resolved, path, strlen(path) + 1); + + if ((resolved[0]) && (resolved[1] == ':') && (resolved[2] == '\0')) { /* make "x:" as "x:\\" */ resolved[2] = '\\'; resolved[3] = '\0'; } if (_fullpath(tempPath, resolved, PATH_MAX) == NULL) return NULL; - + convertToForwardslash(tempPath); - resolved[0] = '/'; // will be our first slash in /x:/users/test1 format + resolved[0] = '/'; /* will be our first slash in /x:/users/test1 format */ strncpy(resolved + 1, tempPath, sizeof(tempPath) - 1); return resolved; } char* -sanitized_path(const char *path) { +sanitized_path(const char *path) +{ static char newPath[PATH_MAX] = { '\0', }; if (path[0] == '/' && path[1]) { if (path[2] == ':') { - if (path[3] == '\0') { // make "/x:" as "x:\\" + if (path[3] == '\0') { /* make "/x:" as "x:\\" */ strncpy(newPath, path + 1, strlen(path) - 1); newPath[2] = '\\'; newPath[3] = '\0'; return newPath; - } else { - return (char *)(path + 1); // skip the first "/" - } - } - } + } else + return (char *)(path + 1); /* skip the first "/" */ + } + } - return (char *)path; + return (char *)path; } -// Maximum reparse buffer info size. The max user defined reparse -// data is 16KB, plus there's a header. -#define MAX_REPARSE_SIZE 17000 -#define IO_REPARSE_TAG_SYMBOLIC_LINK IO_REPARSE_TAG_RESERVED_ZERO -#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) // winnt ntifs -#define IO_REPARSE_TAG_HSM (0xC0000004L) // winnt ntifs -#define IO_REPARSE_TAG_SIS (0x80000007L) // winnt ntifs -#define REPARSE_MOUNTPOINT_HEADER_SIZE 8 -typedef struct _REPARSE_DATA_BUFFER { - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union { - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - struct { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - }; -} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; - -BOOL -ResolveLink(wchar_t * tLink, wchar_t *ret, DWORD * plen, DWORD Flags) { - HANDLE fileHandle; - BYTE reparseBuffer[MAX_REPARSE_SIZE]; - PBYTE reparseData; +BOOL +ResolveLink(wchar_t * tLink, wchar_t *ret, DWORD * plen, DWORD Flags) +{ + HANDLE fileHandle; + BYTE reparseBuffer[MAX_REPARSE_SIZE]; + PBYTE reparseData; PREPARSE_GUID_DATA_BUFFER reparseInfo = (PREPARSE_GUID_DATA_BUFFER)reparseBuffer; PREPARSE_DATA_BUFFER msReparseInfo = (PREPARSE_DATA_BUFFER)reparseBuffer; DWORD returnedLength; - if (Flags & FILE_ATTRIBUTE_DIRECTORY) - { + if (Flags & FILE_ATTRIBUTE_DIRECTORY) { fileHandle = CreateFileW(tLink, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0); - } - else { - - // - // Open the file - // + } else { + /* Open the file */ fileHandle = CreateFileW(tLink, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, 0); } - if (fileHandle == INVALID_HANDLE_VALUE) - { + + if (fileHandle == INVALID_HANDLE_VALUE) { swprintf_s(ret, *plen, L"%ls", tLink); return TRUE; } if (GetFileAttributesW(tLink) & FILE_ATTRIBUTE_REPARSE_POINT) { - if (DeviceIoControl(fileHandle, FSCTL_GET_REPARSE_POINT, NULL, 0, reparseInfo, sizeof(reparseBuffer), &returnedLength, NULL)) { - if (IsReparseTagMicrosoft(reparseInfo->ReparseTag)) { - switch (reparseInfo->ReparseTag) { case 0x80000000 | IO_REPARSE_TAG_SYMBOLIC_LINK: case IO_REPARSE_TAG_MOUNT_POINT: - if (*plen >= msReparseInfo->MountPointReparseBuffer.SubstituteNameLength) - { + if (*plen >= msReparseInfo->MountPointReparseBuffer.SubstituteNameLength) { reparseData = (PBYTE)&msReparseInfo->SymbolicLinkReparseBuffer.PathBuffer; WCHAR temp[1024]; wcsncpy_s(temp, 1024, @@ -815,9 +879,7 @@ ResolveLink(wchar_t * tLink, wchar_t *ret, DWORD * plen, DWORD Flags) { (size_t)msReparseInfo->MountPointReparseBuffer.SubstituteNameLength); temp[msReparseInfo->MountPointReparseBuffer.SubstituteNameLength] = 0; swprintf_s(ret, *plen, L"%ls", &temp[4]); - } - else - { + } else { swprintf_s(ret, *plen, L"%ls", tLink); return FALSE; } @@ -828,16 +890,16 @@ ResolveLink(wchar_t * tLink, wchar_t *ret, DWORD * plen, DWORD Flags) { } } } - } - else { + } else swprintf_s(ret, *plen, L"%ls", tLink); - } CloseHandle(fileHandle); return TRUE; } -int statvfs(const char *path, struct statvfs *buf) { +int +statvfs(const char *path, struct statvfs *buf) +{ DWORD sectorsPerCluster; DWORD bytesPerSector; DWORD freeClusters; @@ -845,8 +907,7 @@ int statvfs(const char *path, struct statvfs *buf) { wchar_t* path_utf16 = utf8_to_utf16(sanitized_path(path)); if (GetDiskFreeSpaceW(path_utf16, §orsPerCluster, &bytesPerSector, - &freeClusters, &totalClusters) == TRUE) - { + &freeClusters, &totalClusters) == TRUE) { debug3("path : [%s]", path); debug3("sectorsPerCluster : [%lu]", sectorsPerCluster); debug3("bytesPerSector : [%lu]", bytesPerSector); @@ -868,74 +929,25 @@ int statvfs(const char *path, struct statvfs *buf) { free(path_utf16); return 0; - } - else - { - debug3("ERROR: Cannot get free space for [%s]. Error code is : %d.\n", - path, GetLastError()); + } else { + debug3("ERROR: Cannot get free space for [%s]. Error code is : %d.\n", path, GetLastError()); free(path_utf16); return -1; } } -int fstatvfs(int fd, struct statvfs *buf) { +int +fstatvfs(int fd, struct statvfs *buf) +{ errno = ENOTSUP; return -1; } -/* w32_strerror start */ -/* Windows CRT defines error string messages only till 43 in errno.h*/ -/* This is an extended list that defines messages for EADDRINUSE through EWOULDBLOCK*/ -char* _sys_errlist_ext[] = { - "Address already in use", // EADDRINUSE 100 - "Address not available", // EADDRNOTAVAIL 101 - "Address family not supported", // EAFNOSUPPORT 102 - "Connection already in progress", // EALREADY 103 - "Bad message", // EBADMSG 104 - "Operation canceled", // ECANCELED 105 - "Connection aborted", // ECONNABORTED 106 - "Connection refused", // ECONNREFUSED 107 - "Connection reset", // ECONNRESET 108 - "Destination address required", // EDESTADDRREQ 109 - "Host is unreachable", // EHOSTUNREACH 110 - "Identifier removed", // EIDRM 111 - "Operation in progress", // EINPROGRESS 112 - "Socket is connected", // EISCONN 113 - "Too many levels of symbolic links", // ELOOP 114 - "Message too long", // EMSGSIZE 115 - "Network is down", // ENETDOWN 116 - "Connection aborted by network", // ENETRESET 117 - "Network unreachable", // ENETUNREACH 118 - "No buffer space available", // ENOBUFS 119 - "No message is available on the STREAM head read queue", // ENODATA 120 - "Link has been severed", // ENOLINK 121 - "No message of the desired type", // ENOMSG 122 - "Protocol not available", // ENOPROTOOPT 123 - "No STREAM resources", // ENOSR 124 - "Not a STREAM", // ENOSTR 125 - "The socket is not connected", // ENOTCONN 126 - "enotecoverable", // ENOTRECOVERABLE 127 - "Not a socket", // ENOTSOCK 128 - "Operation not supported", // ENOTSUP 129 - "Operation not supported on socket", // EOPNOTSUPP 130 - "eother", // EOTHER 131 - "Value too large to be stored in data type", // EOVERFLOW 132 - "eownerdead", // EOWNERDEAD 133 - "Protocol error", // EPROTO 134 - "Protocol not supported", // EPROTONOSUPPORT 135 - "Protocol wrong type for socket", // EPROTOTYPE 136 - "Timer expired", // ETIME 137 - "Connection timed out", // ETIMEDOUT 138 - "Text file busy", // ETXTBSY 139 - "Operation would block" // EWOULDBLOCK 140 -}; - char * -w32_strerror(int errnum) { +w32_strerror(int errnum) +{ if (errnum >= EADDRINUSE && errnum <= EWOULDBLOCK) return _sys_errlist_ext[errnum - EADDRINUSE]; return strerror(errnum); } - -/* w32_strerror end */ \ No newline at end of file diff --git a/contrib/win32/win32compat/no-ops.c b/contrib/win32/win32compat/no-ops.c index 48db70c95..fdd36fedf 100644 --- a/contrib/win32/win32compat/no-ops.c +++ b/contrib/win32/win32compat/no-ops.c @@ -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; +int +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; +} + diff --git a/contrib/win32/win32compat/pwd.c b/contrib/win32/win32compat/pwd.c index a247e8b78..bb1b714a2 100644 --- a/contrib/win32/win32compat/pwd.c +++ b/contrib/win32/win32compat/pwd.c @@ -36,6 +36,7 @@ #include #define SECURITY_WIN32 #include + #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; } @@ -126,7 +132,7 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) { NET_API_STATUS status; 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); - + if ((dsStatus = DsGetDcNameW(NULL, udom_utf16, NULL, NULL, DS_DIRECTORY_SERVICE_PREFERRED, &pdc)) != ERROR_SUCCESS) { error("DsGetDcNameW() failed with error: %d \n", dsStatus); 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); errno = ENOENT; goto done; - } + } } - + 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()); errno = ENOENT; goto done; } - + user_sid = user_sid_local; } /* 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, ®_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, ®_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; } diff --git a/contrib/win32/win32compat/signal.c b/contrib/win32/win32compat/signal.c index ab567a0db..e4fd581a2 100644 --- a/contrib/win32/win32compat/signal.c +++ b/contrib/win32/win32compat/signal.c @@ -28,10 +28,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "w32fd.h" #include +#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 - ) { +static VOID CALLBACK +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,48 +98,45 @@ 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; - +void +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) { +sighandler_t +w32_signal(int signum, sighandler_t handler) +{ sighandler_t prev; - debug2("signal() sig:%d, handler:%p", signum, handler); if (signum >= W32_SIGMAX) { errno = EINVAL; return W32_SIG_ERR; } - prev = sig_handlers[signum]; + prev = sig_handlers[signum]; sig_handlers[signum] = handler; return prev; } -int -w32_sigprocmask(int how, const sigset_t *set, sigset_t *oldset) { +int +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"); @@ -150,8 +145,9 @@ w32_sigprocmask(int how, const sigset_t *set, sigset_t *oldset) { -int -w32_raise(int sig) { +int +w32_raise(int sig) +{ debug("raise sig:%d", sig); if (sig == W32_SIGSEGV) return raise(SIGSEGV); /* raise native exception handler*/ @@ -170,7 +166,7 @@ w32_raise(int sig) { /* if set to ignore, nothing to do */ if (sig_handlers[sig] == W32_SIG_IGN) return 0; - + /* execute any default handlers */ switch (sig) { case W32_SIGCHLD: @@ -184,8 +180,9 @@ w32_raise(int sig) { } /* processes pending signals, return -1 and errno=EINTR if any are processed*/ -static int -sw_process_pending_signals() { +static int +sw_process_pending_signals() +{ sigset_t pending_tmp = pending_signals; BOOL sig_int = FALSE; /* has any signal actually interrupted */ @@ -195,7 +192,7 @@ sw_process_pending_signals() { /* check for expected signals*/ for (i = 0; i < (sizeof(exp) / sizeof(exp[0])); i++) sigdelset(&pending_tmp, exp[i]); - if (pending_tmp) { + if (pending_tmp) { /* unexpected signals queued up */ debug("process_signals() - ERROR unexpected signals in queue: %d", pending_tmp); errno = ENOTSUP; @@ -219,7 +216,7 @@ sw_process_pending_signals() { sigdelset(&pending_tmp, exp[i]); } } - + /* by now all pending signals should have been taken care of*/ if (pending_tmp) @@ -235,17 +232,17 @@ sw_process_pending_signals() { } /* - * Main wait routine used by all blocking calls. - * It wakes up on + * Main wait routine used by all blocking calls. + * It wakes up on * - any signals (errno = EINTR ) - * - any of the supplied events set - * - any APCs caused by IO completions - * - time out + * - any of the supplied events set + * - any APCs caused by IO completions + * - time out * - 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 */ -int +int wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds) { 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); /* 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) diff --git a/contrib/win32/win32compat/signal_sigalrm.c b/contrib/win32/win32compat/signal_sigalrm.c index 4f83c86cc..31f552735 100644 --- a/contrib/win32/win32compat/signal_sigalrm.c +++ b/contrib/win32/win32compat/signal_sigalrm.c @@ -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; } \ No newline at end of file diff --git a/contrib/win32/win32compat/signal_sigchld.c b/contrib/win32/win32compat/signal_sigchld.c index 4ad7c9328..7a43ee70b 100644 --- a/contrib/win32/win32compat/signal_sigchld.c +++ b/contrib/win32/win32compat/signal_sigchld.c @@ -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; @@ -214,7 +214,7 @@ int waitpid(int pid, int *status, int options) { sw_remove_child_at_index(children.num_children - 1); return ret_id; } - + /* all children are alive. wait for one of them to exit */ timeout = INFINITE; if (options & WNOHANG) @@ -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); - } } \ No newline at end of file diff --git a/contrib/win32/win32compat/socketio.c b/contrib/win32/win32compat/socketio.c index c4ba4948a..af946835d 100644 --- a/contrib/win32/win32compat/socketio.c +++ b/contrib/win32/win32compat/socketio.c @@ -33,19 +33,26 @@ #include #include #include -#include "w32fd.h" #include +#include "w32fd.h" #include "inc\utf.h" #define INTERNAL_SEND_BUFFER_SIZE 70*1024 //70KB - #define INTERNAL_RECV_BUFFER_SIZE 70*1024 //70KB - #define errno_from_WSALastError() errno_from_WSAError(WSAGetLastError()) +/* state info that needs to be persisted for an inprocess acceptEx call*/ +struct acceptEx_context { + char lpOutputBuf[1024]; + SOCKET accept_socket; + LPFN_ACCEPTEX lpfnAcceptEx; + LPFN_GETACCEPTEXSOCKADDRS lpfnGuidGetAcceptExSockaddrs; + DWORD bytes_received; +}; + /* maps WSAError to errno */ -static -int errno_from_WSAError(int wsaerrno) +static int +errno_from_WSAError(int wsaerrno) { /* TODO - create a mapping table - more efficient */ switch (wsaerrno) { @@ -70,43 +77,34 @@ int errno_from_WSAError(int wsaerrno) case WSAECONNRESET: return ECONNRESET; default: - /* */ return wsaerrno - 10000; } } /* called before any other calls to socketio_ functions */ -int -socketio_initialize() { +int +socketio_initialize() +{ WSADATA wsaData = { 0 }; return WSAStartup(MAKEWORD(2, 2), &wsaData); } /* cleanup */ -int -socketio_done() { +int +socketio_done() +{ WSACleanup(); return 0; } -/* state info that needs to be persisted for an inprocess acceptEx call*/ -struct acceptEx_context { - char lpOutputBuf[1024]; - SOCKET accept_socket; - LPFN_ACCEPTEX lpfnAcceptEx; - LPFN_GETACCEPTEXSOCKADDRS lpfnGuidGetAcceptExSockaddrs; - DWORD bytes_received; -}; - /* initiate async acceptEx*/ /* TODO - always return 0, set error in context, accept() will pick it up*/ -int -socketio_acceptEx(struct w32_io* pio) { +int +socketio_acceptEx(struct w32_io* pio) +{ struct acceptEx_context *context; - debug3("acceptEx - io:%p", pio); context = (struct acceptEx_context *)pio->internal.context; - ResetEvent(pio->read_overlapped.hEvent); /* create accepting socket */ @@ -118,18 +116,17 @@ socketio_acceptEx(struct w32_io* pio) { } if (TRUE == context->lpfnAcceptEx(pio->sock, - context->accept_socket, - context->lpOutputBuf, - 0, - sizeof(SOCKADDR_STORAGE) + 16, - sizeof(SOCKADDR_STORAGE) + 16, - &context->bytes_received, - &pio->read_overlapped)) + context->accept_socket, + context->lpOutputBuf, + 0, + sizeof(SOCKADDR_STORAGE) + 16, + sizeof(SOCKADDR_STORAGE) + 16, + &context->bytes_received, + &pio->read_overlapped)) { /* we are already connected. Set event so subsequent select will catch */ SetEvent(pio->read_overlapped.hEvent); - } - else { + } else { /* if overlapped io is in progress, we are good */ if (WSAGetLastError() != ERROR_IO_PENDING) { errno = errno_from_WSALastError(); @@ -142,16 +139,14 @@ socketio_acceptEx(struct w32_io* pio) { return 0; } -void -CALLBACK WSARecvCompletionRoutine( - IN DWORD dwError, - IN DWORD cbTransferred, - IN LPWSAOVERLAPPED lpOverlapped, - IN DWORD dwFlags - ) +void +CALLBACK WSARecvCompletionRoutine(IN DWORD dwError, + IN DWORD cbTransferred, + IN LPWSAOVERLAPPED lpOverlapped, + IN DWORD dwFlags) { - 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("WSARecvCompletionCB - io:%p, pending_state:%d, flags:%d, error:%d, received:%d", pio, pio->read_details.pending, dwFlags, dwError, cbTransferred); if (!dwError && !cbTransferred) @@ -164,8 +159,9 @@ CALLBACK WSARecvCompletionRoutine( /* initiates async receive operation*/ /* TODO - always return 0, or make this a void func. any error should be put in context*/ -int -socketio_WSARecv(struct w32_io* pio, BOOL* completed) { +int +socketio_WSARecv(struct w32_io* pio, BOOL* completed) +{ int ret = 0; WSABUF wsabuf; DWORD recv_flags = 0; @@ -176,12 +172,9 @@ socketio_WSARecv(struct w32_io* pio, BOOL* completed) { /* initialize recv buffers if needed */ wsabuf.len = INTERNAL_RECV_BUFFER_SIZE; - if (pio->read_details.buf == NULL) - { + if (pio->read_details.buf == NULL) { wsabuf.buf = malloc(wsabuf.len); - - if (!wsabuf.buf) - { + if (!wsabuf.buf) { errno = ENOMEM; debug("WSARecv - ERROR:%d, io:%p", errno, pio); return -1; @@ -189,29 +182,22 @@ socketio_WSARecv(struct w32_io* pio, BOOL* completed) { pio->read_details.buf = wsabuf.buf; pio->read_details.buf_size = wsabuf.len; - } - else + } else wsabuf.buf = pio->read_details.buf; - - ret = WSARecv(pio->sock, &wsabuf, 1, NULL, &recv_flags, &pio->read_overlapped, - &WSARecvCompletionRoutine); - if (ret == 0) - { + ret = WSARecv(pio->sock, &wsabuf, 1, NULL, &recv_flags, &pio->read_overlapped, &WSARecvCompletionRoutine); + if (ret == 0) { pio->read_details.pending = TRUE; /* receive has completed but APC is pending to be scheduled */ debug2("WSARecv - WSARecv() returned 0, io:%p", pio); if (completed) *completed = TRUE; - } - else { /* (ret == SOCKET_ERROR) */ - if (WSAGetLastError() == WSA_IO_PENDING) - { + } else { /* (ret == SOCKET_ERROR) */ + if (WSAGetLastError() == WSA_IO_PENDING) { /* io is initiated and pending */ debug2("WSARecv - reported IO pending"); pio->read_details.pending = TRUE; - } - else { + } else { errno = errno_from_WSALastError(); debug("WSARecv - WSARecv() ERROR: io:%p %d", pio, errno); return -1; @@ -222,8 +208,9 @@ socketio_WSARecv(struct w32_io* pio, BOOL* completed) { } /* implements socket() */ -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 *pio = (struct w32_io*)malloc(sizeof(struct w32_io)); if (!pio) { errno = ENOMEM; @@ -244,20 +231,20 @@ socketio_socket(int domain, int type, int protocol) { return pio; } -#define SET_ERRNO_ON_ERROR(expr) do { \ - int ret = (expr); \ - if (ret == SOCKET_ERROR) { \ - errno = errno_from_WSALastError(); \ - debug("%s - ERROR:%d", __FUNCTION__, errno); \ - } \ - return ret; \ +#define SET_ERRNO_ON_ERROR(expr) do { \ + int ret = (expr); \ + if (ret == SOCKET_ERROR) { \ + errno = errno_from_WSALastError(); \ + debug("%s - ERROR:%d", __FUNCTION__, errno); \ + } \ + return ret; \ } while (0) /* implements setsockopt() */ -int -socketio_setsockopt(struct w32_io* pio, int level, int optname, const char* optval, - int optlen) { - if ((optname == SO_KEEPALIVE) || (optname == SO_REUSEADDR) || +int +socketio_setsockopt(struct w32_io* pio, int level, int optname, const char* optval, int optlen) +{ + if ((optname == SO_KEEPALIVE) || (optname == SO_REUSEADDR) || (optname == TCP_NODELAY) || (optname == IPV6_V6ONLY)) SET_ERRNO_ON_ERROR(setsockopt(pio->sock, level, optname, optval, optlen)); else { @@ -268,26 +255,30 @@ socketio_setsockopt(struct w32_io* pio, int level, int optname, const char* optv } /* implements getsockopt() */ -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) +{ SET_ERRNO_ON_ERROR(getsockopt(pio->sock, level, optname, optval, optlen)); } /* implements getsockname() */ -int -socketio_getsockname(struct w32_io* pio, struct sockaddr* name, int* namelen) { +int +socketio_getsockname(struct w32_io* pio, struct sockaddr* name, int* namelen) +{ SET_ERRNO_ON_ERROR(getsockname(pio->sock, name, namelen)); } /* implements getpeername */ -int -socketio_getpeername(struct w32_io* pio, struct sockaddr* name, int* namelen) { +int +socketio_getpeername(struct w32_io* pio, struct sockaddr* name, int* namelen) +{ SET_ERRNO_ON_ERROR(getpeername(pio->sock, name, namelen)); } /* implements listen() */ -int -socketio_listen(struct w32_io* pio, int backlog) { +int +socketio_listen(struct w32_io* pio, int backlog) +{ struct acceptEx_context* context; if (SOCKET_ERROR == listen(pio->sock, backlog)) { @@ -313,8 +304,7 @@ socketio_listen(struct w32_io* pio, int backlog) { SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidAcceptEx, sizeof(GuidAcceptEx), &context->lpfnAcceptEx, sizeof(context->lpfnAcceptEx), - &dwBytes, NULL, NULL)) - { + &dwBytes, NULL, NULL)) { free(context); errno = errno_from_WSALastError(); debug("listen - Ioctl1 ERROR:%d, io:%p", errno, pio); @@ -325,8 +315,7 @@ socketio_listen(struct w32_io* pio, int backlog) { SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidGetAcceptExSockaddrs, sizeof(GuidGetAcceptExSockaddrs), &context->lpfnGuidGetAcceptExSockaddrs, sizeof(context->lpfnGuidGetAcceptExSockaddrs), - &dwBytes, NULL, NULL)) - { + &dwBytes, NULL, NULL)) { free(context); errno = errno_from_WSALastError(); debug("listen - Ioctl2 ERROR:%d, io:%p", errno, pio); @@ -344,24 +333,24 @@ socketio_listen(struct w32_io* pio, int backlog) { context->accept_socket = INVALID_SOCKET; pio->internal.context = context; } - + pio->internal.state = SOCK_LISTENING; return 0; } /* implements bind() */ -int -socketio_bind(struct w32_io* pio, const struct sockaddr *name, int namelen) { +int +socketio_bind(struct w32_io* pio, const struct sockaddr *name, int namelen) +{ SET_ERRNO_ON_ERROR(bind(pio->sock, name, namelen)); } /* implements recv() */ -int -socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) { +int +socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) +{ BOOL completed = FALSE; - debug3("recv - io:%p", pio); - if ((buf == NULL) || (len == 0)) { errno = EINVAL; debug("recv - ERROR: invalid arguments, buf:%p, len:%d, io:%p", buf, len, pio); @@ -375,7 +364,6 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) { } /* TODO - ensure socket is in accepted or connected state */ - /* /io is initiated and pending */ if (pio->read_details.pending) { /* if recv is now in blocking mode, wait for data to be available */ @@ -385,8 +373,7 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) { if (0 != wait_for_any_event(NULL, 0, INFINITE)) return -1; } - } - else { + } else { errno = EAGAIN; debug2("recv - io is already pending, io:%p", pio); return -1; @@ -394,27 +381,24 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) { } /* if we have some buffer copy it and return #bytes copied */ - if (pio->read_details.remaining) - { + if (pio->read_details.remaining) { int num_bytes_copied = min((int)len, pio->read_details.remaining); - memcpy(buf, pio->read_details.buf + pio->read_details.completed, - num_bytes_copied); + memcpy(buf, pio->read_details.buf + pio->read_details.completed, + num_bytes_copied); pio->read_details.remaining -= num_bytes_copied; pio->read_details.completed += num_bytes_copied; - debug2("recv - returning %d bytes from prior completed IO, remaining:%d, io:%p", - num_bytes_copied, pio->read_details.remaining, pio); + debug2("recv - returning %d bytes from prior completed IO, remaining:%d, io:%p", + num_bytes_copied, pio->read_details.remaining, pio); return num_bytes_copied; } - /* if there was an error on async call, return */ if (pio->read_details.error) { if (pio->read_details.error == ERROR_GRACEFUL_DISCONNECT) { debug2("recv - connection closed, io:%p", pio); /* connection is closed */ return 0; - } - else { + } else { errno = errno_from_WSAError(pio->read_details.error); debug("recv - from CB ERROR:%d, io:%p", pio->read_details.error, pio); pio->read_details.error = 0; @@ -437,16 +421,14 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) { } } - if (w32_io_is_blocking(pio)) - { + if (w32_io_is_blocking(pio)) { /* wait until io is done */ debug3("recv - socket in blocking mode, io:%p", pio); while (socketio_is_io_available(pio, TRUE) == FALSE) { if (0 != wait_for_any_event(NULL, 0, INFINITE)) return -1; } - } - else { + } else { if (socketio_is_io_available(pio, TRUE) == FALSE) { errno = EAGAIN; debug2("recv - IO is pending, io:%p", pio); @@ -455,17 +437,15 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) { } /* - * by this time we should have some bytes in internal buffer + * by this time we should have some bytes in internal buffer * or an error from callback */ - if (pio->read_details.error) - { + if (pio->read_details.error) { if (pio->read_details.error == ERROR_GRACEFUL_DISCONNECT) { /* connection is closed */ debug2("recv - connection closed(2), io:%p", pio); return 0; - } - else { + } else { errno = errno_from_WSAError(pio->read_details.error); pio->read_details.error = 0; debug("recv - from CB(2) ERROR:%d, io:%p", errno, pio); @@ -478,37 +458,32 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) { memcpy(buf, pio->read_details.buf, num_bytes_copied); pio->read_details.remaining -= num_bytes_copied; pio->read_details.completed = num_bytes_copied; - debug2("recv - (2) returning %d bytes from completed IO, remaining:%d, io:%p", - num_bytes_copied, pio->read_details.remaining, pio); + debug2("recv - (2) returning %d bytes from completed IO, remaining:%d, io:%p", + num_bytes_copied, pio->read_details.remaining, pio); return num_bytes_copied; - } - else { + } else { /* this should not happen */ errno = EOTHER; debug("recv - (2) ERROR:Unexpected IO state, io:%p", pio); return -1; } - } -void -CALLBACK WSASendCompletionRoutine( - IN DWORD dwError, - IN DWORD cbTransferred, - IN LPWSAOVERLAPPED lpOverlapped, - IN DWORD dwFlags - ) +void +CALLBACK WSASendCompletionRoutine(IN DWORD dwError, + IN DWORD cbTransferred, + IN LPWSAOVERLAPPED lpOverlapped, + IN DWORD dwFlags) { - struct w32_io* pio = - (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped)); - debug2("WSASendCB - io:%p, pending_state:%d, error:%d, sent:%d of remaining:%d", - pio, pio->write_details.pending, dwError, cbTransferred, - pio->write_details.remaining); + struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped)); + debug2("WSASendCB - io:%p, pending_state:%d, error:%d, sent:%d of remaining:%d", + pio, pio->write_details.pending, dwError, cbTransferred, + pio->write_details.remaining); pio->write_details.error = dwError; /* TODO - assert that remaining == cbTransferred */ if ((dwError == 0) && (pio->write_details.remaining != cbTransferred)) { - debug("WSASendCB - ERROR: broken assumption, io:%p, sent:%d, remaining:%d", pio, - cbTransferred, pio->write_details.remaining); + debug("WSASendCB - ERROR: broken assumption, io:%p, sent:%d, remaining:%d", pio, + cbTransferred, pio->write_details.remaining); DebugBreak(); } pio->write_details.remaining -= cbTransferred; @@ -516,13 +491,13 @@ CALLBACK WSASendCompletionRoutine( } /* implementation of send() */ -int -socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) { +int +socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) +{ int ret = 0; WSABUF wsabuf; debug2("send - io:%p", pio); - if ((buf == NULL) || (len == 0)) { errno = EINVAL; debug("send - ERROR invalid arguments, buf:%p, len:%d, io:%p", buf, len, pio); @@ -536,26 +511,20 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) { } /* TODO - ensure socket is in accepted or connected state */ - /* if io is already pending */ - if (pio->write_details.pending) - { - if (w32_io_is_blocking(pio)) - { + if (pio->write_details.pending) { + if (w32_io_is_blocking(pio)) { debug2("send - io is pending, call is blocking, 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("send - IO currently pending, EAGAIN, io:%p", pio); return -1; } } - if (pio->write_details.error) { errno = errno_from_WSAError(pio->write_details.error); debug("ERROR:%d, io:%p", errno, pio); @@ -564,11 +533,9 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) { /* initialize buffers if needed */ wsabuf.len = INTERNAL_SEND_BUFFER_SIZE; - if (pio->write_details.buf == NULL) - { + if (pio->write_details.buf == NULL) { wsabuf.buf = malloc(wsabuf.len); - if (!wsabuf.buf) - { + if (!wsabuf.buf) { errno = ENOMEM; debug("send - ERROR:%d, io:%p", errno, pio); return -1; @@ -576,20 +543,16 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) { pio->write_details.buf = wsabuf.buf; pio->write_details.buf_size = wsabuf.len; - } - else { + } else wsabuf.buf = pio->write_details.buf; - } wsabuf.len = min(wsabuf.len, (int)len); memcpy(wsabuf.buf, buf, wsabuf.len); /* TODO - implement flags support if needed */ - ret = WSASend(pio->sock, &wsabuf, 1, NULL, 0, &pio->write_overlapped, - &WSASendCompletionRoutine); + ret = WSASend(pio->sock, &wsabuf, 1, NULL, 0, &pio->write_overlapped, &WSASendCompletionRoutine); - if (ret == 0) - { + if (ret == 0) { /* send has completed and APC is scheduled, let it run */ debug2("send - WSASend() returned 0, APC scheduled io:%p", pio); pio->write_details.pending = TRUE; @@ -603,16 +566,13 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) { /* return num of bytes written */ return wsabuf.len; - } - else { - if (WSAGetLastError() == WSA_IO_PENDING) - { + } else { + if (WSAGetLastError() == WSA_IO_PENDING) { /* io is initiated and pending */ debug2("send - WSASend reported IO pending, io:%p", pio); pio->write_details.pending = TRUE; pio->write_details.remaining = wsabuf.len; - if (w32_io_is_blocking(pio)) - { + if (w32_io_is_blocking(pio)) { /* wait until io is done */ debug3("send - waiting as socket is in blocking mode, io:%p", pio); while (pio->write_details.pending) @@ -626,8 +586,7 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) { debug3("send - returning %d, io:%p", wsabuf.len, pio); return wsabuf.len; - } - else { + } else { errno = errno_from_WSALastError(); debug("send - WSASend() ERROR:%d, io:%p", errno, pio); return -1; @@ -636,41 +595,39 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) { } /* shutdown() implementation */ -int -socketio_shutdown(struct w32_io* pio, int how) { +int +socketio_shutdown(struct w32_io* pio, int how) +{ SET_ERRNO_ON_ERROR(shutdown(pio->sock, how)); } /* socket close() implementation */ -int -socketio_close(struct w32_io* pio) { +int +socketio_close(struct w32_io* pio) +{ debug2("close - io:%p", pio); closesocket(pio->sock); /* wait for pending io to abort */ SleepEx(0, TRUE); - if ( ((pio->internal.state == SOCK_CONNECTED) || (pio->internal.state == SOCK_ACCEPTED)) - && (pio->read_details.pending || pio->write_details.pending)) { - debug2("close - IO is still pending on closed socket. read:%d, write:%d, io:%p", - pio->read_details.pending, pio->write_details.pending, pio); + if (((pio->internal.state == SOCK_CONNECTED) || (pio->internal.state == SOCK_ACCEPTED)) && + (pio->read_details.pending || pio->write_details.pending)) { + debug2("close - IO is still pending on closed socket. read:%d, write:%d, io:%p", + pio->read_details.pending, pio->write_details.pending, pio); DebugBreak(); } if (pio->internal.state == SOCK_LISTENING) { if (pio->read_overlapped.hEvent) CloseHandle(pio->read_overlapped.hEvent); - if (pio->internal.context) - { + if (pio->internal.context) { struct acceptEx_context *ctx = (struct acceptEx_context*)pio->internal.context; if (ctx->accept_socket != INVALID_SOCKET) closesocket(ctx->accept_socket); free(pio->internal.context); } - - } - else if (pio->internal.state == SOCK_CONNECTING) { + } else if (pio->internal.state == SOCK_CONNECTING) { if (pio->write_overlapped.hEvent) CloseHandle(pio->write_overlapped.hEvent); - } - else { + } else { if (pio->read_details.buf) free(pio->read_details.buf); @@ -683,20 +640,20 @@ socketio_close(struct w32_io* pio) { } /* accept() implementation */ -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) +{ struct w32_io *accept_io = NULL; int iResult = 0; struct acceptEx_context* context; - struct sockaddr *local_address,*remote_address; + struct sockaddr *local_address, *remote_address; int local_address_len, remote_address_len; debug3("accept - io:%p", pio); /* start io if not already started */ if (pio->read_details.pending == FALSE) { - if (socketio_acceptEx(pio) != 0) { + if (socketio_acceptEx(pio) != 0) return NULL; - } } if (w32_io_is_blocking(pio)) { @@ -705,15 +662,13 @@ socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen) { if (-1 == wait_for_any_event(&pio->read_overlapped.hEvent, 1, INFINITE)) return NULL; - } - else { + } else { /* if i/o is not ready */ if (FALSE == socketio_is_io_available(pio, TRUE)) { errno = EAGAIN; debug2("accept is pending, io:%p", pio); return NULL; } - } context = (struct acceptEx_context*)pio->internal.context; @@ -726,8 +681,8 @@ socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen) { goto on_error; } - if (0 != setsockopt(context->accept_socket, SOL_SOCKET, - SO_UPDATE_ACCEPT_CONTEXT, (char*)&pio->sock, sizeof(pio->sock))) { + if (0 != setsockopt(context->accept_socket, SOL_SOCKET, + SO_UPDATE_ACCEPT_CONTEXT, (char*)&pio->sock, sizeof(pio->sock))) { errno = errno_from_WSALastError(); debug("accept - ERROR: setsockopt failed:%d, io:%p", errno, pio); goto on_error; @@ -768,8 +723,9 @@ on_error: } /* initiates an async connect*/ -int -socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen) { +int +socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen) +{ struct sockaddr_in tmp_addr4; struct sockaddr_in6 tmp_addr6; @@ -786,22 +742,19 @@ socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen) tmp_addr6.sin6_port = 0; tmp_addr = (SOCKADDR*)&tmp_addr6; tmp_addr_len = sizeof(tmp_addr6); - } - else if (name->sa_family == AF_INET) { + } else if (name->sa_family == AF_INET) { ZeroMemory(&tmp_addr4, sizeof(tmp_addr4)); tmp_addr4.sin_family = AF_INET; tmp_addr4.sin_port = 0; tmp_addr = (SOCKADDR*)&tmp_addr4; tmp_addr_len = sizeof(tmp_addr4); - } - else { + } else { errno = ENOTSUP; debug("connectex - ERROR: unsuppored address family:%d, io:%p", name->sa_family, pio); return -1; } - if (SOCKET_ERROR == bind(pio->sock, tmp_addr, (int)tmp_addr_len)) - { + if (SOCKET_ERROR == bind(pio->sock, tmp_addr, (int)tmp_addr_len)) { errno = errno_from_WSALastError(); debug("connectex - ERROR: bind failed :%d, io:%p", WSAGetLastError(), pio); return -1; @@ -810,27 +763,25 @@ socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen) if (SOCKET_ERROR == WSAIoctl(pio->sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &connectex_guid, sizeof(connectex_guid), &ConnectEx, sizeof(ConnectEx), - &tmp_bytes, NULL, NULL)) - { + &tmp_bytes, NULL, NULL)) { errno = errno_from_WSALastError(); debug("connectex - ioctl ERROR:%d, io:%p", WSAGetLastError(), pio); return -1; } - if ((!pio->write_overlapped.hEvent) - && ((pio->write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)) { + if ((!pio->write_overlapped.hEvent) + && ((pio->write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)) { errno = ENOMEM; debug("connectex - ERROR CreateEvent failed:%d, io:%p", errno, pio); return -1; } ResetEvent(pio->write_overlapped.hEvent); - if (TRUE == ConnectEx(pio->sock, name, namelen, NULL, 0, NULL, - &pio->write_overlapped)) { + if (TRUE == ConnectEx(pio->sock, name, namelen, NULL, 0, NULL, + &pio->write_overlapped)) { /* set completion event to indicates that async connect has completed */ SetEvent(pio->write_overlapped.hEvent); - } - else { + } else { if (WSAGetLastError() != ERROR_IO_PENDING) { CloseHandle(pio->write_overlapped.hEvent); pio->write_overlapped.hEvent = 0; @@ -846,8 +797,9 @@ socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen) } /* connect implementation */ -int -socketio_connect(struct w32_io* pio, const struct sockaddr* name, int namelen) { +int +socketio_connect(struct w32_io* pio, const struct sockaddr* name, int namelen) +{ debug3("connect - io:%p", pio); if (pio->write_details.pending == FALSE) { @@ -858,29 +810,25 @@ socketio_connect(struct w32_io* pio, const struct sockaddr* name, int namelen) { if (w32_io_is_blocking(pio)) { /* block until connect io is complete */ while (FALSE == socketio_is_io_available(pio, TRUE)) { - if (-1 == wait_for_any_event(&pio->write_overlapped.hEvent, - 1, INFINITE)) + if (-1 == wait_for_any_event(&pio->write_overlapped.hEvent, 1, INFINITE)) return -1; } - } - else { + } else { /* if i/o is not ready */ if (FALSE == socketio_is_io_available(pio, TRUE)) { errno = EINPROGRESS; debug2("connect - in progress, io:%p", pio); return -1; } - } return socketio_finish_connect(pio); } -int -socketio_finish_connect(struct w32_io* pio) { - +int +socketio_finish_connect(struct w32_io* pio) +{ debug3("finish_connect, io:%p", pio); - if (pio->write_details.error) { errno = errno_from_WSAError(pio->write_details.error); debug("finish_connect - ERROR: async io completed with error: %d, io:%p", errno, pio); @@ -902,69 +850,61 @@ socketio_finish_connect(struct w32_io* pio) { } /* checks if a given io is ready/available */ -BOOL -socketio_is_io_available(struct w32_io* pio, BOOL rd) { - - if ((pio->internal.state == SOCK_LISTENING) || +BOOL +socketio_is_io_available(struct w32_io* pio, BOOL rd) +{ + if ((pio->internal.state == SOCK_LISTENING) || (pio->internal.state == SOCK_CONNECTING)) { DWORD numBytes = 0; DWORD flags; BOOL sock_listening = (pio->internal.state == SOCK_LISTENING); - OVERLAPPED *overlapped = - sock_listening ? &pio->read_overlapped : &pio->write_overlapped; - BOOL pending = - sock_listening ? pio->read_details.pending : pio->write_details.pending; + OVERLAPPED *overlapped = sock_listening ? &pio->read_overlapped : &pio->write_overlapped; + BOOL pending = sock_listening ? pio->read_details.pending : pio->write_details.pending; if (pending) /* if there is an error to be picked up */ if (sock_listening) { if (pio->read_details.error) return TRUE; - } - else { + } else { if (pio->write_details.error) return TRUE; } - if (WSAGetOverlappedResult(pio->sock, overlapped, - &numBytes, FALSE, &flags)) + if (WSAGetOverlappedResult(pio->sock, overlapped, &numBytes, FALSE, &flags)) return TRUE; else if (WSAGetLastError() != WSA_IO_INCOMPLETE) { - if (sock_listening) - pio->read_details.error = WSAGetLastError(); - else - pio->write_details.error = WSAGetLastError(); - return TRUE; - } + if (sock_listening) + pio->read_details.error = WSAGetLastError(); + else + pio->write_details.error = WSAGetLastError(); + return TRUE; + } - return FALSE; - } - else if (rd) { + return FALSE; + } else if (rd) { if (pio->read_details.remaining || pio->read_details.error) return TRUE; else return FALSE; - } - else { + } else return (pio->write_details.pending == FALSE) ? TRUE : FALSE; - } - } + /*start async io (if needed) for accept and recv*/ -void -socketio_on_select(struct w32_io* pio, BOOL rd) { - +void +socketio_on_select(struct w32_io* pio, BOOL rd) +{ enum w32_io_sock_state sock_state = pio->internal.state; - debug2("on_select - io:%p type:%d rd:%d", pio, pio->type, rd); - //nothing to do for writes (that includes connect) + /* nothing to do for writes (that includes connect) */ if (!rd) return; - //listening socket - acceptEx if needed + /* listening socket - acceptEx if needed */ if (sock_state == SOCK_LISTENING) { - if (pio->read_details.pending == FALSE) + if (pio->read_details.pending == FALSE) if (socketio_acceptEx(pio) != 0) { /* set error, accept will pick it*/ pio->read_details.error = errno; @@ -973,9 +913,8 @@ socketio_on_select(struct w32_io* pio, BOOL rd) { SetEvent(pio->read_overlapped.hEvent); return; } - } - else { - //connected socket - WSARecv if needed + } else { + /* connected socket - WSARecv if needed */ if ((!pio->read_details.pending) && (!socketio_is_io_available(pio, rd))) if (socketio_WSARecv(pio, NULL) != 0) { /* set error, recv() will pick it */ @@ -984,104 +923,103 @@ socketio_on_select(struct w32_io* pio, BOOL rd) { return; } } - } int -w32_gethostname(char *name_utf8, size_t len) { - wchar_t name_utf16[256]; - char* tmp_name_utf8 = NULL; +w32_gethostname(char *name_utf8, size_t len) +{ + wchar_t name_utf16[256]; + char* tmp_name_utf8 = NULL; - if (IsWindows8OrGreater()) { - /* TODO - GetHostNameW not present in Win7, do GetProcAddr on Win8+*/ - // if (GetHostNameW(name_utf16, 256) == SOCKET_ERROR) { - // errno = errno_from_WSALastError(); - // return -1; - // } + if (IsWindows8OrGreater()) { + /* TODO - GetHostNameW not present in Win7, do GetProcAddr on Win8+*/ + /* if (GetHostNameW(name_utf16, 256) == SOCKET_ERROR) { + errno = errno_from_WSALastError(); + return -1; + } - // if ((tmp_name_utf8 = utf16_to_utf8(name_utf16)) == NULL || - // strlen(tmp_name_utf8) >= len) { - // errno = EFAULT; //?? - // return -1; - // } + if ((tmp_name_utf8 = utf16_to_utf8(name_utf16)) == NULL || + strlen(tmp_name_utf8) >= len) { + errno = EFAULT; //?? + return -1; + } - // memcpy(name_utf8, tmp_name_utf8, strlen(tmp_name_utf8) + 1); - // free(tmp_name_utf8); - // return 0; - return gethostname(name_utf8, len); - } - else - return gethostname(name_utf8, len); + memcpy(name_utf8, tmp_name_utf8, strlen(tmp_name_utf8) + 1); + free(tmp_name_utf8); + return 0; */ + return gethostname(name_utf8, len); + } else + return gethostname(name_utf8, len); } void -w32_freeaddrinfo(struct addrinfo *ai) { - struct addrinfo *cur; - while (ai) { - cur = ai; - ai = ai->ai_next; - if (cur->ai_addr) - free(cur->ai_addr); - if (cur->ai_canonname) - free(cur->ai_canonname); - free(cur); - } +w32_freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *cur; + while (ai) { + cur = ai; + ai = ai->ai_next; + if (cur->ai_addr) + free(cur->ai_addr); + if (cur->ai_canonname) + free(cur->ai_canonname); + free(cur); + } } -int +int w32_getaddrinfo(const char *node_utf8, const char *service_utf8, - const struct addrinfo *hints, struct addrinfo **res) { - int ret = 0; - wchar_t *node_utf16 = NULL, *service_utf16 = NULL; - struct addrinfoW *info_w = NULL; - *res = NULL; + const struct addrinfo *hints, struct addrinfo **res) +{ + int ret = 0; + wchar_t *node_utf16 = NULL, *service_utf16 = NULL; + struct addrinfoW *info_w = NULL; + *res = NULL; - if ((node_utf8 && (node_utf16 = utf8_to_utf16(node_utf8)) == NULL) || - (service_utf8 && (service_utf16 = utf8_to_utf16(service_utf8)) == NULL)) { - ret = EAI_MEMORY; - goto done; - } + if ((node_utf8 && (node_utf16 = utf8_to_utf16(node_utf8)) == NULL) || + (service_utf8 && (service_utf16 = utf8_to_utf16(service_utf8)) == NULL)) { + ret = EAI_MEMORY; + goto done; + } - if ((ret = GetAddrInfoW(node_utf16, service_utf16, (ADDRINFOW*)hints, &info_w)) != 0) - goto done; + if ((ret = GetAddrInfoW(node_utf16, service_utf16, (ADDRINFOW*)hints, &info_w)) != 0) + goto done; - /* copy info_w to res */ - { - struct addrinfoW **cur_w = &info_w; - struct addrinfo **cur = res; + /* copy info_w to res */ + { + struct addrinfoW **cur_w = &info_w; + struct addrinfo **cur = res; - while (*cur_w) { - if ((*cur = malloc(sizeof(struct addrinfo))) == NULL) { - ret = EAI_MEMORY; - goto done; - } - memcpy(*cur, *cur_w, sizeof(struct addrinfo)); - (*cur)->ai_next = NULL; - if (((*cur_w)->ai_canonname && ((*cur)->ai_canonname = utf16_to_utf8((*cur_w)->ai_canonname)) == NULL) || - ((*cur_w)->ai_addrlen && ((*cur)->ai_addr = malloc((*cur_w)->ai_addrlen)) == NULL) ) { - ret = EAI_MEMORY; - goto done; + while (*cur_w) { + if ((*cur = malloc(sizeof(struct addrinfo))) == NULL) { + ret = EAI_MEMORY; + goto done; + } + memcpy(*cur, *cur_w, sizeof(struct addrinfo)); + (*cur)->ai_next = NULL; + if (((*cur_w)->ai_canonname && ((*cur)->ai_canonname = utf16_to_utf8((*cur_w)->ai_canonname)) == NULL) || + ((*cur_w)->ai_addrlen && ((*cur)->ai_addr = malloc((*cur_w)->ai_addrlen)) == NULL)) { + ret = EAI_MEMORY; + goto done; - } - if ((*cur_w)->ai_addrlen) - memcpy((*cur)->ai_addr, (*cur_w)->ai_addr, (*cur_w)->ai_addrlen); - cur_w = &(*cur_w)->ai_next; - cur = &(*cur)->ai_next; - } - } + } + if ((*cur_w)->ai_addrlen) + memcpy((*cur)->ai_addr, (*cur_w)->ai_addr, (*cur_w)->ai_addrlen); + cur_w = &(*cur_w)->ai_next; + cur = &(*cur)->ai_next; + } + } done: - if (node_utf16) - free(node_utf16); - if (service_utf16) - free(service_utf16); - if (info_w) - FreeAddrInfoW(info_w); - if (ret != 0 && *res) { - w32_freeaddrinfo(*res); - *res = NULL; - } - return ret; + if (node_utf16) + free(node_utf16); + if (service_utf16) + free(service_utf16); + if (info_w) + FreeAddrInfoW(info_w); + if (ret != 0 && *res) { + w32_freeaddrinfo(*res); + *res = NULL; + } + return ret; } - - diff --git a/contrib/win32/win32compat/w32fd.c b/contrib/win32/win32compat/w32fd.c index a10e25562..3cefb5b57 100644 --- a/contrib/win32/win32compat/w32fd.c +++ b/contrib/win32/win32compat/w32fd.c @@ -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 @@ -171,7 +174,7 @@ w32_io_on_select(struct w32_io* pio, BOOL rd) { if ((pio->type == SOCK_FD)) socketio_on_select(pio, rd); - else + else fileio_on_select(pio, rd); } @@ -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]; @@ -350,13 +356,15 @@ w32_pipe(int *pfds) { fd_table_set(pio[1], write_index); 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); + 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); + 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,64 +384,66 @@ 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); - + return fileio_read(fd_table.w32_ios[fd], dst, 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) return socketio_send(fd_table.w32_ios[fd], buf, max, 0); - + 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) { +long +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; return 0; } - - pio = fd_table.w32_ios[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); @@ -491,7 +503,7 @@ w32_io_process_fd_flags(struct w32_io* pio, int flags) { shi_flags = (flags & FD_CLOEXEC) ? 0 : HANDLE_FLAG_INHERIT; 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); errno = EOTHER; return -1; @@ -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; + ret = fd_table.w32_ios[fd]->fd_flags; + 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); @@ -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"); - } /* 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,17 +817,17 @@ 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; } -int -w32_ftruncate(int fd, off_t length) { +int +w32_ftruncate(int fd, off_t length) +{ LARGE_INTEGER new_postion; - CHECK_FD(fd); new_postion.QuadPart = length; @@ -825,9 +839,9 @@ w32_ftruncate(int fd, off_t length) { return 0; } -int -w32_fsync(int fd) { +int +w32_fsync(int fd) +{ CHECK_FD(fd); - return FlushFileBuffers(w32_fd_to_handle(fd)); } diff --git a/contrib/win32/win32compat/w32fd.h b/contrib/win32/win32compat/w32fd.h index ab4a02d9f..1aad34a7a 100644 --- a/contrib/win32/win32compat/w32fd.h +++ b/contrib/win32/win32compat/w32fd.h @@ -1,7 +1,33 @@ /* - * Author: Manoj Ampalam - * - * Definitions for Win32 wrapper functions with POSIX like signatures +* Author: Manoj Ampalam +* +* 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 @@ -17,7 +43,7 @@ enum w32_io_type { }; enum w32_io_sock_state { - SOCK_INITIALIZED = 0, + SOCK_INITIALIZED = 0, SOCK_LISTENING = 1, /*listen called on socket*/ SOCK_ACCEPTED = 2, /*socket returned from accept()*/ 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 */ 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; - + /*index at which this object is stored in fd_table*/ - int table_index; + int table_index; enum w32_io_type type; /*hanldle type*/ DWORD fd_flags; /*fd flags from POSIX*/ DWORD fd_status_flags; /*fd status flags from POSIX*/ - + /*underlying w32 handle*/ union { 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); 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 \ No newline at end of file diff --git a/contrib/win32/win32compat/w32log.c b/contrib/win32/win32compat/w32log.c index d23e2ef62..1df65d5b8 100644 --- a/contrib/win32/win32compat/w32log.c +++ b/contrib/win32/win32compat/w32log.c @@ -27,11 +27,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include #include #include #include + #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) { +void +syslog(int priority, const char *format, const char *formatBuffer) +{ char msgbufTimestamp[MSGBUFSIZ]; SYSTEMTIME st; diff --git a/contrib/win32/win32compat/win32_dirent.c b/contrib/win32/win32compat/win32_dirent.c index dcfe77a29..28891ac84 100644 --- a/contrib/win32/win32compat/win32_dirent.c +++ b/contrib/win32/win32compat/win32_dirent.c @@ -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 #include #include #include #include -#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; @@ -30,17 +55,17 @@ DIR * opendir(const char *name) wchar_t searchstr[PATH_MAX]; wchar_t* wname = NULL; int needed; - + if ((wname = utf8_to_utf16(sanitized_path(name))) == NULL) { errno = ENOMEM; return NULL; } - // add *.* for Windows _findfirst() search pattern + /* add *.* for Windows _findfirst() search pattern */ swprintf_s(searchstr, PATH_MAX, L"%s\\*.*", wname); free(wname); - if ((hFile = _wfindfirst(searchstr, &c_file)) == -1L) + if ((hFile = _wfindfirst(searchstr, &c_file)) == -1L) return NULL; /* errno is set by _wfindfirst */ else { if ((pdir = malloc(sizeof(DIR))) == NULL) { @@ -48,34 +73,36 @@ DIR * opendir(const char *name) errno = ENOMEM; return NULL; } - + memset(pdir, 0, sizeof(DIR)); pdir->hFile = hFile; 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 path; // path does not have a slash + return (pdest + 1); + + return path; /* path does not have a slash */ } diff --git a/contrib/win32/win32compat/win32_zlib.c b/contrib/win32/win32compat/win32_zlib.c index 0302ff815..8d4073340 100644 --- a/contrib/win32/win32compat/win32_zlib.c +++ b/contrib/win32/win32compat/win32_zlib.c @@ -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; }