Exemplo n.º 1
0
void slay_impl(pid_t *pids, int n, int sig, pid_t pid, int include_children) {
	int i, hit = 0;

	DEBUG_V("slay %d with signal %d", pid, sig);
	kill(pid, sig);
	for (i = 0; i < n; i++) {
		struct proc_bsdinfo info;
		CHECK(proc_pidinfo(pids[i], PROC_PIDTBSDINFO, 0, &info, sizeof info));
		if (info.pbi_pid == pid) {
			if (info.pbi_status == SZOMB) {
				LOG_V("Not killing PID %d because it's already died (in state 'Z').", pid);
			}
			else {
				LOG_V("Kill PID %d (in state 0x%x) with signal %d", pid, info.pbi_status, sig);
				kill(pid, sig);
			}
			hit = 1;
		}
		if (include_children && (info.pbi_ppid == pid)) {
			if (info.pbi_status == SZOMB) {
				LOG_V("Not killing PID %d because it's already died (in state 'Z').", info.pbi_pid);
			}
			else
				slay_impl(pids, n, sig, info.pbi_pid, include_children);
		}
	}
	if (!hit) {
		LOG_V("PID %d was missing from the proc list (while sending signal %d)", pid, sig);
	}
}
Exemplo n.º 2
0
/**
 * Finds a Tagged object based on its tag id.
 * @param string The tag of the object.
 * @return The Tagged object if found or NULL.
 */
Tagged* Container::getTaggedByTag_(const string tag) {
	DEBUG_V("Entering function getTaggedByTag_...");
	ChildrenTagIterator iter = tags_.find(tag);
	if(iter != tags_.end()) {
		return iter->second;
	}
	return NULL;
}
Exemplo n.º 3
0
int start_cnode(const char *cookie_file, ei_cnode *ec, int *epmd_sock, int *listen_sock, const char *reg_name, const char *host_name) {
	char *cookie = 0, *default_node_name = 0, *node_name;
	short creation = 0;
	int s, port, pub, tries;
	socklen_t addr_len;
	struct sockaddr_in addr;

	cookie = read_cookie(cookie_file);
	node_name = (char *)malloc(strlen(reg_name) + strlen(host_name) + 2);
	strcpy(node_name, reg_name);
	strcat(node_name, "@");
	strcat(node_name, host_name);
	/* The thisipaddr parameter is unused at the moment (R13B01). */
	ei_connect_xinit(ec, host_name, reg_name, node_name, 0, cookie, creation);

	if (cookie)
		free(cookie);
	if (default_node_name)
		free(default_node_name);
	free(node_name);

	s = open_port();
	addr_len = sizeof addr;
	getsockname(s, (struct sockaddr *)&addr, &addr_len);
	port = ntohs(addr.sin_port);
	DEBUG_V("bound port %d", port);

	/* It's possible that epmd has been started, but hasn't yet finished starting
	 * up, so we have a few goes at connecting. Like erl, epmd goes directly into
	 * the background when started, not indicating when it's ready. */
	DEBUG("connecting to epmd");
	tries = 0;
	while (1) {
		pub = ei_publish(ec, port);
		if (pub != -1)
			break;
		if (!tries)
			fprintf(stderr, "Waiting for connection to epmd.\n");
		if (tries++ < ERLD_MAX_TRIES) {
			if (debug_flag)
				erl_err_ret("epmd connection failed, polling (attempt %d/%d)", tries, ERLD_MAX_TRIES);
			usleep(ERLD_POLL_TIME * 1000);
		}
		else {
			erl_err_ret("Unable to connect to epmd");
			return -1;
		}
	}
	*epmd_sock = pub;
	*listen_sock = s;
	return 0;
}
Exemplo n.º 4
0
int accept_erlang_connection(ei_cnode *ec, int listen_sock, ErlConnect *onode) {
    int con;

    DEBUG("accepting connection on erlang socket");
    do {
        con = ei_accept(ec, listen_sock, onode);
    } while ((con == ERL_ERROR) && (erl_errno == EINTR));
    if (con == ERL_ERROR) {
        erl_err_sys("ei_accept failed");
        return -1;
    }
    else
        DEBUG_V("connection from node \"%s\"", onode->nodename);
    return con;
}
Exemplo n.º 5
0
int cleanup_child(int sig, const char *child_name, pid_t child_pid) {
	int rv, status, exit_code = 0;
	char *exit_status;

	if (child_pid == -1)
		return 0;
	/* If we're here because of a signal (arg != 0), pass it on to erld */
	if (sig) {
		LOG_V("passing signal %d to %s", sig, child_name);
		kill(child_pid, sig);
	}
	DEBUG_V("Waiting for %s (pid %d) to exit.", child_name, child_pid);
	while (((rv = waitpid(child_pid, &status, 0)) == -1) && (errno == EINTR))
		/* empty */;
	CHECK(rv);
	get_exit_status(status, &exit_status, &exit_code);
	DEBUG("Wait complete.");
	LOG_V("%s exited with status %d: %s.", child_name, exit_code, exit_status);
	syslog(LOG_INFO, "%s exited with status %d: %s.", child_name, exit_code, exit_status);
	free(exit_status);
	return exit_code;
}
Exemplo n.º 6
0
char *read_cookie(const char *cookie_file) {
	char *home, *path, cookie[COOKIE_MAX_SIZE], *buf;
	ssize_t cookie_size;
	int fd;

	if (!cookie_file) {
		home = getenv("HOME");
		if (!home)
			return 0;
		path = alloc_printf("%s/%s", home, DEFAULT_COOKIE_FILE_NAME);
	} else {
		path = alloc_printf("%s", cookie_file);
	}

	CHECK_F(fd = open(path, O_RDONLY), "open(\"%s\")", path);
	CHECK_F(cookie_size = read(fd, cookie, COOKIE_MAX_SIZE), "read(\"%s\")", path);
	close(fd);
	buf = (char *)malloc(cookie_size + 1);
	memcpy(buf, cookie, cookie_size);
	buf[cookie_size] = 0;
	DEBUG_V("cookie from \"%s\" is %zu bytes", path, cookie_size);
	free(path);
	return buf;
}
Exemplo n.º 7
0
/* Return values:
 * - -1 error
 * - 0 nothing
 * - 1 detach */
int cnode_read(int fd, char **ret_str) {
	ei_x_buff x;
	erlang_msg msg;
	int result, index, o_index, arity, type, size, ver, rv = CNODE_IGNORE;
	const char *str;
	char *s;
	char atom[MAXATOMLEN];

	ei_x_new(&x);
	/* We don't use xreceive because we're not expecting any big
	   messages and we don't want a huge term to cause our memory
	   usage to blow out and crash us. */
	/* Use a timeout of 1 millisecond even though we know we'll
	   be able to read at least some bytes, just to be sure we
	   do not get blocked (for long). Really we want to specify
	   "no timeout but don't block" to ei_receive_msg but it
	   doesn't provide that functionality. */
	result = ei_receive_msg_tmo(fd, &msg, &x, 1);

	if (result < 0) {
		LOG_V("ei_receive_msg_tmo failed (%d): %s", erl_errno, strerror(erl_errno));
		switch (erl_errno) {
			case ETIMEDOUT:
				DEBUG("ei_receive_msg_tmo: timed out.");
				break;
			case EAGAIN:
				DEBUG("ei_receive_msg_tmo: try again");
				break;
			case EMSGSIZE:
				DEBUG("ei_receive_msg_tmo: message too big");
				rv = CNODE_ERROR;
				break;
			case EIO:
				LOG_V("ei_receive_msg_tmo: IO error (%d: %s)", errno, strerror(errno));
				if (errno != EAGAIN)
					rv = CNODE_ERROR;
				break;
		}
	}
	else {
		if (result == ERL_TICK) { /* nothing to do */
			DEBUG("node tick message");
		}
		else {
			switch (msg.msgtype) {
				case ERL_SEND: str = "SEND"; break;
				case ERL_REG_SEND: str = "REG_SEND"; break;
				case ERL_LINK: str = "LINK"; break;
				case ERL_UNLINK: str = "UNLINK"; break;
				default: str = "unknown";
			}
			if (msg.msgtype == ERL_REG_SEND) {
				index = 0;

				if (ei_decode_version(x.buff, &index, &ver) == 0) {
					// DEBUG_V("data ver %d", ver);
				}

				o_index = index;

				if (ei_decode_atom(x.buff, &index, atom) == 0) {
					// DEBUG_V("atom %s", atom);
					if (!strcmp(atom, "detach")) {
						DEBUG("got detach message");
						rv = CNODE_DETACH;
					}
					else if (!strcmp(atom, "thump")) {
						rv = CNODE_THUMP;
					}
					else {
						DEBUG("message is unknown");
					}
				}
				else if (ei_decode_tuple_header(x.buff, &index, &arity) == 0) {
					if ((arity == 2)
					&& !ei_decode_atom(x.buff, &index, atom) && !strcmp(atom, "stdout")
					&& !ei_get_type(x.buff, &index, &type, &size)
					&& (type == ERL_STRING_EXT)) {
						*ret_str = (char *)malloc(size + 1);
						if (ei_decode_string(x.buff, &index, *ret_str)) {
							LOG("Failed to decode string for stdout message.");
							free(*ret_str);
							rv = CNODE_ERROR;
						}
						else
							rv = CNODE_STR;
					}
					else {
						index = o_index; // Re-set index to beginning of term.
						s = 0;
						ei_s_print_term(&s, x.buff, &index);
						LOG_V("Unknown tuple (arity %d): %s", arity, s);
						free(s);
					}
				}
				else {
					s = 0;
					ei_s_print_term(&s, x.buff, &index);
					LOG_V("Unknown message: %s", s);
					free(s);
				}
			}
			else {
				DEBUG_V("received %s message", str);
			}
		}
	}
	ei_x_free(&x);
	return rv;
}
Exemplo n.º 8
0
void log_open() {
	const char *tmp_log_file_name = log_file_name ? log_file_name : DEFAULT_LOG_FILE;
	DEBUG_V("Using log file %s", tmp_log_file_name);
	CHECK_F(log_file_fd = open(tmp_log_file_name, O_WRONLY | O_CREAT | O_APPEND | O_LARGEFILE, 0644), "open(%s)", tmp_log_file_name);
}
Exemplo n.º 9
0
/**
 * Get creature by tag
 * @param tag The Creature's tag.
 * @return The Object pointer if found, otherwise NULL
 */
Creature* Container::getCreatureByTag(const string tag) {
	DEBUG_V("Entering function getCreatureByTag...");
	return dynamic_cast<Creature*>(getTaggedByTag_(tag));
}
Exemplo n.º 10
0
RigidBody* Container::getRigidBodyByTag(const string tag) {
	DEBUG_V("Entering function getObjectByTag...");
	return dynamic_cast<RigidBody*>(getTaggedByTag_(tag));
}
Exemplo n.º 11
0
/**
 * Gets the area based on the tag name.
 * @param tag The Area's tag.
 * @return The area pointer if found, otherwise NULL.
 */
Area* Container::getAreaByTag(const string tag) {
	#warning ['TODO']: Probabbly faster to get this from Area list...
	DEBUG_V("Entering function getAreaByTag...");
	return dynamic_cast<Area*>(getTaggedByTag_(tag));
}