Skip to content

[Feat] lib/gis: Resolve spawned programs with find_program instead of cmd.exe on Windows #7736

Description

@wenzeslaus

On Windows, G_spawn_ex() and the G_popen_* functions always run the child through cmd.exe /c, so finding the program is left to cmd.exe and inherits its limits, notably the ~8191 character handling of PATH. spawn.c already contains find_program(), which resolves a program against PATH/PATHEXT directly, but it is only used when shell is 0, which no caller triggers, so it is effectively dead code. Resolving the program with find_program() and passing it to CreateProcess() directly would remove the cmd.exe layer.

Details (analysis generated with Claude Code)

The Windows do_spawn() in lib/gis/spawn.c hardcodes the shell:

status = win_spawn(command, sp->args, env, sp->directory, handles,
                   sp->background, 1);

With shell=1, win_spawn() builds %COMSPEC% /c "program args..." and passes lpApplicationName=NULL, so cmd.exe performs the lookup of the program. With shell=0, win_spawn() resolves the program itself with find_program() and passes it as lpApplicationName -- this path is never taken.

Going through cmd.exe cost a CI failure: r.coin runs r.stats via G_popen_read(), and when the process environment's PATH grew past what cmd.exe handles, cmd.exe reported 'r.stats' is not recognized as an internal or external command even though the directory with r.stats.exe was at the front of PATH. Every process spawned from Python with the same PATH (via CreateProcessW) kept working; only the cmd.exe-mediated spawn failed. Analysis in #7732, resulting r.coin behavior in #7734.

An extra cmd.exe process per spawn and a second layer of quoting rules also go away.

Batch files (e.g., the .bat wrappers for scripts in GISBASE\bin) still need cmd.exe as the interpreter, so the decision has to be per resolved program: if find_program() resolves to .bat/.cmd, run cmd.exe on the resolved absolute path (which still avoids the PATH search by cmd.exe); otherwise call CreateProcess() on the program directly. Whether any caller relies on other cmd.exe behavior needs checking.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions