Any problems with this D wrapper around libcomcom_run_command() C function from C library libcomcom?

Does it work as expected? Is it idiomatic? Is it the right way to do this?

module libcomcom_wrapper;

import std.string;
import std.algorithm.iteration : map;
import std.array : array;
import std.exception : ErrnoException;
import libcomcom;

string runCommand(string file, string[] argv, string[] envp, string input, int timeout = -1) {
    const(char*) output;
    size_t output_len;
    const char*[] childArgv = map!(s => s.toStringz)(argv).array;
    const char*[] childEnvp = map!(s => s.toStringz)(envp).array;
    immutable int res = libcomcom_run_command(input.ptr, input.length,
                                              &output, &output_len,
                                              file.toStringz, childArgv.ptr,
    if (res != 0) {
        throw new ErrnoException("Run command"); // TODO: Localization
    import core.stdc.stdlib : free;
    scope(exit) free(cast(void*) output);
    return output[0..output_len].idup;

The code was taken here.

  • \$\begingroup\$ I've discovered that I can use just toStringz instead of s => s.toStringz. \$\endgroup\$
    – porton
    Jan 24, 2019 at 20:35
  • \$\begingroup\$ Need to add ~ null after every .array (as otherwise there is no array terminator and it is undefined behavior probably) \$\endgroup\$
    – porton
    Jan 26, 2019 at 18:33

1 Answer 1


Nitpick: map!(s => s.toStringz)(argv) would be more idiomatic as argv.map!toStringz. Apart from that, your code looks very much correct. It should work as expected, and is indeed the way to do this.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.