/* Private functions */ Ecore_Pipe * _ecore_pipe_add(Ecore_Pipe_Cb handler, const void *data) { Ecore_Pipe *p = NULL; int fds[2]; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); if (!handler) return NULL; p = ecore_pipe_calloc(1); if (!p) return NULL; if (pipe(fds)) { ecore_pipe_mp_free(p); return NULL; } ECORE_MAGIC_SET(p, ECORE_MAGIC_PIPE); p->fd_read = fds[0]; p->fd_write = fds[1]; p->handler = handler; p->data = data; _ecore_fd_close_on_exec(fds[0]); _ecore_fd_close_on_exec(fds[1]); fcntl(p->fd_read, F_SETFL, O_NONBLOCK); p->fd_handler = ecore_main_fd_handler_add(p->fd_read, ECORE_FD_READ, _ecore_pipe_read, p, NULL, NULL); return p; }
EAPI int ecore_con_info_get(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data, struct addrinfo *hints) { CB_Data *cbdata; int fd[2]; if (pipe(fd) < 0) { ecore_con_event_server_error(svr, strerror(errno)); return 0; } _ecore_fd_close_on_exec(fd[0]); _ecore_fd_close_on_exec(fd[1]); cbdata = calloc(1, sizeof(CB_Data)); if (!cbdata) { close(fd[0]); close(fd[1]); return 0; } cbdata->cb_done = done_cb; cbdata->data = data; cbdata->fd2 = fd[1]; if (!(cbdata->fdh = ecore_main_fd_handler_add(fd[0], ECORE_FD_READ, _ecore_con_info_data_handler, cbdata, NULL, NULL))) { ecore_con_event_server_error(svr, "Memory allocation failure"); free(cbdata); close(fd[0]); close(fd[1]); return 0; } if ((cbdata->pid = fork()) == 0) { Ecore_Con_Info *container; struct addrinfo *result = NULL; char service[NI_MAXSERV] = {0}; char hbuf[NI_MAXHOST] = {0}; char sbuf[NI_MAXSERV] = {0}; unsigned char *tosend = NULL; int tosend_len; int canonname_len = 0; eina_convert_itoa(svr->ecs ? svr->ecs->port : svr->port, service); /* CHILD */ if (!getaddrinfo(svr->ecs ? svr->ecs->ip : svr->name, service, hints, &result) && result) { if (result->ai_canonname) canonname_len = strlen(result->ai_canonname) + 1; tosend_len = sizeof(Ecore_Con_Info) + result->ai_addrlen + canonname_len; tosend = alloca(tosend_len); memset(tosend, 0, tosend_len); container = (Ecore_Con_Info *)tosend; container->size = tosend_len; memcpy(&container->info, result, sizeof(struct addrinfo)); memcpy(tosend + sizeof(Ecore_Con_Info), result->ai_addr, result->ai_addrlen); if (result->ai_canonname) /* FIXME: else... */ memcpy(tosend + sizeof(Ecore_Con_Info) + result->ai_addrlen, result->ai_canonname, canonname_len); if (!getnameinfo(result->ai_addr, result->ai_addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { memcpy(container->ip, hbuf, sizeof(container->ip)); memcpy(container->service, sbuf, sizeof(container->service)); } if (write(fd[1], tosend, tosend_len) < 0) perror("write"); } if (result) freeaddrinfo(result); if (write(fd[1], "", 1) < 0) perror("write"); close(fd[1]); #if defined(__USE_ISOC99) && !defined(__UCLIBC__) _Exit(0); #else _exit(0); #endif } /* PARENT */ cbdata->handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _ecore_con_info_exit_handler, cbdata); close(fd[1]); if (!cbdata->handler) { ecore_main_fd_handler_del(cbdata->fdh); free(cbdata); close(fd[0]); return 0; } info_slaves = (CB_Data *)eina_inlist_append(EINA_INLIST_GET( info_slaves), EINA_INLIST_GET(cbdata)); svr->infos = eina_list_append(svr->infos, cbdata); return 1; }