コード例 #1
0
ファイル: trace_file_drv.c プロジェクト: agelin/Erlang-OTP
/*
** Returns 0 if write to cache, 1 i write to file, and -1 if write failed.
*/
static int my_write(TraceFileData *data, unsigned char *buff, int siz)
{
    int wrote;

    if (data->buff_siz - data->buff_pos >= siz) {
        memcpy(data->buff + data->buff_pos, buff, siz);
        data->buff_pos += siz;
        return 0;
    }

    wrote = data->buff_siz - data->buff_pos;
    memcpy(data->buff + data->buff_pos, buff, wrote);
    if (do_write(data->fd, data->buff, data->buff_siz) < 0) {
        return -1;
    }
    data->buff_pos = 0;
    if (siz - wrote >= data->buff_siz) {
        /* Write directly, no need to buffer... */
        if (do_write(data->fd, buff + wrote, siz - wrote) < 0) {
            return -1;
        }
        return 1;
    }
    memcpy(data->buff, buff + wrote, siz - wrote);
    data->buff_pos = siz - wrote;
    set_port_control_flags(data->port, PORT_CONTROL_FLAG_HEAVY);
    return 1;
}
コード例 #2
0
ファイル: exmpp_xml_expat.c プロジェクト: lmarlow/exmpp
static ErlDrvData
exmpp_xml_start(ErlDrvPort port, char *command)
{
	struct exmpp_xml_data *edd;

	/* Set binary mode. */
	set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);

	/* Allocate driver data structure. */
	edd = driver_alloc(sizeof(*edd));
	if (edd == NULL)
		return (ERL_DRV_ERROR_GENERAL);

	/* Initialize generic context. */
	if (init_context(&edd->ctx) != 0) {
		driver_free(edd);
		return (ERL_DRV_ERROR_GENERAL);
	}
	edd->ctx.make_attributes = exmpp_xml_cb_make_attributes;

	/* Initialize driver instance's context. */
	edd->parser = NULL;

	/* Initialize the declared_nss list. */
	edd->declared_nss = driver_alloc(sizeof(*(edd->declared_nss)));
	if (edd->declared_nss == NULL) {
		free_context(&edd->ctx);
		driver_free(edd);
		return (ERL_DRV_ERROR_GENERAL);
	}
	ei_x_new(edd->declared_nss);

	return ((ErlDrvData)edd);
}
コード例 #3
0
ファイル: wxe_driver.c プロジェクト: Tony1928/erlang
static ErlDrvData 
wxe_driver_start(ErlDrvPort port, char *buff)
{      
   wxe_data *data;
   data = (wxe_data *) malloc(sizeof(wxe_data));
   wxe_debug = 0;
   
   if (data == NULL) {
      fprintf(stderr, " Couldn't alloc mem\r\n");
      return(ERL_DRV_ERROR_GENERAL);  /* ENOMEM */      
   } else {
      set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
      data->driver_data = NULL;
      data->bin = NULL; 
      data->port = port;
      if(WXE_DRV_PORT == 0) {
	 WXE_DRV_PORT = port;
	 wxe_master = data;
	 if(!(start_native_gui(data) == 1))
	    return(ERL_DRV_ERROR_GENERAL);  /* ENOMEM */
      } else {
	 meta_command(CREATE_PORT,data);
      }
      return (ErlDrvData) data;	 
   }
}
コード例 #4
0
ファイル: ERGenDM_drv.C プロジェクト: tomaon/ergen
static ErlDrvData start(ErlDrvPort port, char *) {

  if (NULL != port) {

    void *ptr = driver_alloc(sizeof(driver_data_t));

    if (NULL != ptr) {

      set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);

      driver_data_t *data = (driver_data_t *)ptr;

      data->port = port;

      strcpy(data->path, "flat_in/"); // << EGenLoader.cpp: FLAT_IN_PATH

      TPCE::CDriverGlobalSettings dgs;
      TPCE::TDriverGlobalSettings &dgs_d = dgs.dft;
      data->configured_customer_count = dgs_d.iConfiguredCustomerCount;
      data->active_customer_count = dgs_d.iActiveCustomerCount;
      data->scale_factor = dgs_d.iScaleFactor;
      data->days_of_initial_trades = dgs_d.iDaysOfInitialTrades;

      return (ErlDrvData)data;
    }
  }

  return ERL_DRV_ERROR_GENERAL;
}
コード例 #5
0
static ErlDrvData ejabberd_zlib_drv_start(ErlDrvPort port, char *buff)
{
   ejabberd_zlib_data *d =
      (ejabberd_zlib_data *)driver_alloc(sizeof(ejabberd_zlib_data));
   d->port = port;

   d->d_stream = (z_stream *)driver_alloc(sizeof(z_stream));

   d->d_stream->zalloc = zlib_alloc;
   d->d_stream->zfree = zlib_free;
   d->d_stream->opaque = (voidpf)0;

   deflateInit(d->d_stream, Z_DEFAULT_COMPRESSION);

   d->i_stream = (z_stream *)driver_alloc(sizeof(z_stream));

   d->i_stream->zalloc = zlib_alloc;
   d->i_stream->zfree = zlib_free;
   d->i_stream->opaque = (voidpf)0;

   inflateInit(d->i_stream);

   set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);

   return (ErlDrvData)d;
}
コード例 #6
0
ファイル: cecho.c プロジェクト: Ma3aXuCT/cecho
// =============================================================================
// Erlang Callbacks
// =============================================================================
static ErlDrvData start(ErlDrvPort port, char *command) {
  state *drvstate = (state *)driver_alloc(sizeof(state));
  drvstate->drv_port = port;
  set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
  int i;
  for (i = 0; i < _MAXWINDOWS; i++)
    drvstate->win[i] = NULL;
  return (ErlDrvData)drvstate;
}
コード例 #7
0
ファイル: g729_codec.c プロジェクト: LeoKudrik/rtplib
static ErlDrvData codec_drv_start(ErlDrvPort port, char *buff)
{
	codec_data* d = (codec_data*)driver_alloc(sizeof(codec_data));
	d->port = port;
	d->estate = initBcg729EncoderChannel();
	d->dstate = initBcg729DecoderChannel();
	set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
	return (ErlDrvData)d;
}
コード例 #8
0
ファイル: erlsyslog_drv.c プロジェクト: lemenkov/erlsyslog
static ErlDrvData syslogdrv_start(ErlDrvPort port, char *buf)
{
    syslogdrv_t* d = (syslogdrv_t*)driver_alloc(sizeof(syslogdrv_t));
    d->port = port;
    d->open = 0;
    d->ident = NULL;
    set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
    return (ErlDrvData)d;
}
コード例 #9
0
ファイル: uvc.c プロジェクト: alepharchives/uvc
static ErlDrvData uvc_drv_start(ErlDrvPort port, char *buff)
{
    Uvc* d = (Uvc *)driver_alloc(sizeof(Uvc));
    bzero(d, sizeof(Uvc));
    d->port = port;
    set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
    d->owner_pid = driver_caller(port);
    d->fd = -1;
    return (ErlDrvData)d;
}
コード例 #10
0
ファイル: enm_drv.c プロジェクト: basho/enm
static ErlDrvData
enm_start(ErlDrvPort port, char* command)
{
    EnmData* d = (EnmData*)driver_alloc(sizeof(EnmData));
    memset(d, 0, sizeof *d);
    d->port = port;
    d->waiting_recvs = 0;
    set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
    return (ErlDrvData)d;
}
コード例 #11
0
ファイル: av_decoder.c プロジェクト: alepharchives/avcodec
static ErlDrvData av_decoder_drv_start(ErlDrvPort port, char *buff)
{
    H264Decoder* d = (H264Decoder *)driver_alloc(sizeof(H264Decoder));
    bzero(d, sizeof(H264Decoder));
    d->port = port;
    set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
    d->owner_pid = driver_caller(port);
    d->key = av_decoder_key++;
    return (ErlDrvData)d;
}
コード例 #12
0
ファイル: iconv_erl.c プロジェクト: asynchrony/ejabberd
static ErlDrvData iconv_erl_start(ErlDrvPort port, char *buff)
{
   iconv_data* d = (iconv_data*)driver_alloc(sizeof(iconv_data));
   d->port = port;
   d->cd = NULL;

   set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
   
   return (ErlDrvData)d;
}
コード例 #13
0
static ErlDrvData i2c_drv_start(ErlDrvPort port, char *buff)
{
    set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);

    i2c_drv_portdata* d = (i2c_drv_portdata*)driver_alloc(sizeof(i2c_drv_portdata));
    d->port = port;
    d->fd = 0;
    d->verbose = 0;

    return (ErlDrvData)d;
}
コード例 #14
0
ErlDrvData 
DriverController::start(
    ErlDrvPort port, 
    char* /* buf */)
{
    /* If the flag is set to PORT_CONTROL_FLAG_BINARY, 
       a binary will be returned. */       
    set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); 
    Driver* drv_data = new Driver(*gp_driverMemoryManager);
    return reinterpret_cast<ErlDrvData>( drv_data );
}
コード例 #15
0
ファイル: tls_drv.c プロジェクト: anwars99/ejabberd
static ErlDrvData tls_drv_start(ErlDrvPort port, char *buff)
{
   tls_data *d = (tls_data *)driver_alloc(sizeof(tls_data));
   d->port = port;
   d->bio_read = NULL;
   d->bio_write = NULL;
   d->ssl = NULL;

   set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);

   return (ErlDrvData)d;
}
コード例 #16
0
ファイル: inpevt_driver.c プロジェクト: Feuerlabs/inpevt
static ErlDrvData inpevt_start(ErlDrvPort port, char *command)
{
    IEContext *ctx = 0;

    ctx = (IEContext*) driver_alloc(sizeof(IEContext));
    ctx->mDescriptor = -1;
    ctx->mPort = port;
    ctx->mDport = driver_mk_port(port);
    ctx->mDevice[0] = 0;
//    set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
    set_port_control_flags(port, 0);
    return (ErlDrvData) ctx;
}
コード例 #17
0
ファイル: uart_drv.c プロジェクト: Feuerlabs/uart
static ErlDrvData uart_drv_start(ErlDrvPort port, char* command)
{
    (void) command;
    drv_ctx_t* ctx = NULL;

    INFOF("memory allocated: %ld", dlib_allocated());
    INFOF("total memory allocated: %ld", dlib_total_allocated());

    ctx = DZALLOC(sizeof(drv_ctx_t));

    dthread_init(&ctx->self, port);

    if (strncmp(command, "uart_drv", 8) == 0)
	command += 8;
    if (*command == ' ')
	command++;
    DEBUGF("uart_drv: start (%s)", command);


    if (strcmp(command, "ftdi") == 0) {
#ifdef HAVE_FTDI
	ctx->other = dthread_start(port, uart_ftdi_main, &ctx->self, 4096);
	DEBUGF("uart_drv: ftdi thread = %p", ctx->other);
#endif
    }
    else {
#ifdef __WIN32__
	if ((*command == '\0') || (strcmp(command, "win32") == 0)) {
	    ctx->other = dthread_start(port, uart_win32_main, &ctx->self, 4096);
	    DEBUGF("uart_drv: win32 thread = %p", ctx->other);
	}
#else 
	if ((*command == '\0') || (strcmp(command, "unix") == 0)) {
	    ctx->other = dthread_start(port, uart_unix_main, &ctx->self, 4096);
	    DEBUGF("uart_drv: unix thread = %p", ctx->other);
	}
#endif
    }
    if (ctx->other == NULL) {
	dthread_finish(&ctx->self);
	DFREE(ctx);
	return ERL_DRV_ERROR_BADARG;
    }

    dthread_signal_use(&ctx->self, 1);
    dthread_signal_select(&ctx->self, 1);

    set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
    return (ErlDrvData) ctx;
}
コード例 #18
0
ファイル: innostore_drv.c プロジェクト: basho/innostore
static ErlDrvData innostore_drv_start(ErlDrvPort port, char* buffer)
{
    PortState* state = (PortState*)driver_alloc(sizeof(PortState));
    int worker_rc;

    memset(state, '\0', sizeof(PortState));

    // Save handle to the port
    state->port = port;

    // Save the owner PID
    state->port_owner = driver_connected(port);

    // Initialize in the READY state
    state->port_state = STATE_READY;

    // Make sure port is running in binary mode
    set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);

    // Allocate a mutex and condition variable for the worker
    state->worker_lock = erl_drv_mutex_create("innostore_worker_lock");
    state->worker_cv   = erl_drv_cond_create("innostore_worker_cv");

    // Spin up the worker
    worker_rc = erl_drv_thread_create("innostore_worker", &(state->worker),
                                      &innostore_worker, state, 0);
    if (state->worker_lock != NULL &&
        state->worker_cv != NULL &&
         worker_rc == 0)
    {
        return (ErlDrvData)state;
    }
    else
    {
        log("Innostore: Could not create port [lock=%p, cv=%p]\n",
            state->worker_lock, state->worker_cv);

        if (state->worker_cv != NULL)
            erl_drv_cond_destroy(state->worker_cv);

        if (state->worker_lock != NULL)
            erl_drv_mutex_destroy(state->worker_lock);

        driver_free(state);

        errno = worker_rc;
        return (ErlDrvData) ERL_DRV_ERROR_ERRNO;
    }
}
コード例 #19
0
ファイル: expat_erl.c プロジェクト: IlyaBokovenko/ejabberd
static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff)
{
   expat_data* d = (expat_data*)driver_alloc(sizeof(expat_data));
   d->port = port;
   d->parser = XML_ParserCreate("UTF-8");
   XML_SetUserData(d->parser, d);

   set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);

   XML_SetStartElementHandler(
      d->parser, (XML_StartElementHandler)erlXML_StartElementHandler);
   XML_SetEndElementHandler(
      d->parser, (XML_EndElementHandler)erlXML_EndElementHandler);
   XML_SetCharacterDataHandler(
      d->parser, (XML_CharacterDataHandler)erlXML_CharacterDataHandler);


   return (ErlDrvData)d;
}
コード例 #20
0
ファイル: speex_codec.c プロジェクト: LeoKudrik/rtplib
static ErlDrvData codec_drv_start(ErlDrvPort port, char *buff)
{
	int tmp;
	codec_data* d = (codec_data*)driver_alloc(sizeof(codec_data));
	d->port = port;
	speex_bits_init(&d->bits);
	/* FIXME hardcoded narrowband mode (speex_wb_mode, speex_uwb_mode) */
	d->estate = speex_encoder_init(&speex_nb_mode);
	d->dstate = speex_decoder_init(&speex_nb_mode);
//	tmp=8;
//	speex_encoder_ctl(d->estate, SPEEX_SET_QUALITY, &tmp);
	tmp=3;
	speex_encoder_ctl(d->estate, SPEEX_SET_COMPLEXITY, &tmp);
//	tmp=8000;
//	speex_encoder_ctl(d->estate, SPEEX_SET_SAMPLING_RATE, &tmp);
	tmp=1;
	speex_decoder_ctl(d->dstate, SPEEX_SET_ENH, &tmp);
	set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
	return (ErlDrvData)d;
}
コード例 #21
0
ファイル: trace_file_drv.c プロジェクト: 3112517927/otp
static void trace_file_output(ErlDrvData handle, char *buff,
			      ErlDrvSizeT bufflen)
{
    int heavy = 0;
    TraceFileData *data = (TraceFileData *) handle;
    unsigned char b[5] = "";
    put_be((unsigned) bufflen, b + 1);
    switch (my_write(data, (unsigned char *) b, sizeof(b))) {
    case 1:
	heavy = !0;
    case 0:
	switch (my_write(data, (unsigned char *) buff, bufflen)) {
	case 1:
	    heavy = !0;
	case 0:
	    break;
	case -1:
	    driver_failure_posix(data->port, errno); /* XXX */
	    return;
	}
	break;
    case -1:
	driver_failure_posix(data->port, errno); /* XXX */
	return;
    }
    if (data->wrap) {
	TraceFileWrapData *wrap = data->wrap;
	/* Size limited wrapping log files */
	wrap->len += sizeof(b) + bufflen;
	if (wrap->time == 0 && wrap->len >= wrap->size) {
	    if (wrap_file(data) < 0) {
		driver_failure_posix(data->port, errno); /* XXX */
		return;
	    }
	    heavy = !0;
	}
    }
    if (heavy) {
	set_port_control_flags(data->port, PORT_CONTROL_FLAG_HEAVY);
    }
}
コード例 #22
0
ファイル: ERGenCE_drv.C プロジェクト: tomaon/ergen
static ErlDrvData start(ErlDrvPort port, char *) {

  if (NULL != port) {

    void *ptr = driver_alloc(sizeof(driver_data_t));

    if (NULL != ptr) {

      set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);

      driver_data_t *data = (driver_data_t *)ptr;

      data->port = port;

      strcpy(data->path, "flat_in/"); // << EGenLoader.cpp: FLAT_IN_PATH

      TPCE::CDriverGlobalSettings dgs;
      TPCE::TDriverGlobalSettings &dgs_d = dgs.dft;
      data->configured_customer_count = dgs_d.iConfiguredCustomerCount;
      data->active_customer_count = dgs_d.iActiveCustomerCount;
      data->scale_factor = dgs_d.iScaleFactor;
      data->days_of_initial_trades = dgs_d.iDaysOfInitialTrades;

      TPCE::CTxnMixGeneratorSettings tmgs;
      TPCE::TTxnMixGeneratorSettings &tmgs_d = tmgs.dft;
      data->broker_volume_mix_level = tmgs_d.BrokerVolumeMixLevel;
      data->customer_position_mix_level = tmgs_d.CustomerPositionMixLevel;
      data->market_watch_mix_level = tmgs_d.MarketWatchMixLevel;
      data->security_detail_mix_level = tmgs_d.SecurityDetailMixLevel;
      data->trade_lookup_mix_level = tmgs_d.TradeLookupMixLevel;
      data->trade_order_mix_level = tmgs_d.TradeOrderMixLevel;
      data->trade_status_mix_level = tmgs_d.TradeStatusMixLevel;
      data->trade_update_mix_level = tmgs_d.TradeUpdateMixLevel;

      return (ErlDrvData)data;
    }
  }

  return ERL_DRV_ERROR_GENERAL;
}
コード例 #23
0
ファイル: expat_erl.c プロジェクト: Buttacavoli/ejabberd
static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff)
{
   expat_data* d = (expat_data*)driver_alloc(sizeof(expat_data));
   d->port = port;
   d->parser = XML_ParserCreate_MM("UTF-8", &ms, "\n");
   XML_SetUserData(d->parser, d);

   set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);

   XML_SetStartElementHandler(
      d->parser, (XML_StartElementHandler)erlXML_StartElementHandler);
   XML_SetEndElementHandler(
      d->parser, (XML_EndElementHandler)erlXML_EndElementHandler);
   XML_SetCharacterDataHandler(
      d->parser, (XML_CharacterDataHandler)erlXML_CharacterDataHandler);

   XML_SetStartNamespaceDeclHandler(
      d->parser, (XML_StartNamespaceDeclHandler) erlXML_StartNamespaceDeclHandler);
   XML_SetReturnNSTriplet(d->parser, 1);

   XML_SetDefaultHandler(d->parser, NULL);

   return (ErlDrvData)d;
}
コード例 #24
0
/*
 * Open a port.
 */
static ErlDrvData
jpeg_image_start(ErlDrvPort port, char *buff)
{
  set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
  return (ErlDrvData) 0;
}
コード例 #25
0
ファイル: eep0018.c プロジェクト: toland/eep0018
static ErlDrvData eep0018_start(ErlDrvPort port, char *buff)
{
    set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
    return (ErlDrvData) port;
}
コード例 #26
0
ファイル: trace_ip_drv.c プロジェクト: Owl7/otp
/*
** Open a port
*/
static ErlDrvData trace_ip_start(ErlDrvPort port, char *buff)
{
    TraceIpData *ret;
    int portno;
    int quesiz;
    int flags;
    SOCKET s;
    struct sockaddr_in sin;
    int reuse = 1;

#ifdef HARDDEBUG
    fprintf(stderr,"trace_ip_drv/trace_ip_start (%s)\r\n", buff);
#endif
    if (sscanf(buff,"trace_ip_drv %d %d %d",&portno, &quesiz, &flags) != 3)
	return ERL_DRV_ERROR_GENERAL;

    if (flags > 3 || flags < 0 || portno < 0 || quesiz < 0)
	return ERL_DRV_ERROR_GENERAL;
    
    if (lookup_data_by_port(portno) != NULL)
	return ERL_DRV_ERROR_GENERAL;
    
    if (IS_INVALID_SOCKET(s = socket(AF_INET, SOCK_STREAM, 0)))
	return ERL_DRV_ERROR_GENERAL;

    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 
		   (char *) &reuse, sizeof(reuse)) < 0) {
	closesocket(s);
	return ERL_DRV_ERROR_GENERAL;
    }


    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = INADDR_ANY;
    sin.sin_port = htons((short) portno);
    
    if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) != 0) {
	closesocket(s);
	return ERL_DRV_ERROR_GENERAL;
    }

    if (portno == 0) {
#ifdef HAVE_SOCKLEN_T
	socklen_t sinlen = sizeof(sin);
#else
	int  sinlen = (int) sizeof(sin);
#endif
	if (getsockname(s, (struct sockaddr *)&sin, &sinlen) != 0) {
	    closesocket(s);
	    return ERL_DRV_ERROR_GENERAL;
	} else {
	    portno = ntohs(sin.sin_port);
	}
    }    

    if (listen(s, 1)) { /* No significant backlog needed */
	closesocket(s);
	return ERL_DRV_ERROR_GENERAL;
    }

    if (set_nonblocking(s) != 0){
	closesocket(s);
	return ERL_DRV_ERROR_GENERAL;
    }
    
    /* OK, the socket is created, lets build the structure. */
    /* Deliberately one more pointer than the quesize specified... */
    ret = my_alloc(sizeof(TraceIpData) + 
		   quesiz * sizeof(TraceIpMessage *));
    
    ret->flags = flags | FLAG_LISTEN_PORT;
    ret->listen_portno = portno;
    ret->listenfd = s;
    ret->fd = INVALID_SOCKET;
    ret->port = port;
    ret->next = first_data;
    ret->quesiz = quesiz+1;
    ret->questart = ret->questop = 0;
    memset(ret->que, 0, ret->quesiz);
    
    first_data = ret;
#ifdef __WIN32__
    ret->listen_event_mask = 0;
    ret->listen_event = 0;
    ret->event_mask = 0;
    ret->event = 0;
#endif
    my_driver_select(ret, s, FLAG_READ, SELECT_ON);
    set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);

    return (ErlDrvData) ret;
}
コード例 #27
0
ファイル: sha_drv.c プロジェクト: Dumbris/MongooseIM
static ErlDrvData sha_drv_start(ErlDrvPort port, char *buf)
{
  set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
  return NULL;
}
コード例 #28
0
ファイル: erlsyslog_drv.c プロジェクト: lemenkov/erlsyslog
static ErlDrvSSizeT syslogdrv_control(ErlDrvData handle, unsigned int command,
                                      char *buf, ErlDrvSizeT len,
                                      char **rbuf, ErlDrvSizeT rlen)
{
    syslogdrv_t* d = (syslogdrv_t*)handle;
    int index = 0, version, arity, type, size;

    if (command != SYSLOGDRV_OPEN) {
        return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
    }

    if (ei_decode_version(buf, &index, &version)) {
        return encode_error(*rbuf, "badver");
    }
    if (ei_decode_tuple_header(buf, &index, &arity) || arity != 4) {
        return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
    }
    if (ei_get_type(buf, &index, &type, &size)) {
        return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
    }
    if (type == ERL_STRING_EXT) {
        long logopt, facility, len;
        ErlDrvBinary* ref = 0;

        syslogdrv_t* nd = (syslogdrv_t*)driver_alloc(sizeof(syslogdrv_t));
        if (nd == NULL) {
            return encode_error(*rbuf, "enomem");
        }
        nd->ident = driver_alloc(size+1);
        if (nd->ident == NULL) {
            return encode_error(*rbuf, "enomem");
        }
        if (ei_decode_string(buf, &index, nd->ident)) {
            driver_free(nd->ident);
            driver_free(nd);
            return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
        }
        if (ei_decode_long(buf, &index, &logopt) ||
            ei_decode_long(buf, &index, &facility)) {
            driver_free(nd->ident);
            driver_free(nd);
            return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
        }
        if (ei_get_type(buf, &index, &type, &size)) {
            driver_free(nd->ident);
            driver_free(nd);
            return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
        }
        if (type != ERL_BINARY_EXT) {
            driver_free(nd->ident);
            driver_free(nd);
            return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
        }
        ref = driver_alloc_binary(size);
        if (ref == NULL) {
            return encode_error(*rbuf, "enomem");
        }
        if (ei_decode_binary(buf, &index, ref->orig_bytes, &len)) {
            driver_free_binary(ref);
            driver_free(nd->ident);
            driver_free(nd);
            return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
        }
        nd->logopt = (int)logopt;
        nd->facility = (int)facility;
        nd->open = 1;
        {
            ErlDrvTermData refdata = TERM_DATA(ref->orig_bytes);
            ErlDrvPort port = d->port;
            ErlDrvTermData pid = driver_caller(port);
            ErlDrvData data = (ErlDrvData)nd;
            nd->port = driver_create_port(port, pid, DRV_NAME, data);
            if (nd->port == (ErlDrvPort)-1) {
                driver_free_binary(ref);
                driver_free(nd->ident);
                driver_free(nd);
                return (ErlDrvSSizeT)ERL_DRV_ERROR_GENERAL;
            }
            set_port_control_flags(nd->port, PORT_CONTROL_FLAG_BINARY);
            ErlDrvTermData term[] = {
                ERL_DRV_EXT2TERM, refdata, ref->orig_size,
                ERL_DRV_ATOM, driver_mk_atom("ok"),
                ERL_DRV_PORT, driver_mk_port(nd->port),
                ERL_DRV_TUPLE, 2,
                ERL_DRV_TUPLE, 2,
            };
            erl_drv_output_term(driver_mk_port(port), term, sizeof term/sizeof *term);
        }
        driver_free_binary(ref);
        return 0;
    } else {
        return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
    }
}