aboutsummaryrefslogblamecommitdiffstats
path: root/erts/emulator/test/driver_SUITE_data/io_ready_exit_drv.c
blob: 11ccd2574eb7868c094c6f80328fa52fd85a33fd (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11










                                                                           








                                                                         
                       





















                                                                


                                                                       













                                               










                                   

























                                                                            
                                                               
























                                                                    
                   

                                               

                                                        


                  
                         








                                                                
                                            
                                  
                                                               


















                                                      
/* ``Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * The Initial Developer of the Original Code is Ericsson Utvecklings AB.
 * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
 * AB. All Rights Reserved.''
 * 
 *     $Id$
 */

#ifndef UNIX
#if !defined(__WIN32__)
#define UNIX 1
#endif
#endif

#include <stdio.h>
#include <string.h>
#ifdef UNIX
#include <unistd.h>
#endif
#include "erl_driver.h"

typedef struct {
    ErlDrvPort port;
    int fds[2];
} IOReadyExitDrvData;

static ErlDrvData io_ready_exit_drv_start(ErlDrvPort, char *);
static void io_ready_exit_drv_stop(ErlDrvData);
static void io_ready_exit_ready_input(ErlDrvData, ErlDrvEvent);
static void io_ready_exit_ready_output(ErlDrvData, ErlDrvEvent);
static void io_ready_exit_drv_output(ErlDrvData, char *, int);
static void io_ready_exit_drv_finish(void);
static ErlDrvSSizeT io_ready_exit_drv_control(ErlDrvData, unsigned int,
					      char *, ErlDrvSizeT,
					      char **, ErlDrvSizeT);

static ErlDrvEntry io_ready_exit_drv_entry = { 
    NULL, /* init */
    io_ready_exit_drv_start,
    io_ready_exit_drv_stop,
    NULL /* output */,
    io_ready_exit_ready_input,
    io_ready_exit_ready_output,
    "io_ready_exit_drv",
    NULL /* finish */,
    NULL, /* handle */
    io_ready_exit_drv_control,
    NULL, /* timeout */
    NULL, /* outputv */
    NULL, /* ready_async */
    NULL, /* flush */
    NULL, /* call */
    NULL, /* event */
    ERL_DRV_EXTENDED_MARKER,
    ERL_DRV_EXTENDED_MAJOR_VERSION,
    ERL_DRV_EXTENDED_MINOR_VERSION,
    0, /* ERL_DRV_FLAGs */
    NULL, /* handle2 */
    NULL, /* process_exit */
    NULL  /* stop_select */
};

/* -------------------------------------------------------------------------
** Entry functions
**/

DRIVER_INIT(io_ready_exit_drv)
{
    return &io_ready_exit_drv_entry;
}

static ErlDrvData
io_ready_exit_drv_start(ErlDrvPort port, char *command) {
    IOReadyExitDrvData *oeddp = driver_alloc(sizeof(IOReadyExitDrvData));
    oeddp->port = port;
    oeddp->fds[0] = -1;
    oeddp->fds[1] = -1;
    return (ErlDrvData) oeddp;
}

static void
io_ready_exit_drv_stop(ErlDrvData drv_data) {
    IOReadyExitDrvData *oeddp = (IOReadyExitDrvData *) drv_data;
#ifdef UNIX
    if (oeddp->fds[0] >= 0) {
	driver_select(oeddp->port,
		      (ErlDrvEvent) (ErlDrvSInt) oeddp->fds[0],
		      DO_READ|DO_WRITE,
		      0);
	close(oeddp->fds[0]);
    }
    if (oeddp->fds[1] >= 0)
	close(oeddp->fds[1]);
#endif
    driver_free((void *) oeddp);
}


static void
io_ready_exit_ready_output(ErlDrvData drv_data, ErlDrvEvent event)
{
    IOReadyExitDrvData *oeddp = (IOReadyExitDrvData *) drv_data;
    driver_failure_atom(oeddp->port, "ready_output_driver_failure");
}

static void
io_ready_exit_ready_input(ErlDrvData drv_data, ErlDrvEvent event)
{
    IOReadyExitDrvData *oeddp = (IOReadyExitDrvData *) drv_data;
    driver_failure_atom(oeddp->port, "ready_input_driver_failure");
}

static ErlDrvSSizeT
io_ready_exit_drv_control(ErlDrvData drv_data,
			  unsigned int command,
			  char *buf, ErlDrvSizeT len,
			  char **rbuf, ErlDrvSizeT rlen)
{
    char *abuf;
    char *res_str;
    ErlDrvSSizeT res_len;
    IOReadyExitDrvData *oeddp = (IOReadyExitDrvData *) drv_data;
#ifndef UNIX
    res_str = "nyiftos";
#else
    if (pipe(oeddp->fds) < 0) {
	res_str = "pipe failed";
    }
    else {
	res_str = "ok";
	(void) write(oeddp->fds[1], "!", 1);
	driver_select(oeddp->port,
		      (ErlDrvEvent) (ErlDrvSInt) oeddp->fds[0],
		      DO_READ|DO_WRITE,
		      1);
    }
#endif
    res_len = strlen(res_str);
    if (res_len > rlen) {
	abuf = driver_alloc(sizeof(char)*res_len);
	if (!abuf)
	    return 0;
	*rbuf = abuf;
    }

    memcpy((void *) *rbuf, (void *) res_str, res_len);

    return res_len;
}