mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-14 18:05:27 +07:00
[vfs] updating in Linux/WSL fsnotifier
Dropping `syslog(3)` use; forwarding errors and warnings to the IDE via `stderr` GitOrigin-RevId: c981356950a0ac3cdcd60990a714f8e7e7220496
This commit is contained in:
committed by
intellij-monorepo-bot
parent
4baf87789c
commit
7163a25b10
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,8 +1,11 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#define VERSION "20200827.1844"
|
||||
#define VERSION "20210416.1152"
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include <features.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
@@ -10,6 +13,8 @@
|
||||
|
||||
// messaging and logging
|
||||
void message(const char *text);
|
||||
|
||||
enum { LOG_ERR = 0, LOG_WARNING = 1, LOG_INFO = 2 };
|
||||
void userlog(int priority, const char* format, ...);
|
||||
|
||||
#define CHECK_NULL(p, r) if (p == NULL) { userlog(LOG_ERR, "out of memory"); return r; }
|
||||
|
||||
@@ -1,30 +1,15 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#include "fsnotifier.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <linux/limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/stat.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
@@ -66,7 +51,6 @@ bool init_inotify() {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
userlog(LOG_DEBUG, "inotify fd: %d", get_inotify_fd());
|
||||
|
||||
read_watch_descriptors_count();
|
||||
if (watch_count <= 0) {
|
||||
@@ -122,7 +106,7 @@ static int add_watch(int path_len, watch_node* parent) {
|
||||
int wd = inotify_add_watch(inotify_fd, path_buf, EVENT_MASK);
|
||||
if (wd < 0) {
|
||||
if (errno == EACCES || errno == ENOENT) {
|
||||
userlog(LOG_DEBUG, "inotify_add_watch(%s): %s", path_buf, strerror(errno));
|
||||
userlog(LOG_INFO, "inotify_add_watch(%s): %s", path_buf, strerror(errno));
|
||||
return ERR_IGNORE;
|
||||
}
|
||||
else if (errno == ENOSPC) {
|
||||
@@ -136,13 +120,13 @@ static int add_watch(int path_len, watch_node* parent) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
userlog(LOG_DEBUG, "watching %s: %d", path_buf, wd);
|
||||
userlog(LOG_INFO, "watching %s: %d", path_buf, wd);
|
||||
}
|
||||
|
||||
watch_node* node = table_get(watches, wd);
|
||||
if (node != NULL) {
|
||||
if (node->wd != wd) {
|
||||
userlog(LOG_ERR, "table error: corruption at %d:%s / %d:%s)", wd, path_buf, node->wd, node->path);
|
||||
userlog(LOG_ERR, "table error: corruption at %d:%s / %d:%s / %d", wd, path_buf, node->wd, node->path, watch_count);
|
||||
return ERR_ABORT;
|
||||
}
|
||||
else if (strcmp(node->path, path_buf) != 0) {
|
||||
@@ -199,10 +183,10 @@ static void rm_watch(int wd, bool update_parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
userlog(LOG_DEBUG, "unwatching %s: %d (%p)", node->path, node->wd, node);
|
||||
userlog(LOG_INFO, "unwatching %s: %d (%p)", node->path, node->wd, node);
|
||||
|
||||
if (inotify_rm_watch(inotify_fd, node->wd) < 0) {
|
||||
userlog(LOG_DEBUG, "inotify_rm_watch(%d:%s): %s", node->wd, node->path, strerror(errno));
|
||||
userlog(LOG_INFO, "inotify_rm_watch(%d:%s): %s", node->wd, node->path, strerror(errno));
|
||||
}
|
||||
|
||||
for (int i=0; i<array_size(node->kids); i++) {
|
||||
@@ -231,7 +215,7 @@ static int walk_tree(int path_len, watch_node* parent, bool recursive, array* mo
|
||||
for (int j=0; j<array_size(mounts); j++) {
|
||||
char* mount = array_get(mounts, j);
|
||||
if (strncmp(path_buf, mount, strlen(mount)) == 0) {
|
||||
userlog(LOG_DEBUG, "watch path '%s' crossed mount point '%s' - skipping", path_buf, mount);
|
||||
userlog(LOG_INFO, "watch path '%s' crossed mount point '%s' - skipping", path_buf, mount);
|
||||
return ERR_IGNORE;
|
||||
}
|
||||
}
|
||||
@@ -240,7 +224,7 @@ static int walk_tree(int path_len, watch_node* parent, bool recursive, array* mo
|
||||
if (recursive) {
|
||||
if ((dir = opendir(path_buf)) == NULL) {
|
||||
if (errno == EACCES || errno == ENOENT || errno == ENOTDIR) {
|
||||
userlog(LOG_DEBUG, "opendir(%s): %d", path_buf, errno);
|
||||
userlog(LOG_INFO, "opendir(%s): %d", path_buf, errno);
|
||||
return ERR_IGNORE;
|
||||
}
|
||||
else {
|
||||
@@ -277,7 +261,7 @@ static int walk_tree(int path_len, watch_node* parent, bool recursive, array* mo
|
||||
if (entry->d_type == DT_UNKNOWN) {
|
||||
struct stat st;
|
||||
if (stat(path_buf, &st) != 0) {
|
||||
userlog(LOG_DEBUG, "(DT_UNKNOWN) stat(%s): %d", path_buf, errno);
|
||||
userlog(LOG_INFO, "(DT_UNKNOWN) stat(%s): %d", path_buf, errno);
|
||||
continue;
|
||||
}
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
@@ -351,7 +335,7 @@ static bool process_inotify_event(struct inotify_event* event) {
|
||||
}
|
||||
|
||||
bool is_dir = (event->mask & IN_ISDIR) == IN_ISDIR;
|
||||
userlog(LOG_DEBUG, "inotify: wd=%d mask=%d dir=%d name=%s", event->wd, event->mask & (~IN_ISDIR), is_dir, node->path);
|
||||
userlog(LOG_INFO, "inotify: wd=%d mask=%d dir=%d name=%s", event->wd, event->mask & (~IN_ISDIR), is_dir, node->path);
|
||||
|
||||
int path_len = node->path_len;
|
||||
memcpy(path_buf, node->path, path_len + 1);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#include "fsnotifier.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <linux/limits.h>
|
||||
#include <mntent.h>
|
||||
#include <paths.h>
|
||||
#include <stdarg.h>
|
||||
@@ -12,23 +12,12 @@
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/stat.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define LOG_ENV "FSNOTIFIER_LOG_LEVEL"
|
||||
#define LOG_ENV_DEBUG "debug"
|
||||
#define LOG_ENV_INFO "info"
|
||||
#define LOG_ENV_WARNING "warning"
|
||||
#define LOG_ENV_ERROR "error"
|
||||
#define LOG_ENV_OFF "off"
|
||||
|
||||
|
||||
#define USAGE_MSG \
|
||||
"fsnotifier - IntelliJ IDEA companion program for watching and reporting file and directory structure modifications.\n\n" \
|
||||
"fsnotifier utilizes \"user\" facility of syslog(3) - messages usually can be found in /var/log/user.log.\n" \
|
||||
"Verbosity is regulated via " LOG_ENV " environment variable, possible values are: " \
|
||||
LOG_ENV_DEBUG ", " LOG_ENV_INFO ", " LOG_ENV_WARNING ", " LOG_ENV_ERROR ", " LOG_ENV_OFF "; default is " LOG_ENV_WARNING ".\n\n" \
|
||||
"Use 'fsnotifier --selftest' to perform some self-diagnostics (output will be logged and printed to console).\n"
|
||||
"fsnotifier - IntelliJ Platform companion program for watching and reporting file and directory structure modifications.\n\n" \
|
||||
"Use 'fsnotifier --selftest' to perform some self-diagnostics (output will be printed to console).\n"
|
||||
|
||||
#define HELP_MSG \
|
||||
"Try 'fsnotifier --help' for more information.\n"
|
||||
@@ -44,10 +33,8 @@ typedef struct {
|
||||
|
||||
static array* roots = NULL;
|
||||
|
||||
static int log_level = 0;
|
||||
static bool self_test = false;
|
||||
|
||||
static void init_log();
|
||||
static void run_self_test();
|
||||
static bool main_loop();
|
||||
static int read_input();
|
||||
@@ -82,13 +69,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
init_log();
|
||||
if (!self_test) {
|
||||
userlog(LOG_INFO, "started (v." VERSION ")");
|
||||
}
|
||||
else {
|
||||
userlog(LOG_INFO, "started (self-test mode) (v." VERSION ")");
|
||||
}
|
||||
userlog(LOG_INFO, "fsnotifier self-test mode (v." VERSION ")");
|
||||
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
|
||||
@@ -116,63 +97,29 @@ int main(int argc, char** argv) {
|
||||
array_delete(roots);
|
||||
|
||||
userlog(LOG_INFO, "finished (%d)", rv);
|
||||
closelog();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static void init_log() {
|
||||
int level = LOG_WARNING;
|
||||
|
||||
char* env_level = getenv(LOG_ENV);
|
||||
if (env_level != NULL) {
|
||||
if (strcmp(env_level, LOG_ENV_DEBUG) == 0) level = LOG_DEBUG;
|
||||
else if (strcmp(env_level, LOG_ENV_INFO) == 0) level = LOG_INFO;
|
||||
else if (strcmp(env_level, LOG_ENV_WARNING) == 0) level = LOG_WARNING;
|
||||
else if (strcmp(env_level, LOG_ENV_ERROR) == 0) level = LOG_ERR;
|
||||
}
|
||||
|
||||
if (self_test) {
|
||||
level = LOG_DEBUG;
|
||||
}
|
||||
|
||||
char ident[32];
|
||||
snprintf(ident, sizeof(ident), "fsnotifier[%d]", getpid());
|
||||
openlog(ident, 0, LOG_USER);
|
||||
log_level = level;
|
||||
}
|
||||
|
||||
|
||||
void message(const char *text) {
|
||||
output("MESSAGE\n%s\n", text);
|
||||
}
|
||||
|
||||
|
||||
void userlog(int priority, const char* format, ...) {
|
||||
if (priority > log_level) {
|
||||
return;
|
||||
}
|
||||
|
||||
void userlog(int level, const char* format, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vsyslog(priority, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (self_test) {
|
||||
const char* level = "debug";
|
||||
switch (priority) {
|
||||
case LOG_ERR: level = "error"; break;
|
||||
case LOG_WARNING: level = " warn"; break;
|
||||
case LOG_INFO: level = " info"; break;
|
||||
}
|
||||
printf("fsnotifier[%d] %s: ", getpid(), level);
|
||||
|
||||
fputs(level == LOG_ERR ? "[E] " : level == LOG_WARNING ? "[W] " : "[I] ", stdout);
|
||||
va_start(ap, format);
|
||||
vprintf(format, ap);
|
||||
vfprintf(stdout, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
printf("\n");
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
else if (level <= LOG_WARNING) {
|
||||
va_start(ap, format);
|
||||
vfprintf(stderr, format, ap);
|
||||
va_end(ap);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,10 +172,8 @@ static bool main_loop() {
|
||||
|
||||
static int read_input() {
|
||||
char* line = read_line(stdin);
|
||||
userlog(LOG_DEBUG, "input: %s", (line ? line : "<null>"));
|
||||
|
||||
if (line == NULL || strcmp(line, "EXIT") == 0) {
|
||||
userlog(LOG_INFO, "exiting: %s", line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -236,9 +181,8 @@ static int read_input() {
|
||||
array* new_roots = array_create(20);
|
||||
CHECK_NULL(new_roots, ERR_ABORT);
|
||||
|
||||
while (1) {
|
||||
while (true) {
|
||||
line = read_line(stdin);
|
||||
userlog(LOG_DEBUG, "input: %s", (line ? line : "<null>"));
|
||||
if (line == NULL || strlen(line) == 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -270,7 +214,7 @@ static bool update_roots(array* new_roots) {
|
||||
array_delete(new_roots);
|
||||
return true;
|
||||
}
|
||||
else if (array_size(new_roots) == 1 && strcmp(array_get(new_roots, 0), "/") == 0) { // refuse to watch entire tree
|
||||
else if (array_size(new_roots) == 1 && strcmp(array_get(new_roots, 0), "/") == 0) { // refuse to watch the entire tree
|
||||
output("UNWATCHEABLE\n/\n#\n");
|
||||
userlog(LOG_INFO, "unwatchable: /");
|
||||
array_delete_vs_data(new_roots);
|
||||
@@ -394,7 +338,7 @@ static array* unwatchable_mounts() {
|
||||
|
||||
struct mntent* ent;
|
||||
while ((ent = getmntent(mtab)) != NULL) {
|
||||
userlog(LOG_DEBUG, "mtab: %s : %s", ent->mnt_dir, ent->mnt_type);
|
||||
userlog(LOG_INFO, "mtab: %s : %s", ent->mnt_dir, ent->mnt_type);
|
||||
if (strcmp(ent->mnt_type, MNTTYPE_IGNORE) != 0 && !is_watchable(ent->mnt_type)) {
|
||||
CHECK_NULL(array_push(mounts, strdup(ent->mnt_dir)), NULL);
|
||||
}
|
||||
@@ -424,13 +368,10 @@ static void inotify_callback(const char* path, int event) {
|
||||
}
|
||||
else if (event & IN_UNMOUNT) {
|
||||
output("RESET\n");
|
||||
userlog(LOG_DEBUG, "RESET");
|
||||
}
|
||||
}
|
||||
|
||||
static void report_event(const char* event, const char* path) {
|
||||
userlog(LOG_DEBUG, "%s: %s", event, path);
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
|
||||
char* copy = path, *p;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
compile_clang() { clang -O2 -Wall -Wextra -Wpedantic -std=c11 -D_DEFAULT_SOURCE "$@"; }
|
||||
compile_cc() { cc -O2 -Wall -Wextra -Wpedantic -Wno-unknown-pragmas -std=c11 -D_DEFAULT_SOURCE "$@"; }
|
||||
# Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
compile_clang() { clang -O2 -Wall -Wextra -Wpedantic -std=c11 "$@"; }
|
||||
compile_cc() { cc -O2 -Wall -Wextra -Wpedantic -Wno-unknown-pragmas -std=c11 "$@"; }
|
||||
|
||||
VER=$(date "+%Y%m%d.%H%M")
|
||||
sed -i.bak "s/#define VERSION .*/#define VERSION \"${VER}\"/" fsnotifier.h && rm fsnotifier.h.bak
|
||||
@@ -12,7 +13,7 @@ if [ "$ARCH" = "x86_64" ] || [ "$ARCH" = "amd64" ]; then
|
||||
compile_clang -o fsnotifier64 main.c inotify.c util.c && \
|
||||
chmod 755 fsnotifier64
|
||||
|
||||
# dependencies: libc6-dev:i386 libgcc-9-dev:i386
|
||||
# dependencies: libc6-dev-i386 libgcc-9-dev-i386-cross
|
||||
printf "\n\n*** Compiling i386 version (fsnotifier) ...\n"
|
||||
compile_clang -target i686-linux-elf -o fsnotifier main.c inotify.c util.c && \
|
||||
chmod 755 fsnotifier
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#include "fsnotifier.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user