Пример #1
0
static ErlDrvData
start(ErlDrvPort port, char *command)
{
    mcd_data_t *mcd = driver_alloc(sizeof(mcd_data_t));

    if (!mcd)
	goto error;

    mcd->ofd = -1;
    mcd->ifd = -1;

#ifdef UNIX

    mcd->ofd = open("/dev/null", O_WRONLY);
    if (mcd->ofd < 0)
	goto error;
    if (driver_select(port, (ErlDrvEvent) (long) mcd->ofd, DO_WRITE, 1) != 0)
	goto error;

    mcd->ifd = open("/dev/zero", O_RDONLY);
    if (mcd->ifd < 0)
	goto error;
    if (driver_select(port, (ErlDrvEvent) (long) mcd->ifd, DO_READ, 1) != 0)
	goto error;
#endif

    driver_set_timer(port, 0);

    return (ErlDrvData) mcd;

 error:
    stop((ErlDrvData) mcd);
    return ERL_DRV_ERROR_GENERAL;
}
Пример #2
0
/*
** Timeout from driver_set_timer.
*/
static void trace_file_timeout(ErlDrvData handle) {
    TraceFileData *data = (TraceFileData *) handle;
    if (data->wrap) {
        if (wrap_file(data) < 0) {
            driver_failure_posix(data->port, errno); /* XXX */
            return;
        } else {
            driver_set_timer(data->port, data->wrap->time);
        }
    }
}
Пример #3
0
/* set the timer, this is monitored from erlang measuring the time */
static void timer_read(ErlDrvData p, char *buf, ErlDrvSizeT len)
{
    ErlDrvPort port = (ErlDrvPort) p;
    char reply[1];

    if (buf[0] == START_TIMER) { 
	/* fprintf(stderr, "[timer_drv] Setting timeout: %i\n", get_int32(buf + 1)); */
	driver_set_timer(port, get_int32(buf + 1));
    } else if (buf[0] == CANCEL_TIMER) {
	/*	fprintf(stderr, "[timer_drv] Timer cancelled\n"); */
	driver_cancel_timer(port);
	reply[0] = CANCELLED;
	driver_output(port, reply, 1);
    }
}
Пример #4
0
/*
** Open a port
*/
static ErlDrvData trace_file_start(ErlDrvPort port, char *buff)
{
    unsigned size, cnt, time, tail, len;
    char *p;
    TraceFileData     *data;
    TraceFileWrapData *wrap;
    FILETYPE fd;
    int n, w;
    static const char name[] = "trace_file_drv";

#ifdef HARDDEBUG
    fprintf(stderr,"hello (%s)\r\n", buff);
#endif
    w = 0; /* Index of where sscanf gave up */
    size = 0; /* Warning elimination */
    cnt = 0;  /* -""- */
    time = 0;  /* -""- */
    tail = 0; /* -""- */
    n = sscanf(buff, "trace_file_drv %n w %u %u %u %u %n",
               &w, &size, &cnt, &time, &tail, &w);

    if (w < sizeof(name) || (n != 0 && n != 4))
        return ERL_DRV_ERROR_BADARG;

    /* Search for "n <Filename>" in the rest of the string */
    p = buff + w;
    for (p = buff + w; *p == ' '; p++); /* Skip space (necessary?) */
    if (*p++ != 'n')
        return ERL_DRV_ERROR_BADARG;
    if (*p++ != ' ')
        return ERL_DRV_ERROR_BADARG;
    /* Here we are at the start of the filename; p */
    len = strlen(p);
    if (tail >= len)
        /* Tail must start within filename */
        return ERL_DRV_ERROR_BADARG;

    data = my_alloc(sizeof(TraceFileData) - 1 + BUFFER_SIZE);

    /* We have to check the length in case we are running on
     * VxWorks since too long pathnames may cause bus errors
     * instead of error return from file operations.
     */
    if (n == 4) {
        /* Size limited wrapping log */
        unsigned d = digits(cnt); /* Nof digits in filename counter */
        if (len+d >= MAXPATHLEN) {
            errno = ENAMETOOLONG;
            return ERL_DRV_ERROR_ERRNO;
        }
        wrap = my_alloc(sizeof(TraceFileWrapData));
        wrap->size = size;
        wrap->cnt = cnt;
        wrap->time = time;
        wrap->len = 0;
        strcpy(wrap->cur.name, p);
        wrap->cur.suffix = tail;
        wrap->cur.tail = tail;
        wrap->cur.len = len;
        wrap->cur.cnt = cnt;
        wrap->cur.n = cnt;
        next_name(&wrap->cur); /* Incr to suffix "0" */
        wrap->del = wrap->cur; /* Struct copy! */
        p = wrap->cur.name; /* Use new name for open */
    } else {
        /* Regular log */
        if (len >= MAXPATHLEN) {
            errno = ENAMETOOLONG;
            return ERL_DRV_ERROR_ERRNO;
        }
        wrap = NULL;
    }

    if ((fd = open(p, O_WRONLY | O_TRUNC | O_CREAT
#ifdef O_BINARY
                   | O_BINARY
#endif
                   , 0777)) < 0) {
        if (wrap)
            driver_free(wrap);
        driver_free(data);
        return ERL_DRV_ERROR_ERRNO;
    }

    data->fd = fd;
    data->port = port;
    data->buff_siz = BUFFER_SIZE;
    data->buff_pos = 0;
    data->wrap = wrap;

    if (first_data) {
        data->prev = first_data->prev;
        first_data->prev = data;
    } else
        data->prev = NULL;
    data->next = first_data;
    first_data = data;

    if (wrap && wrap->time > 0)
        driver_set_timer(port, wrap->time);

    return (ErlDrvData) data;
}
Пример #5
0
static void echo_drv_output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) {
    EchoDrvData* data_p = (EchoDrvData *) drv_data;
    ErlDrvPort port = data_p->erlang_port;

    switch (buf[0]) {
    case ECHO_DRV_OUTPUT:
    {
        driver_output(port, buf+1, len-1);
        break;
    }
    case ECHO_DRV_OUTPUT2:
    {
         driver_output2(port, "a", 1, buf+1, len-1);
         break;
    }
    case ECHO_DRV_OUTPUT_BINARY:
    {
        ErlDrvBinary *bin = driver_alloc_binary(len-1);
        memcpy(&bin->orig_bytes, buf+1, len-1);
        driver_output_binary(port, "a", 1, bin, 1, len - 2);
        driver_free_binary(bin);
        break;
    }
    case ECHO_DRV_OUTPUTV:
    {
        ErlIOVec iov;
        ErlDrvSizeT sz;
        driver_enq(port, buf + 1, len - 1);
        sz = driver_peekqv(port, &iov);
        driver_outputv(port, "a", 1, &iov, 0);
        driver_deq(port, sz);
        break;
    }
    case ECHO_DRV_SET_TIMER:
    {
        driver_set_timer(port, 10);
        break;
    }
    case ECHO_DRV_FAILURE_EOF:
    {
        driver_failure_eof(port);
        break;
    }
    case ECHO_DRV_FAILURE_ATOM:
    {
        driver_failure_atom(port, buf+1);
        break;
    }
    case ECHO_DRV_FAILURE_POSIX:
    {
        driver_failure_posix(port, EAGAIN);
        break;
    }
    case ECHO_DRV_FAILURE:
    {
        driver_failure(port, buf[1]);
        break;
    }
    case ECHO_DRV_OUTPUT_TERM:
    case ECHO_DRV_DRIVER_OUTPUT_TERM:
    case ECHO_DRV_SEND_TERM:
    case ECHO_DRV_DRIVER_SEND_TERM:
    {
        ErlDrvTermData term[] = {
            ERL_DRV_ATOM, driver_mk_atom("echo"),
            ERL_DRV_PORT, driver_mk_port(port),
            ERL_DRV_BUF2BINARY, (ErlDrvTermData)(buf+1),
                                (ErlDrvTermData)(len - 1),
            ERL_DRV_TUPLE, 3};
        switch (buf[0]) {
        case ECHO_DRV_OUTPUT_TERM:
            erl_drv_output_term(driver_mk_port(port), term, sizeof(term) / sizeof(ErlDrvTermData));
            break;
        case ECHO_DRV_DRIVER_OUTPUT_TERM:
            driver_output_term(port, term, sizeof(term) / sizeof(ErlDrvTermData));
            break;
        case ECHO_DRV_SEND_TERM:
            driver_send_term(port, data_p->caller,
                             term, sizeof(term) / sizeof(ErlDrvTermData));
            break;
        case ECHO_DRV_DRIVER_SEND_TERM:
            erl_drv_send_term(driver_mk_port(port), data_p->caller,
                              term, sizeof(term) / sizeof(ErlDrvTermData));
            break;
        }
        break;
    }
    case ECHO_DRV_SAVE_CALLER:
        data_p->caller = driver_caller(port);
        break;
    default:
        break;
    }
}