Odin icon indicating copy to clipboard operation
Odin copied to clipboard

Spawning a process

Open HumanEntity opened this issue 1 year ago • 4 comments

Description

I am a odin newbie so I might overlooked something but as a way of learning odin I wanted to make simple build system for odin. And when I was trying to spawn shell process I didn't find anything to do this in core.

Example solution in Odin

For example something like this:

package main

import "core:process"
import "core:fmt"

main :: proc () {
    process_handle, process_spawn_err := process.spawn({"echo", "'Hello, World"})
    if process_spawn_err != nil {
        fmt.panicf("Failed to start command: %v", process_spawn_err)
    }
    output := process.output(process_handle)
    fmt.println(output)
}

Solution in Rust

use std::process::Command;

let output = Command::new("echo")
    .arg("Hello world")
    .output()
    .expect("Failed to start command")
println!("{output}")

HumanEntity avatar Mar 24 '24 15:03 HumanEntity

There is a procedure "process_start" inside core/os/os2/process.odin. But it is not implemented yet or better the whole os2 folder is under construction. If you are on windows you could use the "CreateProcessW" procedure in core/sys/windows/kernel32.odin. If you are on linux there is a "execvp" procedure in core/os/os_linux.odin. Perhaps that helps. Maybe there are other alternatives I couldnt find.

gordonshamway23 avatar Mar 24 '24 16:03 gordonshamway23

This is currently being addressed by the following PR: #3310

If I'm not mistaken the code in the PR practically handles the use-case specified, though it requires a tiny bit more work before I can confidently suggest you copying the code for your own usage.

flysand7 avatar Mar 25 '24 06:03 flysand7

It would be great to have something similar to go's os/exec.

edyu avatar Aug 23 '24 17:08 edyu

Like @flysand7 said, this is being worked on in the new os package, currently at core:os/os2 and not intended for general use yet.

The example provided here can be done there with the current functionality like so:

package main

import os "core:os/os2"
import    "core:fmt"

main :: proc() {
	if err := echo(); err != nil {
		os.print_error(os.stderr, err, "failed to execute echo")
	}
}

echo :: proc() -> (err: os.Error) {
	r, w := os.pipe() or_return
	defer os.close(r)

	p: os.Process; {
		defer os.close(w)

		p = os.process_start({
			command = {"echo", "Hello world"},
			stdout  = w,
		}) or_return
	}

	output := os.read_entire_file(r, context.temp_allocator) or_return

	_ = os.process_wait(p) or_return

	fmt.print(string(output))
	return
}

laytan avatar Aug 23 '24 18:08 laytan