diff --git a/erts/doc/references/driver_entry.md b/erts/doc/references/driver_entry.md index d7e4cf8f6b2c..0a9ea7f4c2cc 100644 --- a/erts/doc/references/driver_entry.md +++ b/erts/doc/references/driver_entry.md @@ -114,14 +114,8 @@ typedef struct erl_drv_entry { int (*init)(void); /* Called at system startup for statically linked drivers, and after loading for dynamically loaded drivers */ -#ifndef ERL_SYS_DRV ErlDrvData (*start)(ErlDrvPort port, char *command); - /* Called when open_port/2 is invoked, - return value -1 means failure */ -#else - ErlDrvData (*start)(ErlDrvPort port, char *command, SysDriverOpts* opts); - /* Special options, only for system driver */ -#endif + /* Called when open_port/2 is invoked */ void (*stop)(ErlDrvData drv_data); /* Called when port is closed, and when the emulator is halted */ diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index f918cbfe6b06..dfbea733b1f3 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -225,7 +225,9 @@ struct erts_driver_t_ { DE_Handle *handle; erts_mtx_t *lock; ErlDrvEntry *entry; - ErlDrvData (*start)(ErlDrvPort port, char *command, SysDriverOpts* opts); + ErlDrvData (*start)(ErlDrvPort port, char *command); + ErlDrvData (*start_sys_drv)(ErlDrvPort port, char *command, + SysDriverOpts* opts); void (*stop)(ErlDrvData drv_data); void (*finish)(void); void (*flush)(ErlDrvData drv_data); diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index a1215883844d..41a02d22296a 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -93,7 +93,7 @@ static erts_atomic64_t bytes_in; static erts_atomic64_t bytes_out; static void deliver_result(Port *p, Eterm sender, Eterm pid, Eterm res); -static int init_driver(erts_driver_t *, ErlDrvEntry *, DE_Handle *); +static int init_driver(erts_driver_t *, ErlDrvEntry *, DE_Handle *, bool); static void terminate_port(Port *p); static void pdl_init(void); static int driver_failure_term(ErlDrvPort ix, Eterm term, int eof); @@ -685,7 +685,7 @@ erts_open_driver(erts_driver_t* driver, /* Pointer to driver. */ &opts->high_msgq_watermark); error_number = error_type = 0; - if (driver->start) { + if (driver->start || driver->start_sys_drv) { ERTS_MSACC_PUSH_STATE_M(); if (ERTS_IS_P_TRACED_FL(port, F_TRACE_SCHED_PORTS)) { trace_sched_ports_where(port, am_in, am_open); @@ -710,7 +710,13 @@ erts_open_driver(erts_driver_t* driver, /* Pointer to driver. */ } #endif - drv_data = (*driver->start)(ERTS_Port2ErlDrvPort(port), name, opts); + if (driver->start_sys_drv) { + drv_data = (*driver->start_sys_drv)(ERTS_Port2ErlDrvPort(port), + name, opts); + } + else { + drv_data = (*driver->start)(ERTS_Port2ErlDrvPort(port), name); + } if (((SWord) drv_data) == -1) error_type = -1; else if (((SWord) drv_data) == -2) { @@ -3024,10 +3030,10 @@ void erts_init_io(int port_tab_size, erts_tsd_set(driver_list_lock_status_key, (void *) 1); erts_rwmtx_rwlock(&erts_driver_list_lock); - init_driver(&fd_driver, &fd_driver_entry, NULL); - init_driver(&spawn_driver, &spawn_driver_entry, NULL); + init_driver(&fd_driver, &fd_driver_entry, NULL, true); + init_driver(&spawn_driver, &spawn_driver_entry, NULL, true); #ifndef __WIN32__ - init_driver(&forker_driver, &forker_driver_entry, NULL); + init_driver(&forker_driver, &forker_driver_entry, NULL, true); #endif erts_init_static_drivers(); for (dp = driver_tab; dp->de != NULL; dp++) @@ -7547,7 +7553,8 @@ no_stop_select_callback(ErlDrvEvent event, void* private) ((DE)->major_version == (MAJOR) && (DE)->minor_version >= (MINOR))) static int -init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle) +init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle, + bool is_system_driver) { drv->name_atom = erts_atom_put((byte*)de->driver_name, sys_strlen(de->driver_name), @@ -7570,7 +7577,14 @@ init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle) } drv->entry = de; - drv->start = de->start; + if (is_system_driver) { + drv->start = NULL; + drv->start_sys_drv = de->start; + } + else { + drv->start = (ErlDrvData (*)(ErlDrvPort, char *)) de->start; + drv->start_sys_drv = NULL; + } drv->stop = de->stop; drv->finish = de->finish; drv->flush = de->flush; @@ -7651,7 +7665,7 @@ int erts_add_driver_entry(ErlDrvEntry *de, DE_Handle *handle, } if (!err) { - err = init_driver(dp, de, handle); + err = init_driver(dp, de, handle, false); if (taint) { erts_add_taint(dp->name_atom);