Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/control/cmd/ddb/main.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// (C) Copyright 2022-2024 Intel Corporation.
// (C) Copyright 2026 Hewlett Packard Enterprise Development LP
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
Expand All @@ -8,6 +9,7 @@ package main

import (
"bufio"
"fmt"
"os"
"path"
"path/filepath"
Expand Down Expand Up @@ -242,6 +244,13 @@ Example Paths:

func main() {
var opts cliOptions

// Must be called before any write to stdout.
if err := logging.DisableCStdoutBuffering(); err != nil {
fmt.Fprintf(os.Stderr, "Error disabling stdout buffering: %v\n", err)
os.Exit(1)
}

log := logging.NewCommandLineLogger()

if err := parseOpts(os.Args[1:], &opts, log); err != nil {
Expand Down
39 changes: 39 additions & 0 deletions src/control/logging/cstdio.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// (C) Copyright 2026 Hewlett Packard Enterprise Development LP
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//

package logging

/*
#include <stdio.h>
*/
import "C"
import "github.com/pkg/errors"

// DisableCStdoutBuffering disables C code write to stdout buffering and must be called before any write to stdout.
//
// When a Go program's stdout is connected to a pipe (e.g. redirected or piped to another
// process), C stdout becomes fully-buffered by Unix convention instead of line-buffered,
// which can cause output from C functions such as printf() to be lost or delayed.
// Disabling buffering ensures that C stdout output is flushed immediately, consistent
// with the behavior of Go's own stdout.
//
// References:
// - https://stackoverflow.com/questions/42634640/using-cgo-why-does-c-output-not-survive-piping-when-golangs-does
// - https://stackoverflow.com/questions/1716296/why-does-printf-not-flush-after-the-call-unless-a-newline-is-in-the-format-strin
// - https://stackoverflow.com/questions/3723795/is-stdout-line-buffered-unbuffered-or-indeterminate-by-default
// - https://groups.google.com/g/comp.lang.c/c/dvRKt-iuO40#
func DisableCStdoutBuffering() error {
rc, err := C.setvbuf(C.stdout, nil, C._IONBF, 0)
if rc == 0 {
return nil
}

if err != nil {
return errors.Wrap(err, "failed to disable C stdout buffering")
}

return errors.Errorf("failed to disable C stdout buffering: rc=%d", int(rc))
}
Loading