#[SOLVED] core:os/os2 pipes

1 messages · Page 1 of 1 (latest)

green vector
#

I wanted to pipe a process output into the input of another and not show anything in stdout, but I don't really get how I should do it. I managed to make a pipe and start the processes but I can't get stdout to be quiet:

package example

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

main :: proc()
{
  openssl_command := []string{"openssl", "s_client", "-quiet", "-connect", "github.com:443", "-servername", "github.com"}
  curl_command := []string{"curl", "-L", "-s", "-o", "odin-logo.png", "https://github.com/odin-lang/Odin/blob/master/misc/logo-slim.png"}

  readPipe, writePipe, err := os2.pipe()
  fmt.assertf(err == nil, "Could not create pipe: %v", err)
  curl_desc := os2.Process_Desc { command = curl_command, stdin = readPipe }
  openssl_desc := os2.Process_Desc { command = openssl_command, stdout = writePipe }

  curl_process, openssl_process: os2.Process
  state: os2.Process_State

  openssl_process, err = os2.process_start(openssl_desc)
  fmt.assertf(err == nil, "Could not start openssl process: %v", err)
  state, err = os2.process_wait(openssl_process)
  fmt.assertf(err == nil, "Could not wait for openssl process: %v", err)
  err = os2.process_close(openssl_process)
  fmt.assertf(err == nil, "Could not close openssl process: %v", err)
  os2.close(writePipe)

  curl_process, err = os2.process_start(curl_desc)
  fmt.assertf(err == nil, "Could not start curl process: %v", err)
  state, err = os2.process_wait(curl_process)
  fmt.assertf(err == nil, "Could not wait for curl process: %v", err)
  err = os2.process_close(curl_process)
  fmt.assertf(err == nil, "Could not close curl process: %v", err)
  os2.close(readPipe)
}

The problem is, curl has the '-s' flag to specify quiet output but I can't get openssl to be quiet even with the '-quiet' flag 😭

PS: This isn't the website I actually want to download from, I just put it as a placeholder

limber coral
#

Is it doing what you want minus the extra output?

#

It seems odd to run openssl until completion and close the pipe before starting curl.

#

I would think you want to start both, then wait on them.

green vector
#

I mean why wouldn't it? But I was centered on having it not print to screen

dim kettle
#

It is quiet for me

green vector
#

Hm what version of the compiler are you using?

dim kettle
#

Even without any flags it should be quiet, because you don't specify a stderr in your descriptor

green vector
#

That's what I thought

dim kettle
#

if you leave that blank (nil) it is going to void that output

#

What OS are you on?

green vector
#

Windows

dim kettle
#

I don't have windows on right now but I can scan the code to see if it's doing something else

green vector
#

~\odin.exe version dev-2025-04-nightly:d9f990d

dim kettle
#

Oh yeah

#

windows implementation makes nil mean "pipe it to the stderr of the current process"

#

which is not what other implementations do and not what we want

green vector
#

Okay, I guess I'll keep it as is for now or I might look into the windows implementation to see if I can change it

dim kettle
#

(I need to have some way to close that handle though)

#

(currently leaking that null handle)

limber coral
dim kettle
#

added closing to that branch now

dim kettle
#

should start both, wait for ssl, close write end of pipe, wait for curl, close read end of pipe

green vector
limber coral
#

If you have a repo already, you could:

git remote add laytan https://github.com/laytan/Odin.git
git fetch laytan
git checkout fix-process-windows-handles-handling
dim kettle
#

I am starting up my windows machine to see if it works and submit it

green vector
#

The (slightly modified) version works now, no output to cmd

package test

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

main :: proc()
{
  openssl_command := []string{"openssl", "s_client", "-quiet", "-connect", "github.com:443", "-servername", "github.com"}
  curl_command := []string{"curl", "-L", "-s", "-o", "odin-logo.png", "https://github.com/odin-lang/Odin/blob/master/misc/logo-slim.png"}

  readPipe, writePipe, err := os2.pipe()
  fmt.assertf(err == nil, "Could not create pipe: %v", err)
  curl_desc := os2.Process_Desc { command = curl_command, stdin = readPipe }
  openssl_desc := os2.Process_Desc { command = openssl_command, stdout = writePipe }

  curl_process, openssl_process: os2.Process
  state: os2.Process_State

  openssl_process, err = os2.process_start(openssl_desc)
  fmt.assertf(err == nil, "Could not start openssl process: %v", err)
  curl_process, err = os2.process_start(curl_desc)
  fmt.assertf(err == nil, "Could not start curl process: %v", err)

  state, err = os2.process_wait(openssl_process)
  fmt.assertf(err == nil, "Could not wait for openssl process: %v", err)
  os2.close(writePipe)
  state, err = os2.process_wait(curl_process)
  fmt.assertf(err == nil, "Could not wait for curl process: %v", err)
  os2.close(readPipe)

  err = os2.process_close(openssl_process)
  fmt.assertf(err == nil, "Could not close openssl process: %v", err)
  err = os2.process_close(curl_process)
  fmt.assertf(err == nil, "Could not close curl process: %v", err)
}
#

I ran it with: odin run test.odin -file -sanitize:address, not sure if the -sanitize:address is enough though

green vector
dim kettle
#

No that's fine

green vector
# green vector The (slightly modified) version works now, no output to cmd ```cpp package test ...

I did a smaller test while waiting since this one involved pipes

package test

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

main :: proc()
{
  smaller_test()
}

smaller_test :: proc()
{
  state: os2.Process_State
  process, err := os2.process_start({ command = {"echo", "hellope"}})
  fmt.assertf(err == nil, "Could not start process: %v", err)
  state, err = os2.process_wait(process)
  fmt.assertf(err == nil, "Could not wait for process: %v", err)
  err = os2.process_close(process)
  fmt.assertf(err == nil, "Could not close process: %v", err)
}
#

(also works)

dim kettle
#

Yeah everything is working on my end too, thanks