-
Notifications
You must be signed in to change notification settings - Fork 0
fix: cross-compile cmd/azemu for Windows (v0.3.0 release blocker) #80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| //go:build !windows | ||
|
|
||
| package main | ||
|
|
||
| import "syscall" | ||
|
|
||
| // execProcess replaces the current process image with the named binary, the | ||
| // classic exec(3) behaviour. On success it never returns. | ||
| func execProcess(bin string, argv, env []string) error { | ||
| return syscall.Exec(bin, argv, env) | ||
| } | ||
|
|
||
| // detachSysProcAttr starts the child in its own session (setsid) so it | ||
| // survives the parent's exit and detaches from the controlling terminal. | ||
| func detachSysProcAttr() *syscall.SysProcAttr { | ||
| return &syscall.SysProcAttr{Setsid: true} | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| //go:build windows | ||
|
|
||
| package main | ||
|
|
||
| import ( | ||
| "errors" | ||
| "os" | ||
| "os/exec" | ||
| "syscall" | ||
| ) | ||
|
|
||
| // execProcess emulates Unix exec on Windows, which has no execve. It runs the | ||
| // binary as a child inheriting stdio, waits for it, and exits with the child's | ||
| // exit code so the wrapper is transparent to the caller. | ||
| func execProcess(bin string, argv, env []string) error { | ||
| cmd := exec.Command(bin, argv[1:]...) //nolint:gosec // bin is resolved via exec.LookPath | ||
| cmd.Args = argv | ||
| cmd.Env = env | ||
| cmd.Stdin = os.Stdin | ||
| cmd.Stdout = os.Stdout | ||
| cmd.Stderr = os.Stderr | ||
|
|
||
| if err := cmd.Run(); err != nil { | ||
| var exit *exec.ExitError | ||
| if errors.As(err, &exit) { | ||
| os.Exit(exit.ExitCode()) | ||
| } | ||
| return err | ||
| } | ||
| os.Exit(0) | ||
| return nil | ||
| } | ||
|
|
||
| // detachSysProcAttr starts the child in a new process group so it is not killed | ||
| // when the parent's console closes. Windows has no setsid equivalent. | ||
| func detachSysProcAttr() *syscall.SysProcAttr { | ||
| return &syscall.SysProcAttr{CreationFlags: 0x00000200} // CREATE_NEW_PROCESS_GROUP | ||
|
Comment on lines
+34
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🌐 Web query:
💡 Result: No, Citations:
🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '\n== cmd/azemu/adapter_windows.go ==\n'
sed -n '1,120p' cmd/azemu/adapter_windows.go
printf '\n== cmd/azemu/adapter.go (background startup references) ==\n'
rg -n "startAzemuBackground|detachSysProcAttr|SysProcAttr|CreationFlags|DETACHED_PROCESS|CREATE_NEW_CONSOLE|CREATE_NEW_PROCESS_GROUP" cmd/azemu/adapter.go cmd/azemu/adapter_windows.goRepository: ZeroDeth/azemu Length of output: 1852
🤖 Prompt for AI Agents
Comment on lines
+34
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '\n== File map ==\n'
git ls-files cmd/azemu | sed -n '1,120p'
printf '\n== adapter_windows.go ==\n'
cat -n cmd/azemu/adapter_windows.go
printf '\n== Search for detachSysProcAttr usage ==\n'
rg -n "detachSysProcAttr|SysProcAttr|CreationFlags|CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW|DETACHED_PROCESS" cmd/azemu -S
printf '\n== Nearby process launch code ==\n'
for f in $(rg -l "detachSysProcAttr|SysProcAttr" cmd/azemu -S); do
echo "--- $f ---"
cat -n "$f"
doneRepository: ZeroDeth/azemu Length of output: 9686 🌐 Web query:
💡 Result: When using the CreateProcess function on Windows, the flags CREATE_NEW_PROCESS_GROUP and DETACHED_PROCESS interact with console signaling and inheritance as follows: CREATE_NEW_PROCESS_GROUP When this flag is specified, the new process becomes the root of a new console process group [1][2]. - Console Signals: This flag implicitly calls SetConsoleCtrlHandler(NULL, TRUE) for the new process, which disables CTRL+C signals for that process and its entire process group [3][1][4]. CTRL+BREAK signals remain enabled and can still be used to interrupt the process group [3][4]. - Process Group Management: This flag allows the use of GenerateConsoleCtrlEvent to send signals (specifically CTRL+BREAK) to the entire group [1][5]. - Conflicts: This flag is ignored if used in conjunction with CREATE_NEW_CONSOLE [1][6]. DETACHED_PROCESS When this flag is specified, a console process does not inherit the parent process's console [1][7]. - Console State: The new process begins without an attached console [1][7]. It may call AllocConsole at a later time to create one [1][7]. - Conflicts: This flag cannot be used with CREATE_NEW_CONSOLE [1][6]. Interaction and Limitations - Console Handling: While CREATE_NEW_PROCESS_GROUP affects how a process group responds to signals within a shared console, DETACHED_PROCESS ensures the child does not share the parent's console at all [1][2][7]. - Termination: Console Close events are sent to all processes attached to a console. If a process is detached, it is not attached to the parent's console, and therefore will not receive close events associated with that parent's console window [7]. Processes in a new process group that remain attached to the same console as the parent will continue to receive signals unless explicitly handled otherwise [2][5]. In summary, use CREATE_NEW_PROCESS_GROUP when you need to manage signal propagation (e.g., in a shell) or isolate a group for termination via CTRL+BREAK [3][2]. Use DETACHED_PROCESS when you need to ensure a child process does not interfere with or receive input/output from the parent's console [7][8]. Citations:
This still shares the parent console. 🤖 Prompt for AI Agents |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: ZeroDeth/azemu
Length of output: 3433
🌐 Web query:
Go build constraints unix tag syscall.Exec SysProcAttr.Setsid supported GOOS non-windows💡 Result:
In Go, the
syscall.SysProcAttr.Setsidfield andsyscall.Execfunction are Unix-specific and are not supported on Windows [1][2][3][4]. 1. Setsid: TheSetsidfield withinsyscall.SysProcAttris available on Unix-like operating systems (such as Linux and macOS) to create a new session for a process [5][6]. Because it relies on Unix system primitives that do not exist on Windows, attempting to useSysProcAttrwithSetsidset totrueon Windows will result in compilation errors if not properly constrained [1][2]. 2. syscall.Exec: Thesyscall.Execfunction performs anexecvesystem call, which replaces the current process with a new one [7][3]. This functionality is fundamentally Unix-specific; on Windows, the function exists in thesyscallpackage but immediately returns an error (EWINDOWS) [3][4]. To handle these differences, Go developers typically use build constraints (also known as build tags) to separate platform-specific code [8]. You can use the//go:buildconstraint to include files only on specific operating systems [8]. For example, you can create a file for Unix systems: //go:build!windows package mypackage func setAttributes(attr *syscall.SysProcAttr) { attr.Setsid = true } And a corresponding file for Windows: //go:build windows package mypackage func setAttributes(attr *syscall.SysProcAttr) { // Setsid is not supported on Windows } Alternatively, the "unix" build tag can be used to include code on all Unix-like platforms (e.g., //go:build unix) [9]. For general process execution that needs to work across platforms, it is highly recommended to use theos/execpackage instead ofsyscall.Exec, asos/execprovides a cross-platform abstraction [3][10].Citations:
Narrow the build constraint to Unix targets.
!windowsstill includes non-Unix GOOS values, so this file can be selected wheresyscall.ExecandSysProcAttr.Setsidare unavailable. Use//go:build unixor an explicit supported GOOS list instead.🤖 Prompt for AI Agents