mirror of
https://github.com/osnr/TabFS.git
synced 2024-06-19 22:25:04 +02:00
cygwin support
This commit is contained in:
parent
38a5677dec
commit
f06a879b40
|
@ -22,6 +22,10 @@ ifeq ($(shell uname -s),FreeBSD)
|
||||||
CFLAGS += -L$(FREEBSD_ROOT)/lib -I$(FREEBSD_ROOT)/include $(CFLAGS_EXTRA)
|
CFLAGS += -L$(FREEBSD_ROOT)/lib -I$(FREEBSD_ROOT)/include $(CFLAGS_EXTRA)
|
||||||
LIBS = -lfuse -pthread
|
LIBS = -lfuse -pthread
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(shell uname -o),Cygwin)
|
||||||
|
CFLAGS += $(shell pkg-config --cflags fuse)
|
||||||
|
LIBS = $(shell pkg-config --libs fuse)
|
||||||
|
endif
|
||||||
|
|
||||||
all: $(TARGETS)
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
|
34
fs/tabfs.c
34
fs/tabfs.c
|
@ -18,6 +18,16 @@
|
||||||
#include "vendor/frozen.h"
|
#include "vendor/frozen.h"
|
||||||
#include "vendor/frozen.c"
|
#include "vendor/frozen.c"
|
||||||
|
|
||||||
|
static unsigned int get_thread_id(void) {
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
// note: using this because pthread_self() didn't seem to be unique under cygwin
|
||||||
|
extern int GetCurrentThreadId(void);
|
||||||
|
return GetCurrentThreadId();
|
||||||
|
#else
|
||||||
|
return (uintptr_t)pthread_self();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#define eprintln(fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__)
|
#define eprintln(fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__)
|
||||||
|
|
||||||
// protects:
|
// protects:
|
||||||
|
@ -115,8 +125,11 @@ static int do_exchange(unsigned int id,
|
||||||
char c;
|
char c;
|
||||||
read_or_die(mydata.msgpipe[0], &c, 1);
|
read_or_die(mydata.msgpipe[0], &c, 1);
|
||||||
|
|
||||||
|
// note: protecting this with the same lock fixes random fd-related crashes under cygwin
|
||||||
|
pthread_mutex_lock(&write_lock);
|
||||||
close(mydata.msgpipe[0]);
|
close(mydata.msgpipe[0]);
|
||||||
close(mydata.msgpipe[1]);
|
close(mydata.msgpipe[1]);
|
||||||
|
pthread_mutex_unlock(&write_lock);
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
if (1 == json_scanf(mydata.data, mydata.size, "{error: %d}", &err)) {
|
if (1 == json_scanf(mydata.data, mydata.size, "{error: %d}", &err)) {
|
||||||
|
@ -185,7 +198,7 @@ static int count_fmt_args(const char *s) {
|
||||||
|
|
||||||
#define exchange_json(datap, sizep, keys_fmt, ...) \
|
#define exchange_json(datap, sizep, keys_fmt, ...) \
|
||||||
do { \
|
do { \
|
||||||
unsigned int id = (uintptr_t)pthread_self(); \
|
unsigned int id = get_thread_id(); \
|
||||||
int req_rv = do_exchange(id, datap, sizep, \
|
int req_rv = do_exchange(id, datap, sizep, \
|
||||||
"{id: %u, " keys_fmt "}", \
|
"{id: %u, " keys_fmt "}", \
|
||||||
id, ##__VA_ARGS__); \
|
id, ##__VA_ARGS__); \
|
||||||
|
@ -206,7 +219,7 @@ static int count_fmt_args(const char *s) {
|
||||||
free(data); data = NULL; \
|
free(data); data = NULL; \
|
||||||
} else { \
|
} else { \
|
||||||
eprintln("%s: could only parse %d of %d keys!", \
|
eprintln("%s: could only parse %d of %d keys!", \
|
||||||
__func__, num_expected, num_scanned); \
|
__func__, num_scanned, num_expected); \
|
||||||
free(data); data = NULL; \
|
free(data); data = NULL; \
|
||||||
return -EIO; \
|
return -EIO; \
|
||||||
} \
|
} \
|
||||||
|
@ -225,6 +238,11 @@ static int tabfs_getattr(const char *path, struct stat *stbuf) {
|
||||||
"st_mode: %d, st_nlink: %d, st_size: %d",
|
"st_mode: %d, st_nlink: %d, st_size: %d",
|
||||||
&stbuf->st_mode, &stbuf->st_nlink, &stbuf->st_size);
|
&stbuf->st_mode, &stbuf->st_nlink, &stbuf->st_size);
|
||||||
|
|
||||||
|
#if defined(CYGFUSE)
|
||||||
|
// user must be set for writing files to work under cygwin
|
||||||
|
stbuf->st_uid = geteuid();
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,6 +470,7 @@ int main(int argc, char **argv) {
|
||||||
freopen("log.txt", "a", stderr);
|
freopen("log.txt", "a", stderr);
|
||||||
setvbuf(stderr, NULL, _IONBF, 0);
|
setvbuf(stderr, NULL, _IONBF, 0);
|
||||||
|
|
||||||
|
#if !defined(CYGFUSE)
|
||||||
char killcmd[128];
|
char killcmd[128];
|
||||||
sprintf(killcmd, "pgrep tabfs | grep -v %d | xargs kill -9 2>/dev/null", getpid());
|
sprintf(killcmd, "pgrep tabfs | grep -v %d | xargs kill -9 2>/dev/null", getpid());
|
||||||
system(killcmd);
|
system(killcmd);
|
||||||
|
@ -465,6 +484,17 @@ int main(int argc, char **argv) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
system("mkdir -p \"$TABFS_MOUNT_DIR\"");
|
system("mkdir -p \"$TABFS_MOUNT_DIR\"");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CYGFUSE)
|
||||||
|
// winfsp-fuse needs to create the mount directory itself
|
||||||
|
// try to remove it using rmdir (will work if it's empty)
|
||||||
|
if (0 == access(getenv("TABFS_MOUNT_DIR"), R_OK) &&
|
||||||
|
0 != rmdir(getenv("TABFS_MOUNT_DIR"))) {
|
||||||
|
eprintln("error: the mount directory \"%s\" already exists!", getenv("TABFS_MOUNT_DIR"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
int err = pthread_create(&thread, NULL, reader_main, NULL);
|
int err = pthread_create(&thread, NULL, reader_main, NULL);
|
||||||
|
|
16
install.sh
16
install.sh
|
@ -49,12 +49,18 @@ case "$OS $BROWSER" in
|
||||||
MANIFEST_LOCATION="$HOME/Library/Application Support/Chromium/NativeMessagingHosts";;
|
MANIFEST_LOCATION="$HOME/Library/Application Support/Chromium/NativeMessagingHosts";;
|
||||||
"Darwin vivaldi")
|
"Darwin vivaldi")
|
||||||
MANIFEST_LOCATION="$HOME/Library/Application Support/Vivaldi/NativeMessagingHosts";;
|
MANIFEST_LOCATION="$HOME/Library/Application Support/Vivaldi/NativeMessagingHosts";;
|
||||||
|
"CYGWIN_NT"*)
|
||||||
|
MANIFEST_LOCATION="$PWD/fs";;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
mkdir -p "$MANIFEST_LOCATION"
|
mkdir -p "$MANIFEST_LOCATION"
|
||||||
|
|
||||||
APP_NAME="com.rsnous.tabfs"
|
APP_NAME="com.rsnous.tabfs"
|
||||||
EXE_PATH=$(pwd)/fs/tabfs
|
EXE_PATH=$(pwd)/fs/tabfs
|
||||||
|
if [[ "$OS" == CYGWIN_NT* ]]; then
|
||||||
|
# convert to native path and json-escape backslashes
|
||||||
|
EXE_PATH="$(cygpath -w "$EXE_PATH" | sed 's:\\:\\\\:g')"
|
||||||
|
fi
|
||||||
|
|
||||||
case "$BROWSER" in
|
case "$BROWSER" in
|
||||||
chrome | chromium | chromebeta | brave | vivaldi | edgedev)
|
chrome | chromium | chromebeta | brave | vivaldi | edgedev)
|
||||||
|
@ -83,4 +89,14 @@ EOF
|
||||||
);;
|
);;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
if [[ "$OS" == CYGWIN_NT* ]]; then
|
||||||
|
case "$BROWSER" in
|
||||||
|
chrome | chromium | chromebeta | brave | vivaldi | edgedev)
|
||||||
|
REGKEY="HKCU\\Software\\Google\\Chrome\\NativeMessagingHosts\\$APP_NAME";;
|
||||||
|
firefox)
|
||||||
|
REGKEY="HKCU\\Software\\Mozilla\\NativeMessagingHosts\\$APP_NAME";;
|
||||||
|
esac
|
||||||
|
reg add "$REGKEY" /ve /t REG_SZ /d "$(cygpath -w "$MANIFEST_LOCATION")\\$APP_NAME.json" /f
|
||||||
|
fi
|
||||||
|
|
||||||
echo "$MANIFEST" > "$MANIFEST_LOCATION/$APP_NAME.json"
|
echo "$MANIFEST" > "$MANIFEST_LOCATION/$APP_NAME.json"
|
||||||
|
|
11
test/test.c
11
test/test.c
|
@ -9,6 +9,13 @@
|
||||||
#include <wordexp.h>
|
#include <wordexp.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
// needs to be the native path for file:// urls to work
|
||||||
|
#define PWD "$(cygpath -w \"$(pwd)\")"
|
||||||
|
#else
|
||||||
|
#define PWD "$(pwd)"
|
||||||
|
#endif
|
||||||
|
|
||||||
int file_contents_equal(char* path, char* contents) {
|
int file_contents_equal(char* path, char* contents) {
|
||||||
// hehe: https://twitter.com/ianh_/status/1340450349065244675
|
// hehe: https://twitter.com/ianh_/status/1340450349065244675
|
||||||
setenv("path", path, 1);
|
setenv("path", path, 1);
|
||||||
|
@ -55,7 +62,7 @@ int main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
assert(system("echo file://$(pwd)/test-resources/test-page.html > ../fs/mnt/tabs/create") == 0);
|
assert(system("echo file://" PWD "/test-resources/test-page.html > ../fs/mnt/tabs/create") == 0);
|
||||||
assert(file_contents_equal("../fs/mnt/tabs/last-focused/title.txt", "Title of Test Page"));
|
assert(file_contents_equal("../fs/mnt/tabs/last-focused/title.txt", "Title of Test Page"));
|
||||||
assert(file_contents_equal("../fs/mnt/tabs/last-focused/text.txt", "Body Text of Test Page"));
|
assert(file_contents_equal("../fs/mnt/tabs/last-focused/text.txt", "Body Text of Test Page"));
|
||||||
|
|
||||||
|
@ -87,7 +94,7 @@ int main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
assert(system("echo file://$(pwd)/test-resources/test-textarea.html > ../fs/mnt/tabs/create") == 0);
|
assert(system("echo file://" PWD "/test-resources/test-textarea.html > ../fs/mnt/tabs/create") == 0);
|
||||||
{
|
{
|
||||||
assert(system("echo \"document.getElementById('ta').value\" > ../fs/mnt/tabs/last-focused/evals/ta.js") == 0);
|
assert(system("echo \"document.getElementById('ta').value\" > ../fs/mnt/tabs/last-focused/evals/ta.js") == 0);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ const {Routes, tryMatchRoute} = require('../extension/background');
|
||||||
{ entries: ['.', '..', 'windows', 'extensions', 'tabs', 'runtime'] });
|
{ entries: ['.', '..', 'windows', 'extensions', 'tabs', 'runtime'] });
|
||||||
assert.deepEqual(await Routes['/tabs'].readdir(),
|
assert.deepEqual(await Routes['/tabs'].readdir(),
|
||||||
{ entries: ['.', '..', 'create',
|
{ entries: ['.', '..', 'create',
|
||||||
'by-id', 'by-title', 'last-focused'] });
|
'by-title', 'last-focused', 'by-id'] });
|
||||||
|
|
||||||
assert.deepEqual(tryMatchRoute('/'), [Routes['/'], {}]);
|
assert.deepEqual(tryMatchRoute('/'), [Routes['/'], {}]);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue