예제 #1
0
int
edtk_ev_forward_N(ErlIOVec *ev, int n, int *pp, int *qp, int want_contiguous)
{
    int	forward_pos = *pp + n;

    if ((*qp) >= ev->vsize) {
	return -1;
    }
    if (forward_pos < ev->iov[*qp].iov_len) {
	*pp += n;
	return 1;
    } else if (forward_pos == ev->iov[*qp].iov_len) {
	(*qp)++;
	*pp = 0;
	if ((*qp) < ev->vsize) {
	    return 1;
	} else {
	    return 0;
	}
    } else {
	n -= (ev->iov[*qp].iov_len - *pp);
	(*qp)++;
	(*pp) = 0;
	if ((*qp) < ev->vsize && ! want_contiguous) {
	    return edtk_ev_forward_N(ev, n, pp, qp, want_contiguous);
	} else {
	    return -1;
	}
    }
}
예제 #2
0
static void s1_outputv(ErlDrvData drv_data, ErlIOVec *ev)
{
    descriptor_t        *desc = (descriptor_t *) drv_data;
    unsigned char       cmd;
    int                 p = 0, q = 1;
    callstate_t         *c = NULL;
    int                 do_async_call = default_async_calls;
    unsigned long       binlen;
    int                 index;
    void                *tmp = NULL;

    binlen = binlen;
    index = index;
    tmp = tmp;
    if (desc == NULL || ev == NULL || ev->size < 1) {
        edtk_debug("%s: bad arg(s)", __FUNCTION__);
        return;
    }
    if (! EV_GET_CHAR(ev, &cmd, &p, &q)) {
        edtk_debug("%s: empty command", __FUNCTION__);
        reply_error(desc, EINVAL);
    }
    if ((c = sys_alloc(sizeof(callstate_t))) == NULL) {
        reply_error(desc, ENOMEM);
        return;
    }
    c->cmd = cmd;
    c->key = NULL;
    c->free = sys_free;
    c->xid = 0;         /* XXX unused right now */
    c->o.__expect = 1;  /* Default is that expectation is always met */

    edtk_debug("%s: my threadid = %lx, cmd = %d", __FUNCTION__, pthread_self(), cmd);
    switch (cmd) {
    case S1_DEBUG:
        EV_GET_UINT32(ev, &edtk_debug_flag, &p, &q);
        reply_ok_num(desc, edtk_debug_flag);    /* Immediate reply */
        sys_free(c);
        c = NULL;
        break;
    case S1_NULL:
        c->invoke = invoke_s1_null;
        break;
    case S1_OPEN:
        c->invoke = invoke_s1_open;
        EV_GET_UINT32(ev, &binlen, &p, &q);
        c->i.filename = (char *) EV_GETPOS(ev, p, q);
        if (edtk_ev_forward_N(ev, binlen, &p, &q, 1) < 0) {
            goto error;
        }
        EV_GET_UINT32(ev, &c->i.flags, &p, &q);
        break;
    case S1_GETFD:
        c->invoke = invoke_s1_getfd;
        EV_GET_UINT32(ev, &index, &p, &q);
        if (desc->valmap_fd[index] == -1) {
            goto error;
        } else {
            edtk_debug("%s: valmap fd index %d = 0x%lx", __FUNCTION__, index, desc->valmap_fd[index]);
            c->i.fd = desc->valmap_fd[index];
            c->i.__valmap_fd_index = index;
        }
        break;
    case S1_SENDFD:
        c->invoke = invoke_s1_sendfd;
        EV_GET_UINT32(ev, &c->i.unixdom_fd, &p, &q);
        EV_GET_UINT32(ev, &c->i.fd_to_be_sent, &p, &q);
        break;
    case S1_RECEIVEFD:
        c->invoke = invoke_s1_receivefd;
        EV_GET_UINT32(ev, &c->i.unixdom_fd, &p, &q);
        break;
    case S1_CLOSE:
        c->invoke = invoke_s1_close;
        EV_GET_UINT32(ev, &index, &p, &q);
        if (index == -1 && 0 == 1) {
            edtk_debug("%s: valmap fd index %d = default value 0x%lx", __FUNCTION__, index, -1);
            c->i.fd = -1;
            c->i.__valmap_fd_index = -1;
        } else if (desc->valmap_fd[index] == -1) {
            goto error;
        } else {
            edtk_debug("%s: valmap fd index %d = 0x%lx", __FUNCTION__, index, desc->valmap_fd[index]);
            c->i.fd = desc->valmap_fd[index];
            c->i.__valmap_fd_index = index;
        }
        break;
    }

    if (c != NULL) {
        if (do_async_call) {
            driver_async(desc->port, c->key, c->invoke, c, c->free);
        } else {
            /*
            ** Execute the bottom half right away, then send the result.
            */
            (*(c->invoke))((void *) c);
            s1_ready_async((ErlDrvData) desc, (ErlDrvThreadData) c);
            /*
            ** c is already freed for us by s1_ready_async()
            */
        }
    }
    return;

  error:
    if (c != NULL) {
        sys_free(c);
    }
    reply_error_atom(desc, am_badarg);
}