void *erts_sys_ddll_call_nif_init(void *function) { return erts_sys_ddll_call_init(function); }
static int do_load_driver_entry(DE_Handle *dh, char *path, char *name) { void *init_handle; int res; ErlDrvEntry *dp; assert_drv_list_rwlocked(); if ((res = erts_sys_ddll_open(path, &(dh->handle), NULL)) != ERL_DE_NO_ERROR) { return res; } if ((res = erts_sys_ddll_load_driver_init(dh->handle, &init_handle)) != ERL_DE_NO_ERROR) { res = ERL_DE_LOAD_ERROR_NO_INIT; goto error; } dp = erts_sys_ddll_call_init(init_handle); if (dp == NULL) { res = ERL_DE_LOAD_ERROR_FAILED_INIT; goto error; } switch (dp->extended_marker) { case ERL_DRV_EXTENDED_MARKER: if (dp->major_version < ERL_DRV_MIN_REQUIRED_MAJOR_VERSION_ON_LOAD || (ERL_DRV_EXTENDED_MAJOR_VERSION < dp->major_version || (ERL_DRV_EXTENDED_MAJOR_VERSION == dp->major_version && ERL_DRV_EXTENDED_MINOR_VERSION < dp->minor_version))) { /* Incompatible driver version */ res = ERL_DE_LOAD_ERROR_INCORRECT_VERSION; goto error; } break; default: /* Old driver; needs to be recompiled... */ res = ERL_DE_LOAD_ERROR_INCORRECT_VERSION; goto error; } if (strcmp(name, dp->driver_name) != 0) { res = ERL_DE_LOAD_ERROR_BAD_NAME; goto error; } erts_atomic_init_nob(&(dh->refc), (erts_aint_t) 0); erts_atomic32_init_nob(&dh->port_count, 0); dh->full_path = erts_alloc(ERTS_ALC_T_DDLL_HANDLE, sys_strlen(path) + 1); sys_strcpy(dh->full_path, path); dh->flags = 0; dh->status = ERL_DE_OK; if (erts_add_driver_entry(dp, dh, 1) != 0 /* io.c */) { /* * The init in the driver struct did not return 0 */ erts_free(ERTS_ALC_T_DDLL_HANDLE, dh->full_path); dh->full_path = NULL; res = ERL_DE_LOAD_ERROR_FAILED_INIT; goto error; } return ERL_DE_NO_ERROR; error: erts_sys_ddll_close(dh->handle); return res; }