diff --git a/vlib/os/os_nix.c.v b/vlib/os/os_nix.c.v index 276d2c3a73..ced0acc0d2 100644 --- a/vlib/os/os_nix.c.v +++ b/vlib/os/os_nix.c.v @@ -343,16 +343,19 @@ pub fn execute(cmd string) Result { output: 'exec("$cmd") failed' } } + fd := fileno(f) buf := unsafe { malloc_noscan(4096) } mut res := strings.new_builder(1024) defer { unsafe { res.free() } } unsafe { - bufbp := buf - for C.fgets(&char(bufbp), 4096, f) != 0 { - buflen := vstrlen(bufbp) - res.write_ptr(bufbp, buflen) + for { + len := C.read(fd, buf, 4096) + if len == 0 { + break + } + res.write_ptr(buf, len) } } soutput := res.str() diff --git a/vlib/os/os_test.v b/vlib/os/os_test.v index f76e967677..a15484ead0 100644 --- a/vlib/os/os_test.v +++ b/vlib/os/os_test.v @@ -841,3 +841,20 @@ fn test_expand_tilde_to_home() { assert home_test == home_expansion_test assert os.expand_tilde_to_home('~') == os.home_dir() } + +fn test_execute() { + $if !linux { + return + } + // The output of the next command contains a 0 byte in the middle. + // Nevertheless, the execute function *should* return a string that + // contains it: + result := os.execute('printenv --null LANGUAGE LANG') + hexresult := result.output.bytes().hex() + println(result.exit_code) + println(result.output.len) + println(hexresult) + assert result.exit_code == 0 + assert result.output.len > 0 + assert hexresult.contains('00') +}