diff --git a/example1/example.rkt b/example1/example.rkt index a946d30..beec84b 100644 --- a/example1/example.rkt +++ b/example1/example.rkt @@ -312,7 +312,9 @@ ) ) ) - + +(webview-set-loglevel 'debug) + (define (run-example) (let* ((ini (new ini% [file 'web-racket-example1])) (context (new wv-context% [base-path cur-dir] [ini ini])) diff --git a/main.rkt b/main.rkt index e728138..1be7cee 100644 --- a/main.rkt +++ b/main.rkt @@ -1,5 +1,6 @@ #lang racket/base +(require "private/racket-webview.rkt") (require "private/wv-context.rkt") (require "private/wv-window.rkt") (require "private/wv-dialog.rkt") @@ -8,4 +9,5 @@ "private/wv-window.rkt" "private/wv-dialog.rkt" ) + webview-set-loglevel ) diff --git a/private/lib/linux/x86_64/librktwebview.so b/private/lib/linux/x86_64/librktwebview.so index 3ca127e..72d5008 100755 Binary files a/private/lib/linux/x86_64/librktwebview.so and b/private/lib/linux/x86_64/librktwebview.so differ diff --git a/private/lib/linux/x86_64/rktwebview_prg b/private/lib/linux/x86_64/rktwebview_prg index d65bb72..b8db3e4 100755 Binary files a/private/lib/linux/x86_64/rktwebview_prg and b/private/lib/linux/x86_64/rktwebview_prg differ diff --git a/private/racket-webview-qt.rkt b/private/racket-webview-qt.rkt index 3240ae3..ac3113a 100644 --- a/private/racket-webview-qt.rkt +++ b/private/racket-webview-qt.rkt @@ -44,6 +44,7 @@ rkt-webview-file-save rkt-webview-messagebox rkt-webview-version + rkt-webview-set-loglevel ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -193,6 +194,14 @@ ;; Types / Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define _rkt_loglevel_t + (_enum '(error = 1 + warning = 2 + info = 3 + debug = 4) + ) + ) + (define _rkt_result_t (_enum '(no_result_yet = -1 oke = 0 @@ -286,6 +295,9 @@ (define-rktwebview rkt_webview_cleanup (_fun -> _void)) +;RKTWEBVIEW_EXPORT void rkt_webview_set_loglevel(rkt_webview_loglevel_t l); +(define-rktwebview rkt_webview_set_loglevel + (_fun _rkt_loglevel_t -> _void)) ;RKTWEBVIEW_EXPORT int rkt_webview_events_waiting(); (define-rktwebview rkt_webview_events_waiting @@ -580,6 +592,9 @@ ((rkt-wv-close-callback handle)) #t) +(define (rkt-webview-set-loglevel l) + (rkt_webview_set_loglevel l)) + (define (rkt-webview-set-ou-token handle token) (rkt_webview_set_ou_token (rkt-wv-win handle) token) #t) diff --git a/private/racket-webview.rkt b/private/racket-webview.rkt index e986420..7d3a17a 100644 --- a/private/racket-webview.rkt +++ b/private/racket-webview.rkt @@ -112,6 +112,8 @@ wv-win-window-nr wv-context? + webview-set-loglevel + ;test ) @@ -493,6 +495,14 @@ (rkt-webview-set-html! (wv-win-handle wv) (xexpr->string html)) ) ) + +(define (loglevel? x) + (and (symbol? x) + (or (eq? x 'error) (eq? x 'info) (eq? x 'debug) (eq? x 'warning)))) + +(define/contract (webview-set-loglevel l) + (-> loglevel? void?) + (rkt-webview-set-loglevel l)) (define/contract (webview-set-url! wv url) (-> wv-win? (or/c string? url?) symbol?) diff --git a/rktwebview_qt/main.cpp b/rktwebview_qt/main.cpp index 86f82ec..aac9b19 100644 --- a/rktwebview_qt/main.cpp +++ b/rktwebview_qt/main.cpp @@ -63,7 +63,10 @@ int main(int argc, char *argv[]) { const char *me = argv[0]; - INFO1("%s runs\n", argv[0]); + { + time_t my_time = time(NULL); + INFO1("Starting at %s", ctime(&my_time)); + } if (argc < 6) { ERROR1("%s: wrong number of arguments\n", me); @@ -113,6 +116,11 @@ int main(int argc, char *argv[]) delete handler->shm; delete handler; + { + time_t my_time = time(NULL); + INFO1("Exiting at %s", ctime(&my_time)); + } + return 0; } @@ -140,6 +148,13 @@ void Handler::run() result_queue->enqueue(oke); } break; + case CMD_SET_LOGLEVEL: { + int ll = data_obj["wv"].toInt(); + setLogLevel(ll); + bool oke = true; + result_queue->enqueue(oke); + } + break; case CMD_CONTEXT_NEW: { QString boilerplate_js = data_obj["boilerplate_js"].toString(); bool has_pem_cert = data_obj["has_pem_cert"].toBool(); diff --git a/rktwebview_qt/rkt_protocol.h b/rktwebview_qt/rkt_protocol.h index aacfe2b..663bbc3 100644 --- a/rktwebview_qt/rkt_protocol.h +++ b/rktwebview_qt/rkt_protocol.h @@ -26,6 +26,7 @@ #define CMD_FILE_SAVE 23 // arguments: wv: int, title: string, base_dir: string, permitted_exts: string -> result_t: int #define CMD_SET_OU_TOKEN 24 // arguments: wv: int, token: string -> result_t: int #define CMD_MSG_BOX 25 // arguments: wv: int, title:string, message: string, submessage: string, type:int -> result_t: int +#define CMD_SET_LOGLEVEL 26 // arguments: ll: int #define RESULT_QUIT 36379 diff --git a/rktwebview_qt/rktwebview.cpp b/rktwebview_qt/rktwebview.cpp index 716dbac..0aebc2c 100644 --- a/rktwebview_qt/rktwebview.cpp +++ b/rktwebview_qt/rktwebview.cpp @@ -7,8 +7,12 @@ #include #include #else +#include #include #include +#include +#include +#include #endif #include @@ -101,7 +105,7 @@ bool runRktWebview(Handle_t *handler) sa.bInheritHandle = TRUE; HANDLE h = CreateFile(logfile.c_str(), - FILE_APPEND_DATA, + 0, //FILE_APPEND_DATA, FILE_SHARE_WRITE | FILE_SHARE_READ, &sa, OPEN_ALWAYS, @@ -137,7 +141,19 @@ bool runRktWebview(Handle_t *handler) #else char *argv[] = { rkt_webview_prg_path, const_cast(handler->name.c_str()), shm_size_str, command_slot, command_result_slot, event_slot, nullptr }; - int r = posix_spawn(&handler->rkt_webview_prg_pid, rkt_webview_prg_path, nullptr, nullptr, argv, environ); + struct passwd *pw = getpwuid(getuid()); + const char *homedir = pw->pw_dir; + + std::string log_file = std::string(homedir) + "/.racket-webview.log"; + + posix_spawn_file_actions_t action; + posix_spawn_file_actions_init(&action); + posix_spawn_file_actions_addopen(&action, STDOUT_FILENO, log_file.c_str(), O_CREAT|O_WRONLY, 0600); + posix_spawn_file_actions_addopen(&action, STDERR_FILENO, log_file.c_str(), O_WRONLY|O_APPEND, 0600); + + int r = posix_spawn(&handler->rkt_webview_prg_pid, rkt_webview_prg_path, &action, nullptr, argv, environ); + + posix_spawn_file_actions_destroy(&action); return (r == 0); #endif @@ -443,6 +459,15 @@ result_t rkt_webview_show_normal(rktwebview_t w) CMDRES0(CMD_SHOW_NORMAL, w) } +void rkt_webview_set_loglevel(rkt_webview_loglevel_t l) +{ + auto f = [l]() { + CMDRES0(CMD_SET_LOGLEVEL, static_cast(l)); + }; + f(); +} + + window_state_t rkt_webview_window_state(rktwebview_t w) { auto f = [w]() { @@ -550,7 +575,8 @@ void rkt_webview_env(const char *env_cmds[]) #ifdef WIN32 _putenv(env_cmds[i]); #else - putenv(env_cmds[i]); + putenv(const_cast(env_cmds[i])); #endif } } + diff --git a/rktwebview_qt/rktwebview.h b/rktwebview_qt/rktwebview.h index 5bd8fd2..c969e5f 100644 --- a/rktwebview_qt/rktwebview.h +++ b/rktwebview_qt/rktwebview.h @@ -13,6 +13,7 @@ extern "C" { RKTWEBVIEW_EXPORT void rkt_webview_env(const char *env_cmds[]); RKTWEBVIEW_EXPORT void rkt_webview_init(); RKTWEBVIEW_EXPORT void rkt_webview_cleanup(); +RKTWEBVIEW_EXPORT void rkt_webview_set_loglevel(rkt_webview_loglevel_t l); //RKTWEBVIEW_EXPORT void rkt_webview_process_events(int for_ms); RKTWEBVIEW_EXPORT void rkt_webview_free_data(rkt_data_t *d); diff --git a/rktwebview_qt/rktwebview_types.h b/rktwebview_qt/rktwebview_types.h index e0b1e19..a1edcc8 100644 --- a/rktwebview_qt/rktwebview_types.h +++ b/rktwebview_qt/rktwebview_types.h @@ -11,6 +11,14 @@ typedef struct { char *event; } rkt_event_t; + +typedef enum { + log_error = 1, + log_warning = 2, + log_info = 3, + log_debug = 4 +} rkt_webview_loglevel_t; + typedef enum { no_result_yet = -1, oke = 0, diff --git a/rktwebview_qt/shm.cpp b/rktwebview_qt/shm.cpp index 869831a..74c3fe8 100644 --- a/rktwebview_qt/shm.cpp +++ b/rktwebview_qt/shm.cpp @@ -3,6 +3,10 @@ #include #include +#ifdef __linux +#define _strdup strdup +#endif + typedef struct __shm_item__ { ShmPlace next; @@ -263,7 +267,7 @@ public: _sem = sem_open(_sem_name, O_RDWR, S_IRUSR | S_IWUSR, 0); _shm_fd = shm_open(name, O_RDWR, 0600); } - _mem = mmap(nullptr, _size, PROT_READ|PROT_WRITE, MAP_SHARED, _shm_fd, 0); + _mem = reinterpret_cast(mmap(nullptr, _size, PROT_READ|PROT_WRITE, MAP_SHARED, _shm_fd, 0)); _slots = reinterpret_cast (_mem + sizeof(int) + sizeof(ShmPlace) + sizeof(ShmPlace)); _used = reinterpret_cast(_mem); @@ -341,10 +345,6 @@ class ShmSemApi { } free(_name); } - }; -}; - -public: }; #endif diff --git a/rktwebview_qt/utils.cpp b/rktwebview_qt/utils.cpp index 70c1ea2..33b70e6 100644 --- a/rktwebview_qt/utils.cpp +++ b/rktwebview_qt/utils.cpp @@ -1,7 +1,17 @@ #include "utils.h" +#include + +typedef struct { + std::chrono::time_point start; +} timer; + + static int _log_level = LOG_INFO; +static timer *_timer = nullptr; + + int logLevel() { @@ -23,3 +33,19 @@ const char *logIndicator(int l) } return "UNKNOWN"; } + +void logElapsed() +{ + if (_timer == nullptr) { + _timer = new timer; + _timer->start = std::chrono::system_clock::now(); + } + + auto c = std::chrono::system_clock::now(); + auto duration = c - _timer->start; + auto milliseconds + = std::chrono::duration_cast( + duration) + .count(); + fprintf(stderr, "%8.3lf: ", milliseconds/ 1000.0); +} diff --git a/rktwebview_qt/utils.h b/rktwebview_qt/utils.h index 5a20701..b7e42d6 100644 --- a/rktwebview_qt/utils.h +++ b/rktwebview_qt/utils.h @@ -28,6 +28,7 @@ inline std::string basedir(const std::string &path) int logLevel(); void setLogLevel(int l); +void logElapsed(); const char *logIndicator(int l); #define LOG_ERROR 1 @@ -35,7 +36,7 @@ const char *logIndicator(int l); #define LOG_INFO 3 #define LOG_DEBUG 4 -#define MKLOGSTMT(level, code) if (logLevel() >= level) { fprintf(stderr, "%s: ", logIndicator(level));code;fflush(stderr); } +#define MKLOGSTMT(level, code) if (logLevel() >= level) { fprintf(stderr, "%s: ", logIndicator(level));logElapsed();code;fflush(stderr); } #define MKL0(level, msg) MKLOGSTMT(level, fprintf(stderr, msg)) #define MKL1(level, msg, a) MKLOGSTMT(level, fprintf(stderr, msg, a)) #define MKL2(level, msg, a, b) MKLOGSTMT(level, fprintf(stderr, msg, a, b))