Пример #1
0
void run_js(void *jsargs) {
  js_call *call_data = (js_call *) jsargs;
  spidermonkey_drv_t *dd = call_data->driver_data;
  ErlDrvBinary *args = call_data->args;
  driver_free(call_data);
  char *data = args->orig_bytes;
  char *command = read_command(&data);
  char *call_id = read_string(&data);
  char *result = NULL;
  if (strncmp(command, "ej", 2) == 0) {
    char *filename = read_string(&data);
    char *code = read_string(&data);
    result = sm_eval(dd->vm, filename, code, 1);
    if (strstr(result, "{\"error\"") != NULL) {
      send_error_string_response(dd, call_id, result);
    }
    else {
      send_string_response(dd, call_id, result);
    }
    driver_free(filename);
    driver_free(code);
    driver_free(result);
  }
  else if (strncmp(command, "dj", 2) == 0) {
    char *filename = read_string(&data);
    char *code = read_string(&data);
    result = sm_eval(dd->vm, filename, code, 0);
    if (result == NULL) {
      send_ok_response(dd, call_id);
    }
    else {
      send_error_string_response(dd, call_id, result);
      driver_free(result);
    }
    driver_free(filename);
    driver_free(code);
  }
  else if (strncmp(command, "sd", 2) == 0) {
    dd->shutdown = 1;
    send_ok_response(dd, call_id);
  }
  else {
    unknown_command(dd, call_id);
  }
  driver_free(command);
  driver_free(call_id);
  driver_binary_dec_refc(args);
}
Пример #2
0
static void process(ErlDrvData handle, ErlIOVec *ev) {
  spidermonkey_drv_t *dd = (spidermonkey_drv_t *) handle;
  char *data = ev->binv[1]->orig_bytes;
  char *command = read_command(&data);
  if (strncmp(command, "ij", 2) == 0) {
    char *call_id = read_string(&data);
    int thread_stack = read_int32(&data);
    if (thread_stack < 8) {
      thread_stack = 8;
    }
    thread_stack = thread_stack * (1024 * 1024);
    int heap_size = read_int32(&data) * (1024 * 1024);
    dd->vm = sm_initialize(thread_stack, heap_size);
    send_ok_response(dd, call_id);
    driver_free(call_id);
  }
  else {
    js_call *call_data = (js_call *) driver_alloc(sizeof(js_call));
    call_data->driver_data = dd;
    call_data->args = ev->binv[1];
    driver_binary_inc_refc(call_data->args);
    ErlDrvPort port = dd->port;
    unsigned long thread_key = (unsigned long) port;
    driver_async(dd->port, (unsigned int *) &thread_key, (asyncfun) run_js, (void *) call_data, NULL);
  }
  driver_free(command);
}
Пример #3
0
static void handle_flush(const char *req, int *req_index)
{
    char dirstr[MAXATOMLEN];
    if (ei_decode_atom(req, req_index, dirstr) < 0) {
        send_error_response("einval");
        return;
    }

    enum uart_direction direction;
    if (strcmp(dirstr, "receive") == 0)
        direction = UART_DIRECTION_RECEIVE;
    else if (strcmp(dirstr, "transmit") == 0)
        direction = UART_DIRECTION_TRANSMIT;
    else if (strcmp(dirstr, "both") == 0)
        direction = UART_DIRECTION_BOTH;
    else {
        send_error_response("einval");
        return;
    }

    if (!uart_is_open(uart)) {
        send_error_response("ebadf");
        return;
    }

    if (uart_flush(uart, direction) >= 0)
        send_ok_response();
    else
        send_error_response(uart_last_error());
}
Пример #4
0
static void handle_write_completed(int rc, const uint8_t *data)
{
    free((uint8_t *) data);

    if (rc == 0)
        send_ok_response();
    else
        send_error_response(uart_last_error());
}
Пример #5
0
static void handle_close(const char *req, int *req_index)
{
    (void) req;
    (void) req_index;

    if (uart_is_open(uart))
        uart_close(uart);

    send_ok_response();
}
Пример #6
0
static void handle_drain(const char *req, int *req_index)
{
    (void) req;
    (void) req_index;
    if (!uart_is_open(uart)) {
        send_error_response("ebadf");
        return;
    }

    if (uart_drain(uart) >= 0)
        send_ok_response();
    else
        send_error_response(uart_last_error());
}
Пример #7
0
static void handle_configure(const char *req, int *req_index)
{
    struct uart_config config = current_config;
    if (parse_option_list(req, req_index, &config) < 0) {
        send_error_response("einval");
        return;
    }

    if (uart_configure(uart, &config) >= 0) {
        current_config = config;
        send_ok_response();
    } else {
        send_error_response(uart_last_error());
    }
}
Пример #8
0
static void handle_set_break(const char *req, int *req_index)
{
    int val;
    if (ei_decode_boolean(req, req_index, &val) < 0) {
        send_error_response("einval");
        return;
    }

    if (!uart_is_open(uart)) {
        send_error_response("ebadf");
        return;
    }

    if (uart_set_break(uart, !!val) >= 0)
        send_ok_response();
    else
        send_error_response(uart_last_error());
}
Пример #9
0
/*
 * Handle {name, kv_list}
 *
 *    name is the serial port name
 *    kv_list a list of configuration values (speed, parity, etc.)
 */
static void handle_open(const char *req, int *req_index)
{
    int term_type;
    int term_size;

    if (ei_decode_tuple_header(req, req_index, &term_size) < 0 ||
            term_size != 2)
        errx(EXIT_FAILURE, ":open requires a 2-tuple");

    char name[32];
    long binary_len;
    if (ei_get_type(req, req_index, &term_type, &term_size) < 0 ||
            term_type != ERL_BINARY_EXT ||
            term_size >= (int) sizeof(name) ||
            ei_decode_binary(req, req_index, name, &binary_len) < 0) {
        // The name is almost certainly too long, so report that it
        // doesn't exist.
        send_error_response("enoent");
        return;
    }
    name[term_size] = '\0';

    struct uart_config config = current_config;
    if (parse_option_list(req, req_index, &config) < 0) {
        send_error_response("einval");
        return;
    }

    // If the uart was already open, close and open it again
    if (uart_is_open(uart))
        uart_close(uart);

    if (uart_open(uart, name, &config) >= 0) {
        current_config = config;
        send_ok_response();
    } else {
        send_error_response(uart_last_error());
    }
}