1 /* 2 * %CopyrightBegin% 3 * 4 * Copyright Ericsson AB 1998-2016. 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 #ifndef EI_H 21 #define EI_H 22 23 #define EI_HAVE_TIMEOUT 1 /* Flag to user code that we have them */ 24 #define USE_EI_UNDOCUMENTED /* Want declarations for undocumented */ 25 26 /************************************************************************/ 27 /* This file defines the complete interface to ei */ 28 /************************************************************************/ 29 30 /* -------------------------------------------------------------------- */ 31 /* Include types needed below */ 32 /* -------------------------------------------------------------------- */ 33 34 #if defined(__WIN32__) 35 #include <winsock2.h> 36 #include <windows.h> 37 #include <winbase.h> 38 typedef LONG_PTR ssize_t; /* Sigh... */ 39 #else 40 #include <sys/types.h> /* ssize_t */ 41 #endif 42 43 #include <stdio.h> /* Need type FILE */ 44 #include <errno.h> /* Need EHOSTUNREACH, ENOMEM, ... */ 45 46 #if !(defined(__WIN32__) || defined(_WIN32)) && !defined(VXWORKS) || (defined(VXWORKS) && defined(HAVE_SENS)) 47 # include <netdb.h> 48 #endif 49 50 51 /* -------------------------------------------------------------------- */ 52 /* Defines part of API */ 53 /* -------------------------------------------------------------------- */ 54 55 /* 56 * Some error codes might be missing, so here's a backstop definitions 57 * of the ones we use with `erl_errno': 58 */ 59 60 #ifndef EMSGSIZE /* Message too long */ 61 #define EMSGSIZE EIO 62 #endif 63 64 #ifndef ETIMEDOUT /* Connection timed out */ 65 #define ETIMEDOUT EIO 66 #endif 67 68 #ifndef EHOSTUNREACH /* No route to host */ 69 #define EHOSTUNREACH EIO 70 #endif 71 72 /* FIXME just a few are documented, does it mean they can't be returned? */ 73 74 #define ERL_ERROR -1 /* Error of some kind */ 75 #define ERL_NO_DAEMON -2 /* No contact with EPMD */ 76 #define ERL_NO_PORT -3 /* No port received from EPMD */ 77 #define ERL_CONNECT_FAIL -4 /* Connect to Erlang Node failed */ 78 #define ERL_TIMEOUT -5 /* A timeout has expired */ 79 #define ERL_NO_REMOTE -6 /* Cannot execute rsh */ 80 81 #define ERL_TICK 0 82 #define ERL_MSG 1 83 84 #define ERL_NO_TIMEOUT -1 85 86 /* these are the control message types */ 87 #define ERL_LINK 1 88 #define ERL_SEND 2 89 #define ERL_EXIT 3 90 #define ERL_UNLINK 4 91 #define ERL_NODE_LINK 5 92 #define ERL_REG_SEND 6 93 #define ERL_GROUP_LEADER 7 94 #define ERL_EXIT2 8 95 #define ERL_PASS_THROUGH 'p' 96 97 /* new ones for tracing, from Kenneth */ 98 #define ERL_SEND_TT 12 99 #define ERL_EXIT_TT 13 100 #define ERL_REG_SEND_TT 16 101 #define ERL_EXIT2_TT 18 102 #define ERL_MONITOR_P 19 103 #define ERL_DEMONITOR_P 20 104 #define ERL_MONITOR_P_EXIT 21 105 106 107 /* -------------------------------------------------------------------- */ 108 /* Defines used for ei_get_type_internal() output */ 109 /* -------------------------------------------------------------------- */ 110 /* 111 * these are the term type indicators used in 112 * the external (distribution) format 113 */ 114 115 /* FIXME we don't want to export these..... */ 116 117 #define ERL_SMALL_INTEGER_EXT 'a' 118 #define ERL_INTEGER_EXT 'b' 119 #define ERL_FLOAT_EXT 'c' 120 #define NEW_FLOAT_EXT 'F' 121 #define ERL_ATOM_EXT 'd' 122 #define ERL_SMALL_ATOM_EXT 's' 123 #define ERL_ATOM_UTF8_EXT 'v' 124 #define ERL_SMALL_ATOM_UTF8_EXT 'w' 125 #define ERL_REFERENCE_EXT 'e' 126 #define ERL_NEW_REFERENCE_EXT 'r' 127 #define ERL_NEWER_REFERENCE_EXT 'Z' 128 #define ERL_PORT_EXT 'f' 129 #define ERL_NEW_PORT_EXT 'Y' 130 #define ERL_PID_EXT 'g' 131 #define ERL_NEW_PID_EXT 'X' 132 #define ERL_SMALL_TUPLE_EXT 'h' 133 #define ERL_LARGE_TUPLE_EXT 'i' 134 #define ERL_NIL_EXT 'j' 135 #define ERL_STRING_EXT 'k' 136 #define ERL_LIST_EXT 'l' 137 #define ERL_BINARY_EXT 'm' 138 #define ERL_SMALL_BIG_EXT 'n' 139 #define ERL_LARGE_BIG_EXT 'o' 140 #define ERL_NEW_FUN_EXT 'p' 141 #define ERL_MAP_EXT 't' 142 #define ERL_FUN_EXT 'u' 143 144 #define ERL_NEW_CACHE 'N' /* c nodes don't know these two */ 145 #define ERL_CACHED_ATOM 'C' 146 147 148 /* -------------------------------------------------------------------- */ 149 /* Define the erl_errno macro */ 150 /* -------------------------------------------------------------------- */ 151 152 #ifdef __cplusplus 153 extern "C" { 154 #endif 155 156 /* 157 * GCC's attributes are too useful to not use. Other compilers 158 * just lose opportunities to optimize and warn. 159 */ 160 #if !defined(__GNUC__) || __GNUC__ < 2 161 # define __attribute__(foo) /* nothing */ 162 #endif 163 164 /* 165 * Define the 'erl_errno' facility. Unfortunately this lives on in 166 * the 'ei' interface as well.... :-( 167 */ 168 169 #if defined(_REENTRANT) || defined(VXWORKS) || defined(__WIN32__) 170 171 /* 'erl_errno' as a function return value */ 172 volatile int* __erl_errno_place(void) __attribute__ ((__const__)); 173 174 #define erl_errno (*__erl_errno_place ()) 175 176 #else /* !_REENTRANT && !VXWORKS && !__WIN32__ */ 177 178 extern volatile int __erl_errno; 179 180 #define erl_errno __erl_errno 181 182 #endif /* !_REENTRANT && !VXWORKS && !__WIN32__ */ 183 184 185 /* -------------------------------------------------------------------- */ 186 /* Type definitions */ 187 /* -------------------------------------------------------------------- */ 188 189 /* 190 * To avoid confusion about the MAXHOSTNAMELEN when compiling the 191 * library and when using the library we set a value that we use 192 */ 193 194 #define EI_MAX_COOKIE_SIZE 512 195 #define MAXATOMLEN (255 + 1) 196 #define MAXATOMLEN_UTF8 (255*4 + 1) 197 #define EI_MAXHOSTNAMELEN (MAXATOMLEN - 2) 198 #define EI_MAXALIVELEN (MAXATOMLEN - 2) 199 #define MAXNODELEN MAXATOMLEN 200 201 typedef enum { 202 ERLANG_ASCII = 1, 203 ERLANG_LATIN1 = 2, 204 ERLANG_UTF8 = 4 205 }erlang_char_encoding; 206 207 /* a pid */ 208 typedef struct { 209 char node[MAXATOMLEN_UTF8]; 210 unsigned int num; 211 unsigned int serial; 212 unsigned int creation; 213 } erlang_pid; 214 215 /* a port */ 216 typedef struct { 217 char node[MAXATOMLEN_UTF8]; 218 unsigned int id; 219 unsigned int creation; 220 } erlang_port; 221 222 /* a ref */ 223 typedef struct { 224 char node[MAXATOMLEN_UTF8]; 225 int len; 226 unsigned int n[3]; 227 unsigned int creation; 228 } erlang_ref; 229 230 /* a trace token */ 231 typedef struct { 232 long serial; 233 long prev; 234 erlang_pid from; 235 long label; 236 long flags; 237 } erlang_trace; 238 239 /* a message */ 240 typedef struct { 241 long msgtype; 242 erlang_pid from; 243 erlang_pid to; 244 char toname[MAXATOMLEN_UTF8]; 245 char cookie[MAXATOMLEN_UTF8]; 246 erlang_trace token; 247 } erlang_msg; 248 249 /* a fun */ 250 typedef struct { 251 long arity; 252 char module[MAXATOMLEN_UTF8]; 253 erlang_char_encoding module_org_enc; 254 char md5[16]; 255 long index; 256 long old_index; 257 long uniq; 258 long n_free_vars; 259 erlang_pid pid; 260 long free_var_len; 261 char* free_vars; 262 } erlang_fun; 263 264 /* a big */ 265 typedef struct { 266 unsigned int arity; 267 int is_neg; 268 void *digits; 269 } erlang_big; 270 271 typedef struct { 272 char ei_type; 273 int arity; 274 int size; 275 union { 276 long i_val; 277 double d_val; 278 char atom_name[MAXATOMLEN_UTF8]; 279 erlang_pid pid; 280 erlang_port port; 281 erlang_ref ref; 282 } value; 283 } ei_term; 284 285 /* XXX */ 286 287 typedef struct { 288 char ipadr[4]; /* stored in network byte order */ 289 char nodename[MAXNODELEN+1]; 290 } ErlConnect; 291 292 #define EI_SCLBK_INF_TMO (~((unsigned) 0)) 293 294 #define EI_SCLBK_FLG_FULL_IMPL (1 << 0) 295 296 typedef struct { 297 int flags; 298 299 int (*socket)(void **ctx, void *setup_ctx); 300 int (*close)(void *ctx); 301 int (*listen)(void *ctx, void *addr, int *len, int backlog); 302 int (*accept)(void **ctx, void *addr, int *len, unsigned tmo); 303 int (*connect)(void *ctx, void *addr, int len, unsigned tmo); 304 int (*writev)(void *ctx, const void *iov, int iovcnt, ssize_t *len, unsigned tmo); 305 int (*write)(void *ctx, const char *buf, ssize_t *len, unsigned tmo); 306 int (*read)(void *ctx, char *buf, ssize_t *len, unsigned tmo); 307 308 int (*handshake_packet_header_size)(void *ctx, int *sz); 309 int (*connect_handshake_complete)(void *ctx); 310 int (*accept_handshake_complete)(void *ctx); 311 int (*get_fd)(void *ctx, int *fd); 312 313 /* end of version 1 */ 314 315 } ei_socket_callbacks; 316 317 typedef struct ei_cnode_s { 318 char thishostname[EI_MAXHOSTNAMELEN+1]; 319 char thisnodename[MAXNODELEN+1]; 320 char thisalivename[EI_MAXALIVELEN+1]; 321 /* Currently this_ipaddr isn't used */ 322 /* struct in_addr this_ipaddr; */ 323 char ei_connect_cookie[EI_MAX_COOKIE_SIZE+1]; 324 short creation; 325 erlang_pid self; 326 ei_socket_callbacks *cbs; 327 void *setup_context; 328 } ei_cnode; 329 330 typedef struct in_addr *Erl_IpAddr; 331 332 333 /* A dynamic version of ei XX */ 334 335 typedef struct ei_x_buff_TAG { 336 char* buff; 337 int buffsz; 338 int index; 339 } ei_x_buff; 340 341 /* -------------------------------------------------------------------- */ 342 /* Function definitions (listed in same order as documentation) */ 343 /* -------------------------------------------------------------------- */ 344 345 /* Handle the connection */ 346 347 int ei_connect_init(ei_cnode* ec, const char* this_node_name, 348 const char *cookie, short creation); 349 int ei_connect_xinit (ei_cnode* ec, const char *thishostname, 350 const char *thisalivename, const char *thisnodename, 351 Erl_IpAddr thisipaddr, const char *cookie, 352 const short creation); 353 354 int ei_connect_init_ussi(ei_cnode* ec, const char* this_node_name, 355 const char *cookie, short creation, 356 ei_socket_callbacks *cbs, int cbs_sz, 357 void *setup_context); 358 int ei_connect_xinit_ussi(ei_cnode* ec, const char *thishostname, 359 const char *thisalivename, const char *thisnodename, 360 Erl_IpAddr thisipaddr, const char *cookie, 361 const short creation, ei_socket_callbacks *cbs, 362 int cbs_sz, void *setup_context); 363 364 int ei_connect(ei_cnode* ec, char *nodename); 365 int ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned ms); 366 int ei_xconnect(ei_cnode* ec, Erl_IpAddr adr, char *alivename); 367 int ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr adr, char *alivename, unsigned ms); 368 369 int ei_receive(int fd, unsigned char *bufp, int bufsize); 370 int ei_receive_tmo(int fd, unsigned char *bufp, int bufsize, unsigned ms); 371 int ei_receive_msg(int fd, erlang_msg* msg, ei_x_buff* x); 372 int ei_receive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned ms); 373 int ei_xreceive_msg(int fd, erlang_msg* msg, ei_x_buff* x); 374 int ei_xreceive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned ms); 375 376 int ei_send(int fd, erlang_pid* to, char* buf, int len); 377 int ei_send_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned ms); 378 int ei_reg_send(ei_cnode* ec, int fd, char *server_name, char* buf, int len); 379 int ei_reg_send_tmo(ei_cnode* ec, int fd, char *server_name, char* buf, int len, unsigned ms); 380 381 int ei_rpc(ei_cnode* ec, int fd, char *mod, char *fun, 382 const char* inbuf, int inbuflen, ei_x_buff* x); 383 int ei_rpc_to(ei_cnode* ec, int fd, char *mod, char *fun, 384 const char* buf, int len); 385 int ei_rpc_from(ei_cnode* ec, int fd, int timeout, erlang_msg* msg, 386 ei_x_buff* x); 387 388 int ei_publish(ei_cnode* ec, int port); 389 int ei_publish_tmo(ei_cnode* ec, int port, unsigned ms); 390 int ei_listen(ei_cnode *ec, int *port, int backlog); 391 int ei_xlisten(ei_cnode *ec, Erl_IpAddr adr, int *port, int backlog); 392 int ei_accept(ei_cnode* ec, int lfd, ErlConnect *conp); 393 int ei_accept_tmo(ei_cnode* ec, int lfd, ErlConnect *conp, unsigned ms); 394 int ei_unpublish(ei_cnode* ec); 395 int ei_unpublish_tmo(const char *alive, unsigned ms); 396 397 int ei_close_connection(int fd); 398 399 const char *ei_thisnodename(const ei_cnode* ec); 400 const char *ei_thishostname(const ei_cnode* ec); 401 const char *ei_thisalivename(const ei_cnode* ec); 402 403 erlang_pid *ei_self(ei_cnode* ec); 404 405 /* 406 * settings 407 */ 408 409 void ei_set_compat_rel(unsigned rel); 410 void ei_set_tracelevel(int); 411 int ei_get_tracelevel(void); 412 413 /* 414 * We have erl_gethost*() so we include ei versions as well. 415 */ 416 417 #if defined(VXWORKS) 418 419 extern int h_errno; 420 421 /* 422 * We need these definitions - if the user has SENS then he gets them 423 * from netdb.h, otherwise we define them ourselves. 424 * 425 * If you are getting "multiple definition" errors here, 426 * make sure you have included <netdb.h> BEFORE "erl_interface.h" 427 * or define HAVE_SENS in your CFLAGS. 428 */ 429 430 #if !defined(HAVE_SENS) && !defined(HOST_NOT_FOUND) /* just in case */ 431 432 struct hostent { 433 char *h_name; /* official name of host */ 434 char **h_aliases; /* alias list */ 435 int h_addrtype; /* host address type */ 436 int h_length; /* length of address */ 437 char **h_addr_list; /* list of addresses from name server */ 438 #define h_addr h_addr_list[0] /* address, for backward compatiblity */ 439 unsigned int unused; /* SENS defines this as ttl */ 440 }; 441 442 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ 443 #define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */ 444 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ 445 #define NO_DATA 4 /* Valid name, no data record of requested type */ 446 #define NO_ADDRESS NO_DATA /* no address, look for MX record */ 447 448 #endif /* !HAVE_SENS && !HOST_NOT_FOUND */ 449 #endif /* VXWORKS */ 450 451 452 struct hostent *ei_gethostbyname(const char *name); 453 struct hostent *ei_gethostbyaddr(const char *addr, int len, int type); 454 struct hostent *ei_gethostbyname_r(const char *name, 455 struct hostent *hostp, 456 char *buffer, 457 int buflen, 458 int *h_errnop); 459 struct hostent *ei_gethostbyaddr_r(const char *addr, 460 int length, 461 int type, 462 struct hostent *hostp, 463 char *buffer, 464 int buflen, 465 int *h_errnop); 466 467 468 /* Encode/decode functions */ 469 470 int ei_encode_version(char *buf, int *index); 471 int ei_x_encode_version(ei_x_buff* x); 472 int ei_encode_long(char *buf, int *index, long p); 473 int ei_x_encode_long(ei_x_buff* x, long n); 474 int ei_encode_ulong(char *buf, int *index, unsigned long p); 475 int ei_x_encode_ulong(ei_x_buff* x, unsigned long n); 476 int ei_encode_double(char *buf, int *index, double p); 477 int ei_x_encode_double(ei_x_buff* x, double dbl); 478 int ei_encode_boolean(char *buf, int *index, int p); 479 int ei_x_encode_boolean(ei_x_buff* x, int p); 480 int ei_encode_char(char *buf, int *index, char p); 481 int ei_x_encode_char(ei_x_buff* x, char p); 482 int ei_encode_string(char *buf, int *index, const char *p); 483 int ei_encode_string_len(char *buf, int *index, const char *p, int len); 484 int ei_x_encode_string(ei_x_buff* x, const char* s); 485 int ei_x_encode_string_len(ei_x_buff* x, const char* s, int len); 486 int ei_encode_atom(char *buf, int *index, const char *p); 487 int ei_encode_atom_as(char *buf, int *index, const char *p, 488 erlang_char_encoding from, erlang_char_encoding to); 489 int ei_encode_atom_len(char *buf, int *index, const char *p, int len); 490 int ei_encode_atom_len_as(char *buf, int *index, const char *p, int len, 491 erlang_char_encoding from, erlang_char_encoding to); 492 int ei_x_encode_atom(ei_x_buff* x, const char* s); 493 int ei_x_encode_atom_as(ei_x_buff* x, const char* s, 494 erlang_char_encoding from, erlang_char_encoding to); 495 int ei_x_encode_atom_len(ei_x_buff* x, const char* s, int len); 496 int ei_x_encode_atom_len_as(ei_x_buff* x, const char* s, int len, 497 erlang_char_encoding from, erlang_char_encoding to); 498 int ei_encode_binary(char *buf, int *index, const void *p, long len); 499 int ei_x_encode_binary(ei_x_buff* x, const void* s, int len); 500 int ei_encode_pid(char *buf, int *index, const erlang_pid *p); 501 int ei_x_encode_pid(ei_x_buff* x, const erlang_pid* pid); 502 int ei_encode_fun(char* buf, int* index, const erlang_fun* p); 503 int ei_x_encode_fun(ei_x_buff* x, const erlang_fun* fun); 504 int ei_encode_port(char *buf, int *index, const erlang_port *p); 505 int ei_x_encode_port(ei_x_buff* x, const erlang_port *p); 506 int ei_encode_ref(char *buf, int *index, const erlang_ref *p); 507 int ei_x_encode_ref(ei_x_buff* x, const erlang_ref *p); 508 int ei_encode_term(char *buf, int *index, void *t); /* ETERM* actually */ 509 int ei_x_encode_term(ei_x_buff* x, void* t); 510 int ei_encode_trace(char *buf, int *index, const erlang_trace *p); 511 int ei_x_encode_trace(ei_x_buff* x, const erlang_trace *p); 512 int ei_encode_tuple_header(char *buf, int *index, int arity); 513 int ei_x_encode_tuple_header(ei_x_buff* x, long n); 514 int ei_encode_list_header(char *buf, int *index, int arity); 515 int ei_x_encode_list_header(ei_x_buff* x, long n); 516 #define ei_encode_empty_list(buf,i) ei_encode_list_header(buf,i,0) 517 int ei_x_encode_empty_list(ei_x_buff* x); 518 int ei_encode_map_header(char *buf, int *index, int arity); 519 int ei_x_encode_map_header(ei_x_buff* x, long n); 520 521 /* 522 * ei_get_type() returns the type and "size" of the item at 523 * buf[index]. For strings and atoms, size is the number of characters 524 * not including the terminating 0. For binaries, size is the number 525 * of bytes. For lists and tuples, size is the arity of the 526 * object. For other types, size is 0. In all cases, index is left 527 * unchanged. 528 */ 529 530 int ei_get_type(const char *buf, const int *index, int *type, int *size); 531 int ei_get_type_internal(const char *buf, const int *index, int *type, 532 int *size); 533 534 /* Step through buffer, decoding the given type into the buffer 535 * provided. On success, 0 is returned and index is updated to point 536 * to the start of the next item in the buffer. If the type of item at 537 * buf[index] is not the requested type, -1 is returned and index is 538 * not updated. The buffer provided by the caller must be sufficiently 539 * large to contain the decoded object. 540 */ 541 int ei_decode_version(const char *buf, int *index, int *version); 542 int ei_decode_long(const char *buf, int *index, long *p); 543 int ei_decode_ulong(const char *buf, int *index, unsigned long *p); 544 int ei_decode_double(const char *buf, int *index, double *p); 545 int ei_decode_boolean(const char *buf, int *index, int *p); 546 int ei_decode_char(const char *buf, int *index, char *p); 547 int ei_decode_string(const char *buf, int *index, char *p); 548 int ei_decode_atom(const char *buf, int *index, char *p); 549 int ei_decode_atom_as(const char *buf, int *index, char *p, int destlen, erlang_char_encoding want, erlang_char_encoding* was, erlang_char_encoding* result); 550 int ei_decode_binary(const char *buf, int *index, void *p, long *len); 551 int ei_decode_fun(const char* buf, int* index, erlang_fun* p); 552 void free_fun(erlang_fun* f); 553 int ei_decode_pid(const char *buf, int *index, erlang_pid *p); 554 int ei_decode_port(const char *buf, int *index, erlang_port *p); 555 int ei_decode_ref(const char *buf, int *index, erlang_ref *p); 556 int ei_decode_term(const char *buf, int *index, void *t); /* ETERM** actually */ 557 int ei_decode_trace(const char *buf, int *index, erlang_trace *p); 558 int ei_decode_tuple_header(const char *buf, int *index, int *arity); 559 int ei_decode_list_header(const char *buf, int *index, int *arity); 560 int ei_decode_map_header(const char *buf, int *index, int *arity); 561 562 /* 563 * ei_decode_ei_term() returns 1 if term is decoded, 0 if term is OK, 564 * but not decoded here and -1 if something is wrong. ONLY changes 565 * index if term is decoded (return value 1)! 566 */ 567 568 int ei_decode_ei_term(const char* buf, int* index, ei_term* term); 569 570 571 /* 572 * ei_print_term to print out a binary coded term 573 */ 574 575 int ei_print_term(FILE *fp, const char* buf, int* index); 576 int ei_s_print_term(char** s, const char* buf, int* index); 577 578 /* 579 * format to build binary format terms a bit like printf 580 */ 581 582 int ei_x_format(ei_x_buff* x, const char* fmt, ...); 583 int ei_x_format_wo_ver(ei_x_buff* x, const char *fmt, ...); 584 585 int ei_x_new(ei_x_buff* x); 586 int ei_x_new_with_version(ei_x_buff* x); 587 int ei_x_free(ei_x_buff* x); 588 int ei_x_append(ei_x_buff* x, const ei_x_buff* x2); 589 int ei_x_append_buf(ei_x_buff* x, const char* buf, int len); 590 int ei_skip_term(const char* buf, int* index); 591 592 /*************************************************************************** 593 * 594 * Hash types needed by registry types 595 * 596 ***************************************************************************/ 597 598 #define EI_SMALLKEY 32 599 600 typedef struct bucket_s { 601 int rawhash; 602 const char *key; 603 char keybuf[EI_SMALLKEY]; 604 const void *value; 605 struct bucket_s *next; 606 } ei_bucket; 607 608 /* users of the package declare variables as pointers to this. */ 609 typedef struct { 610 ei_bucket **tab; 611 int (*hash)(const char *); /* hash function for this table */ 612 int size; /* size of table */ 613 int nelem; /* nr elements */ 614 int npos; /* nr occupied positions */ 615 ei_bucket *freelist; /* reuseable freed buckets */ 616 } ei_hash; 617 618 619 /*************************************************************************** 620 * 621 * Registry defines, types, functions 622 * 623 ***************************************************************************/ 624 625 /* -------------------------------------------------------------------- */ 626 /* XXXXXXXXXXX */ 627 /* -------------------------------------------------------------------- */ 628 629 /* registry object attributes */ 630 #define EI_DIRTY 0x01 /* dirty bit (object value differs from backup) */ 631 #define EI_DELET 0x02 /* object is deleted */ 632 #define EI_INT 0x10 /* object is an integer */ 633 #define EI_FLT 0x20 /* object is a float */ 634 #define EI_STR 0x40 /* object is a string */ 635 #define EI_BIN 0x80 /* object is a binary, i.e. pointer to arbitrary type */ 636 637 638 /* -------------------------------------------------------------------- */ 639 /* XXXXXXXXXXX */ 640 /* -------------------------------------------------------------------- */ 641 642 typedef struct ei_reg_inode { 643 int attr; 644 int size; 645 union { 646 long i; 647 double f; 648 char *s; 649 void *p; 650 } val; 651 struct ei_reg_inode *next; 652 } ei_reg_obj; 653 654 typedef struct { 655 ei_reg_obj *freelist; 656 ei_hash *tab; 657 } ei_reg; 658 659 struct ei_reg_stat { 660 int attr; /* object attributes (see above) */ 661 int size; /* size in bytes (for STR and BIN) 0 for others */ 662 }; 663 664 struct ei_reg_tabstat { 665 int size; /* size of table */ 666 int nelem; /* number of stored elements */ 667 int npos; /* number of occupied positions */ 668 int collisions; /* number of positions with more than one element */ 669 }; 670 671 672 int ei_init(void); 673 674 /* -------------------------------------------------------------------- */ 675 /* XXXXXXXXXXX */ 676 /* -------------------------------------------------------------------- */ 677 678 /* FIXME move comments to source */ 679 680 /* open / close registry. On open, a descriptor is returned that must 681 * be specified in all subsequent calls to registry functions. You can 682 * open as many registries as you like. 683 */ 684 ei_reg *ei_reg_open(int size); 685 int ei_reg_resize(ei_reg *oldreg, int newsize); 686 int ei_reg_close(ei_reg *reg); 687 688 /* set values... these routines assign values to keys. If the key 689 * exists, the previous value is discarded and the new one replaces 690 * it. 691 * 692 * BIN objects require an additional argument indicating the size in 693 * bytes of the stored object. This will be used when the object is 694 * backed up, since it will need to be copied at that time. Remember 695 * also that pointers are process-space specific and it is not 696 * meaningful to back them up for later recall. If you are storing 697 * binary objects for backup, make sure that they are self-contained 698 * (without references to other objects). 699 * 700 * On success the function returns 0, otherwise a value 701 * indicating the reason for failure will be returned. 702 */ 703 int ei_reg_setival(ei_reg *reg, const char *key, long i); 704 int ei_reg_setfval(ei_reg *reg, const char *key, double f); 705 int ei_reg_setsval(ei_reg *reg, const char *key, const char *s); 706 int ei_reg_setpval(ei_reg *reg, const char *key, const void *p, int size); 707 708 /* general set function (specifiy type via flags) 709 * optional arguments are as for equivalent type-specific function, 710 * i.e.: 711 * ei_reg_setval(fd, path, EI_INT, int i); 712 * ei_reg_setval(fd, path, EI_FLT, float f); 713 * ei_reg_setval(fd, path, EI_STR, const char *s); 714 * ei_reg_setval(fd, path, EI_BIN, const void *p, int size); 715 */ 716 int ei_reg_setval(ei_reg *reg, const char *key, int flags, ...); 717 718 /* get value of specific type object */ 719 /* warning: it may be difficult to detect errors when using these 720 * functions, since the error values are returned "in band" 721 */ 722 long ei_reg_getival(ei_reg *reg, const char *key); 723 double ei_reg_getfval(ei_reg *reg, const char *key); 724 const char *ei_reg_getsval(ei_reg *reg, const char *key); 725 const void *ei_reg_getpval(ei_reg *reg, const char *key, int *size); 726 727 /* get value of any type object (must specify) 728 * Retrieve a value from an object. The type of value expected and a 729 * pointer to a large enough buffer must be provided. flags must be 730 * set to the appropriate type (see type constants above) and the 731 * object type must match. If (flags == 0) the pointer is *assumed* to 732 * be of the correct type for the object. In any case, the actual 733 * object type is always returned on success. 734 * 735 * The argument following flags must be one of int*, double*, const 736 * char** and const void**. 737 * 738 * for BIN objects an int* is needed to return the size of the object, i.e. 739 * int ei_reg_getval(ei_reg *reg, const char *path, int flags, void **p, int *size); 740 */ 741 int ei_reg_getval(ei_reg *reg, const char *key, int flags, ...); 742 743 /* mark the object as dirty. Normally this operation will not be 744 * necessary, as it is done automatically by all of the above 'set' 745 * functions. However, if you modify the contents of an object pointed 746 * to by a STR or BIN object, then the registry will not be aware of 747 * the change. As a result, the object may be missed on a subsequent 748 * backup operation. Use this function to set the dirty bit on the 749 * object. 750 */ 751 int ei_reg_markdirty(ei_reg *reg, const char *key); 752 753 /* remove objects. The value, if any, is discarded. For STR and BIN 754 * objects, the object itself is removed using free(). */ 755 int ei_reg_delete(ei_reg *reg, const char *key); 756 757 /* get information about an object */ 758 int ei_reg_stat(ei_reg *reg, const char *key, struct ei_reg_stat *obuf); 759 760 /* get information about table */ 761 int ei_reg_tabstat(ei_reg *reg, struct ei_reg_tabstat *obuf); 762 763 /* dump to / restore from backup */ 764 /* fd is open descriptor to Erlang, mntab is Mnesia table name */ 765 /* flags here: */ 766 #define EI_FORCE 0x1 /* dump all records (not just dirty ones) */ 767 #define EI_NOPURGE 0x2 /* don't purge deleted records */ 768 int ei_reg_dump(int fd, ei_reg *reg, const char *mntab, int flags); 769 int ei_reg_restore(int fd, ei_reg *reg, const char *mntab); 770 int ei_reg_purge(ei_reg *reg); 771 772 773 /* -------------------------------------------------------------------- */ 774 /* Encoding/decoding bugnums to GNU MP format */ 775 /* -------------------------------------------------------------------- */ 776 777 /* If the user included <gmp.h> we supply some more functions */ 778 779 #if defined(__GNU_MP_VERSION) \ 780 && __GNU_MP_VERSION == 4 && __GNU_MP_VERSION_MINOR >= 1 781 782 int ei_decode_bignum(const char *buf, int *index, mpz_t obj); 783 int ei_encode_bignum(char *buf, int *index, mpz_t obj); 784 int ei_x_encode_bignum(ei_x_buff *x, mpz_t obj); 785 786 #endif /* __GNU_MP_VERSION */ 787 788 /* -------------------------------------------------------------------- */ 789 /* Function definitions not documented FIXME */ 790 /* -------------------------------------------------------------------- */ 791 792 /* FIXME replace this primitive type size code */ 793 794 #ifdef __WIN32__ 795 #define EI_LONGLONG __int64 796 #define EI_ULONGLONG unsigned __int64 797 #else 798 #define EI_LONGLONG long long 799 #define EI_ULONGLONG unsigned long long 800 #endif 801 802 #ifndef VXWORKS 803 int ei_decode_longlong(const char *buf, int *index, EI_LONGLONG *p); 804 int ei_decode_ulonglong(const char *buf, int *index, EI_ULONGLONG *p); 805 int ei_encode_longlong(char *buf, int *index, EI_LONGLONG p); 806 int ei_encode_ulonglong(char *buf, int *index, EI_ULONGLONG p); 807 int ei_x_encode_longlong(ei_x_buff* x, EI_LONGLONG n); 808 int ei_x_encode_ulonglong(ei_x_buff* x, EI_ULONGLONG n); 809 #endif 810 811 #ifdef USE_EI_UNDOCUMENTED 812 813 /* 814 * Decode a list of integers into an integer array (i.e. even if it is 815 * encoded as a string). count gets number of items in array. 816 * See "decode_intlist.c". 817 */ 818 819 int ei_decode_intlist(const char *buf, int *index, long *a, int *count); 820 821 /* 822 * FIXME: used in IC, document? 823 * bufp = address of pointer to dynamically allocated buffer - may be reallocated by 824 * this function if it is too small for the message 825 * bufsz = in/out value: in=user buffer size, out=new buffer size 826 * msglen = nr bytes in received message 827 */ 828 int ei_receive_encoded(int fd, char **bufp, int *bufsz, erlang_msg *to, 829 int *msglen); 830 int ei_receive_encoded_tmo(int fd, char **bufp, int *bufsz, erlang_msg *to, 831 int *msglen, unsigned ms); 832 int ei_send_encoded(int fd, const erlang_pid *to, char *msg, int msglen); 833 int ei_send_encoded_tmo(int fd, const erlang_pid *to, char *msg, int msglen, 834 unsigned ms); 835 int ei_send_reg_encoded(int fd, const erlang_pid *from, const char *to, 836 char *msg, int msglen); 837 int ei_send_reg_encoded_tmo(int fd, const erlang_pid *from, const char *to, 838 char *msg, int msglen, unsigned ms); 839 840 /* 841 * Bacward compatibility with old undocumented but used interface... 842 * FIXME use wrapper function instead?! 843 */ 844 #define ei_send_encoded_timeout(Fd,To,Msg,MsgLen,Ms) \ 845 ei_send_encoded_tmo((Fd),(To),(Msg),(MsgLen),(Ms)) 846 #define ei_send_reg_encoded_timeout(Fd,From,To,Msg,MsgLen,Ms) \ 847 ei_send_reg_encoded_tmo((Fd),(From),(To),(Msg),(MsgLen),(Ms)) 848 849 850 /* FIXME: is this really the best way to handle bignums? */ 851 int ei_encode_big(char *buf, int *index, erlang_big* big); 852 int ei_x_encode_big(ei_x_buff* x, erlang_big* big); 853 int ei_decode_big(const char *buf, int *index, erlang_big* p); 854 int ei_big_comp(erlang_big *x, erlang_big *y); 855 int ei_big_to_double(erlang_big *b, double *resp); 856 int ei_small_to_big(int s, erlang_big *b); 857 erlang_big *ei_alloc_big(unsigned int arity); 858 void ei_free_big(erlang_big *b); 859 860 #endif /* USE_EI_UNDOCUMENTED */ 861 862 #ifdef __cplusplus 863 } 864 #endif 865 866 #endif /* EI_H */ 867