int ei_encode_pid(char *buf, int *index, const erlang_pid *p) { char* s = buf + *index; const char tag = (p->creation > 3) ? ERL_NEW_PID_EXT : ERL_PID_EXT; ++(*index); /* skip ERL_PID_EXT */ if (ei_encode_atom_len_as(buf, index, p->node, strlen(p->node), ERLANG_UTF8, ERLANG_LATIN1|ERLANG_UTF8) < 0) return -1; if (buf) { put8(s, tag); s = buf + *index; /* now the integers */ put32be(s,p->num & 0x7fff); /* 15 bits */ put32be(s,p->serial & 0x1fff); /* 13 bits */ if (tag == ERL_PID_EXT) { put8(s,(p->creation & 0x03)); /* 2 bits */ } else { put32be(s, p->creation); /* 32 bits */ } } *index += 4 + 4 + (tag == ERL_PID_EXT ? 1 : 4); return 0; }
int ei_encode_pid(char *buf, int *index, const erlang_pid *p) { char *s = buf + *index; char *s0 = s; int len = strlen(p->node); if (!buf) s += 13 + len; else { put8(s,ERL_PID_EXT); /* first the nodename */ put8(s,ERL_ATOM_EXT); put16be(s,len); memmove(s, p->node, len); s += len; /* now the integers */ put32be(s,p->num & 0x7fff); /* 15 bits */ put32be(s,p->serial & 0x1fff); /* 13 bits */ put8(s,(p->creation & 0x03)); /* 2 bits */ } *index += s-s0; return 0; }
int ei_encode_fun(char *buf, int *index, const erlang_fun *p) { int ix = *index; if (p->arity == -1) { /* ERL_FUN_EXT */ if (buf != NULL) { char* s = buf + ix; put8(s, ERL_FUN_EXT); put32be(s, p->n_free_vars); } ix += sizeof(char) + 4; if (ei_encode_pid(buf, &ix, &p->pid) < 0) return -1; if (ei_encode_atom_as(buf, &ix, p->module, ERLANG_UTF8, p->module_org_enc) < 0) return -1; if (ei_encode_long(buf, &ix, p->index) < 0) return -1; if (ei_encode_long(buf, &ix, p->uniq) < 0) return -1; if (buf != NULL) memcpy(buf + ix, p->free_vars, p->free_var_len); ix += p->free_var_len; } else { char *size_p; /* ERL_NEW_FUN_EXT */ if (buf != NULL) { char* s = buf + ix; put8(s, ERL_NEW_FUN_EXT); size_p = s; s += 4; put8(s, p->arity); memcpy(s, p->md5, sizeof(p->md5)); s += sizeof(p->md5); put32be(s, p->index); put32be(s, p->n_free_vars); } else size_p = NULL; ix += 1 + 4 + 1 + sizeof(p->md5) + 4 + 4; if (ei_encode_atom_as(buf, &ix, p->module, ERLANG_UTF8, p->module_org_enc) < 0) return -1; if (ei_encode_long(buf, &ix, p->old_index) < 0) return -1; if (ei_encode_long(buf, &ix, p->uniq) < 0) return -1; if (ei_encode_pid(buf, &ix, &p->pid) < 0) return -1; if (buf != NULL) memcpy(buf + ix, p->free_vars, p->free_var_len); ix += p->free_var_len; if (size_p != NULL) { int sz = buf + ix - size_p; put32be(size_p, sz); } } *index = ix; return 0; }
static int send_name_or_challenge(int fd, char *nodename, int f_chall, unsigned challenge, unsigned version, unsigned ms) { char *buf; unsigned char *s; char dbuf[DEFBUF_SIZ]; int siz = 2 + 1 + 2 + 4 + strlen(nodename); const char* function[] = {"SEND_NAME", "SEND_CHALLENGE"}; int res; if (f_chall) siz += 4; buf = (siz > DEFBUF_SIZ) ? malloc(siz) : dbuf; if (!buf) { erl_errno = ENOMEM; return -1; } s = (unsigned char *)buf; put16be(s,siz - 2); put8(s, 'n'); put16be(s, version); put32be(s, (DFLAG_EXTENDED_REFERENCES | DFLAG_DIST_MONITOR | DFLAG_EXTENDED_PIDS_PORTS | DFLAG_FUN_TAGS | DFLAG_NEW_FUN_TAGS | DFLAG_NEW_FLOATS | DFLAG_SMALL_ATOM_TAGS | DFLAG_UTF8_ATOMS | DFLAG_MAP_TAG | DFLAG_BIG_CREATION)); if (f_chall) put32be(s, challenge); memcpy(s, nodename, strlen(nodename)); if ((res = ei_write_fill_t(fd, buf, siz, ms)) != siz) { EI_TRACE_ERR1("send_name_or_challenge", "-> %s socket write failed", function[f_chall]); if (buf != dbuf) free(buf); erl_errno = (res == -2) ? ETIMEDOUT : EIO; return -1; } if (buf != dbuf) free(buf); return 0; }
void ei_link(listener_t *listener, erlang_pid * from, erlang_pid * to) { char msgbuf[2048]; char *s; int index = 0; switch_socket_t *sock = NULL; switch_os_sock_put(&sock, &listener->sockdes, listener->pool); index = 5; /* max sizes: */ ei_encode_version(msgbuf, &index); /* 1 */ ei_encode_tuple_header(msgbuf, &index, 3); ei_encode_long(msgbuf, &index, ERL_LINK); ei_encode_pid(msgbuf, &index, from); /* 268 */ ei_encode_pid(msgbuf, &index, to); /* 268 */ /* 5 byte header missing */ s = msgbuf; put32be(s, index - 4); /* 4 */ put8(s, ERL_PASS_THROUGH); /* 1 */ /* sum: 542 */ switch_mutex_lock(listener->sock_mutex); if (switch_socket_send(sock, msgbuf, (switch_size_t *) &index)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to link to process on %s\n", listener->peer_nodename); } switch_mutex_unlock(listener->sock_mutex); }
void ei_link(listener_t *listener, erlang_pid * from, erlang_pid * to) { char msgbuf[2048]; char *s; int index = 0; index = 5; /* max sizes: */ ei_encode_version(msgbuf, &index); /* 1 */ ei_encode_tuple_header(msgbuf, &index, 3); ei_encode_long(msgbuf, &index, ERL_LINK); ei_encode_pid(msgbuf, &index, from); /* 268 */ ei_encode_pid(msgbuf, &index, to); /* 268 */ /* 5 byte header missing */ s = msgbuf; put32be(s, index - 4); /* 4 */ put8(s, ERL_PASS_THROUGH); /* 1 */ /* sum: 542 */ switch_mutex_lock(listener->sock_mutex); #ifdef WIN32 send(listener->sockfd, msgbuf, index, 0); #else if (write(listener->sockfd, msgbuf, index) == -1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to link to process on %s\n", listener->peer_nodename); } #endif switch_mutex_unlock(listener->sock_mutex); }
/* this sends either link or unlink ('which' decides) */ static int link_unlink(int fd, const erlang_pid *from, const erlang_pid *to, int which, unsigned ms) { char msgbuf[EISMALLBUF]; char *s; int index = 0; int n; index = 5; /* max sizes: */ ei_encode_version(msgbuf,&index); /* 1 */ ei_encode_tuple_header(msgbuf,&index,3); ei_encode_long(msgbuf,&index,which); ei_encode_pid(msgbuf,&index,from); /* 268 */ ei_encode_pid(msgbuf,&index,to); /* 268 */ /* 5 byte header missing */ s = msgbuf; put32be(s, index - 4); /* 4 */ put8(s, ERL_PASS_THROUGH); /* 1 */ /* sum: 542 */ #ifdef DEBUG_DIST if (ei_trace_distribution > 1) ei_show_sendmsg(stderr,msgbuf,NULL); #endif n = ei_write_fill_t(fd,msgbuf,index,ms); return (n==index ? 0 : -1); }
int ei_encode_ulong(char *buf, int *index, unsigned long p) { char *s = buf + *index; char *s0 = s; if (p > ERL_MAX) { if (!buf) s += 7; else { put8(s,ERL_SMALL_BIG_EXT); put8(s,4); /* len = four bytes */ put8(s, 0); /* save sign separately */ put32le(s,p); /* OBS: Little Endian, and p now positive */ } } else if ((p < 256) && (p >= 0)) { if (!buf) s += 2; else { put8(s,ERL_SMALL_INTEGER_EXT); put8(s,(p & 0xff)); } } else { if (!buf) s += 5; else { put8(s,ERL_INTEGER_EXT); put32be(s,p); } } *index += s-s0; return 0; }
void ei_link(listener_t *listener, erlang_pid * from, erlang_pid * to) { char msgbuf[2048]; char *s; int index = 0; int ret; index = 5; /* max sizes: */ ei_encode_version(msgbuf, &index); /* 1 */ ei_encode_tuple_header(msgbuf, &index, 3); ei_encode_long(msgbuf, &index, ERL_LINK); ei_encode_pid(msgbuf, &index, from); /* 268 */ ei_encode_pid(msgbuf, &index, to); /* 268 */ /* 5 byte header missing */ s = msgbuf; put32be(s, index - 4); /* 4 */ put8(s, ERL_PASS_THROUGH); /* 1 */ /* sum: 542 */ switch_mutex_lock(listener->sock_mutex); #ifdef WIN32 ret = send(listener->sockfd, msgbuf, index, 0); #else ret = write(listener->sockfd, msgbuf, index); #endif switch_mutex_unlock(listener->sock_mutex); }
static int send_challenge_reply(int fd, unsigned char digest[16], unsigned challenge, unsigned ms) { char *s; char buf[DEFBUF_SIZ]; int siz = 2 + 1 + 4 + 16; int res; s = buf; put16be(s,siz - 2); put8(s, 'r'); put32be(s, challenge); memcpy(s, digest, 16); if ((res = ei_write_fill_t(fd, buf, siz, ms)) != siz) { EI_TRACE_ERR0("send_challenge_reply", "-> SEND_CHALLENGE_REPLY socket write failed"); erl_errno = (res == -2) ? ETIMEDOUT : EIO; return -1; } if (ei_tracelevel >= 3) { char buffer[33]; EI_TRACE_CONN2("send_challenge_reply", "-> SEND_CHALLENGE_REPLY (ok) challenge = %d, digest = %s", challenge,hex((char*)digest, buffer)); } return 0; }
int ei_encode_ref(char *buf, int *index, const erlang_ref *p) { char *s = buf + *index; int i; (*index) += 1 + 2; /* skip to node atom */ if (ei_encode_atom_len_as(buf, index, p->node, strlen(p->node), ERLANG_UTF8, ERLANG_LATIN1|ERLANG_UTF8) < 0) { return -1; } /* Always encode as an extended reference; all participating parties are now expected to be able to decode extended references. */ if (buf) { put8(s,ERL_NEW_REFERENCE_EXT); /* first, number of integers */ put16be(s, p->len); /* then the nodename */ s = buf + *index; /* now the integers */ put8(s,(p->creation & 0x03)); for (i = 0; i < p->len; i++) put32be(s,p->n[i]); } *index += p->len*4 + 1; return 0; }
/* length (4), PASS_THROUGH (1), header, message */ int ei_ei_send_reg_encoded(ei_cnode* ec, int fd, const erlang_pid *from, const char *to, const char *msg, int msglen) { char *s, header[1400]; /* see size calculation below */ erlang_trace *token = NULL; int index = 5; /* reserve 5 bytes for control message */ #ifdef HAVE_WRITEV struct iovec v[2]; #endif /* are we tracing? */ /* check that he can receive trace tokens first */ if (ei_distversion(fd) > 0) token = ei_trace(0,(erlang_trace *)NULL); /* header = REG_SEND, from, cookie, toname max sizes: */ ei_encode_version(header,&index); /* 1 */ if (token) { ei_encode_tuple_header(header,&index,5); /* 2 */ ei_encode_long(header,&index,ERL_REG_SEND_TT); /* 2 */ } else { ei_encode_tuple_header(header,&index,4); ei_encode_long(header,&index,ERL_REG_SEND); } ei_encode_pid(header,&index,from); /* 268 */ ei_encode_atom(header,&index,"" /*ei_getfdcookie(ec, fd)*/ ); /* 258 */ ei_encode_atom(header,&index,to); /* 268 */ if (token) ei_encode_trace(header,&index,token); /* 534 */ /* control message (precedes header actually) */ /* length = 1 ('p') + header len + message len */ s = header; put32be(s, index + msglen - 4); /* 4 */ put8(s, ERL_PASS_THROUGH); /* 1 */ /*** sum: 1336 */ #ifdef DEBUG_DIST if (ei_trace_distribution > 0) ei_show_sendmsg(stderr,header,msg); #endif #ifdef HAVE_WRITEV v[0].iov_base = (char *)header; v[0].iov_len = index; v[1].iov_base = (char *)msg; v[1].iov_len = msglen; if (writev(fd,v,2) != index+msglen) return -1; #else /* no writev() */ if (writesocket(fd,header,index) != index) return -1; if (writesocket(fd,msg,msglen) != msglen) return -1; #endif return 0; }
void es_openAudio(sdl_data *sd, int len, char *buff) { int sendlen; char *bp, *start; int ff; SDL_AudioSpec desired, obtained, *obptr; bp = buff; ff = get8(bp); desired.freq = get32be(bp); desired.format = get16be(bp); desired.channels = get8(bp); desired.samples = get16be(bp); desired.padding = get16be(bp); desired.callback = myaudiomixer; /* Init the global data structures */ wave.sound = NULL; wave.soundpos = 0; wave.soundlen = 0; if(ff == 1) /* Force the requested format */ obptr = NULL; else obptr = &obtained; bp = start = sdl_getbuff(sd, 16); if( SDL_OpenAudio(&desired, obptr) < 0 ) { fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); } else { if(ff == 1) obptr = &desired; put32be(bp, obptr->freq); put16be(bp, obptr->format); put8(bp, obptr->channels); put8(bp, obptr->silence); put16be(bp, obptr->samples); put16be(bp, obptr->padding); put32be(bp, obptr->size); wave.silence = obptr->silence; } sendlen = (int) (bp - start); sdl_send(sd, sendlen); }
void es_joystick_getBall(sdl_data *sd, int len,char *buff) { int sendlen; char *bp, *start; SDL_Joystick *joy; int dx, dy; Uint8 ball; bp = buff; POPGLPTR(joy, bp); ball = get8(bp); bp = start = sdl_get_temp_buff(sd, 8); if(0 == SDL_JoystickGetBall(joy, ball, &dx, &dy)) { put32be(bp, dx); put32be(bp, dy); } sendlen = bp - start; sdl_send(sd, sendlen); }
int ei_send_exit_tmo(int fd, const erlang_pid *from, const erlang_pid *to, const char *reason, unsigned ms) { char sbuf[EISMALLBUF]; erlang_trace *token = NULL; char *dbuf = NULL; char *msgbuf; char *s; int index = 0; int len = strlen(reason) + 1080; /* see below */ if (len > EISMALLBUF) if (!(dbuf = malloc(len))) return -1; msgbuf = (dbuf ? dbuf : sbuf); /* are we tracing? */ /* check that he can receive trace tokens first */ if (ei_distversion(fd) > 0) token = ei_trace(0,NULL); index = 5; /* max sizes: */ ei_encode_version(msgbuf,&index); /* 1 */ if (token) { ei_encode_tuple_header(msgbuf,&index,5); /* 2 */ ei_encode_long(msgbuf,&index,ERL_EXIT_TT); /* 2 */ } else { ei_encode_tuple_header(msgbuf,&index,4); ei_encode_long(msgbuf,&index,ERL_EXIT); } ei_encode_pid(msgbuf,&index,from); /* 268 */ ei_encode_pid(msgbuf,&index,to); /* 268 */ if (token) ei_encode_trace(msgbuf,&index,token); /* 534 */ /* Reason */ ei_encode_string(msgbuf,&index,reason); /* len */ /* 5 byte header missing */ s = msgbuf; put32be(s, index - 4); /* 4 */ put8(s, ERL_PASS_THROUGH); /* 1 */ /*** sum: len + 1080 */ /* FIXME incorrect level */ if (ei_tracelevel > 1) ei_show_sendmsg(stderr,msgbuf,NULL); ei_write_fill_t(fd,msgbuf,index,ms); /* FIXME ignore timeout etc? erl_errno?! */ if (dbuf) free(dbuf); return 0; }
void es_joystick_eventState(sdl_data *sd, int len,char *buff) { int sendlen; char *bp, *start; int state; bp = buff; state = get32be(bp); bp = start = sdl_get_temp_buff(sd, 4); state = SDL_JoystickEventState(state); put32be(bp, state); sendlen = bp - start; sdl_send(sd, sendlen); }
void es_loadWAV(sdl_data *sd, int len, char *bp) { int sendlen; char *name, *start; SDL_AudioSpec obtained; Uint8 * ptr; Uint32 blen; name = bp; bp = start = sdl_get_temp_buff(sd, 28); if(NULL != SDL_LoadWAV(name, &obtained, &ptr, &blen)) { put32be(bp, obtained.freq); put16be(bp, obtained.format); put8(bp, obtained.channels); put8(bp, obtained.silence); put16be(bp, obtained.samples); put16be(bp, obtained.padding); put32be(bp, obtained.size); PUSHGLPTR(ptr, bp); put32be(bp, blen); } sendlen = (int) (bp - start); sdl_send(sd, sendlen); }
void es_joystick_getAxis(sdl_data *sd, int len,char *buff) { int sendlen; char *bp, *start; SDL_Joystick *joy; int state, axis; bp = buff; POPGLPTR(joy, bp); axis = get8(bp); bp = start = sdl_get_temp_buff(sd, 4); state = SDL_JoystickGetAxis(joy, axis); put32be(bp, state); sendlen = bp - start; sdl_send(sd, sendlen); }
int ei_encode_binary(char *buf, int *index, const void *p, long len) { char *s = buf + *index; char *s0 = s; if (!buf) s += 5; else { put8(s,ERL_BINARY_EXT); put32be(s,len); memmove(s,p,len); } s += len; *index += s-s0; return 0; }
void es_convertAudio(sdl_data *sd, int len, char *buff) { char *bp, *start; void *mptr; Uint16 oformat, nformat; Uint8 ochannels, nchannels; int ofreq, nfreq, osize, nsize; SDL_AudioCVT wav_cvt; int sendlen; bp = buff; oformat = get16be(bp); ochannels = get8(bp); ofreq = get32be(bp); nformat = get16be(bp); nchannels = get8(bp); nfreq = get32be(bp); POPGLPTR(mptr, bp); osize = get32be(bp); bp = start = sdl_getbuff(sd, 12); /* Build AudioCVT */ if(SDL_BuildAudioCVT(&wav_cvt,oformat, ochannels, ofreq, nformat, nchannels, nfreq) >= 0) { /* Setup for conversion */ nsize = osize*wav_cvt.len_mult; wav_cvt.buf=(Uint8 *)malloc(nsize); if(wav_cvt.buf != NULL) { wav_cvt.len=osize; memcpy(wav_cvt.buf, mptr, osize); if (SDL_ConvertAudio(&wav_cvt) >= 0) { PUSHGLPTR(wav_cvt.buf, bp); put32be(bp, nsize); } } } sendlen = (int) (bp - start); sdl_send(sd, sendlen); }
int ei_encode_port(char *buf, int *index, const erlang_port *p) { char *s = buf + *index; ++(*index); /* skip ERL_PORT_EXT */ if (ei_encode_atom_len_as(buf, index, p->node, strlen(p->node), ERLANG_UTF8, ERLANG_LATIN1|ERLANG_UTF8) < 0) { return -1; } if (buf) { put8(s,ERL_PORT_EXT); s = buf + *index; /* now the integers */ put32be(s,p->id & 0x0fffffff /* 28 bits */); put8(s,(p->creation & 0x03)); } *index += 4 + 1; return 0; }
int ei_encode_ulonglong(char *buf, int *index, EI_ULONGLONG p) { char *s = buf + *index; char *s0 = s; if (p < 256) { if (!buf) s += 2; else { put8(s,ERL_SMALL_INTEGER_EXT); put8(s,(p & 0xff)); } } else if (p <= ERL_MAX) { if (!buf) s += 5; else { put8(s,ERL_INTEGER_EXT); put32be(s,p); } } else { /* We know 28-64 bits needed, i.e four to eight bytes */ if (buf) { char *arityp; int arity = 0; put8(s,ERL_SMALL_BIG_EXT); arityp = s++; /* fill in later */ put8(s, 0); /* save sign separately */ while (p) { *s++ = p & 0xff; /* take lowest byte */ p >>= 8; /* shift unsigned */ arity++; } put8(arityp,arity); } else { s += 3; /* Type, arity and sign */ while (p) { s++; /* take lowest byte */ p >>= 8; /* shift unsigned */ } } }
void ei_link(ei_node_t *ei_node, erlang_pid * from, erlang_pid * to) { char msgbuf[2048]; char *s; int index = 0; index = 5; /* max sizes: */ ei_encode_version(msgbuf, &index); /* 1 */ ei_encode_tuple_header(msgbuf, &index, 3); ei_encode_long(msgbuf, &index, ERL_LINK); ei_encode_pid(msgbuf, &index, from); /* 268 */ ei_encode_pid(msgbuf, &index, to); /* 268 */ /* 5 byte header missing */ s = msgbuf; put32be(s, index - 4); /* 4 */ put8(s, ERL_PASS_THROUGH); /* 1 */ /* sum: 542 */ if (write(ei_node->nodefd, msgbuf, index) == -1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to link to process on %s\n", ei_node->peer_nodename); } }
int ei_encode_list_header(char *buf, int *index, int arity) { char *s = buf + *index; char *s0 = s; if (arity < 0) return -1; else if (arity > 0) { if (!buf) s += 5; else { put8(s,ERL_LIST_EXT); put32be(s,arity); } } else { /* empty list */ if (!buf) s++; else put8(s,ERL_NIL_EXT); } *index += s-s0; return 0; }
int ei_encode_fun(char *buf, int *index, const erlang_fun *p) { int ix = *index; switch (p->type) { case EI_FUN_CLOSURE: if (p->arity == -1) { /* ERL_FUN_EXT */ if (buf != NULL) { char* s = buf + ix; put8(s, ERL_FUN_EXT); put32be(s, p->u.closure.n_free_vars); } ix += sizeof(char) + 4; if (ei_encode_pid(buf, &ix, &p->u.closure.pid) < 0) return -1; if (ei_encode_atom_as(buf, &ix, p->module, ERLANG_UTF8, ERLANG_UTF8) < 0) return -1; if (ei_encode_long(buf, &ix, p->u.closure.index) < 0) return -1; if (ei_encode_long(buf, &ix, p->u.closure.uniq) < 0) return -1; if (buf != NULL) memcpy(buf + ix, p->u.closure.free_vars, p->u.closure.free_var_len); ix += p->u.closure.free_var_len; } else { char *size_p; if (buf != NULL) { char* s = buf + ix; put8(s, ERL_NEW_FUN_EXT); size_p = s; s += 4; put8(s, p->arity); memcpy(s, p->u.closure.md5, sizeof(p->u.closure.md5)); s += sizeof(p->u.closure.md5); put32be(s, p->u.closure.index); put32be(s, p->u.closure.n_free_vars); } else size_p = NULL; ix += 1 + 4 + 1 + sizeof(p->u.closure.md5) + 4 + 4; if (ei_encode_atom_as(buf, &ix, p->module, ERLANG_UTF8, ERLANG_UTF8) < 0) return -1; if (ei_encode_long(buf, &ix, p->u.closure.old_index) < 0) return -1; if (ei_encode_long(buf, &ix, p->u.closure.uniq) < 0) return -1; if (ei_encode_pid(buf, &ix, &p->u.closure.pid) < 0) return -1; if (buf != NULL) memcpy(buf + ix, p->u.closure.free_vars, p->u.closure.free_var_len); ix += p->u.closure.free_var_len; if (size_p != NULL) { int sz = buf + ix - size_p; put32be(size_p, sz); } } break; case EI_FUN_EXPORT: if (buf != NULL) { char* s = buf + ix; put8(s, ERL_EXPORT_EXT); } ix++; if (ei_encode_atom_as(buf, &ix, p->module, ERLANG_UTF8, ERLANG_UTF8) < 0) return -1; if (ei_encode_atom_as(buf, &ix, p->u.exprt.func, ERLANG_UTF8, ERLANG_UTF8) < 0) return -1; if (ei_encode_long(buf, &ix, p->arity) < 0) return -1; break; } *index = ix; return 0; }
int ei_send_encoded_tmo(int fd, const erlang_pid *to, char *msg, int msglen, unsigned ms) { char *s, header[1200]; /* see size calculation below */ erlang_trace *token = NULL; int index = 5; /* reserve 5 bytes for control message */ int res; #ifdef HAVE_WRITEV struct iovec v[2]; #endif /* are we tracing? */ /* check that he can receive trace tokens first */ if (ei_distversion(fd) > 0) token = ei_trace(0,NULL); /* header = SEND, cookie, to max sizes: */ ei_encode_version(header,&index); /* 1 */ if (token) { ei_encode_tuple_header(header,&index,4); /* 2 */ ei_encode_long(header,&index,ERL_SEND_TT); /* 2 */ } else { ei_encode_tuple_header(header,&index,3); ei_encode_long(header,&index,ERL_SEND); } ei_encode_atom(header,&index,ei_getfdcookie(fd)); /* 258 */ ei_encode_pid(header,&index,to); /* 268 */ if (token) ei_encode_trace(header,&index,token); /* 534 */ /* control message (precedes header actually) */ /* length = 1 ('p') + header len + message len */ s = header; put32be(s, index + msglen - 4); /* 4 */ put8(s, ERL_PASS_THROUGH); /* 1 */ /*** sum: 1070 */ if (ei_tracelevel >= 4) ei_show_sendmsg(stderr,header,msg); #ifdef HAVE_WRITEV v[0].iov_base = (char *)header; v[0].iov_len = index; v[1].iov_base = (char *)msg; v[1].iov_len = msglen; if ((res = ei_writev_fill_t(fd,v,2,ms)) != index+msglen) { erl_errno = (res == -2) ? ETIMEDOUT : EIO; return -1; } #else /* !HAVE_WRITEV */ if ((res = ei_write_fill_t(fd,header,index,ms)) != index) { erl_errno = (res == -2) ? ETIMEDOUT : EIO; return -1; } if ((res = ei_write_fill_t(fd,msg,msglen,ms)) != msglen) { erl_errno = (res == -2) ? ETIMEDOUT : EIO; return -1; } #endif /* !HAVE_WRITEV */ return 0; }
int ei_send_reg_encoded_tmo(int fd, const erlang_pid *from, const char *to, char *msg, int msglen, unsigned ms) { char *s, header[1400]; /* see size calculation below */ erlang_trace *token = NULL; int index = 5; /* reserve 5 bytes for control message */ int err; ei_socket_callbacks *cbs; void *ctx; ssize_t len, tot_len; unsigned tmo = ms == 0 ? EI_SCLBK_INF_TMO : ms; err = EI_GET_CBS_CTX__(&cbs, &ctx, fd); if (err) { EI_CONN_SAVE_ERRNO__(err); return ERL_ERROR; } /* are we tracing? */ /* check that he can receive trace tokens first */ if (ei_distversion(fd) > 0) token = ei_trace(0,NULL); /* header = REG_SEND, from, cookie, toname max sizes: */ ei_encode_version(header,&index); /* 1 */ if (token) { ei_encode_tuple_header(header,&index,5); /* 2 */ ei_encode_long(header,&index,ERL_REG_SEND_TT); /* 2 */ } else { ei_encode_tuple_header(header,&index,4); ei_encode_long(header,&index,ERL_REG_SEND); } ei_encode_pid(header, &index, from); /* 268 */ ei_encode_atom(header, &index, ei_getfdcookie(fd)); /* 258 */ ei_encode_atom(header, &index, to); /* 268 */ if (token) ei_encode_trace(header,&index,token); /* 534 */ /* control message (precedes header actually) */ /* length = 1 ('p') + header len + message len */ s = header; put32be(s, index + msglen - 4); /* 4 */ put8(s, ERL_PASS_THROUGH); /* 1 */ /*** sum: 1336 */ if (ei_tracelevel >= 4) ei_show_sendmsg(stderr,header,msg); #ifdef EI_HAVE_STRUCT_IOVEC__ if (ei_socket_callbacks_have_writev__(cbs)) { struct iovec v[2]; v[0].iov_base = (char *)header; v[0].iov_len = index; v[1].iov_base = (char *)msg; v[1].iov_len = msglen; len = tot_len = (ssize_t) index+msglen; err = ei_writev_fill_ctx_t__(cbs, ctx, v, 2, &len, tmo); if (!err && len != tot_len) err = EIO; if (err) { EI_CONN_SAVE_ERRNO__(err); return -1; } return 0; } #endif /* EI_HAVE_STRUCT_IOVEC__ */ /* no writev() */ len = tot_len = (ssize_t) index; err = ei_write_fill_ctx_t__(cbs, ctx, header, &len, tmo); if (!err && len != tot_len) err = EIO; if (err) { EI_CONN_SAVE_ERRNO__(err); return -1; } len = tot_len = (ssize_t) msglen; err = ei_write_fill_ctx_t__(cbs, ctx, msg, &len, tmo); if (!err && len != tot_len) err = EIO; if (err) { EI_CONN_SAVE_ERRNO__(err); return -1; } return 0; }