Commit fcb94a17 authored by Alexander Alashkin's avatar Alexander Alashkin Committed by Cesanta Bot

Port Mongoose to WinCE, part I

PUBLISHED_FROM=292d73fa3e90377b1f929ae47ae1073dab5a4089
parent 8ff010ca
......@@ -143,6 +143,8 @@ MG_INTERNAL void mg_handle_put(struct mg_connection *nc, const char *path,
struct http_message *hm);
#endif
MG_INTERNAL int mg_get_errno();
#endif /* CS_MONGOOSE_SRC_INTERNAL_H_ */
#ifdef MG_MODULE_LINES
#line 1 "common/cs_dbg.h"
......@@ -1963,7 +1965,7 @@ static int mg_resolve2(const char *host, struct in_addr *ina) {
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if ((rv = getaddrinfo(host, NULL, NULL, &servinfo)) != 0) {
DBG(("getaddrinfo(%s) failed: %s", host, strerror(errno)));
DBG(("getaddrinfo(%s) failed: %s", host, strerror(mg_get_errno())));
return 0;
}
for (p = servinfo; p != NULL; p = p->ai_next) {
......@@ -1975,7 +1977,7 @@ static int mg_resolve2(const char *host, struct in_addr *ina) {
#else
struct hostent *he;
if ((he = gethostbyname(host)) == NULL) {
DBG(("gethostbyname(%s) failed: %s", host, strerror(errno)));
DBG(("gethostbyname(%s) failed: %s", host, strerror(mg_get_errno())));
} else {
memcpy(ina, he->h_addr_list[0], sizeof(*ina));
return 1;
......@@ -2821,8 +2823,11 @@ void mg_set_non_blocking_mode(sock_t sock) {
}
static int mg_is_error(int n) {
return n == 0 || (n < 0 && errno != EINTR && errno != EINPROGRESS &&
errno != EAGAIN && errno != EWOULDBLOCK
int err = mg_get_errno();
return n == 0 || (n < 0 && err != EINPROGRESS && err != EWOULDBLOCK
#ifndef WINCE
&& err != EAGAIN && err != EINTR
#endif
#ifdef _WIN32
&& WSAGetLastError() != WSAEINTR &&
WSAGetLastError() != WSAEWOULDBLOCK
......@@ -2835,21 +2840,21 @@ void mg_if_connect_tcp(struct mg_connection *nc,
int rc, proto = 0;
nc->sock = socket(AF_INET, SOCK_STREAM, proto);
if (nc->sock == INVALID_SOCKET) {
nc->err = errno ? errno : 1;
nc->err = mg_get_errno() ? mg_get_errno() : 1;
return;
}
#if !defined(MG_ESP8266)
mg_set_non_blocking_mode(nc->sock);
#endif
rc = connect(nc->sock, &sa->sa, sizeof(sa->sin));
nc->err = mg_is_error(rc) ? errno : 0;
nc->err = mg_is_error(rc) ? mg_get_errno() : 0;
LOG(LL_INFO, ("%p sock %d err %d", nc, nc->sock, nc->err));
}
void mg_if_connect_udp(struct mg_connection *nc) {
nc->sock = socket(AF_INET, SOCK_DGRAM, 0);
if (nc->sock == INVALID_SOCKET) {
nc->err = errno ? errno : 1;
nc->err = mg_get_errno() ? mg_get_errno() : 1;
return;
}
if (nc->flags & MG_F_ENABLE_BROADCAST) {
......@@ -2864,7 +2869,7 @@ int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) {
int proto = 0;
sock_t sock = mg_open_listening_socket(sa, SOCK_STREAM, proto);
if (sock == INVALID_SOCKET) {
return (errno ? errno : 1);
return (mg_get_errno() ? mg_get_errno() : 1);
}
mg_sock_set(nc, sock);
return 0;
......@@ -2872,7 +2877,7 @@ int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) {
int mg_if_listen_udp(struct mg_connection *nc, union socket_address *sa) {
sock_t sock = mg_open_listening_socket(sa, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) return (errno ? errno : 1);
if (sock == INVALID_SOCKET) return (mg_get_errno() ? mg_get_errno() : 1);
mg_sock_set(nc, sock);
return 0;
}
......@@ -2913,7 +2918,7 @@ static int mg_accept_conn(struct mg_connection *lc) {
/* NOTE(lsm): on Windows, sock is always > FD_SETSIZE */
sock_t sock = accept(lc->sock, &sa.sa, &sa_len);
if (sock == INVALID_SOCKET) {
if (mg_is_error(-1)) DBG(("%p: failed to accept: %d", lc, errno));
if (mg_is_error(-1)) DBG(("%p: failed to accept: %d", lc, mg_get_errno()));
return 0;
}
nc = mg_if_accept_new_conn(lc);
......@@ -3000,7 +3005,7 @@ static void mg_write_to_socket(struct mg_connection *nc) {
if (nc->flags & MG_F_UDP) {
int n =
sendto(nc->sock, io->buf, io->len, 0, &nc->sa.sa, sizeof(nc->sa.sin));
DBG(("%p %d %d %d %s:%hu", nc, nc->sock, n, errno,
DBG(("%p %d %d %d %s:%hu", nc, nc->sock, n, mg_get_errno(),
inet_ntoa(nc->sa.sin.sin_addr), ntohs(nc->sa.sin.sin_port)));
if (n > 0) {
mbuf_remove(io, n);
......@@ -3114,7 +3119,7 @@ static int mg_recvfrom(struct mg_connection *nc, union socket_address *sa,
}
n = recvfrom(nc->sock, *buf, MG_UDP_RECV_BUFFER_SIZE, 0, &sa->sa, sa_len);
if (n <= 0) {
DBG(("%p recvfrom: %s", nc, strerror(errno)));
DBG(("%p recvfrom: %s", nc, strerror(mg_get_errno())));
MG_FREE(*buf);
}
return n;
......@@ -3149,7 +3154,7 @@ static int mg_ssl_err(struct mg_connection *conn, int res) {
static void mg_ssl_begin(struct mg_connection *nc) {
int server_side = (nc->listener != NULL);
int res = server_side ? SSL_accept(nc->ssl) : SSL_connect(nc->ssl);
DBG(("%p %d res %d %d", nc, server_side, res, errno));
DBG(("%p %d res %d %d", nc, server_side, res, mg_get_errno()));
if (res == 1) {
nc->flags |= MG_F_SSL_HANDSHAKE_DONE;
......@@ -5168,8 +5173,8 @@ void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
"HTTP/1.1 500 Internal Server Error\r\n"
"Content-Type: text/plain\r\n"
"Connection: close\r\n\r\n");
LOG(LL_ERROR, ("Failed to open %s: %d\n", fus->lfn, errno));
mg_printf(nc, "Failed to open %s: %d\n", fus->lfn, errno);
LOG(LL_ERROR, ("Failed to open %s: %d\n", fus->lfn, mg_get_errno()));
mg_printf(nc, "Failed to open %s: %d\n", fus->lfn, mg_get_errno());
/* Do not close the connection just yet, discard remainder of the data.
* This is because at the time of writing some browsers (Chrome) fail to
* render response before all the data is sent. */
......@@ -5184,11 +5189,11 @@ void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
(struct file_upload_state *) mp->user_data;
if (fus == NULL || fus->fp == NULL) break;
if (fwrite(mp->data.p, 1, mp->data.len, fus->fp) != mp->data.len) {
LOG(LL_ERROR, ("Failed to write to %s: %d, wrote %d", fus->lfn, errno,
(int) fus->num_recd));
if (errno == ENOSPC
LOG(LL_ERROR, ("Failed to write to %s: %d, wrote %d", fus->lfn,
mg_get_errno(), (int) fus->num_recd));
if (mg_get_errno() == ENOSPC
#ifdef SPIFFS_ERR_FULL
|| errno == SPIFFS_ERR_FULL
|| mg_get_errno() == SPIFFS_ERR_FULL
#endif
) {
mg_printf(nc,
......@@ -5203,7 +5208,7 @@ void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
"Content-Type: text/plain\r\n"
"Connection: close\r\n\r\n");
mg_printf(nc, "Failed to write to %s: %d, wrote %d", mp->file_name,
errno, (int) fus->num_recd);
mg_get_errno(), (int) fus->num_recd);
}
fclose(fus->fp);
remove(fus->lfn);
......@@ -5431,7 +5436,8 @@ static void mg_do_ssi_include(struct mg_connection *nc, struct http_message *hm,
}
if ((fp = fopen(path, "rb")) == NULL) {
mg_printf(nc, "SSI include error: fopen(%s): %s", path, strerror(errno));
mg_printf(nc, "SSI include error: fopen(%s): %s", path,
strerror(mg_get_errno()));
} else {
mg_set_close_on_exec(fileno(fp));
if (mg_match_prefix(opts->ssi_pattern, strlen(opts->ssi_pattern), path) >
......@@ -5452,7 +5458,7 @@ static void do_ssi_exec(struct mg_connection *nc, char *tag) {
if (sscanf(tag, " \"%[^\"]\"", cmd) != 1) {
mg_printf(nc, "Bad SSI #exec: [%s]", tag);
} else if ((fp = popen(cmd, "r")) == NULL) {
mg_printf(nc, "Cannot SSI #exec: [%s]: %s", cmd, strerror(errno));
mg_printf(nc, "Cannot SSI #exec: [%s]: %s", cmd, strerror(mg_get_errno()));
} else {
mg_send_file_data(nc, fp);
pclose(fp);
......@@ -5611,8 +5617,8 @@ void mg_http_serve_file(struct mg_connection *nc, struct http_message *hm,
cs_stat_t st;
DBG(("%p [%s] %.*s", nc, path, (int) mime_type.len, mime_type.p));
if (mg_stat(path, &st) != 0 || (pd->file.fp = fopen(path, "rb")) == NULL) {
int code;
switch (errno) {
int code, err = mg_get_errno();
switch (err) {
case EACCES:
code = 403;
break;
......@@ -6128,7 +6134,7 @@ static void mg_scan_directory(struct mg_connection *nc, const char *dir,
}
closedir(dirp);
} else {
DBG(("%p opendir(%s) -> %d", nc, dir, errno));
DBG(("%p opendir(%s) -> %d", nc, dir, mg_get_errno()));
}
}
......@@ -6917,7 +6923,6 @@ static void *mg_push_to_stdin(void *arg) {
DBG(("%s", "FORWARED EVERYTHING TO CGI"));
CloseHandle(tp->hPipe);
MG_FREE(tp);
_endthread();
return NULL;
}
......@@ -6939,7 +6944,6 @@ static void *mg_pull_from_stdout(void *arg) {
shutdown(tp->s, 2); // Without this, IO thread may get truncated data
closesocket(tp->s);
MG_FREE(tp);
_endthread();
return NULL;
}
......@@ -7701,7 +7705,9 @@ int mg_base64_decode(const unsigned char *s, int len, char *dst) {
#if MG_ENABLE_THREADS
void *mg_start_thread(void *(*f)(void *), void *p) {
#ifdef _WIN32
#ifdef WINCE
return (void *) CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) f, p, 0, NULL);
#elif defined(_WIN32)
return (void *) _beginthread((void(__cdecl *) (void *) ) f, 0, p);
#else
pthread_t thread_id = (pthread_t) 0;
......@@ -7724,7 +7730,7 @@ void *mg_start_thread(void *(*f)(void *), void *p) {
/* Set close-on-exec bit for a given socket. */
void mg_set_close_on_exec(sock_t sock) {
#ifdef _WIN32
#if defined(_WIN32) && !defined(WINCE)
(void) SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0);
#elif defined(__unix__)
fcntl(sock, F_SETFD, FD_CLOEXEC);
......@@ -7833,7 +7839,7 @@ void mg_hexdump_connection(struct mg_connection *nc, const char *path,
MG_SOCK_STRINGIFY_PORT |
MG_SOCK_STRINGIFY_REMOTE);
fprintf(
fp, "%lu %p %s %s %s %d\n", (unsigned long) time(NULL), (void *) nc, src,
fp, "%lu %p %s %s %s %d\n", (unsigned long) mg_time(), (void *) nc, src,
ev == MG_EV_RECV ? "<-" : ev == MG_EV_SEND
? "->"
: ev == MG_EV_ACCEPT
......@@ -7983,6 +7989,15 @@ int mg_match_prefix(const char *pattern, int pattern_len, const char *str) {
const struct mg_str pstr = {pattern, (size_t) pattern_len};
return mg_match_prefix_n(pstr, mg_mk_str(str));
}
MG_INTERNAL int mg_get_errno() {
#ifndef WINCE
return errno;
#else
/* TODO(alashkin): translate error codes? */
return GetLastError();
#endif
}
#ifdef MG_MODULE_LINES
#line 1 "mongoose/src/mqtt.c"
#endif
......@@ -8972,20 +8987,24 @@ static int mg_get_ip_address_of_nameserver(char *name, size_t name_len) {
int i;
LONG err;
HKEY hKey, hSub;
char subkey[512], value[128],
*key = "SYSTEM\\ControlSet001\\Services\\Tcpip\\Parameters\\Interfaces";
wchar_t subkey[512], value[128],
*key = L"SYSTEM\\ControlSet001\\Services\\Tcpip\\Parameters\\Interfaces";
if ((err = RegOpenKeyA(HKEY_LOCAL_MACHINE, key, &hKey)) != ERROR_SUCCESS) {
fprintf(stderr, "cannot open reg key %s: %ld\n", key, err);
if ((err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hKey)) !=
ERROR_SUCCESS) {
fprintf(stderr, "cannot open reg key %S: %ld\n", key, err);
ret = -1;
} else {
for (ret = -1, i = 0;
RegEnumKeyA(hKey, i, subkey, sizeof(subkey)) == ERROR_SUCCESS; i++) {
DWORD type, len = sizeof(value);
if (RegOpenKeyA(hKey, subkey, &hSub) == ERROR_SUCCESS &&
(RegQueryValueExA(hSub, "NameServer", 0, &type, (void *) value,
for (ret = -1, i = 0; 1; i++) {
DWORD subkey_size = sizeof(subkey), type, len = sizeof(value);
if (RegEnumKeyExW(hKey, i, subkey, &subkey_size, NULL, NULL, NULL,
NULL) != ERROR_SUCCESS) {
break;
}
if (RegOpenKeyExW(hKey, subkey, 0, KEY_READ, &hSub) == ERROR_SUCCESS &&
(RegQueryValueExW(hSub, L"NameServer", 0, &type, (void *) value,
&len) == ERROR_SUCCESS ||
RegQueryValueExA(hSub, "DhcpNameServer", 0, &type, (void *) value,
RegQueryValueExW(hSub, L"DhcpNameServer", 0, &type, (void *) value,
&len) == ERROR_SUCCESS)) {
/*
* See https://github.com/cesanta/mongoose/issues/176
......@@ -8994,14 +9013,14 @@ static int mg_get_ip_address_of_nameserver(char *name, size_t name_len) {
* If it's empty, check the next interface.
* If it's multiple IP addresses, take the first one.
*/
char *comma = strchr(value, ',');
wchar_t *comma = wcschr(value, ',');
if (value[0] == '\0') {
continue;
}
if (comma != NULL) {
*comma = '\0';
}
snprintf(name, name_len, "udp://%s:53", value);
snprintf(name, name_len, "udp://%S:53", value);
ret = 0;
RegCloseKey(hSub);
break;
......@@ -9074,7 +9093,7 @@ int mg_resolve_from_hosts_file(const char *name, union socket_address *usa) {
}
static void mg_resolve_async_eh(struct mg_connection *nc, int ev, void *data) {
time_t now = time(NULL);
time_t now = (time_t) mg_time();
struct mg_resolve_async_request *req;
struct mg_dns_message *msg;
......@@ -12049,3 +12068,24 @@ ssize_t kr_recv(int fd, void *buf, size_t len, int flags) {
}
#endif /* defined(MG_NET_IF_LWIP) && defined(SSL_KRYPTON) */
#ifdef MG_MODULE_LINES
#line 1 "common/platforms/wince/wince_libc.c"
#endif
/*
* Copyright (c) 2016 Cesanta Software Limited
* All rights reserved
*/
#ifdef WINCE
const char *strerror(int err) {
/*
* TODO(alashkin): there is no strerror on WinCE;
* look for similar wce_xxxx function
*/
static char buf[10];
snprintf(buf, sizeof(buf), "%d", err);
return buf;
}
#endif
......@@ -49,6 +49,7 @@
#define CS_P_MSP432 5
#define CS_P_CC3100 6
#define CS_P_MBED 7
#define CS_P_WINCE 8
/* If not specified explicitly, we guess platform by defines. */
#ifndef CS_PLATFORM
......@@ -60,6 +61,8 @@
#define CS_PLATFORM CS_P_CC3200
#elif defined(__unix__) || defined(__APPLE__)
#define CS_PLATFORM CS_P_UNIX
#elif defined(WINCE)
#define CS_PLATFORM CS_P_WINCE
#elif defined(_WIN32)
#define CS_PLATFORM CS_P_WINDOWS
#elif defined(__MBED__)
......@@ -78,6 +81,7 @@
/* Amalgamated: #include "common/platforms/platform_cc3200.h" */
/* Amalgamated: #include "common/platforms/platform_cc3100.h" */
/* Amalgamated: #include "common/platforms/platform_mbed.h" */
/* Amalgamated: #include "common/platforms/platform_wince.h" */
/* Common stuff */
......@@ -862,6 +866,169 @@ int sl_set_ssl_opts(struct mg_connection *nc);
#endif /* CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_ */
#ifdef MG_MODULE_LINES
#line 1 "common/platforms/platform_wince.h"
#endif
#ifndef CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_
#define CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_
#if CS_PLATFORM == CS_P_WINCE
/*
* MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
* MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
* MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
* MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
* MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
* MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
* MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio 2003)
* MSVC++ 7.0 _MSC_VER == 1300
* MSVC++ 6.0 _MSC_VER == 1200
* MSVC++ 5.0 _MSC_VER == 1100
*/
#pragma warning(disable : 4127) /* FD_SET() emits warning, disable it */
#pragma warning(disable : 4204) /* missing c99 support */
#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
#endif
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <assert.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#pragma comment(lib, "ws2.lib") /* Linking with WinCE winsock library */
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#define strdup _strdup
#ifndef EINPROGRESS
#define EINPROGRESS WSAEINPROGRESS
#endif
#ifndef EWOULDBLOCK
#define EWOULDBLOCK WSAEWOULDBLOCK
#endif
#ifndef __func__
#define STRX(x) #x
#define STR(x) STRX(x)
#define __func__ __FILE__ ":" STR(__LINE__)
#endif
#define snprintf _snprintf
#define fileno _fileno
#define vsnprintf _vsnprintf
#define sleep(x) Sleep((x) *1000)
#define to64(x) _atoi64(x)
#define rmdir _rmdir
#if defined(_MSC_VER) && _MSC_VER >= 1400
#define fseeko(x, y, z) _fseeki64((x), (y), (z))
#else
#define fseeko(x, y, z) fseek((x), (y), (z))
#endif
typedef int socklen_t;
#if _MSC_VER >= 1700
#include <stdint.h>
#else
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#endif
typedef SOCKET sock_t;
typedef uint32_t in_addr_t;
#ifndef UINT16_MAX
#define UINT16_MAX 65535
#endif
#ifndef UINT32_MAX
#define UINT32_MAX 4294967295
#endif
#ifndef pid_t
#define pid_t HANDLE
#endif
#define INT64_FMT "I64d"
#define INT64_X_FMT "I64x"
/* TODO(alashkin): check if this is correct */
#define SIZE_T_FMT "u"
typedef struct _stati64 cs_stat_t;
#ifndef S_ISDIR
#define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(x) (((x) &_S_IFMT) == _S_IFREG)
#endif
#define DIRSEP '\\'
#ifndef va_copy
#ifdef __va_copy
#define va_copy __va_copy
#else
#define va_copy(x, y) (x) = (y)
#endif
#endif
#ifndef MG_MAX_HTTP_REQUEST_SIZE
#define MG_MAX_HTTP_REQUEST_SIZE 8192
#endif
#ifndef MG_MAX_HTTP_SEND_MBUF
#define MG_MAX_HTTP_SEND_MBUF 4096
#endif
#ifndef MG_MAX_HTTP_HEADERS
#define MG_MAX_HTTP_HEADERS 40
#endif
#ifndef CS_ENABLE_STDIO
#define CS_ENABLE_STDIO 1
#endif
typedef unsigned int* uintptr_t;
#define abort() DebugBreak();
#ifndef BUFSIZ
#define BUFSIZ 4096
#define ENOMEM ERROR_NOT_ENOUGH_MEMORY
#endif
const char *strerror();
#define MG_ENABLE_FILESYSTEM 0
/*
* WinCE lacks a lot of used in CGI API functions
* TODO(alaskin): look for wce_xxxx alternatives
*/
#define MG_ENABLE_CGI 0
#endif /* CS_PLATFORM == CS_P_WINCE */
#endif /* CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_ */
#ifdef MG_MODULE_LINES
#line 1 "common/cs_time.h"
#endif
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment