1 /* 2 * %CopyrightBegin% 3 * 4 * Copyright Ericsson AB 1999-2017. All Rights Reserved. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * %CopyrightEnd% 19 */ 20 21 /* 22 * Include file for erlang driver writers. 23 */ 24 25 #ifndef __ERL_DRIVER_H__ 26 #define __ERL_DRIVER_H__ 27 28 #ifdef HAVE_CONFIG_H 29 # include "config.h" 30 #endif 31 32 #define ERL_DRV_DEPRECATED_FUNC 33 #ifdef __GNUC__ 34 # if __GNUC__ >= 3 35 # undef ERL_DRV_DEPRECATED_FUNC 36 # define ERL_DRV_DEPRECATED_FUNC __attribute__((deprecated)) 37 # endif 38 #endif 39 40 #include "erl_drv_nif.h" 41 42 #include <stdlib.h> 43 44 #if defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_) 45 #ifndef STATIC_ERLANG_DRIVER 46 /* Windows dynamic drivers, everything is different... */ 47 #define ERL_DRIVER_TYPES_ONLY 48 #define WIN32_DYNAMIC_ERL_DRIVER 49 #endif 50 #endif 51 52 #ifndef EXTERN 53 # ifdef __cplusplus 54 # define EXTERN extern "C" 55 # else 56 # define EXTERN extern 57 # endif 58 #endif 59 60 #define ERL_DRV_READ ((int)ERL_NIF_SELECT_READ) 61 #define ERL_DRV_WRITE ((int)ERL_NIF_SELECT_WRITE) 62 #define ERL_DRV_USE ((int)ERL_NIF_SELECT_STOP) 63 #define ERL_DRV_USE_NO_CALLBACK (ERL_DRV_USE | (ERL_DRV_USE << 1)) 64 65 /* Old deprecated */ 66 #define DO_READ ERL_DRV_READ 67 #define DO_WRITE ERL_DRV_WRITE 68 69 #define ERL_DRV_EXTENDED_MARKER (0xfeeeeeed) 70 #define ERL_DRV_EXTENDED_MAJOR_VERSION 3 71 #define ERL_DRV_EXTENDED_MINOR_VERSION 3 72 73 /* 74 * The emulator will refuse to load a driver with a major version 75 * lower than ERL_DRV_MIN_REQUIRED_MAJOR_VERSION_ON_LOAD. The load 76 * may however fail if user have not removed use of deprecated 77 * symbols. 78 * 79 * The ERL_DRV_MIN_REQUIRED_MAJOR_VERSION_ON_LOAD have to allow 80 * loading of drivers built at least two major OTP releases 81 * ago. 82 * 83 * Bump of major version to 3 happened in OTP 17. That is, in 84 * OTP 19 we can increase ERL_DRV_MIN_REQUIRED_MAJOR_VERSION_ON_LOAD 85 * to 3. 86 */ 87 #define ERL_DRV_MIN_REQUIRED_MAJOR_VERSION_ON_LOAD 2 88 89 /* 90 * The emulator will refuse to load a driver with different major 91 * version than the one used by the emulator. 92 */ 93 94 95 /* Values for set_port_control_flags() */ 96 97 #define PORT_CONTROL_FLAG_BINARY (1 << 0) 98 #define PORT_CONTROL_FLAG_HEAVY (1 << 1) 99 100 /* Values for get_port_flags() */ 101 102 #define PORT_FLAG_BINARY (1 << 0) 103 #define PORT_FLAG_LINE (1 << 1) 104 105 106 #define ERL_DRV_FLAG_USE_PORT_LOCKING (1 << 0) 107 #define ERL_DRV_FLAG_SOFT_BUSY (1 << 1) 108 #define ERL_DRV_FLAG_NO_BUSY_MSGQ (1 << 2) 109 #define ERL_DRV_FLAG_USE_INIT_ACK (1 << 3) 110 111 /* 112 * Integer types 113 */ 114 115 typedef ErlNapiUInt64 ErlDrvUInt64; 116 typedef ErlNapiSInt64 ErlDrvSInt64; 117 typedef ErlNapiUInt ErlDrvUInt; 118 typedef ErlNapiSInt ErlDrvSInt; 119 typedef ErlNapiUInt ErlDrvTermData; 120 121 #if defined(__WIN32__) || defined(_WIN32) 122 typedef ErlDrvUInt ErlDrvSizeT; 123 typedef ErlDrvSInt ErlDrvSSizeT; 124 #else 125 typedef size_t ErlDrvSizeT; 126 typedef ssize_t ErlDrvSSizeT; 127 #endif 128 129 /* 130 * A binary as seen in a driver. Note that a binary should never be 131 * altered by the driver when it has been sent to Erlang. 132 */ 133 134 typedef struct erl_drv_binary { 135 ErlDrvSInt orig_size; /* total length of binary */ 136 char orig_bytes[1]; /* the data (char instead of byte!) */ 137 } ErlDrvBinary; 138 139 140 /* 141 * Note: These types are incomplete to catch type errors easier. 142 */ 143 144 typedef struct _erl_drv_data* ErlDrvData; /* Data to be used by the driver itself. */ 145 #ifndef ERL_SYS_DRV 146 typedef struct _erl_drv_event* ErlDrvEvent; /* An event to be selected on. */ 147 #endif 148 typedef struct _erl_drv_port* ErlDrvPort; /* A port descriptor. */ 149 typedef struct _erl_drv_port* ErlDrvThreadData; /* Thread data. */ 150 151 typedef struct { 152 unsigned long megasecs; 153 unsigned long secs; 154 unsigned long microsecs; 155 } ErlDrvNowData; 156 157 typedef ErlDrvSInt64 ErlDrvTime; 158 159 #define ERL_DRV_TIME_ERROR ((ErlDrvSInt64) ERTS_NAPI_TIME_ERROR__) 160 161 typedef enum { 162 ERL_DRV_SEC = ERTS_NAPI_SEC__, 163 ERL_DRV_MSEC = ERTS_NAPI_MSEC__, 164 ERL_DRV_USEC = ERTS_NAPI_USEC__, 165 ERL_DRV_NSEC = ERTS_NAPI_NSEC__ 166 } ErlDrvTimeUnit; 167 168 /* 169 * Error codes that can be return from driver. 170 */ 171 172 /* 173 * Exception code from open_port/2 will be {'EXIT',{einval,Where}}. 174 */ 175 #define ERL_DRV_ERROR_GENERAL ((ErlDrvData) -1) 176 177 /* 178 * Exception code from open_port/2 will be {'EXIT',{Errno,Where}}, 179 * where Errno is a textual representation of the errno variable 180 * (e.g. eacces if errno is EACCES). 181 */ 182 #define ERL_DRV_ERROR_ERRNO ((ErlDrvData) -2) 183 184 /* 185 * Exception code from open_port/2 will be {'EXIT',{badarg,Where}}. 186 */ 187 #define ERL_DRV_ERROR_BADARG ((ErlDrvData) -3) 188 189 typedef struct erl_io_vec { 190 int vsize; /* length of vectors */ 191 ErlDrvSizeT size; /* total size in bytes */ 192 SysIOVec* iov; 193 ErlDrvBinary** binv; 194 } ErlIOVec; 195 196 /* 197 * erl driver thread types 198 */ 199 200 typedef struct ErlDrvTid_ *ErlDrvTid; 201 typedef struct ErlDrvMutex_ ErlDrvMutex; 202 typedef struct ErlDrvCond_ ErlDrvCond; 203 typedef struct ErlDrvRWLock_ ErlDrvRWLock; 204 typedef int ErlDrvTSDKey; 205 206 /* 207 * 208 */ 209 typedef struct erl_drv_port_data_lock * ErlDrvPDL; 210 211 /* 212 * This structure defines a driver. 213 */ 214 215 typedef struct erl_drv_entry { 216 int (*init)(void); /* called at system start up for statically 217 linked drivers, and after loading for 218 dynamically loaded drivers */ 219 220 #ifndef ERL_SYS_DRV 221 ErlDrvData (*start)(ErlDrvPort port, char *command); 222 /* called when open_port/2 is invoked. 223 return value -1 means failure. */ 224 #else 225 ErlDrvData (*start)(ErlDrvPort port, char *command, SysDriverOpts* opts); 226 /* special options, only for system driver */ 227 #endif 228 void (*stop)(ErlDrvData drv_data); 229 /* called when port is closed, and when the 230 emulator is halted. */ 231 void (*output)(ErlDrvData drv_data, char *buf, ErlDrvSizeT len); 232 /* called when we have output from erlang to 233 the port */ 234 void (*ready_input)(ErlDrvData drv_data, ErlDrvEvent event); 235 /* called when we have input from one of 236 the driver's handles */ 237 void (*ready_output)(ErlDrvData drv_data, ErlDrvEvent event); 238 /* called when output is possible to one of 239 the driver's handles */ 240 char *driver_name; /* name supplied as command 241 in open_port XXX ? */ 242 void (*finish)(void); /* called before unloading the driver - 243 DYNAMIC DRIVERS ONLY */ 244 void *handle; /* Reserved -- Used by emulator internally */ 245 ErlDrvSSizeT (*control)(ErlDrvData drv_data, unsigned int command, 246 char *buf, ErlDrvSizeT len, char **rbuf, 247 ErlDrvSizeT rlen); /* "ioctl" for drivers - invoked by 248 port_control/3 */ 249 void (*timeout)(ErlDrvData drv_data); /* Handling of timeout in driver */ 250 void (*outputv)(ErlDrvData drv_data, ErlIOVec *ev); 251 /* called when we have output from erlang 252 to the port */ 253 void (*ready_async)(ErlDrvData drv_data, ErlDrvThreadData thread_data); 254 void (*flush)(ErlDrvData drv_data); 255 /* called when the port is about to be 256 closed, and there is data in the 257 driver queue that needs to be flushed 258 before 'stop' can be called */ 259 ErlDrvSSizeT (*call)(ErlDrvData drv_data, 260 unsigned int command, char *buf, ErlDrvSizeT len, 261 char **rbuf, ErlDrvSizeT rlen, 262 unsigned int *flags); /* Works mostly like 'control', 263 a synchronous 264 call into the driver. */ 265 void (*unused_event_callback)(void); 266 int extended_marker; /* ERL_DRV_EXTENDED_MARKER */ 267 int major_version; /* ERL_DRV_EXTENDED_MAJOR_VERSION */ 268 int minor_version; /* ERL_DRV_EXTENDED_MINOR_VERSION */ 269 int driver_flags; /* ERL_DRV_FLAGs */ 270 void *handle2; /* Reserved -- Used by emulator internally */ 271 void (*process_exit)(ErlDrvData drv_data, ErlDrvMonitor *monitor); 272 /* Called when a process monitor fires */ 273 void (*stop_select)(ErlDrvEvent event, void* reserved); 274 /* Called on behalf of driver_select when 275 it is safe to release 'event'. A typical 276 unix driver would call close(event) */ 277 void (*emergency_close)(ErlDrvData drv_data); 278 /* called when the port is closed abruptly. 279 specifically when erl_crash_dump is called. */ 280 /* When adding entries here, dont forget to pad in obsolete/driver.h */ 281 } ErlDrvEntry; 282 283 /* 284 * This macro is used to name a dynamic driver's init function in 285 * a way that doesn't lead to conflicts. This is crucial when using 286 * operating systems that has one namespace for all symbols 287 * (e.g. VxWorks). Example: if you have an dynamic driver C source 288 * file named echo_drv.c, you use the macro like this: 289 * 290 * DRIVER_INIT(echo_drv) 291 * { 292 * .... 293 * } 294 * 295 * This function will be called by the Erlang I/O system when the driver is loaded. 296 * It must initialize a ErlDrvEntry structure and return a pointer to it. 297 */ 298 299 #ifdef STATIC_ERLANG_DRIVER 300 # define ERLANG_DRIVER_NAME(NAME) NAME ## _driver_init 301 # define ERL_DRIVER_EXPORT 302 #else 303 # define ERLANG_DRIVER_NAME(NAME) driver_init 304 # if defined(__GNUC__) && __GNUC__ >= 4 305 # define ERL_DRIVER_EXPORT __attribute__ ((visibility("default"))) 306 # elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550) 307 # define ERL_DRIVER_EXPORT __global 308 # else 309 # define ERL_DRIVER_EXPORT 310 # endif 311 #endif 312 313 #ifndef ERL_DRIVER_TYPES_ONLY 314 315 #define DRIVER_INIT(DRIVER_NAME) \ 316 ERL_DRIVER_EXPORT ErlDrvEntry* ERLANG_DRIVER_NAME(DRIVER_NAME)(void); \ 317 ERL_DRIVER_EXPORT ErlDrvEntry* ERLANG_DRIVER_NAME(DRIVER_NAME)(void) 318 319 #define ERL_DRV_BUSY_MSGQ_DISABLED (~((ErlDrvSizeT) 0)) 320 #define ERL_DRV_BUSY_MSGQ_READ_ONLY ((ErlDrvSizeT) 0) 321 #define ERL_DRV_BUSY_MSGQ_LIM_MAX (ERL_DRV_BUSY_MSGQ_DISABLED - 1) 322 #define ERL_DRV_BUSY_MSGQ_LIM_MIN ((ErlDrvSizeT) 1) 323 324 /* 325 * These are the functions available for driver writers. 326 */ 327 EXTERN void erl_drv_busy_msgq_limits(ErlDrvPort port, 328 ErlDrvSizeT *low, 329 ErlDrvSizeT *high); 330 331 EXTERN int driver_select(ErlDrvPort port, ErlDrvEvent event, int mode, int on); 332 333 EXTERN int driver_output(ErlDrvPort port, char *buf, ErlDrvSizeT len); 334 EXTERN int driver_output2(ErlDrvPort port, char *hbuf, ErlDrvSizeT hlen, 335 char *buf, ErlDrvSizeT len); 336 EXTERN int driver_output_binary(ErlDrvPort port, char *hbuf, ErlDrvSizeT hlen, 337 ErlDrvBinary* bin, 338 ErlDrvSizeT offset, ErlDrvSizeT len); 339 EXTERN int driver_outputv(ErlDrvPort port, char* hbuf, ErlDrvSizeT hlen, 340 ErlIOVec *ev, ErlDrvSizeT skip); 341 EXTERN ErlDrvSizeT driver_vec_to_buf(ErlIOVec *ev, char *buf, ErlDrvSizeT len); 342 EXTERN int driver_set_timer(ErlDrvPort port, unsigned long time); 343 EXTERN int driver_cancel_timer(ErlDrvPort port); 344 EXTERN int driver_read_timer(ErlDrvPort port, unsigned long *time_left); 345 346 /* 347 * Inform runtime system about lengthy work. 348 */ 349 EXTERN int erl_drv_consume_timeslice(ErlDrvPort port, int percent); 350 351 /* 352 * Get plain-text error message from within a driver 353 */ 354 EXTERN char* erl_errno_id(int error); 355 356 /* 357 * The following functions are used to initiate a close of a port 358 * from a driver. 359 */ 360 EXTERN int driver_failure_eof(ErlDrvPort port); 361 EXTERN int driver_failure_atom(ErlDrvPort port, char *string); 362 EXTERN int driver_failure_posix(ErlDrvPort port, int error); 363 EXTERN int driver_failure(ErlDrvPort port, int error); 364 EXTERN int driver_exit (ErlDrvPort port, int err); 365 366 367 /* 368 * Port Data Lock 369 */ 370 371 EXTERN ErlDrvPDL driver_pdl_create(ErlDrvPort); 372 EXTERN void driver_pdl_lock(ErlDrvPDL); 373 EXTERN void driver_pdl_unlock(ErlDrvPDL); 374 EXTERN ErlDrvSInt driver_pdl_get_refc(ErlDrvPDL); 375 EXTERN ErlDrvSInt driver_pdl_inc_refc(ErlDrvPDL); 376 EXTERN ErlDrvSInt driver_pdl_dec_refc(ErlDrvPDL); 377 378 /* 379 * Process monitors 380 */ 381 EXTERN int 382 driver_monitor_process(ErlDrvPort port, ErlDrvTermData process, 383 ErlDrvMonitor *monitor); 384 EXTERN int 385 driver_demonitor_process(ErlDrvPort port, const ErlDrvMonitor *monitor); 386 EXTERN ErlDrvTermData 387 driver_get_monitored_process(ErlDrvPort port, const ErlDrvMonitor *monitor); 388 EXTERN int driver_compare_monitors(const ErlDrvMonitor *monitor1, 389 const ErlDrvMonitor *monitor2); 390 391 /* 392 * Port attributes 393 */ 394 EXTERN void set_busy_port(ErlDrvPort port, int on); 395 EXTERN void set_port_control_flags(ErlDrvPort port, int flags); 396 397 EXTERN int get_port_flags(ErlDrvPort port); 398 399 400 /* Binary interface */ 401 402 /* 403 * NOTE: DO NOT overwrite a binary with new data (if the data is delivered); 404 * since the binary is a shared object it MUST be written once. 405 */ 406 407 EXTERN ErlDrvBinary* driver_alloc_binary(ErlDrvSizeT size); 408 EXTERN ErlDrvBinary* driver_realloc_binary(ErlDrvBinary *bin, ErlDrvSizeT size); 409 EXTERN void driver_free_binary(ErlDrvBinary *bin); 410 411 /* Referenc count on driver binaries */ 412 EXTERN ErlDrvSInt driver_binary_get_refc(ErlDrvBinary *dbp); 413 EXTERN ErlDrvSInt driver_binary_inc_refc(ErlDrvBinary *dbp); 414 EXTERN ErlDrvSInt driver_binary_dec_refc(ErlDrvBinary *dbp); 415 416 /* Allocation interface */ 417 EXTERN void *driver_alloc(ErlDrvSizeT size); 418 EXTERN void *driver_realloc(void *ptr, ErlDrvSizeT size); 419 EXTERN void driver_free(void *ptr); 420 421 /* Queue interface */ 422 EXTERN int driver_enq(ErlDrvPort port, char* buf, ErlDrvSizeT len); 423 EXTERN int driver_pushq(ErlDrvPort port, char* buf, ErlDrvSizeT len); 424 EXTERN ErlDrvSizeT driver_deq(ErlDrvPort port, ErlDrvSizeT size); 425 EXTERN ErlDrvSizeT driver_sizeq(ErlDrvPort port); 426 EXTERN int driver_enq_bin(ErlDrvPort port, ErlDrvBinary *bin, ErlDrvSizeT offset, 427 ErlDrvSizeT len); 428 EXTERN int driver_pushq_bin(ErlDrvPort port, ErlDrvBinary *bin, ErlDrvSizeT offset, 429 ErlDrvSizeT len); 430 431 EXTERN ErlDrvSizeT driver_peekqv(ErlDrvPort port, ErlIOVec *ev); 432 EXTERN SysIOVec* driver_peekq(ErlDrvPort port, int *vlen); 433 EXTERN int driver_enqv(ErlDrvPort port, ErlIOVec *ev, ErlDrvSizeT skip); 434 EXTERN int driver_pushqv(ErlDrvPort port, ErlIOVec *ev, ErlDrvSizeT skip); 435 436 /* 437 * Add and remove driver entries. 438 */ 439 EXTERN void add_driver_entry(ErlDrvEntry *de); 440 EXTERN int remove_driver_entry(ErlDrvEntry *de); 441 442 /* 443 * System info 444 */ 445 EXTERN void driver_system_info(ErlDrvSysInfo *sip, size_t si_size); 446 447 /* 448 * erl driver thread functions. 449 */ 450 451 EXTERN ErlDrvMutex *erl_drv_mutex_create(char *name); 452 EXTERN void erl_drv_mutex_destroy(ErlDrvMutex *mtx); 453 EXTERN int erl_drv_mutex_trylock(ErlDrvMutex *mtx); 454 EXTERN void erl_drv_mutex_lock(ErlDrvMutex *mtx); 455 EXTERN void erl_drv_mutex_unlock(ErlDrvMutex *mtx); 456 EXTERN ErlDrvCond *erl_drv_cond_create(char *name); 457 EXTERN void erl_drv_cond_destroy(ErlDrvCond *cnd); 458 EXTERN void erl_drv_cond_signal(ErlDrvCond *cnd); 459 EXTERN void erl_drv_cond_broadcast(ErlDrvCond *cnd); 460 EXTERN void erl_drv_cond_wait(ErlDrvCond *cnd, ErlDrvMutex *mtx); 461 EXTERN ErlDrvRWLock *erl_drv_rwlock_create(char *name); 462 EXTERN void erl_drv_rwlock_destroy(ErlDrvRWLock *rwlck); 463 EXTERN int erl_drv_rwlock_tryrlock(ErlDrvRWLock *rwlck); 464 EXTERN void erl_drv_rwlock_rlock(ErlDrvRWLock *rwlck); 465 EXTERN void erl_drv_rwlock_runlock(ErlDrvRWLock *rwlck); 466 EXTERN int erl_drv_rwlock_tryrwlock(ErlDrvRWLock *rwlck); 467 EXTERN void erl_drv_rwlock_rwlock(ErlDrvRWLock *rwlck); 468 EXTERN void erl_drv_rwlock_rwunlock(ErlDrvRWLock *rwlck); 469 EXTERN int erl_drv_tsd_key_create(char *name, ErlDrvTSDKey *key); 470 EXTERN void erl_drv_tsd_key_destroy(ErlDrvTSDKey key); 471 EXTERN void erl_drv_tsd_set(ErlDrvTSDKey key, void *data); 472 EXTERN void *erl_drv_tsd_get(ErlDrvTSDKey key); 473 EXTERN ErlDrvThreadOpts *erl_drv_thread_opts_create(char *name); 474 EXTERN void erl_drv_thread_opts_destroy(ErlDrvThreadOpts *opts); 475 EXTERN int erl_drv_thread_create(char *name, 476 ErlDrvTid *tid, 477 void * (*func)(void *), 478 void *args, 479 ErlDrvThreadOpts *opts); 480 EXTERN ErlDrvTid erl_drv_thread_self(void); 481 EXTERN int erl_drv_equal_tids(ErlDrvTid tid1, ErlDrvTid tid2); 482 EXTERN void erl_drv_thread_exit(void *resp); 483 EXTERN int erl_drv_thread_join(ErlDrvTid, void **respp); 484 485 EXTERN char* erl_drv_mutex_name(ErlDrvMutex *mtx); 486 EXTERN char* erl_drv_cond_name(ErlDrvCond *cnd); 487 EXTERN char* erl_drv_rwlock_name(ErlDrvRWLock *rwlck); 488 EXTERN char* erl_drv_thread_name(ErlDrvTid tid); 489 490 /* 491 * Misc. 492 */ 493 EXTERN int null_func(void); 494 495 #endif /* !ERL_DRIVER_TYPES_ONLY */ 496 497 /* Constants for return flags from the 'port_call' callback */ 498 #define DRIVER_CALL_KEEP_BUFFER 0x1 499 500 /* ErlDrvTerm is the type to use for casts when building 501 * terms that should be sent to connected process, 502 * for instance a tuple on the form {tcp, Port, [Tag|Binary]} 503 * 504 * ErlDrvTerm spec[] = { 505 * ERL_DRV_ATOM, driver_mk_atom("tcp"), 506 * ERL_DRV_PORT, driver_mk_port(drv->ix), 507 * ERL_DRV_INT, REPLY_TAG, 508 * ERL_DRV_BINARY, (ErlDrvTerm)bin, 50, 0, 509 * ERL_DRV_LIST, 2, 510 * ERL_DRV_TUPLE, 3, 511 * } 512 * 513 */ 514 515 #define TERM_DATA(x) ((ErlDrvTermData) (x)) 516 517 /* Possible types to send from driver Argument type */ 518 #define ERL_DRV_NIL ((ErlDrvTermData) 1) /* None */ 519 #define ERL_DRV_ATOM ((ErlDrvTermData) 2) /* driver_mk_atom(string) */ 520 #define ERL_DRV_INT ((ErlDrvTermData) 3) /* ErlDrvSInt */ 521 #define ERL_DRV_PORT ((ErlDrvTermData) 4) /* driver_mk_port(ix) */ 522 #define ERL_DRV_BINARY ((ErlDrvTermData) 5) /* ErlDrvBinary*, 523 * ErlDrvUInt size, 524 * ErlDrvUInt offs */ 525 #define ERL_DRV_STRING ((ErlDrvTermData) 6) /* char*, ErlDrvUInt */ 526 #define ERL_DRV_TUPLE ((ErlDrvTermData) 7) /* ErlDrvUInt */ 527 #define ERL_DRV_LIST ((ErlDrvTermData) 8) /* ErlDrvUInt */ 528 #define ERL_DRV_STRING_CONS ((ErlDrvTermData) 9) /* char*, ErlDrvUInt */ 529 #define ERL_DRV_PID ((ErlDrvTermData) 10) /* driver_connected,... */ 530 531 #define ERL_DRV_FLOAT ((ErlDrvTermData) 11) /* double * */ 532 #define ERL_DRV_EXT2TERM ((ErlDrvTermData) 12) /* char *, ErlDrvUInt */ 533 #define ERL_DRV_UINT ((ErlDrvTermData) 13) /* ErlDrvUInt */ 534 #define ERL_DRV_BUF2BINARY ((ErlDrvTermData) 14) /* char *, ErlDrvUInt */ 535 #define ERL_DRV_INT64 ((ErlDrvTermData) 15) /* ErlDrvSInt64 * */ 536 #define ERL_DRV_UINT64 ((ErlDrvTermData) 16) /* ErlDrvUInt64 * */ 537 538 #define ERL_DRV_MAP ((ErlDrvTermData) 17) /* ErlDrvUInt */ 539 540 #ifndef ERL_DRIVER_TYPES_ONLY 541 542 /* make terms for driver_output_term and driver_send_term */ 543 EXTERN ErlDrvTermData driver_mk_atom(char*); 544 EXTERN ErlDrvTermData driver_mk_port(ErlDrvPort); 545 EXTERN ErlDrvTermData driver_connected(ErlDrvPort); 546 EXTERN ErlDrvTermData driver_caller(ErlDrvPort); 547 extern const ErlDrvTermData driver_term_nil; 548 EXTERN ErlDrvTermData driver_mk_term_nil(void); 549 EXTERN ErlDrvPort driver_create_port(ErlDrvPort creator_port, 550 ErlDrvTermData connected, /* pid */ 551 char* name, /* driver name */ 552 ErlDrvData drv_data); 553 554 555 /* 556 * driver_output_term() is deprecated, and scheduled for removal in 557 * OTP-R17. Use erl_drv_output_term() instead. For more information 558 * see the erl_driver(3) documentation. 559 */ 560 EXTERN int driver_output_term(ErlDrvPort ix, 561 ErlDrvTermData* data, 562 int len) ERL_DRV_DEPRECATED_FUNC; 563 /* 564 * driver_send_term() is deprecated, and scheduled for removal in 565 * OTP-R17. Use erl_drv_send_term() instead. For more information 566 * see the erl_driver(3) documentation. 567 */ 568 EXTERN int driver_send_term(ErlDrvPort ix, 569 ErlDrvTermData to, 570 ErlDrvTermData* data, 571 int len) ERL_DRV_DEPRECATED_FUNC; 572 573 /* output term data to the port owner */ 574 EXTERN int erl_drv_output_term(ErlDrvTermData port, 575 ErlDrvTermData* data, 576 int len); 577 /* output term data to a specific process */ 578 EXTERN int erl_drv_send_term(ErlDrvTermData port, 579 ErlDrvTermData to, 580 ErlDrvTermData* data, 581 int len); 582 583 /* Async IO functions */ 584 EXTERN unsigned int driver_async_port_key(ErlDrvPort port); 585 586 EXTERN long driver_async(ErlDrvPort ix, 587 unsigned int* key, 588 void (*async_invoke)(void*), 589 void* async_data, 590 void (*async_free)(void*)); 591 592 /* Locks the driver in the machine "forever", there is 593 no unlock function. Note that this is almost never useful, as an open 594 port towards the driver locks it until the port is closed, why unexpected 595 unloading "never" happens. */ 596 EXTERN int driver_lock_driver(ErlDrvPort ix); 597 598 /* Get the current 'now' timestamp (analogue to erlang:now()) */ 599 EXTERN int driver_get_now(ErlDrvNowData *now) ERL_DRV_DEPRECATED_FUNC; 600 601 /* Erlang Monotonic Time */ 602 EXTERN ErlDrvTime erl_drv_monotonic_time(ErlDrvTimeUnit time_unit); 603 /* Time offset between Erlang Monotonic Time and Erlang System Time */ 604 EXTERN ErlDrvTime erl_drv_time_offset(ErlDrvTimeUnit time_unit); 605 /* Time unit conversion */ 606 EXTERN ErlDrvTime erl_drv_convert_time_unit(ErlDrvTime val, 607 ErlDrvTimeUnit from, 608 ErlDrvTimeUnit to); 609 610 /* These were removed from the ANSI version, now they're back. */ 611 612 EXTERN void *driver_dl_open(char *); 613 EXTERN void *driver_dl_sym(void *, char *); 614 EXTERN int driver_dl_close(void *); 615 EXTERN char *driver_dl_error(void); 616 617 /* environment */ 618 EXTERN int erl_drv_putenv(const char *key, char *value); 619 EXTERN int erl_drv_getenv(const char *key, char *value, size_t *value_size); 620 621 /* spawn start init ack */ 622 EXTERN void erl_drv_init_ack(ErlDrvPort ix, ErlDrvData res); 623 624 /* set the pid seen in port_info */ 625 EXTERN void erl_drv_set_os_pid(ErlDrvPort ix, ErlDrvSInt pid); 626 627 #endif /* !ERL_DRIVER_TYPES_ONLY */ 628 629 #ifdef WIN32_DYNAMIC_ERL_DRIVER 630 # include "erl_win_dyn_driver.h" 631 #endif 632 633 #endif 634 635 /* also in global.h, but driver's can't include global.h */ 636 void dtrace_drvport_str(ErlDrvPort port, char *port_buf); 637