Skip to content

Commit

Permalink
util (ble/util/msleep): fix hang in Cygwin by switching from /dev/udp…
Browse files Browse the repository at this point in the history
…/*/* to /dev/zero
  • Loading branch information
akinomyoga committed Feb 20, 2021
1 parent f03b87b commit d4d718a
Show file tree
Hide file tree
Showing 10 changed files with 435 additions and 119 deletions.
6 changes: 6 additions & 0 deletions GNUmakefile
Expand Up @@ -77,6 +77,12 @@ $(OUTDIR)/lib/%.txt: lib/%.txt | $(OUTDIR)/lib
cp -p $< $@
$(OUTDIR)/lib/core-syntax.sh: lib/core-syntax.sh lib/core-syntax-ctx.def | $(OUTDIR)/lib
$(MWGPP) $< > $@
$(OUTDIR)/lib/init-msys1.sh: lib/init-msys1.sh lib/init-msys1-helper.c | $(OUTDIR)/lib
$(MWGPP) $< > $@

#outfiles += $(OUTDIR)/lib/init-msleep.sh
#$(OUTDIR)/lib/init-msleep.sh: lib/init-msleep.sh lib/init-msleep.c | $(OUTDIR)/lib
# $(MWGPP) $< > $@

#------------------------------------------------------------------------------
# contrib
Expand Down
3 changes: 2 additions & 1 deletion ble.pp
Expand Up @@ -306,7 +306,7 @@ function ble/bin/.freeze-utility-path {

# POSIX utilities

_ble_init_posix_command_list=(sed date rm mkdir mkfifo sleep stty tty sort awk chmod grep cat wc mv sh od)
_ble_init_posix_command_list=(sed date rm mkdir mkfifo sleep stty tty sort awk chmod grep cat wc mv sh od cp)
function ble/.check-environment {
if ! ble/bin#has "${_ble_init_posix_command_list[@]}"; then
local cmd commandMissing=
Expand Down Expand Up @@ -862,6 +862,7 @@ function ble/base/unload {
ble-decode/keymap/unload
ble-edit/bind/clear-keymap-definition-loader
ble/bin/rm -rf "$_ble_base_run/$$".* 2>/dev/null
blehook/invoke unload
return 0
}
blehook EXIT+=ble/base/unload
Expand Down
32 changes: 32 additions & 0 deletions lib/init-msleep.c
@@ -0,0 +1,32 @@
// For Cygwin and MSYS
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <errno.h>

#define BUILTIN_ENABLED 0x01
struct word_desc { char* word; int flags; };
struct word_list { struct word_list* next; struct word_desc* word; };
struct builtin {
const char* name;
int (*function)(struct word_list*);
int flags;
const char** long_doc;
const char* short_doc;
char* handle;
};

static int msleep_builtin(struct word_list* list) {
if (!list || !list->word) return 2;
double value = atof(list->word->word) * 0.001;
if (value < 0.0) return 2;
if (value == 0.0) return 0;
struct timespec tv;
tv.tv_sec = floor(value);
tv.tv_nsec = floor((value - floor(value)) * 1e9);
while (nanosleep(&tv, &tv) == -1 && errno == EINTR);
return 0;
}
static const char* msleep_doc[] = { "This is a builtin for ble.sh. Sleep for 'msec' milliseconds.", 0 };
struct builtin msleep_struct = { "ble/builtin/msleep", msleep_builtin, BUILTIN_ENABLED, msleep_doc, "ble/builtin/msleep msec", 0, };
29 changes: 29 additions & 0 deletions lib/init-msleep.sh
@@ -0,0 +1,29 @@
#!/bin/bash

function ble/util/msleep/.use-compiled-builtin/compile {
local builtin_path=$1
[[ -x $builtin_path && $builtin_path -nt $_ble_base/lib/init-msleep.sh ]] && return 0

local CC=cc
ble/bin#has gcc && CC=gcc

local include='#include' # '#' で始まる行はインストール時に消される
"$CC" -O2 -s -shared -o "$builtin_path" -xc - << EOF || return 1
#%$ sed 's/^#include/$include/' lib/init-msleep.c
EOF
[[ -x $builtin_path ]]
} &>/dev/null

function ble/util/msleep/.use-compiled-builtin {
local basename=$_ble_edit_io_fname2
local fname_buff=$basename.buff

local builtin_path=$_ble_base_cache/$HOSTNAME.init-msleep.so
local builtin_runpath=$_ble_base_run/$$.init-msleep.so
ble/util/msleep/.use-compiled-builtin/compile "$builtin_path" &&
ble/bin/cp "$builtin_path" "$builtin_runpath" || return 1

enable -f "$builtin_runpath" msleep || return 1
blehook unload+='enable -d ble/builtin/msleep &>/dev/null'
function ble/util/msleep { ble/builtin/msleep "$1"; }
}
75 changes: 75 additions & 0 deletions lib/init-msys1-helper.c
@@ -0,0 +1,75 @@
// For MSYS 1.0
#include <stdio.h>
#include <windows.h>
#include <sys/stat.h>
#include <signal.h>

BOOL is_process_alive(HANDLE handle) {
DWORD result;
return GetExitCodeProcess(handle, &result) && result == STILL_ACTIVE;
}

BOOL is_file(const char* filename) {
struct stat st;
return stat(filename, &st) == 0 && S_ISREG(st.st_mode);
}

int main(int argc, char** argv) {
const char* winpid = argv[1];
const char* fname_buff = argv[2];
const char* fname_read = argv[3];

signal(SIGINT, SIG_IGN);
//signal(SIGQUIT, SIG_IGN);

int ppid = atoi(winpid);
if (!ppid) {
fprintf(stderr, "ble.sh (msys1): invalid process ID '%s'\n", winpid);
return 1;
}
HANDLE parent_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ppid);
if (parent_process == NULL) {
fprintf(stderr, "ble.sh (msys1): failed to open the parent process '%s'\n", winpid);
return 1;
}

int exit_code = 0;
BOOL terminate = FALSE;
while (!terminate) {
unlink(fname_read);
if (rename(fname_buff, fname_read) != 0) {
perror("ble.sh (msys1)");
fprintf(stderr, "ble.sh (msys1): failed to move the file '%s' -> '%s'\n", fname_buff, fname_read);
terminate = TRUE;
exit_code = 1;
break;
}

FILE* f = fopen(fname_read, "r");
if (!f) {
fprintf(stderr, "ble.sh (msys1): failed to open the file '%s'\n", fname_read);
terminate = TRUE;
exit_code = 1;
break;
}

for (;;) {
if (!is_process_alive(parent_process)) {
terminate = TRUE;
break;
}
if (is_file(fname_buff)) break;

int count = 0;
char buff[4096];
while (count = fread(&buff, 1, sizeof buff, f))
fwrite(buff, 1, count, stdout);
fflush(stdout);
Sleep(20);
}
fclose(f);
}

CloseHandle(parent_process);
return exit_code;
}
75 changes: 1 addition & 74 deletions lib/init-msys1.sh
Expand Up @@ -39,80 +39,7 @@ function ble-edit/io:msys1/compile-helper {
# /mingw/bin/gcc
local include='#include' # '#' で始まる行はインストール時に消される
gcc -O2 -s -o "$helper" -xc - << EOF || return 1
$include <stdio.h>
$include <windows.h>
$include <sys/stat.h>
$include <signal.h>
BOOL is_process_alive(HANDLE handle) {
DWORD result;
return GetExitCodeProcess(handle, &result) && result == STILL_ACTIVE;
}
BOOL is_file(const char* filename) {
struct stat st;
return stat(filename, &st) == 0 && S_ISREG(st.st_mode);
}
int main(int argc, char** argv) {
const char* winpid = argv[1];
const char* fname_buff = argv[2];
const char* fname_read = argv[3];
signal(SIGINT, SIG_IGN);
//signal(SIGQUIT, SIG_IGN);
int ppid = atoi(winpid);
if (!ppid) {
fprintf(stderr, "ble.sh (msys1): invalid process ID '%s'\n", winpid);
return 1;
}
HANDLE parent_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ppid);
if (parent_process == NULL) {
fprintf(stderr, "ble.sh (msys1): failed to open the parent process '%s'\n", winpid);
return 1;
}
int exit_code = 0;
BOOL terminate = FALSE;
while (!terminate) {
unlink(fname_read);
if (rename(fname_buff, fname_read) != 0) {
perror("ble.sh (msys1)");
fprintf(stderr, "ble.sh (msys1): failed to move the file '%s' -> '%s'\n", fname_buff, fname_read);
terminate = TRUE;
exit_code = 1;
break;
}
FILE* f = fopen(fname_read, "r");
if (!f) {
fprintf(stderr, "ble.sh (msys1): failed to open the file '%s'\n", fname_read);
terminate = TRUE;
exit_code = 1;
break;
}
for (;;) {
if (!is_process_alive(parent_process)) {
terminate = TRUE;
break;
}
if (is_file(fname_buff)) break;
int count = 0;
char buff[4096];
while (count = fread(&buff, 1, sizeof buff, f))
fwrite(buff, 1, count, stdout);
fflush(stdout);
Sleep(20);
}
fclose(f);
}
CloseHandle(parent_process);
return exit_code;
}
#%$ sed 's/^#include/$include/' lib/init-msys1-helper.c
EOF

[[ -x $helper ]]
Expand Down
3 changes: 2 additions & 1 deletion memo/ChangeLog.md
Expand Up @@ -33,14 +33,15 @@
- edit (sword): fix definition of `sword` (shell words) `#D1441` f923388
- edit (`kill-forward-logical-line`): fix a bug not deleting newline at the end of the line `#D1443` 09cf7f1
- complete (mandb): fix an encoding prpblem of utf8 manuals `#D1446` 7a4a480
- util (`ble/util/msleep`): fix hang in Cygwin by swithing from `/dev/udp/0.0.0.0/80` to `/dev/zero` `#D1452` 0000000
- global:work around bash-4.2 bug of `declare -gA` (reported by 0xC0ncord) `#D1470` 8856a04
- global: fix declaration of associative arrays for `ble-reload` `#D1471` 3cae6e4

## Internal changes and fixes

- main: include hostname in local runtime directory `#D1444` 6494836
- global: update the style of document comments ff4c4e7
- util: add function `ble/string#quote-words` `#D1451` 0000000
- util: add function `ble/string#quote-words` `#D1451` f03b87b

<!---------------------------------------------------------------------------->
# ble-0.4.0-devel2
Expand Down

0 comments on commit d4d718a

Please sign in to comment.