Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions lcm-logger/glib_util.c
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving as these changes all look reasonable and don't appear to break anything for me, but they don't appear to fix this issue:

The other issue I've found was lcm-logger.exe quits after creating the log file. This seems to be down to different ways of handling signals between windows and linux. I've made some minor windows-specific tweaks which allows lcm-logger.exe to run without issue on Windows.

Both lcm-logger and lcm-logplayer appear to be no-ops. No matter what commands I run, they immediately return with no output.

Original file line number Diff line number Diff line change
Expand Up @@ -132,21 +132,28 @@ int signal_pipe_attach_glib(signal_pipe_glib_handler_t func, gpointer user_data)
return 0;
}

#ifndef _WIN32
static void spgqok_handler(int signum, void *user)
{
g_main_loop_quit(_mainloop);
signal_pipe_cleanup();
}
#endif

int signal_pipe_glib_quit_on_kill()
{
#ifdef _WIN32
// Windows does not support Unix-style signal handling reliably.
return 0;
#else
if (0 != signal_pipe_init())
return -1;

signal_pipe_add_signal(SIGINT);
signal_pipe_add_signal(SIGTERM);
signal_pipe_add_signal(SIGKILL);
return signal_pipe_attach_glib(spgqok_handler, _mainloop);
#endif
}

static int lcm_message_ready(GIOChannel *source, GIOCondition cond, lcm_t *lcm)
Expand Down Expand Up @@ -182,7 +189,11 @@ int glib_mainloop_attach_lcm(lcm_t *lcm)

glib_attached_lcm_t *galcm = (glib_attached_lcm_t *) calloc(1, sizeof(glib_attached_lcm_t));

#ifdef _WIN32
galcm->ioc = g_io_channel_win32_new_socket(lcm_get_fileno(lcm));
#else
galcm->ioc = g_io_channel_unix_new(lcm_get_fileno(lcm));
#endif
galcm->sid = g_io_add_watch(galcm->ioc, G_IO_IN, (GIOFunc) lcm_message_ready, lcm);
galcm->lcm = lcm;

Expand Down
15 changes: 13 additions & 2 deletions lcm-python/lcm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,20 @@ def tell (self):
LCM_BIN_DIR = os.path.join(os.path.dirname(__file__), '..', 'bin')

def run_script(name: str, args) -> int:
file_extension = '.bat' if platform.system() == 'Windows' else ''
try:
return subprocess.call([os.path.join(LCM_BIN_DIR, name + file_extension), *args], close_fds=False)
if platform.system() == 'Windows':
candidates = [
os.path.join(LCM_BIN_DIR, f"{name}.bat"),
os.path.join(LCM_BIN_DIR, f"{name}.exe")
]
else:
candidates = [os.path.join(LCM_BIN_DIR, name)]

for executable in candidates:
if os.path.exists(executable):
return subprocess.call([executable, *args], close_fds=False)

raise FileNotFoundError(f"No executable found for {name} in {LCM_BIN_DIR}")
Comment on lines +181 to +193
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On windows the init.py function doesn't load all the binaries as expected. It attempts to launch .bat files but for some applications, such as lcm-logger.exe a .bat doesn't exist in the bin folder.

I can reproduce this issue. After running pip install . -v --config-settings=cmake.args=--preset=vcpkg-vs with a venv activate, running lcm-logger produces the error:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\lcm\.venv\Scripts\lcm-logger.exe\__main__.py", line 7, in <module>
    sys.exit(run_logger())
             ~~~~~~~~~~^^
  File "C:\Users\lcm\.venv\Lib\site-packages\lcm\__init__.py", line 196, in run_logger
    raise SystemExit(run_script('lcm-logger', sys.argv[1:]))
                     ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\lcm\.venv\Lib\site-packages\lcm\__init__.py", line 182, in run_script
    return subprocess.call([os.path.join(LCM_BIN_DIR, name + file_extension), *args], close_fds=False)
           ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\AppData\Local\Programs\Python\Python313-arm64\Lib\subprocess.py", line 397, in call
    with Popen(*popenargs, **kwargs) as p:
         ~~~~~^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\AppData\Local\Programs\Python\Python313-arm64\Lib\subprocess.py", line 1038, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
    ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                        pass_fds, cwd, env,
                        ^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
                        gid, gids, uid, umask,
                        ^^^^^^^^^^^^^^^^^^^^^^
                        start_new_session, process_group)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\AppData\Local\Programs\Python\Python313-arm64\Lib\subprocess.py", line 1550, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
                       ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
                             # no special security
                             ^^^^^^^^^^^^^^^^^^^^^
    ...<4 lines>...
                             cwd,
                             ^^^^
                             startupinfo)
                             ^^^^^^^^^^^^
FileNotFoundError: [WinError 2] The system cannot find the file specified

These changes fix that issue for me.

except KeyboardInterrupt:
return 0

Expand Down
Loading