erlang_pid *erl_whereis(int fd, const char *name) { ETERM *reply; ETERM *n; /* FIXME problem for threaded ? */ static erlang_pid pid; n = erl_format("[~a]",name); reply = erl_rpc(fd,"erlang","whereis",n); erl_free_term(n); if (reply && (ERL_IS_PID(reply))) { char *node; node = ERL_PID_NODE(reply); strcpy(pid.node,node); pid.num = ERL_PID_NUMBER(reply); pid.serial = ERL_PID_SERIAL(reply); pid.creation = ERL_PID_CREATION(reply); erl_free_term(reply); return &pid; } if (reply) erl_free_term(reply); return NULL; }
/* * Sends an Erlang message to a process at an Erlang node */ int erl_send(int fd, ETERM *to ,ETERM *msg) { erlang_pid topid; ei_x_buff x; int r; ei_x_new_with_version(&x); ei_x_encode_term(&x, msg); /* make the to-pid */ if (!ERL_IS_PID(to)) { ei_x_free(&x); erl_errno = EINVAL; return -1; } if (to->uval.pidval.node.latin1) { strcpy(topid.node, to->uval.pidval.node.latin1); } else { strcpy(topid.node, to->uval.pidval.node.utf8); } topid.num = ERL_PID_NUMBER(to); topid.serial = ERL_PID_SERIAL(to); topid.creation = ERL_PID_CREATION(to); r = ei_send(fd, &topid, x.buff, x.index); ei_x_free(&x); return r == 0; }
static int hello_open(const char *path, struct fuse_file_info *fi) { int res = 0; ETERM * response = erl_rpc(FERL_DATA->erlang_fd,"gen_server","call",erl_format("[nefs,{open,~s,~i}]",path,fi->flags)); ETERM * pattern = erl_format("{ok,Fd}"); ETERM * pattern2 = erl_format("{error,access}"); if(erl_match(pattern, response)) { ETERM * Fd_Pid = erl_var_content(pattern, "Fd"); if(ERL_IS_PID(Fd_Pid)){ fi->fh = Fd_Pid; //store off the file handle pid to be used in subsequent functions }else{ res= -ENOENT; } }else if(erl_match(pattern2, response)){ res = -EACCES; }else{ res = -ENOENT; } return res; }
int main(void) #endif { ei_x_buff eix; int index = 0; ETERM **etermpp = NULL, *etermp = NULL; char *charp = NULL; unsigned char uchar, **ucharpp = NULL, *ucharp = NULL; void *voidp = NULL; Erl_Heap *erl_heapp = NULL; int intx = 0; int *intp = NULL; unsigned int uintx, *uintp; unsigned long *ulongp = NULL; long longx = 0; double doublex = 0.0; short shortx = 42; FILE *filep = NULL; Erl_IpAddr erl_ipaddr = NULL; ErlMessage *erlmessagep = NULL; ErlConnect *erlconnectp = NULL; struct hostent *hostp = NULL; struct in_addr *inaddrp = NULL; /* Converion to erl_interface format is in liberl_interface */ intx = erl_errno; ei_encode_term(charp, &index, voidp); ei_x_encode_term(&eix, voidp); ei_decode_term(charp, &index, voidp); erl_init(voidp, longx); erl_connect_init(intx, charp,shortx); erl_connect_xinit(charp,charp,charp,erl_ipaddr,charp,shortx); erl_connect(charp); erl_xconnect(erl_ipaddr,charp); erl_close_connection(intx); erl_receive(intx, ucharp, intx); erl_receive_msg(intx, ucharp, intx, erlmessagep); erl_xreceive_msg(intx, ucharpp, intp, erlmessagep); erl_send(intx, etermp, etermp); erl_reg_send(intx, charp, etermp); erl_rpc(intx,charp,charp,etermp); erl_rpc_to(intx,charp,charp,etermp); erl_rpc_from(intx,intx,erlmessagep); erl_publish(intx); erl_accept(intx,erlconnectp); erl_thiscookie(); erl_thisnodename(); erl_thishostname(); erl_thisalivename(); erl_thiscreation(); erl_unpublish(charp); erl_err_msg(charp); erl_err_quit(charp); erl_err_ret(charp); erl_err_sys(charp); erl_cons(etermp,etermp); erl_copy_term(etermp); erl_element(intx,etermp); erl_hd(etermp); erl_iolist_to_binary(etermp); erl_iolist_to_string(etermp); erl_iolist_length(etermp); erl_length(etermp); erl_mk_atom(charp); erl_mk_binary(charp,intx); erl_mk_empty_list(); erl_mk_estring(charp, intx); erl_mk_float(doublex); erl_mk_int(intx); erl_mk_list(etermpp,intx); erl_mk_pid(charp,uintx,uintx,uchar); erl_mk_port(charp,uintx,uchar); erl_mk_ref(charp,uintx,uchar); erl_mk_long_ref(charp,uintx,uintx,uintx,uchar); erl_mk_string(charp); erl_mk_tuple(etermpp,intx); erl_mk_uint(uintx); erl_mk_var(charp); erl_print_term(filep,etermp); /* erl_sprint_term(charp,etermp); */ erl_size(etermp); erl_tl(etermp); erl_var_content(etermp, charp); erl_format(charp); erl_match(etermp, etermp); erl_global_names(intx, intp); erl_global_register(intx, charp, etermp); erl_global_unregister(intx, charp); erl_global_whereis(intx, charp, charp); erl_init_malloc(erl_heapp,longx); erl_alloc_eterm(uchar); erl_eterm_release(); erl_eterm_statistics(ulongp,ulongp); erl_free_array(etermpp,intx); erl_free_term(etermp); erl_free_compound(etermp); erl_malloc(longx); erl_free(voidp); erl_compare_ext(ucharp, ucharp); erl_decode(ucharp); erl_decode_buf(ucharpp); erl_encode(etermp,ucharp); erl_encode_buf(etermp,ucharpp); erl_ext_size(ucharp); erl_ext_type(ucharp); erl_peek_ext(ucharp,intx); erl_term_len(etermp); erl_gethostbyname(charp); erl_gethostbyaddr(charp, intx, intx); erl_gethostbyname_r(charp, hostp, charp, intx, intp); erl_gethostbyaddr_r(charp, intx, intx, hostp, charp, intx, intp); erl_init_resolve(); erl_distversion(intx); erl_epmd_connect(inaddrp); erl_epmd_port(inaddrp, charp, intp); charp = ERL_ATOM_PTR(etermp); intx = ERL_ATOM_SIZE(etermp); ucharp = ERL_BIN_PTR(etermp); intx = ERL_BIN_SIZE(etermp); etermp = ERL_CONS_HEAD(etermp); etermp = ERL_CONS_TAIL(etermp); intx = ERL_COUNT(etermp); doublex= ERL_FLOAT_VALUE(etermp); uintx = ERL_INT_UVALUE(etermp); intx = ERL_INT_VALUE(etermp); intx = ERL_IS_ATOM(etermp); intx = ERL_IS_BINARY(etermp); intx = ERL_IS_CONS(etermp); intx = ERL_IS_EMPTY_LIST(etermp); intx = ERL_IS_FLOAT(etermp); intx = ERL_IS_INTEGER(etermp); intx = ERL_IS_LIST(etermp); intx = ERL_IS_PID(etermp); intx = ERL_IS_PORT(etermp); intx = ERL_IS_REF(etermp); intx = ERL_IS_TUPLE(etermp); intx = ERL_IS_UNSIGNED_INTEGER(etermp); uchar = ERL_PID_CREATION(etermp); charp = ERL_PID_NODE(etermp); uintx = ERL_PID_NUMBER(etermp); uintx = ERL_PID_SERIAL(etermp); uchar = ERL_PORT_CREATION(etermp); charp = ERL_PORT_NODE(etermp); uintx = ERL_PORT_NUMBER(etermp); uchar = ERL_REF_CREATION(etermp); intx = ERL_REF_LEN(etermp); charp = ERL_REF_NODE(etermp); uintx = ERL_REF_NUMBER(etermp); uintp = ERL_REF_NUMBERS(etermp); etermp = ERL_TUPLE_ELEMENT(etermp,intx); intx = ERL_TUPLE_SIZE(etermp); return BUFSIZ + EAGAIN + EHOSTUNREACH + EINVAL + EIO + EMSGSIZE + ENOMEM + ERL_ATOM + ERL_BINARY + ERL_ERROR + ERL_EXIT + ERL_FLOAT + ERL_INTEGER + ERL_LINK + ERL_LIST + ERL_MSG + ERL_NO_TIMEOUT + ERL_PID + ERL_PORT + ERL_REF + ERL_REG_SEND + ERL_SEND + ERL_SMALL_BIG + ERL_TICK + ERL_TIMEOUT + ERL_TUPLE + ERL_UNLINK + ERL_U_INTEGER + ERL_U_SMALL_BIG + ERL_VARIABLE + ETIMEDOUT + MAXNODELEN + MAXREGLEN; }
void watcher(void* data) { TRACE(("watcher thread started!")); info_t* threadinfo = (info_t*)data; int triggerfd, cnt, ret; char attrdata[1024]; struct pollfd ufd; if (!ERL_IS_PID(threadinfo->topid)) { fprintf(stderr, "PID is not a pid. wat."); pthread_exit(NULL); } TRACE(("watcher thread got fname(%d): %s", strlen(threadinfo->fname), threadinfo->fname)); //TRACE(("watcher got PID <.%d.%d> and fd %d", // ERL_PID_NUMBER(&threadinfo->topid), // ERL_PID_SERIAL(&threadinfo->topid), // threadinfo->erlvm_fd)); fprintf(stderr, "watcher got PID "); erl_print_term(stderr, threadinfo->topid); fprintf(stderr, "\n"); if ((ufd.fd = open(threadinfo->fname, O_RDONLY)) < 0) { TRACE(("unable to open file %s", threadinfo->fname)); perror("unable to open file"); goto end_watcher; } ufd.events = POLLPRI | POLLERR; // dummy read cnt = read(ufd.fd, attrdata, 1023); TRACE(("dummy read got value %d", cnt)); TRACE(("starting up main watcher loop")); while ((ret = poll(&ufd, 1, 10000)) >= 0) { TRACE(("began watcher loop")); if (ret == 0) { TRACE(("watcher thread poll() timed out, continuing.")); continue; } if (ufd.revents & (POLLPRI|POLLERR)) { TRACE(("watcher caught an event!")); close(ufd.fd); if ((ufd.fd = open(threadinfo->fname, O_RDONLY)) < 0) { TRACE(("unable to re-open file %s", threadinfo->fname)); perror("unable to re-open file"); break; } cnt = read(ufd.fd, attrdata, 1023); attrdata[cnt] = '\0'; TRACE(("watcher got %d bytes: %s", cnt, attrdata)); ETERM* notification = erl_format("{data, ~s}", attrdata); int sendret = erl_send(threadinfo->erlvm_fd, threadinfo->topid, notification); if (!sendret) { switch(erl_errno) { case(EINVAL): fprintf(stderr, "unable to send notification: bad PID\n"); break; case(ENOMEM): fprintf(stderr, "unable to send notification: no memory\n"); break; case(EIO): fprintf(stderr, "unable to send notification: I/O error\n"); break; default: fprintf(stderr, "unable to send notification: unspecified error\n"); break; } } else { TRACE(("sent notification")); } free(notification); } else { printf("watcher got something weird! revents = %d\n", ufd.revents); } ufd.revents = 0; TRACE(("finishing watcher loop")); } end_watcher: erl_free_compound(threadinfo->topid); free(threadinfo->fname); pthread_t* dying = threadinfo->self; free(threadinfo); free(dying); TRACE(("watcher thread exiting")); pthread_exit(NULL); }