dexecve 1.3.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 74

dexecve #

Pub Version .github/workflows/main.yml semantic-release Conventional Commits KeepAChangelog License

Replace the running process, with a POSIX execve system call.

Usage #

import 'package:dexecve/dexecve.dart';

void main() {
  dexecve('ping', ['1.1.1.1']);
}

see ./example/main.dart for more details

Dart FFI & Golang #

This project is a working example of how to integrate dartlang and golang using dart's c interop.

Steps basically look like this:

  1. Create a golang c-shared library.

    hello.go

    package main
    
    import "C"
    
    import (
     "fmt"
    )
    
    //export HelloWorld
    func HelloWorld() {
     fmt.Println("hello world")
    }
    
    func main() {}
    
  2. Compile the library. eg: go build -o libhello.so -buildmode=c-shared hello.go

    You may want to cross compile the library for multiple platforms. Cross compilation of a static golang binary is relatively straight forward these days however it's not as easy to cross compile a library as cgo is required which normally is disabled for cross compilation.

    I have found xgo very helpful for this.

  3. Write the dart ffi code to interface with the library. This feels almost like writing TypeScript typings for a JavaScript library.

    hello.dart

    import 'dart:ffi';
    
    DynamicLibrary _lib = DynamicLibrary.open('libhello.so');
    
    typedef HelloWorld = void Function();
    typedef HelloWorld_func = Void Function();
    final HelloWorld helloWorld = _lib.lookup<NativeFunction<HelloWorld_func>>('HelloWorld').asFunction();
    
  4. Consume the function in your dart code and profit :)

    main.dart

    import 'hello.dart';
    
    void main() {
      helloWorld();
    }
    

Essentially all this project does is call golang's syscall.Exec() function.

I understand this might be overkill and a much smaller package could be created if I used C directly. One day I might do just that...

In my opinion this creates a very powerful tool chain, dartlang feels very familiar with Classes, Generics, Extension Methods, Exceptions, Async/Await and many other concepts that other more main stream languages have had for a very long time.

While golang offers a very powerful concurrency model, handy tools like defer, a simplified programming model, native performance and a larger ecosystem which can help to fill any gaps in the current dart ecosystem.

Anything I can do in Go and I can do in Dart!

Further Resources #

1.3.0 (2020-05-07) #

Bug Fixes #

  • pubspec: circular dependency of drun (c2f10a6)

Features #

  • lookpath: allow the execution of hashbangs on windows (14f2e97)

1.2.2 (2020-04-15) #

Bug Fixes #

  • windows: use ProcessStartMode.inheritStdio (ec00665)

1.2.1 (2020-04-15) #

Bug Fixes #

  • environment: add values from the correct map (6b11e4c)

1.2.0 (2020-04-15) #

Bug Fixes #

  • environment: added some additional null checks (ad8407e)

Features #

  • windows: fallback to a child process (6ef8456)

1.1.0 (2020-03-18) #

Bug Fixes #

  • lints: various small changes to pass linters (b215a2f)
  • memory-leak: free the input string pointer inside the go function (1f25f24)
  • added an example by using what was sut.dart (b9665f7)

Features #

  • env: environment is now a map instead of a list (cefdb5c)

1.0.0 (2020-03-17) #

Features #

example/main.dart

import 'dart:io' as io;
import 'package:path/path.dart' as p;
import 'package:dexecve/dexecve.dart';

void main(List<String> argv) {
  // This branch should be executed by `dexecve` call below
  if (argv.isNotEmpty && argv[0] == 'executed') {
    print('PID CHILD: ${io.pid}');
    print('FOO=${io.Platform.environment['FOO']}');
    return;
  }

  // This PID should be inherited by the next invocation of this script
  print('PID PARENT: ${io.pid}');

  // This can be an absolute or relative path.
  // Under the hood we use the golang `exec.LookPath` function to find the binary.
  // see: https://golang.org/pkg/os/exec/#LookPath
  var binaryToExecute = 'dart';

  // The arguments to pass to the binary
  // NOTE: This example is actually used as part of the test for this project
  // and assumes the current working directory in the root of this project.
  var args = [p.absolute('example', 'main.dart'), 'executed'];

  // Optionally you may pass a MAP that represents the environment variables
  // the binary should see.
  var environment = {'FOO': 'BAR'};

  // By default the executed binary will also inherit the environment from the
  // current process. You can disable this functionality if you wish.
  var inheritEnvironment = false;

  // If the binary is succesfully executed then no further instructions in this
  // app will be executed, effectively it would be as though you called the
  // `exit()` function.
  dexecve(
    binaryToExecute,
    args,
    environment: environment,
    inheritEnvironment: inheritEnvironment,
  );

  print('I should never see this');
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  dexecve: ^1.3.0

2. Install it

You can install packages from the command line:

with pub:


$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:dexecve/dexecve.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
47
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
74
Learn more about scoring.

We analyzed this package on Jul 7, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.13

Analysis suggestions

Package not compatible with SDK flutter

Because it is not compatible with any of the supported runtimes: flutter-native, flutter-web

Package not compatible with runtime flutter-native on android

Because of the import of dart:cli via the import chain package:dexecve/dexecve.dartpackage:dexecve/src/exec.dartdart:cli

Package not compatible with runtime flutter-native on ios

Because of the import of dart:cli via the import chain package:dexecve/dexecve.dartpackage:dexecve/src/exec.dartdart:cli

Package not compatible with runtime flutter-native on linux

Because of the import of dart:cli via the import chain package:dexecve/dexecve.dartpackage:dexecve/src/exec.dartdart:cli

Package not compatible with runtime flutter-native on macos

Because of the import of dart:cli via the import chain package:dexecve/dexecve.dartpackage:dexecve/src/exec.dartdart:cli

Package not compatible with runtime flutter-native on windows

Because of the import of dart:cli via the import chain package:dexecve/dexecve.dartpackage:dexecve/src/exec.dartdart:cli

Package not compatible with runtime flutter-web on web

Because of the import of dart:io via the import chain package:dexecve/dexecve.dartpackage:dexecve/src/go_string.dartpackage:ffi/ffi.dartpackage:ffi/src/allocation.dartdart:io

Package not compatible with runtime web

Because of the import of dart:io via the import chain package:dexecve/dexecve.dartpackage:dexecve/src/go_string.dartpackage:ffi/ffi.dartpackage:ffi/src/allocation.dartdart:io

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.7.0 <3.0.0
dexeca ^1.2.0 1.3.0
ffi ^0.1.3 0.1.3
path ^1.6.4 1.7.0
Dev dependencies
drun ^2.0.2
pedantic ^1.8.0
test ^1.14.1