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 '19 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 '19 at 18:33

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, privacy policy and cookie policy

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