mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-30 01:05:14 +02:00
Fixed wstat fix for file permission issue
https://github.com/PowerShell/Win32-OpenSSH/issues/176 1.If there are no sufficient permissions to open a file then _wstat64() is returning file not present but it should return the accessed denied.Fixed this. 2.Code cleanup in the posix compat files to align with the openbsd coding standard.
This commit is contained in:
parent
73180c876d
commit
4d0c1db166
@ -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;
|
||||
}
|
||||
|
@ -32,9 +32,10 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <io.h>
|
||||
#include "w32fd.h"
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "w32fd.h"
|
||||
#include "inc\utf.h"
|
||||
#include "misc_internal.h"
|
||||
|
||||
@ -44,6 +45,14 @@
|
||||
#define WRITE_BUFFER_SIZE 100*1024
|
||||
#define errno_from_Win32LastError() errno_from_Win32Error(GetLastError())
|
||||
|
||||
struct createFile_flags {
|
||||
DWORD dwDesiredAccess;
|
||||
DWORD dwShareMode;
|
||||
SECURITY_ATTRIBUTES securityAttributes;
|
||||
DWORD dwCreationDisposition;
|
||||
DWORD dwFlagsAndAttributes;
|
||||
};
|
||||
|
||||
int termio_initiate_read(struct w32_io* pio);
|
||||
int termio_initiate_write(struct w32_io* pio, DWORD num_bytes);
|
||||
|
||||
@ -73,7 +82,8 @@ static int pipe_counter = 0;
|
||||
* to it. These handles are associated with read end and write end of the pipe
|
||||
*/
|
||||
int
|
||||
fileio_pipe(struct w32_io* pio[2]) {
|
||||
fileio_pipe(struct w32_io* pio[2])
|
||||
{
|
||||
HANDLE read_handle = INVALID_HANDLE_VALUE, write_handle = INVALID_HANDLE_VALUE;
|
||||
struct w32_io *pio_read = NULL, *pio_write = NULL;
|
||||
char pipe_name[PATH_MAX];
|
||||
@ -158,18 +168,10 @@ error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct createFile_flags {
|
||||
DWORD dwDesiredAccess;
|
||||
DWORD dwShareMode;
|
||||
SECURITY_ATTRIBUTES securityAttributes;
|
||||
DWORD dwCreationDisposition;
|
||||
DWORD dwFlagsAndAttributes;
|
||||
};
|
||||
|
||||
/* maps open() file modes and flags to ones needed by CreateFile */
|
||||
static int
|
||||
createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
|
||||
|
||||
createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags)
|
||||
{
|
||||
/* check flags */
|
||||
int rwflags = flags & 0x3;
|
||||
int c_s_flags = flags & 0xfffffff0;
|
||||
@ -185,8 +187,7 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
|
||||
}
|
||||
|
||||
/*only following create and status flags currently supported*/
|
||||
if (c_s_flags & ~(O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC
|
||||
| O_EXCL | O_BINARY)) {
|
||||
if (c_s_flags & ~(O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC | O_EXCL | O_BINARY)) {
|
||||
debug("open - ERROR: Unsupported flags: %d", flags);
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
@ -240,11 +241,12 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
|
||||
|
||||
/* open() implementation. Uses CreateFile to open file, console, device, etc */
|
||||
struct w32_io*
|
||||
fileio_open(const char *path_utf8, int flags, int mode) {
|
||||
fileio_open(const char *path_utf8, int flags, int mode)
|
||||
{
|
||||
struct w32_io* pio = NULL;
|
||||
struct createFile_flags cf_flags;
|
||||
HANDLE handle;
|
||||
wchar_t *path_utf16 = NULL;
|
||||
wchar_t *path_utf16 = NULL;
|
||||
|
||||
debug2("open - pathname:%s, flags:%d, mode:%d", path_utf8, flags, mode);
|
||||
/* check input params*/
|
||||
@ -254,11 +256,11 @@ struct w32_io*
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((path_utf16 = utf8_to_utf16(path_utf8)) == NULL) {
|
||||
errno = ENOMEM;
|
||||
debug("utf8_to_utf16 failed - ERROR:%d", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
if ((path_utf16 = utf8_to_utf16(path_utf8)) == NULL) {
|
||||
errno = ENOMEM;
|
||||
debug("utf8_to_utf16 failed for file:%s error:%d", path_utf8, GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (createFile_flags_setup(flags, mode, &cf_flags) == -1)
|
||||
return NULL;
|
||||
@ -269,17 +271,17 @@ struct w32_io*
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
errno = errno_from_Win32LastError();
|
||||
debug("open - CreateFile ERROR:%d", GetLastError());
|
||||
free(path_utf16);
|
||||
debug("failed to open file:%s error:%d", path_utf8, GetLastError());
|
||||
free(path_utf16);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(path_utf16);
|
||||
free(path_utf16);
|
||||
pio = (struct w32_io*)malloc(sizeof(struct w32_io));
|
||||
if (pio == NULL) {
|
||||
CloseHandle(handle);
|
||||
errno = ENOMEM;
|
||||
debug("open - ERROR:%d", errno);
|
||||
debug("fileio_open(), failed to allocate memory error:%d", errno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -292,13 +294,10 @@ struct w32_io*
|
||||
return pio;
|
||||
}
|
||||
|
||||
VOID CALLBACK ReadCompletionRoutine(
|
||||
_In_ DWORD dwErrorCode,
|
||||
_In_ DWORD dwNumberOfBytesTransfered,
|
||||
_Inout_ LPOVERLAPPED lpOverlapped
|
||||
) {
|
||||
struct w32_io* pio =
|
||||
(struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped));
|
||||
VOID CALLBACK
|
||||
ReadCompletionRoutine(_In_ DWORD dwErrorCode, _In_ DWORD dwNumberOfBytesTransfered, _Inout_ LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped));
|
||||
debug2("ReadCB pio:%p, pending_state:%d, error:%d, received:%d",
|
||||
pio, pio->read_details.pending, dwErrorCode, dwNumberOfBytesTransfered);
|
||||
pio->read_details.error = dwErrorCode;
|
||||
@ -311,7 +310,8 @@ VOID CALLBACK ReadCompletionRoutine(
|
||||
/* initiate an async read */
|
||||
/* TODO: make this a void func, store error in context */
|
||||
int
|
||||
fileio_ReadFileEx(struct w32_io* pio, unsigned int bytes_requested) {
|
||||
fileio_ReadFileEx(struct w32_io* pio, unsigned int bytes_requested)
|
||||
{
|
||||
debug2("ReadFileEx io:%p", pio);
|
||||
|
||||
if (pio->read_details.buf == NULL) {
|
||||
@ -342,11 +342,11 @@ fileio_ReadFileEx(struct w32_io* pio, unsigned int bytes_requested) {
|
||||
|
||||
/* read() implementation */
|
||||
int
|
||||
fileio_read(struct w32_io* pio, void *dst, unsigned int max) {
|
||||
fileio_read(struct w32_io* pio, void *dst, unsigned int max)
|
||||
{
|
||||
int bytes_copied;
|
||||
|
||||
debug3("read - io:%p remaining:%d", pio, pio->read_details.remaining);
|
||||
|
||||
/* if read is pending */
|
||||
if (pio->read_details.pending) {
|
||||
if (w32_io_is_blocking(pio)) {
|
||||
@ -426,11 +426,11 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max) {
|
||||
return bytes_copied;
|
||||
}
|
||||
|
||||
VOID CALLBACK WriteCompletionRoutine(
|
||||
_In_ DWORD dwErrorCode,
|
||||
_In_ DWORD dwNumberOfBytesTransfered,
|
||||
_Inout_ LPOVERLAPPED lpOverlapped
|
||||
) {
|
||||
VOID CALLBACK
|
||||
WriteCompletionRoutine(_In_ DWORD dwErrorCode,
|
||||
_In_ DWORD dwNumberOfBytesTransfered,
|
||||
_Inout_ LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
struct w32_io* pio =
|
||||
(struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped));
|
||||
debug2("WriteCB - pio:%p, pending_state:%d, error:%d, transferred:%d of remaining: %d",
|
||||
@ -450,21 +450,18 @@ VOID CALLBACK WriteCompletionRoutine(
|
||||
|
||||
/* write() implementation */
|
||||
int
|
||||
fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
|
||||
fileio_write(struct w32_io* pio, const void *buf, unsigned int max)
|
||||
{
|
||||
int bytes_copied;
|
||||
|
||||
debug2("write - io:%p", pio);
|
||||
|
||||
if (pio->write_details.pending) {
|
||||
if (w32_io_is_blocking(pio))
|
||||
{
|
||||
if (w32_io_is_blocking(pio)) {
|
||||
debug2("write - io pending, blocking call made, io:%p", pio);
|
||||
while (pio->write_details.pending) {
|
||||
while (pio->write_details.pending)
|
||||
if (wait_for_any_event(NULL, 0, INFINITE) == -1)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
errno = EAGAIN;
|
||||
debug2("write - IO is already pending, io:%p", pio);
|
||||
return -1;
|
||||
@ -502,14 +499,12 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (WriteFileEx(WINHANDLE(pio), pio->write_details.buf, bytes_copied,
|
||||
&pio->write_overlapped, &WriteCompletionRoutine)) {
|
||||
pio->write_details.pending = TRUE;
|
||||
pio->write_details.remaining = bytes_copied;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
errno = errno_from_Win32LastError();
|
||||
/* read end of the pipe closed ? */
|
||||
if ((FILETYPE(pio) == FILE_TYPE_PIPE) && (errno == ERROR_BROKEN_PIPE)) {
|
||||
@ -531,6 +526,7 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* execute APC to give a chance for write to complete */
|
||||
SleepEx(0, TRUE);
|
||||
|
||||
@ -548,8 +544,8 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
|
||||
|
||||
/* fstat() implemetation */
|
||||
int
|
||||
fileio_fstat(struct w32_io* pio, struct _stat64 *buf) {
|
||||
|
||||
fileio_fstat(struct w32_io* pio, struct _stat64 *buf)
|
||||
{
|
||||
int fd = _open_osfhandle((intptr_t)pio->handle, 0);
|
||||
debug2("fstat - pio:%p", pio);
|
||||
if (fd == -1) {
|
||||
@ -561,12 +557,23 @@ fileio_fstat(struct w32_io* pio, struct _stat64 *buf) {
|
||||
}
|
||||
|
||||
int
|
||||
fileio_stat(const char *path, struct _stat64 *buf) {
|
||||
fileio_stat(const char *path, struct _stat64 *buf)
|
||||
{
|
||||
wchar_t wpath[PATH_MAX];
|
||||
wchar_t* wtmp = NULL;
|
||||
struct w32_io* pio;
|
||||
|
||||
if ((wtmp = utf8_to_utf16(path)) == NULL)
|
||||
fatal("failed to covert input arguments");
|
||||
|
||||
/* If we doesn't have sufficient permissions then _wstat4() is returning
|
||||
* file not found so added fileio_open() which will set the errorno correctly (access denied)
|
||||
*/
|
||||
if (NULL == (pio = fileio_open(path, O_RDONLY, 0)))
|
||||
return -1;
|
||||
|
||||
fileio_close(pio);
|
||||
|
||||
wcscpy(&wpath[0], wtmp);
|
||||
free(wtmp);
|
||||
|
||||
@ -574,7 +581,8 @@ fileio_stat(const char *path, struct _stat64 *buf) {
|
||||
}
|
||||
|
||||
long
|
||||
fileio_lseek(struct w32_io* pio, long offset, int origin) {
|
||||
fileio_lseek(struct w32_io* pio, long offset, int origin)
|
||||
{
|
||||
debug2("lseek - pio:%p", pio);
|
||||
if (origin != SEEK_SET) {
|
||||
debug("lseek - ERROR, origin is not supported %d", origin);
|
||||
@ -589,13 +597,12 @@ fileio_lseek(struct w32_io* pio, long offset, int origin) {
|
||||
|
||||
/* fdopen implementation */
|
||||
FILE*
|
||||
fileio_fdopen(struct w32_io* pio, const char *mode) {
|
||||
|
||||
fileio_fdopen(struct w32_io* pio, const char *mode)
|
||||
{
|
||||
int fd_flags = 0;
|
||||
debug2("fdopen - io:%p", pio);
|
||||
|
||||
/* logic below doesn't work with overlapped file HANDLES */
|
||||
|
||||
if (mode[1] == '\0') {
|
||||
switch (*mode) {
|
||||
case 'r':
|
||||
@ -611,8 +618,7 @@ fileio_fdopen(struct w32_io* pio, const char *mode) {
|
||||
debug("fdopen - ERROR unsupported mode %s", mode);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
errno = ENOTSUP;
|
||||
debug("fdopen - ERROR unsupported mode %s", mode);
|
||||
return NULL;
|
||||
@ -630,8 +636,8 @@ fileio_fdopen(struct w32_io* pio, const char *mode) {
|
||||
}
|
||||
|
||||
void
|
||||
fileio_on_select(struct w32_io* pio, BOOL rd) {
|
||||
|
||||
fileio_on_select(struct w32_io* pio, BOOL rd)
|
||||
{
|
||||
if (!rd)
|
||||
return;
|
||||
|
||||
@ -643,8 +649,7 @@ fileio_on_select(struct w32_io* pio, BOOL rd) {
|
||||
errno = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (fileio_ReadFileEx(pio, INT_MAX) != 0) {
|
||||
pio->read_details.error = errno;
|
||||
errno = 0;
|
||||
@ -653,16 +658,15 @@ fileio_on_select(struct w32_io* pio, BOOL rd) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fileio_close(struct w32_io* pio) {
|
||||
|
||||
fileio_close(struct w32_io* pio)
|
||||
{
|
||||
debug2("fileclose - pio:%p", pio);
|
||||
|
||||
CancelIo(WINHANDLE(pio));
|
||||
//let queued APCs (if any) drain
|
||||
/* let queued APCs (if any) drain */
|
||||
SleepEx(0, TRUE);
|
||||
if (pio->type != STD_IO_FD) {//STD handles are never explicitly closed
|
||||
if (pio->type != STD_IO_FD) { /* STD handles are never explicitly closed */
|
||||
CloseHandle(WINHANDLE(pio));
|
||||
|
||||
if (pio->read_details.buf)
|
||||
@ -677,14 +681,14 @@ fileio_close(struct w32_io* pio) {
|
||||
}
|
||||
|
||||
BOOL
|
||||
fileio_is_io_available(struct w32_io* pio, BOOL rd) {
|
||||
fileio_is_io_available(struct w32_io* pio, BOOL rd)
|
||||
{
|
||||
if (rd) {
|
||||
if (pio->read_details.remaining || pio->read_details.error)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
else { //write
|
||||
} else { /* write */
|
||||
return (pio->write_details.pending == FALSE) ? TRUE : FALSE;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -31,23 +31,28 @@
|
||||
#include "inc\sys\types.h"
|
||||
|
||||
/* uuidswap.c defs */
|
||||
void temporarily_use_uid(struct passwd *pw){
|
||||
return;
|
||||
void
|
||||
temporarily_use_uid(struct passwd *pw)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
permanently_drop_suid(uid_t uid) {
|
||||
return;
|
||||
permanently_drop_suid(uid_t uid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
restore_uid(void) {
|
||||
return;
|
||||
restore_uid(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
permanently_set_uid(struct passwd *pw) {
|
||||
return;
|
||||
permanently_set_uid(struct passwd *pw)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -56,74 +61,88 @@ int muxserver_sock = -1;
|
||||
typedef struct Channel Channel;
|
||||
unsigned int muxclient_command = 0;
|
||||
void
|
||||
muxserver_listen(void){
|
||||
return;
|
||||
muxserver_listen(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
mux_exit_message(Channel *c, int exitval) {
|
||||
return;
|
||||
mux_exit_message(Channel *c, int exitval)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
mux_tty_alloc_failed(Channel *c) {
|
||||
return;
|
||||
mux_tty_alloc_failed(Channel *c)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
muxclient(const char *path) {
|
||||
return;
|
||||
muxclient(const char *path)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
innetgr(const char *netgroup, const char *host,
|
||||
const char *user, const char *domain) {
|
||||
return -1;
|
||||
innetgr(const char *netgroup, const char *host, const char *user, const char *domain)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* groupaccess.c*/
|
||||
int
|
||||
ga_init(const char *user, gid_t base) {
|
||||
return -1;
|
||||
ga_init(const char *user, gid_t base)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ga_match(char * const *groups, int n) {
|
||||
return -1;
|
||||
ga_match(char * const *groups, int n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ga_match_pattern_list(const char *group_pattern) {
|
||||
return -1;
|
||||
ga_match_pattern_list(const char *group_pattern)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
ga_free(void) {
|
||||
return;
|
||||
ga_free(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int chroot(const char *path) {
|
||||
return -1;
|
||||
int
|
||||
chroot(const char *path)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int initgroups(const char *user, gid_t group) {
|
||||
return -1;
|
||||
int
|
||||
initgroups(const char *user, gid_t group)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* sshd.c */
|
||||
int
|
||||
setgroups(gid_t group, char* name) {
|
||||
return 0;
|
||||
setgroups(gid_t group, char* name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
setsid(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int startup_handler(void) {
|
||||
setsid(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
startup_handler(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <DsGetDC.h>
|
||||
#define SECURITY_WIN32
|
||||
#include <security.h>
|
||||
|
||||
#include "inc\pwd.h"
|
||||
#include "inc\grp.h"
|
||||
#include "inc\utf.h"
|
||||
@ -45,8 +46,10 @@ static struct passwd pw;
|
||||
static char* pw_shellpath = NULL;
|
||||
#define SHELL_HOST "\\ssh-shellhost.exe"
|
||||
|
||||
|
||||
int
|
||||
initialize_pw() {
|
||||
initialize_pw()
|
||||
{
|
||||
if (pw_shellpath == NULL) {
|
||||
if ((pw_shellpath = malloc(strlen(w32_programdir()) + strlen(SHELL_HOST) + 1)) == NULL)
|
||||
fatal("initialize_pw - out of memory");
|
||||
@ -59,6 +62,7 @@ initialize_pw() {
|
||||
*head = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (pw.pw_shell != pw_shellpath) {
|
||||
memset(&pw, 0, sizeof(pw));
|
||||
pw.pw_shell = pw_shellpath;
|
||||
@ -71,7 +75,8 @@ initialize_pw() {
|
||||
}
|
||||
|
||||
void
|
||||
reset_pw() {
|
||||
reset_pw()
|
||||
{
|
||||
initialize_pw();
|
||||
if (pw.pw_name)
|
||||
free(pw.pw_name);
|
||||
@ -88,7 +93,8 @@ reset_pw() {
|
||||
}
|
||||
|
||||
static struct passwd*
|
||||
get_passwd(const char *user_utf8, LPWSTR user_sid) {
|
||||
get_passwd(const char *user_utf8, LPWSTR user_sid)
|
||||
{
|
||||
struct passwd *ret = NULL;
|
||||
wchar_t *user_utf16 = NULL, *uname_utf16, *udom_utf16, *tmp;
|
||||
char *uname_utf8 = NULL, *udom_utf8 = NULL, *pw_home_utf8 = NULL, *user_sid_utf8 = NULL;
|
||||
@ -102,7 +108,7 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) {
|
||||
|
||||
errno = 0;
|
||||
reset_pw();
|
||||
if ((user_utf16 = utf8_to_utf16(user_utf8) ) == NULL) {
|
||||
if ((user_utf16 = utf8_to_utf16(user_utf8)) == NULL) {
|
||||
errno = ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
@ -151,8 +157,8 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) {
|
||||
|
||||
/* if one of below fails, set profile path to Windows directory */
|
||||
if (swprintf(reg_path, PATH_MAX, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", user_sid) == PATH_MAX ||
|
||||
RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, ®_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;
|
||||
}
|
||||
|
@ -28,10 +28,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "w32fd.h"
|
||||
#include <errno.h>
|
||||
#include "w32fd.h"
|
||||
#include "signal_internal.h"
|
||||
#include "inc\signal.h"
|
||||
|
||||
#undef signal
|
||||
#undef raise
|
||||
#undef SIGINT
|
||||
@ -48,30 +49,27 @@
|
||||
|
||||
/* pending signals to be processed */
|
||||
sigset_t pending_signals;
|
||||
|
||||
/* signal handler table*/
|
||||
sighandler_t sig_handlers[W32_SIGMAX];
|
||||
extern struct _children children;
|
||||
|
||||
static VOID CALLBACK
|
||||
sigint_APCProc(
|
||||
_In_ ULONG_PTR dwParam
|
||||
) {
|
||||
sigint_APCProc(_In_ ULONG_PTR dwParam)
|
||||
{
|
||||
debug3("SIGINT APCProc()");
|
||||
sigaddset(&pending_signals, W32_SIGINT);
|
||||
}
|
||||
|
||||
static VOID CALLBACK
|
||||
sigterm_APCProc(
|
||||
_In_ ULONG_PTR dwParam
|
||||
) {
|
||||
sigterm_APCProc(_In_ ULONG_PTR dwParam)
|
||||
{
|
||||
debug3("SIGTERM APCProc()");
|
||||
sigaddset(&pending_signals, W32_SIGTERM);
|
||||
}
|
||||
|
||||
static VOID CALLBACK
|
||||
sigtstp_APCProc(
|
||||
_In_ ULONG_PTR dwParam
|
||||
) {
|
||||
sigtstp_APCProc(_In_ ULONG_PTR dwParam)
|
||||
{
|
||||
debug3("SIGTSTP APCProc()");
|
||||
sigaddset(&pending_signals, W32_SIGTSTP);
|
||||
}
|
||||
@ -100,35 +98,31 @@ native_sig_handler(DWORD dwCtrlType)
|
||||
}
|
||||
|
||||
static VOID CALLBACK
|
||||
sigwinch_APCProc(
|
||||
_In_ ULONG_PTR dwParam
|
||||
) {
|
||||
sigwinch_APCProc(_In_ ULONG_PTR dwParam)
|
||||
{
|
||||
debug3("SIGTERM APCProc()");
|
||||
sigaddset(&pending_signals, W32_SIGWINCH);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
queue_terminal_window_change_event() {
|
||||
queue_terminal_window_change_event()
|
||||
{
|
||||
QueueUserAPC(sigwinch_APCProc, main_thread, (ULONG_PTR)NULL);
|
||||
}
|
||||
|
||||
void
|
||||
sw_init_signal_handler_table() {
|
||||
int i;
|
||||
|
||||
sw_init_signal_handler_table()
|
||||
{
|
||||
SetConsoleCtrlHandler(native_sig_handler, TRUE);
|
||||
sigemptyset(&pending_signals);
|
||||
/* this automatically sets all to W32_SIG_DFL (0)*/
|
||||
memset(sig_handlers, 0, sizeof(sig_handlers));
|
||||
}
|
||||
|
||||
extern struct _children children;
|
||||
|
||||
sighandler_t
|
||||
w32_signal(int signum, sighandler_t handler) {
|
||||
w32_signal(int signum, sighandler_t handler)
|
||||
{
|
||||
sighandler_t prev;
|
||||
|
||||
debug2("signal() sig:%d, handler:%p", signum, handler);
|
||||
if (signum >= W32_SIGMAX) {
|
||||
errno = EINVAL;
|
||||
@ -141,7 +135,8 @@ w32_signal(int signum, sighandler_t handler) {
|
||||
}
|
||||
|
||||
int
|
||||
w32_sigprocmask(int how, const sigset_t *set, sigset_t *oldset) {
|
||||
w32_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
|
||||
{
|
||||
/* this is only used by sshd to block SIGCHLD while doing waitpid() */
|
||||
/* our implementation of waidpid() is never interrupted, so no need to implement this for now*/
|
||||
debug3("sigprocmask() how:%d");
|
||||
@ -151,7 +146,8 @@ w32_sigprocmask(int how, const sigset_t *set, sigset_t *oldset) {
|
||||
|
||||
|
||||
int
|
||||
w32_raise(int sig) {
|
||||
w32_raise(int sig)
|
||||
{
|
||||
debug("raise sig:%d", sig);
|
||||
if (sig == W32_SIGSEGV)
|
||||
return raise(SIGSEGV); /* raise native exception handler*/
|
||||
@ -185,7 +181,8 @@ w32_raise(int sig) {
|
||||
|
||||
/* processes pending signals, return -1 and errno=EINTR if any are processed*/
|
||||
static int
|
||||
sw_process_pending_signals() {
|
||||
sw_process_pending_signals()
|
||||
{
|
||||
sigset_t pending_tmp = pending_signals;
|
||||
BOOL sig_int = FALSE; /* has any signal actually interrupted */
|
||||
|
||||
@ -266,55 +263,49 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
|
||||
debug3("wait() on %d events and %d children", num_events, live_children);
|
||||
/* TODO - implement signal catching and handling */
|
||||
if (num_all_events) {
|
||||
DWORD ret = WaitForMultipleObjectsEx(num_all_events, all_events, FALSE,
|
||||
milli_seconds, TRUE);
|
||||
DWORD ret = WaitForMultipleObjectsEx(num_all_events, all_events, FALSE, milli_seconds, TRUE);
|
||||
if ((ret >= WAIT_OBJECT_0) && (ret <= WAIT_OBJECT_0 + num_all_events - 1)) {
|
||||
//woken up by event signalled
|
||||
/* is this due to a child process going down*/
|
||||
/* woken up by event signalled
|
||||
* is this due to a child process going down
|
||||
*/
|
||||
if (live_children && ((ret - WAIT_OBJECT_0) < live_children)) {
|
||||
sigaddset(&pending_signals, W32_SIGCHLD);
|
||||
sw_child_to_zombie(ret - WAIT_OBJECT_0);
|
||||
}
|
||||
}
|
||||
else if (ret == WAIT_IO_COMPLETION) {
|
||||
} else if (ret == WAIT_IO_COMPLETION) {
|
||||
/* APC processed due to IO or signal*/
|
||||
}
|
||||
else if (ret == WAIT_TIMEOUT) {
|
||||
} else if (ret == WAIT_TIMEOUT) {
|
||||
/* timed out */
|
||||
return 0;
|
||||
}
|
||||
/* some other error*/
|
||||
else {
|
||||
} else { /* some other error*/
|
||||
errno = EOTHER;
|
||||
debug("ERROR: unxpected wait end: %d", ret);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
DWORD ret = SleepEx(milli_seconds, TRUE);
|
||||
if (ret == WAIT_IO_COMPLETION) {
|
||||
/* APC processed due to IO or signal*/
|
||||
}
|
||||
else if (ret == 0) {
|
||||
} else if (ret == 0) {
|
||||
/* timed out */
|
||||
return 0;
|
||||
}
|
||||
else { //some other error
|
||||
} else { /* some other error */
|
||||
errno = EOTHER;
|
||||
debug("ERROR: unxpected SleepEx error: %d", ret);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (pending_signals) {
|
||||
if (pending_signals)
|
||||
return sw_process_pending_signals();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sw_initialize() {
|
||||
sw_initialize()
|
||||
{
|
||||
memset(&children, 0, sizeof(children));
|
||||
sw_init_signal_handler_table();
|
||||
if (sw_init_timer() != 0)
|
||||
|
@ -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;
|
||||
}
|
@ -34,7 +34,8 @@
|
||||
struct _children children;
|
||||
|
||||
int
|
||||
register_child(HANDLE child, DWORD pid) {
|
||||
register_child(HANDLE child, DWORD pid)
|
||||
{
|
||||
DWORD first_zombie_index;
|
||||
|
||||
debug("Register child %p pid %d, %d zombies of %d", child, pid,
|
||||
@ -43,6 +44,7 @@ register_child(HANDLE child, DWORD pid) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (children.num_zombies) {
|
||||
first_zombie_index = children.num_children - children.num_zombies;
|
||||
children.handles[children.num_children] = children.handles[first_zombie_index];
|
||||
@ -50,26 +52,23 @@ register_child(HANDLE child, DWORD pid) {
|
||||
|
||||
children.handles[first_zombie_index] = child;
|
||||
children.process_id[first_zombie_index] = pid;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
children.handles[children.num_children] = child;
|
||||
children.process_id[children.num_children] = pid;
|
||||
}
|
||||
|
||||
|
||||
children.num_children++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sw_remove_child_at_index(DWORD index) {
|
||||
sw_remove_child_at_index(DWORD index)
|
||||
{
|
||||
DWORD last_non_zombie;
|
||||
|
||||
debug("Unregister child at index %d, %d zombies of %d", index,
|
||||
children.num_zombies, children.num_children);
|
||||
|
||||
if ((index >= children.num_children)
|
||||
|| (children.num_children == 0)) {
|
||||
if ((index >= children.num_children) || (children.num_children == 0)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
@ -78,15 +77,13 @@ sw_remove_child_at_index(DWORD index) {
|
||||
if (children.num_zombies == 0) {
|
||||
children.handles[index] = children.handles[children.num_children - 1];
|
||||
children.process_id[index] = children.process_id[children.num_children - 1];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* if its a zombie */
|
||||
if (index >= (children.num_children - children.num_zombies)) {
|
||||
children.handles[index] = children.handles[children.num_children - 1];
|
||||
children.process_id[index] = children.process_id[children.num_children - 1];
|
||||
children.num_zombies--;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
last_non_zombie = children.num_children - children.num_zombies - 1;
|
||||
children.handles[index] = children.handles[last_non_zombie];
|
||||
children.process_id[index] = children.process_id[last_non_zombie];
|
||||
@ -101,7 +98,8 @@ sw_remove_child_at_index(DWORD index) {
|
||||
}
|
||||
|
||||
int
|
||||
sw_child_to_zombie(DWORD index) {
|
||||
sw_child_to_zombie(DWORD index)
|
||||
{
|
||||
DWORD last_non_zombie, zombie_pid;
|
||||
HANDLE zombie_handle;
|
||||
|
||||
@ -114,7 +112,6 @@ sw_child_to_zombie(DWORD index) {
|
||||
}
|
||||
|
||||
last_non_zombie = children.num_children - children.num_zombies - 1;
|
||||
|
||||
if (last_non_zombie != index) {
|
||||
/* swap */
|
||||
zombie_pid = children.process_id[index];
|
||||
@ -129,7 +126,8 @@ sw_child_to_zombie(DWORD index) {
|
||||
}
|
||||
|
||||
int
|
||||
w32_kill(int pid, int sig) {
|
||||
w32_kill(int pid, int sig)
|
||||
{
|
||||
int child_index, i;
|
||||
if (pid == GetCurrentProcessId())
|
||||
return w32_raise(sig);
|
||||
@ -148,7 +146,9 @@ w32_kill(int pid, int sig) {
|
||||
}
|
||||
|
||||
|
||||
int waitpid(int pid, int *status, int options) {
|
||||
int
|
||||
waitpid(int pid, int *status, int options)
|
||||
{
|
||||
DWORD index, ret, ret_id, exit_code, timeout = 0;
|
||||
HANDLE process = NULL;
|
||||
|
||||
@ -230,20 +230,19 @@ int waitpid(int pid, int *status, int options) {
|
||||
if (status)
|
||||
*status = exit_code;
|
||||
return ret_id;
|
||||
}
|
||||
else if (ret == WAIT_TIMEOUT) {
|
||||
} else if (ret == WAIT_TIMEOUT) {
|
||||
/* TODO - assert that WNOHANG was specified*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
DebugBreak();//fatal
|
||||
DebugBreak(); /* fatal */
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
sw_cleanup_child_zombies() {
|
||||
sw_cleanup_child_zombies()
|
||||
{
|
||||
int pid = 1;
|
||||
while (pid > 0) {
|
||||
while (pid > 0)
|
||||
pid = waitpid(-1, NULL, WNOHANG);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -67,7 +67,8 @@ void fd_table_set(struct w32_io* pio, int index);
|
||||
|
||||
/* initializes mapping table*/
|
||||
static int
|
||||
fd_table_initialize() {
|
||||
fd_table_initialize()
|
||||
{
|
||||
memset(&fd_table, 0, sizeof(fd_table));
|
||||
memset(&w32_io_stdin, 0, sizeof(w32_io_stdin));
|
||||
w32_io_stdin.std_handle = STD_INPUT_HANDLE;
|
||||
@ -86,7 +87,8 @@ fd_table_initialize() {
|
||||
|
||||
/* get a free slot in mapping table with least index*/
|
||||
static int
|
||||
fd_table_get_min_index() {
|
||||
fd_table_get_min_index()
|
||||
{
|
||||
int min_index = 0;
|
||||
unsigned char* bitmap = fd_table.occupied.bitmap;
|
||||
unsigned char tmp;
|
||||
@ -102,9 +104,7 @@ fd_table_get_min_index() {
|
||||
}
|
||||
|
||||
tmp = *bitmap;
|
||||
|
||||
while (tmp & 0x80)
|
||||
{
|
||||
while (tmp & 0x80) {
|
||||
tmp <<= 1;
|
||||
min_index++;
|
||||
}
|
||||
@ -114,7 +114,8 @@ fd_table_get_min_index() {
|
||||
|
||||
/* maps pio to fd (specified by index)*/
|
||||
static void
|
||||
fd_table_set(struct w32_io* pio, int index) {
|
||||
fd_table_set(struct w32_io* pio, int index)
|
||||
{
|
||||
fd_table.w32_ios[index] = pio;
|
||||
pio->table_index = index;
|
||||
assert(pio->type != UNKNOWN_FD);
|
||||
@ -131,19 +132,20 @@ fd_table_clear(int index)
|
||||
}
|
||||
|
||||
void
|
||||
w32posix_initialize() {
|
||||
if ((fd_table_initialize() != 0)
|
||||
|| (socketio_initialize() != 0))
|
||||
w32posix_initialize()
|
||||
{
|
||||
if ((fd_table_initialize() != 0) || (socketio_initialize() != 0))
|
||||
DebugBreak();
|
||||
main_thread = OpenThread(THREAD_SET_CONTEXT | SYNCHRONIZE, FALSE, GetCurrentThreadId());
|
||||
if ((main_thread == NULL) || (sw_initialize() != 0) || w32_programdir() == NULL) {
|
||||
DebugBreak();
|
||||
fatal("failed to initialize w32posix wrapper");
|
||||
}
|
||||
if ((main_thread == NULL) || (sw_initialize() != 0) || w32_programdir() == NULL) {
|
||||
DebugBreak();
|
||||
fatal("failed to initialize w32posix wrapper");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
w32posix_done() {
|
||||
w32posix_done()
|
||||
{
|
||||
socketio_done();
|
||||
}
|
||||
|
||||
@ -159,7 +161,8 @@ w32_io_is_blocking(struct w32_io* pio)
|
||||
* as it decides on what fds can be set.
|
||||
*/
|
||||
BOOL
|
||||
w32_io_is_io_available(struct w32_io* pio, BOOL rd) {
|
||||
w32_io_is_io_available(struct w32_io* pio, BOOL rd)
|
||||
{
|
||||
if (pio->type == SOCK_FD)
|
||||
return socketio_is_io_available(pio, rd);
|
||||
else
|
||||
@ -195,7 +198,8 @@ w32_io_on_select(struct w32_io* pio, BOOL rd)
|
||||
} while (0)
|
||||
|
||||
int
|
||||
w32_socket(int domain, int type, int protocol) {
|
||||
w32_socket(int domain, int type, int protocol)
|
||||
{
|
||||
int min_index = fd_table_get_min_index();
|
||||
struct w32_io* pio = NULL;
|
||||
|
||||
@ -216,7 +220,6 @@ w32_socket(int domain, int type, int protocol) {
|
||||
int
|
||||
w32_accept(int fd, struct sockaddr* addr, int* addrlen)
|
||||
{
|
||||
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
int min_index = fd_table_get_min_index();
|
||||
@ -236,72 +239,72 @@ w32_accept(int fd, struct sockaddr* addr, int* addrlen)
|
||||
}
|
||||
|
||||
int
|
||||
w32_setsockopt(int fd, int level, int optname, const void* optval, int optlen) {
|
||||
|
||||
w32_setsockopt(int fd, int level, int optname, const void* optval, int optlen)
|
||||
{
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_setsockopt(fd_table.w32_ios[fd], level, optname, (const char*)optval, optlen);
|
||||
}
|
||||
|
||||
int
|
||||
w32_getsockopt(int fd, int level, int optname, void* optval, int* optlen) {
|
||||
|
||||
w32_getsockopt(int fd, int level, int optname, void* optval, int* optlen)
|
||||
{
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_getsockopt(fd_table.w32_ios[fd], level, optname, (char*)optval, optlen);
|
||||
}
|
||||
|
||||
int
|
||||
w32_getsockname(int fd, struct sockaddr* name, int* namelen) {
|
||||
|
||||
w32_getsockname(int fd, struct sockaddr* name, int* namelen)
|
||||
{
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_getsockname(fd_table.w32_ios[fd], name, namelen);
|
||||
}
|
||||
|
||||
int
|
||||
w32_getpeername(int fd, struct sockaddr* name, int* namelen) {
|
||||
|
||||
w32_getpeername(int fd, struct sockaddr* name, int* namelen)
|
||||
{
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_getpeername(fd_table.w32_ios[fd], name, namelen);
|
||||
}
|
||||
|
||||
int
|
||||
w32_listen(int fd, int backlog) {
|
||||
|
||||
w32_listen(int fd, int backlog)
|
||||
{
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_listen(fd_table.w32_ios[fd], backlog);
|
||||
}
|
||||
|
||||
int
|
||||
w32_bind(int fd, const struct sockaddr *name, int namelen) {
|
||||
|
||||
w32_bind(int fd, const struct sockaddr *name, int namelen)
|
||||
{
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_bind(fd_table.w32_ios[fd], name, namelen);
|
||||
}
|
||||
|
||||
int
|
||||
w32_connect(int fd, const struct sockaddr* name, int namelen) {
|
||||
|
||||
w32_connect(int fd, const struct sockaddr* name, int namelen)
|
||||
{
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_connect(fd_table.w32_ios[fd], name, namelen);
|
||||
}
|
||||
|
||||
int
|
||||
w32_recv(int fd, void *buf, size_t len, int flags) {
|
||||
|
||||
w32_recv(int fd, void *buf, size_t len, int flags)
|
||||
{
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_recv(fd_table.w32_ios[fd], buf, len, flags);
|
||||
}
|
||||
|
||||
int
|
||||
w32_send(int fd, const void *buf, size_t len, int flags) {
|
||||
|
||||
w32_send(int fd, const void *buf, size_t len, int flags)
|
||||
{
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
return socketio_send(fd_table.w32_ios[fd], buf, len, flags);
|
||||
@ -309,7 +312,8 @@ w32_send(int fd, const void *buf, size_t len, int flags) {
|
||||
|
||||
|
||||
int
|
||||
w32_shutdown(int fd, int how) {
|
||||
w32_shutdown(int fd, int how)
|
||||
{
|
||||
debug2("shutdown - fd:%d how:%d", fd, how);
|
||||
CHECK_FD(fd);
|
||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||
@ -317,15 +321,17 @@ w32_shutdown(int fd, int how) {
|
||||
}
|
||||
|
||||
int
|
||||
w32_socketpair(int domain, int type, int protocol, int sv[2]) {
|
||||
errno = ENOTSUP;
|
||||
w32_socketpair(int domain, int type, int protocol, int sv[2])
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
debug("socketpair - ERROR not supported");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
w32_pipe(int *pfds) {
|
||||
w32_pipe(int *pfds)
|
||||
{
|
||||
int read_index, write_index;
|
||||
struct w32_io* pio[2];
|
||||
|
||||
@ -351,12 +357,14 @@ w32_pipe(int *pfds) {
|
||||
pfds[0] = read_index;
|
||||
pfds[1] = write_index;
|
||||
debug("pipe - r-h:%d,io:%p,fd:%d w-h:%d,io:%p,fd:%d",
|
||||
pio[0]->handle, pio[0], read_index, pio[1]->handle, pio[1], write_index);
|
||||
pio[0]->handle, pio[0], read_index, pio[1]->handle, pio[1], write_index);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
w32_open(const char *pathname, int flags, ...) {
|
||||
w32_open(const char *pathname, int flags, ...)
|
||||
{
|
||||
int min_index = fd_table_get_min_index();
|
||||
struct w32_io* pio;
|
||||
|
||||
@ -376,9 +384,9 @@ w32_open(const char *pathname, int flags, ...) {
|
||||
}
|
||||
|
||||
int
|
||||
w32_read(int fd, void *dst, size_t max) {
|
||||
w32_read(int fd, void *dst, size_t max)
|
||||
{
|
||||
CHECK_FD(fd);
|
||||
|
||||
if (fd_table.w32_ios[fd]->type == SOCK_FD)
|
||||
return socketio_recv(fd_table.w32_ios[fd], dst, max, 0);
|
||||
|
||||
@ -386,7 +394,8 @@ w32_read(int fd, void *dst, size_t max) {
|
||||
}
|
||||
|
||||
int
|
||||
w32_write(int fd, const void *buf, unsigned int max) {
|
||||
w32_write(int fd, const void *buf, unsigned int max)
|
||||
{
|
||||
CHECK_FD(fd);
|
||||
|
||||
if (fd_table.w32_ios[fd]->type == SOCK_FD)
|
||||
@ -395,37 +404,39 @@ w32_write(int fd, const void *buf, unsigned int max) {
|
||||
return fileio_write(fd_table.w32_ios[fd], buf, max);
|
||||
}
|
||||
|
||||
int w32_writev(int fd, const struct iovec *iov, int iovcnt) {
|
||||
int written = 0;
|
||||
int i = 0;
|
||||
int
|
||||
w32_writev(int fd, const struct iovec *iov, int iovcnt)
|
||||
{
|
||||
int written = 0;
|
||||
int i = 0;
|
||||
|
||||
CHECK_FD(fd);
|
||||
CHECK_FD(fd);
|
||||
for (i = 0; i < iovcnt; i++) {
|
||||
int ret = w32_write(fd, iov[i].iov_base, iov[i].iov_len);
|
||||
if (ret > 0)
|
||||
written += ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < iovcnt; i++) {
|
||||
int ret = w32_write(fd, iov[i].iov_base, iov[i].iov_len);
|
||||
|
||||
if (ret > 0) {
|
||||
written += ret;
|
||||
}
|
||||
}
|
||||
|
||||
return written;
|
||||
return written;
|
||||
}
|
||||
|
||||
int
|
||||
w32_fstat(int fd, struct w32_stat *buf) {
|
||||
w32_fstat(int fd, struct w32_stat *buf)
|
||||
{
|
||||
CHECK_FD(fd);
|
||||
return fileio_fstat(fd_table.w32_ios[fd], (struct _stat64*)buf);
|
||||
}
|
||||
|
||||
long
|
||||
w32_lseek(int fd, long offset, int origin) {
|
||||
w32_lseek(int fd, long offset, int origin)
|
||||
{
|
||||
CHECK_FD(fd);
|
||||
return fileio_lseek(fd_table.w32_ios[fd], offset, origin);
|
||||
}
|
||||
|
||||
int
|
||||
w32_isatty(int fd) {
|
||||
w32_isatty(int fd)
|
||||
{
|
||||
struct w32_io* pio;
|
||||
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
|
||||
errno = EBADF;
|
||||
@ -433,7 +444,6 @@ w32_isatty(int fd) {
|
||||
}
|
||||
|
||||
pio = fd_table.w32_ios[fd];
|
||||
|
||||
if (FILETYPE(pio) == FILE_TYPE_CHAR)
|
||||
return 1;
|
||||
else {
|
||||
@ -443,7 +453,8 @@ w32_isatty(int fd) {
|
||||
}
|
||||
|
||||
FILE*
|
||||
w32_fdopen(int fd, const char *mode) {
|
||||
w32_fdopen(int fd, const char *mode)
|
||||
{
|
||||
errno = 0;
|
||||
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
|
||||
errno = EBADF;
|
||||
@ -454,13 +465,13 @@ w32_fdopen(int fd, const char *mode) {
|
||||
}
|
||||
|
||||
int
|
||||
w32_close(int fd) {
|
||||
w32_close(int fd)
|
||||
{
|
||||
struct w32_io* pio;
|
||||
|
||||
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pio = fd_table.w32_ios[fd];
|
||||
|
||||
@ -480,7 +491,8 @@ w32_close(int fd) {
|
||||
}
|
||||
|
||||
static int
|
||||
w32_io_process_fd_flags(struct w32_io* pio, int flags) {
|
||||
w32_io_process_fd_flags(struct w32_io* pio, int flags)
|
||||
{
|
||||
DWORD shi_flags;
|
||||
if (flags & ~FD_CLOEXEC) {
|
||||
debug("fcntl - ERROR unsupported flags %d, io:%p", flags, pio);
|
||||
@ -502,42 +514,43 @@ w32_io_process_fd_flags(struct w32_io* pio, int flags) {
|
||||
}
|
||||
|
||||
int
|
||||
w32_fcntl(int fd, int cmd, ... /* arg */) {
|
||||
w32_fcntl(int fd, int cmd, ... /* arg */)
|
||||
{
|
||||
va_list valist;
|
||||
va_start(valist, cmd);
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
CHECK_FD(fd);
|
||||
|
||||
switch (cmd) {
|
||||
case F_GETFL:
|
||||
ret = fd_table.w32_ios[fd]->fd_status_flags;
|
||||
break;
|
||||
break;
|
||||
case F_SETFL:
|
||||
fd_table.w32_ios[fd]->fd_status_flags = va_arg(valist, int);
|
||||
ret = 0;
|
||||
break;
|
||||
break;
|
||||
case F_GETFD:
|
||||
ret = fd_table.w32_ios[fd]->fd_flags;
|
||||
break;
|
||||
break;
|
||||
case F_SETFD:
|
||||
ret = w32_io_process_fd_flags(fd_table.w32_ios[fd], va_arg(valist, int));
|
||||
break;
|
||||
ret = w32_io_process_fd_flags(fd_table.w32_ios[fd], va_arg(valist, int));
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
debug("fcntl - ERROR not supported cmd:%d", cmd);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
va_end(valist);
|
||||
return ret;
|
||||
va_end(valist);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define SELECT_EVENT_LIMIT 32
|
||||
int
|
||||
w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* exceptfds,
|
||||
const struct timeval *timeout) {
|
||||
w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* exceptfds, const struct timeval *timeout)
|
||||
{
|
||||
ULONGLONG ticks_start = GetTickCount64(), ticks_spent;
|
||||
w32_fd_set read_ready_fds, write_ready_fds;
|
||||
HANDLE events[SELECT_EVENT_LIMIT];
|
||||
@ -566,12 +579,12 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
|
||||
}
|
||||
|
||||
/* TODO - see if this needs to be supported */
|
||||
//if (exceptfds) {
|
||||
// errno = EOPNOTSUPP;
|
||||
// debug("select - ERROR: exceptfds not supported");
|
||||
// DebugBreak();
|
||||
// return -1;
|
||||
//}
|
||||
/* if (exceptfds) {
|
||||
errno = EOPNOTSUPP;
|
||||
debug("select - ERROR: exceptfds not supported");
|
||||
DebugBreak();
|
||||
return -1;
|
||||
} */
|
||||
|
||||
if (readfds) {
|
||||
for (i = 0; i < fds; i++)
|
||||
@ -602,11 +615,10 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
|
||||
* that select needs to listen on
|
||||
*/
|
||||
for (int i = 0; i < fds; i++) {
|
||||
|
||||
if (readfds && FD_ISSET(i, readfds)) {
|
||||
w32_io_on_select(fd_table.w32_ios[i], TRUE);
|
||||
if ((fd_table.w32_ios[i]->type == SOCK_FD)
|
||||
&& (fd_table.w32_ios[i]->internal.state == SOCK_LISTENING)) {
|
||||
if ((fd_table.w32_ios[i]->type == SOCK_FD) &&
|
||||
(fd_table.w32_ios[i]->internal.state == SOCK_LISTENING)) {
|
||||
if (num_events == SELECT_EVENT_LIMIT) {
|
||||
debug("select - ERROR: max #events breach");
|
||||
errno = ENOMEM;
|
||||
@ -618,8 +630,8 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
|
||||
|
||||
if (writefds && FD_ISSET(i, writefds)) {
|
||||
w32_io_on_select(fd_table.w32_ios[i], FALSE);
|
||||
if ((fd_table.w32_ios[i]->type == SOCK_FD)
|
||||
&& (fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)) {
|
||||
if ((fd_table.w32_ios[i]->type == SOCK_FD) &&
|
||||
(fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)) {
|
||||
if (num_events == SELECT_EVENT_LIMIT) {
|
||||
debug("select - ERROR: max #events reached for select");
|
||||
errno = ENOMEM;
|
||||
@ -636,7 +648,6 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
|
||||
|
||||
/* see if any io is ready */
|
||||
for (i = 0; i < fds; i++) {
|
||||
|
||||
if (readfds && FD_ISSET(i, readfds)) {
|
||||
if (w32_io_is_io_available(fd_table.w32_ios[i], TRUE)) {
|
||||
FD_SET(i, &read_ready_fds);
|
||||
@ -677,7 +688,6 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
|
||||
/* check on fd status */
|
||||
out_ready_fds = 0;
|
||||
for (int i = 0; i < fds; i++) {
|
||||
|
||||
if (readfds && FD_ISSET(i, readfds)) {
|
||||
if (w32_io_is_io_available(fd_table.w32_ios[i], TRUE)) {
|
||||
FD_SET(i, &read_ready_fds);
|
||||
@ -695,7 +705,6 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
|
||||
|
||||
if (out_ready_fds == 0)
|
||||
debug3("select - wait ended without any IO completion, looping again");
|
||||
|
||||
}
|
||||
|
||||
/* clear out fds that are not ready yet */
|
||||
@ -709,8 +718,8 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
|
||||
if (FD_ISSET(i, writefds)) {
|
||||
if (FD_ISSET(i, &write_ready_fds)) {
|
||||
/* for connect() completed sockets finish WSA connect process*/
|
||||
if ((fd_table.w32_ios[i]->type == SOCK_FD)
|
||||
&& ((fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)))
|
||||
if ((fd_table.w32_ios[i]->type == SOCK_FD) &&
|
||||
((fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)))
|
||||
if (socketio_finish_connect(fd_table.w32_ios[i]) != 0) {
|
||||
/* finalizeing connect failed - recored error */
|
||||
/* error gets picked up later recv and/or send*/
|
||||
@ -730,7 +739,8 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
|
||||
}
|
||||
|
||||
int
|
||||
w32_dup(int oldfd) {
|
||||
w32_dup(int oldfd)
|
||||
{
|
||||
int min_index;
|
||||
struct w32_io* pio;
|
||||
HANDLE src, target;
|
||||
@ -773,7 +783,8 @@ w32_dup(int oldfd) {
|
||||
}
|
||||
|
||||
int
|
||||
w32_dup2(int oldfd, int newfd) {
|
||||
w32_dup2(int oldfd, int newfd)
|
||||
{
|
||||
CHECK_FD(oldfd);
|
||||
errno = EOPNOTSUPP;
|
||||
debug("dup2 - ERROR: not implemented yet");
|
||||
@ -781,14 +792,17 @@ w32_dup2(int oldfd, int newfd) {
|
||||
}
|
||||
|
||||
HANDLE
|
||||
w32_fd_to_handle(int fd) {
|
||||
w32_fd_to_handle(int fd)
|
||||
{
|
||||
HANDLE h = fd_table.w32_ios[fd]->handle;
|
||||
if (fd <= STDERR_FILENO)
|
||||
h = GetStdHandle(fd_table.w32_ios[fd]->std_handle);
|
||||
return h;
|
||||
}
|
||||
|
||||
int w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock) {
|
||||
int
|
||||
w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock)
|
||||
{
|
||||
int min_index = fd_table_get_min_index();
|
||||
struct w32_io* pio;
|
||||
|
||||
@ -803,7 +817,7 @@ int w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock) {
|
||||
}
|
||||
memset(pio, 0, sizeof(struct w32_io));
|
||||
|
||||
pio->type = is_sock? SOCK_FD : NONSOCK_FD;
|
||||
pio->type = is_sock ? SOCK_FD : NONSOCK_FD;
|
||||
pio->handle = h;
|
||||
fd_table_set(pio, min_index);
|
||||
return min_index;
|
||||
@ -811,9 +825,9 @@ int w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock) {
|
||||
|
||||
|
||||
int
|
||||
w32_ftruncate(int fd, off_t length) {
|
||||
w32_ftruncate(int fd, off_t length)
|
||||
{
|
||||
LARGE_INTEGER new_postion;
|
||||
|
||||
CHECK_FD(fd);
|
||||
|
||||
new_postion.QuadPart = length;
|
||||
@ -826,8 +840,8 @@ w32_ftruncate(int fd, off_t length) {
|
||||
}
|
||||
|
||||
int
|
||||
w32_fsync(int fd) {
|
||||
w32_fsync(int fd)
|
||||
{
|
||||
CHECK_FD(fd);
|
||||
|
||||
return FlushFileBuffers(w32_fd_to_handle(fd));
|
||||
}
|
||||
|
@ -1,7 +1,33 @@
|
||||
/*
|
||||
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
|
||||
*
|
||||
* Definitions for Win32 wrapper functions with POSIX like signatures
|
||||
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
|
||||
*
|
||||
* Definitions for Win32 wrapper functions with POSIX like signatures
|
||||
*
|
||||
* Copyright (c) 2015 Microsoft Corp.
|
||||
* All rights reserved
|
||||
*
|
||||
* Microsoft openssh win32 port
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -32,24 +58,18 @@ struct w32_io {
|
||||
OVERLAPPED read_overlapped;
|
||||
OVERLAPPED write_overlapped;
|
||||
struct {
|
||||
/*internal read buffer*/
|
||||
char *buf;
|
||||
char *buf; /*internal read buffer*/
|
||||
DWORD buf_size;
|
||||
/*bytes in internal buffer remaining to be read by application*/
|
||||
DWORD remaining;
|
||||
/*bytes in internal buffer already read by application*/
|
||||
DWORD completed;
|
||||
DWORD remaining; /*bytes in internal buffer remaining to be read by application*/
|
||||
DWORD completed; /*bytes in internal buffer already read by application*/
|
||||
BOOL pending; /*waiting on a read operation to complete*/
|
||||
DWORD error; /*error reported on async read or accept completion*/
|
||||
}read_details;
|
||||
struct {
|
||||
/*internal write buffer*/
|
||||
char *buf;
|
||||
char *buf; /*internal write buffer*/
|
||||
DWORD buf_size;
|
||||
/*bytes in internal buffer remaining to be written to network*/
|
||||
DWORD remaining;
|
||||
/*bytes in internal buffer already written to network*/
|
||||
DWORD completed;
|
||||
DWORD remaining; /*bytes in internal buffer remaining to be written to network*/
|
||||
DWORD completed; /*bytes in internal buffer already written to network*/
|
||||
BOOL pending; /*waiting on a write operation to complete*/
|
||||
DWORD error; /*error reported on async write or connect completion*/
|
||||
}write_details;
|
||||
@ -89,10 +109,8 @@ BOOL socketio_is_io_available(struct w32_io* pio, BOOL rd);
|
||||
void socketio_on_select(struct w32_io* pio, BOOL rd);
|
||||
struct w32_io* socketio_socket(int domain, int type, int protocol);
|
||||
struct w32_io* socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen);
|
||||
int socketio_setsockopt(struct w32_io* pio, int level, int optname,
|
||||
const char* optval, int optlen);
|
||||
int socketio_getsockopt(struct w32_io* pio, int level, int optname,
|
||||
char* optval, int* optlen);
|
||||
int socketio_setsockopt(struct w32_io* pio, int level, int optname, const char* optval, int optlen);
|
||||
int socketio_getsockopt(struct w32_io* pio, int level, int optname, char* optval, int* optlen);
|
||||
int socketio_getsockname(struct w32_io* pio, struct sockaddr* name, int* namelen);
|
||||
int socketio_getpeername(struct w32_io* pio, struct sockaddr* name, int* namelen);
|
||||
int socketio_listen(struct w32_io* pio, int backlog);
|
||||
@ -145,16 +163,16 @@ int termio_close(struct w32_io* pio);
|
||||
/* If O_CREAT and O_EXCL are set, open() shall fail if the file exists */
|
||||
/* #define O_EXCL 0x400 */
|
||||
/* #define O_BINARY 0x8000 //Gives raw data (while O_TEXT normalises line endings */
|
||||
// open modes
|
||||
/* open modes */
|
||||
#ifndef S_IRUSR
|
||||
#define S_IRUSR 00400 //user has read permission
|
||||
#endif // ! S_IRUSR
|
||||
#define S_IRUSR 00400 /* user has read permission */
|
||||
#endif /* ! S_IRUSR */
|
||||
#ifndef S_IWUSR
|
||||
#define S_IWUSR 00200 //user has write permission
|
||||
#define S_IWUSR 00200 /* user has write permission */
|
||||
#endif
|
||||
#ifndef S_IRGRP
|
||||
#define S_IRGRP 00040 //group has read permission
|
||||
#define S_IRGRP 00040 /* group has read permission */
|
||||
#endif
|
||||
#ifndef S_IROTH
|
||||
#define S_IROTH 00004 //others have read permission
|
||||
#define S_IROTH 00004 /* others have read permission */
|
||||
#endif
|
@ -27,11 +27,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <Windows.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "inc\syslog.h"
|
||||
#include "misc_internal.h"
|
||||
|
||||
@ -39,14 +39,15 @@
|
||||
static int logfd = -1;
|
||||
|
||||
void
|
||||
openlog(char *ident, unsigned int option, int facility) {
|
||||
openlog(char *ident, unsigned int option, int facility)
|
||||
{
|
||||
if (logfd != -1 || ident == NULL)
|
||||
return;
|
||||
|
||||
wchar_t path[PATH_MAX], log_file[PATH_MAX + 12];
|
||||
if (GetModuleFileNameW(NULL, path, PATH_MAX) == 0)
|
||||
|
||||
return;
|
||||
|
||||
path[PATH_MAX - 1] = '\0';
|
||||
|
||||
/* split path root and module */
|
||||
@ -64,20 +65,20 @@ openlog(char *ident, unsigned int option, int facility) {
|
||||
memcpy(p, L"log\0", 8);
|
||||
}
|
||||
|
||||
logfd = _wopen(log_file, O_WRONLY | O_CREAT | O_APPEND,
|
||||
S_IREAD | S_IWRITE);
|
||||
logfd = _wopen(log_file, O_WRONLY | O_CREAT | O_APPEND, S_IREAD | S_IWRITE);
|
||||
if (logfd != -1)
|
||||
SetHandleInformation((HANDLE)_get_osfhandle(logfd),
|
||||
HANDLE_FLAG_INHERIT, 0);
|
||||
SetHandleInformation((HANDLE)_get_osfhandle(logfd), HANDLE_FLAG_INHERIT, 0);
|
||||
}
|
||||
|
||||
void
|
||||
closelog(void) {
|
||||
closelog(void)
|
||||
{
|
||||
/*NOOP*/
|
||||
}
|
||||
|
||||
void
|
||||
syslog(int priority, const char *format, const char *formatBuffer) {
|
||||
syslog(int priority, const char *format, const char *formatBuffer)
|
||||
{
|
||||
char msgbufTimestamp[MSGBUFSIZ];
|
||||
SYSTEMTIME st;
|
||||
|
||||
|
@ -1,19 +1,43 @@
|
||||
// win32_dirent.c
|
||||
// directory entry functions in Windows platform like Ubix/Linux
|
||||
// opendir(), readdir(), closedir().
|
||||
/*
|
||||
* Copyright (c) 2016 Microsoft Corp.
|
||||
* All rights reserved
|
||||
*
|
||||
* directory entry functions in Windows platform like Ubix/Linux
|
||||
* opendir(), readdir(), closedir().
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "inc\utf.h"
|
||||
|
||||
#include "inc\utf.h"
|
||||
#include "inc\dirent.h"
|
||||
#include "inc\libgen.h"
|
||||
#include "misc_internal.h"
|
||||
|
||||
|
||||
struct DIR_ {
|
||||
intptr_t hFile;
|
||||
struct _wfinddata_t c_file;
|
||||
@ -22,7 +46,8 @@ struct DIR_ {
|
||||
|
||||
/* Open a directory stream on NAME.
|
||||
Return a DIR stream on the directory, or NULL if it could not be opened. */
|
||||
DIR * opendir(const char *name)
|
||||
DIR *
|
||||
opendir(const char *name)
|
||||
{
|
||||
struct _wfinddata_t c_file;
|
||||
intptr_t hFile;
|
||||
@ -36,7 +61,7 @@ DIR * opendir(const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// add *.* for Windows _findfirst() search pattern
|
||||
/* add *.* for Windows _findfirst() search pattern */
|
||||
swprintf_s(searchstr, PATH_MAX, L"%s\\*.*", wname);
|
||||
free(wname);
|
||||
|
||||
@ -54,28 +79,30 @@ DIR * opendir(const char *name)
|
||||
memcpy(&pdir->c_file, &c_file, sizeof(c_file));
|
||||
pdir->first = 1;
|
||||
|
||||
return pdir ;
|
||||
return pdir;
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the directory stream DIRP.
|
||||
Return 0 if successful, -1 if not. */
|
||||
int closedir(DIR *dirp)
|
||||
int
|
||||
closedir(DIR *dirp)
|
||||
{
|
||||
if ( dirp && (dirp->hFile) ) {
|
||||
_findclose( dirp->hFile );
|
||||
dirp->hFile = 0;
|
||||
free (dirp);
|
||||
}
|
||||
if (dirp && (dirp->hFile)) {
|
||||
_findclose(dirp->hFile);
|
||||
dirp->hFile = 0;
|
||||
free(dirp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read a directory entry from DIRP.
|
||||
Return a pointer to a `struct dirent' describing the entry,
|
||||
or NULL for EOF or error. The storage returned may be overwritten
|
||||
by a later readdir call on the same DIR stream. */
|
||||
struct dirent *readdir(void *avp)
|
||||
struct dirent *
|
||||
readdir(void *avp)
|
||||
{
|
||||
static struct dirent pdirentry;
|
||||
struct _wfinddata_t c_file;
|
||||
@ -86,11 +113,10 @@ struct dirent *readdir(void *avp)
|
||||
if (dirp->first) {
|
||||
memcpy(&c_file, &dirp->c_file, sizeof(c_file));
|
||||
dirp->first = 0;
|
||||
}
|
||||
else if (_wfindnext(dirp->hFile, &c_file) != 0)
|
||||
} else if (_wfindnext(dirp->hFile, &c_file) != 0)
|
||||
return NULL;
|
||||
|
||||
if (wcscmp(c_file.name, L".") == 0 || wcscmp(c_file.name, L"..") == 0 )
|
||||
if (wcscmp(c_file.name, L".") == 0 || wcscmp(c_file.name, L"..") == 0)
|
||||
continue;
|
||||
|
||||
if ((tmp = utf16_to_utf8(c_file.name)) == NULL) {
|
||||
@ -101,13 +127,14 @@ struct dirent *readdir(void *avp)
|
||||
strncpy(pdirentry.d_name, tmp, strlen(tmp) + 1);
|
||||
free(tmp);
|
||||
|
||||
pdirentry.d_ino = 1; // a fictious one like UNIX to say it is nonzero
|
||||
return &pdirentry ;
|
||||
}
|
||||
pdirentry.d_ino = 1; /* a fictious one like UNIX to say it is nonzero */
|
||||
return &pdirentry;
|
||||
}
|
||||
}
|
||||
|
||||
// return last part of a path. The last path being a filename.
|
||||
char *basename(char *path)
|
||||
/* return last part of a path. The last path being a filename */
|
||||
char *
|
||||
basename(char *path)
|
||||
{
|
||||
char *pdest;
|
||||
|
||||
@ -115,10 +142,10 @@ char *basename(char *path)
|
||||
return ".";
|
||||
pdest = strrchr(path, '/');
|
||||
if (pdest)
|
||||
return (pdest+1);
|
||||
return (pdest + 1);
|
||||
pdest = strrchr(path, '\\');
|
||||
if (pdest)
|
||||
return (pdest+1);
|
||||
return (pdest + 1);
|
||||
|
||||
return path; // path does not have a slash
|
||||
return path; /* path does not have a slash */
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user