diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 254248f9fb..008599727e 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -965,23 +965,27 @@ proc genEcho(p: BProc, n: PNode) =
# this unusal way of implementing it ensures that e.g. ``echo("hallo", 45)``
# is threadsafe.
internalAssert n.kind == nkBracket
- var args: Rope = nil
- var a: TLoc
- for i in countup(0, n.len-1):
- if n.sons[i].skipConv.kind == nkNilLit:
- add(args, ", \"nil\"")
- else:
- initLocExpr(p, n.sons[i], a)
- addf(args, ", $1? ($1)->data:\"nil\"", [rdLoc(a)])
if platform.targetOS == osGenode:
# bypass libc and print directly to the Genode LOG session
+ var args: Rope = nil
+ var a: TLoc
+ for i in countup(0, n.len-1):
+ if n.sons[i].skipConv.kind == nkNilLit:
+ add(args, ", \"nil\"")
+ else:
+ initLocExpr(p, n.sons[i], a)
+ addf(args, ", $1? ($1)->data:\"nil\"", [rdLoc(a)])
p.module.includeHeader("")
linefmt(p, cpsStmts, """Genode::log(""$1);$n""", args)
else:
- p.module.includeHeader("")
- linefmt(p, cpsStmts, "printf($1$2);$n",
- makeCString(repeat("%s", n.len) & tnl), args)
- linefmt(p, cpsStmts, "fflush(stdout);$n")
+ var a: TLoc
+ initLocExpr(p, n, a)
+ linefmt(p, cpsStmts, "#echoBinSafe($1, $2);$n", a.rdLoc, n.len.rope)
+ when false:
+ p.module.includeHeader("")
+ linefmt(p, cpsStmts, "printf($1$2);$n",
+ makeCString(repeat("%s", n.len) & tnl), args)
+ linefmt(p, cpsStmts, "fflush(stdout);$n")
proc gcUsage(n: PNode) =
if gSelectedGC == gcNone: message(n.info, warnGcMem, n.renderTree)
diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim
index 4f266e0aee..c0da983f1c 100644
--- a/lib/system/sysio.nim
+++ b/lib/system/sysio.nim
@@ -404,4 +404,16 @@ proc setStdIoUnbuffered() =
when declared(stdin):
discard c_setvbuf(stdin, nil, IONBF, 0)
+when declared(stdout):
+ proc echoBinSafe(args: openArray[string]) {.compilerProc.} =
+ proc flockfile(f: File) {.importc, noDecl.}
+ proc funlockfile(f: File) {.importc, noDecl.}
+ flockfile(stdout)
+ for s in args:
+ discard c_fwrite(s.cstring, s.len, 1, stdout)
+ const linefeed = "\n" # can be 1 or more chars
+ discard c_fwrite(linefeed.cstring, linefeed.len, 1, stdout)
+ discard c_fflush(stdout)
+ funlockfile(stdout)
+
{.pop.}