aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test/port_bif_SUITE_data/control_drv.c
blob: e9f57a887a453bf04f482c1b0ffb9649cee45200 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <stdio.h>
#include <stdlib.h>
#include "erl_driver.h"


static ErlDrvPort erlang_port;
static ErlDrvData control_start(ErlDrvPort, char*);
static void control_stop(ErlDrvData);
static void control_read(ErlDrvData, char*, int);
static int control_control(ErlDrvData, unsigned int, char*, int, char**, int);

static ErlDrvEntry control_driver_entry =
{
    NULL,
    control_start,
    control_stop,
    control_read,
    NULL,
    NULL,
    "control_drv",
    NULL,
    NULL,
    control_control,
    NULL,
    NULL,
    NULL
};

DRIVER_INIT(control_drv)
{
    erlang_port = (ErlDrvPort)-1;
    return &control_driver_entry;
}

static ErlDrvData control_start(ErlDrvPort port,char *buf)
{
    if (erlang_port != (ErlDrvPort)-1)
	return ERL_DRV_ERROR_GENERAL;
    
    erlang_port = port;
    return (ErlDrvData)port;
}

static void control_read(ErlDrvData port, char *buf, int count)
{
    driver_output(erlang_port, buf, count);
}

static void control_stop(ErlDrvData port)
{
    erlang_port = (ErlDrvPort)-1;
}

static int control_control(ErlDrvData port, unsigned command, char* buf, int count,
			   char** res, int res_size)
{
    switch (command) {
    case 'e':
	if (count > res_size) {
	    *res = (char *) driver_alloc(count);
	}
	memcpy(*res, buf, count);
	return count;
    case 'b':
	set_busy_port(erlang_port, buf[0]);
	return 0;
    case 'i':
	driver_output(erlang_port, buf, count);
	return 0;
    default:
	if (command < 256) {
	    return -1;
	} else {
	    char* p = *res;
	    int i;

	    for (i = 3; i >= 0; i--) {
		p[i] = command;
		command >>= 8;
	    }
	    return 4;
	}
    }
}