Exemplo n.º 1
0
static int FUNC_FS_PROCESS_STOP(struct cmd_data *data)
{
	struct fs_process_ctx *ctx;
	int ret = 0;

	if (data->idx < 0 || data->idx > MAX_PROCESS_CNT) {
		ERROR("index out of range %d", data->idx);
		return -1;
	}

	ctx = &g_proc_context[data->idx];

	if (!ctx->status) {
		ERROR("process %d does not exist", data->idx);
		return -1;
	}

	if (ctx->pid != 0) {
		ret = pclose_ext(ctx->pid, 1);
		if (ret)
			ERROR("process %d failed\n", ctx->pid);
		close(ctx->stdout);
		ctx->pid = 0;
	}

	ctx->status = 0;

	return ret;
}
Exemplo n.º 2
0
static bool Execute_and_report_output (const char* executable, const char* client_host_name, const char* client_IP,
									   const uint16_t client_port, const char* event, TEventType event_type, const size_t payload_len,
									   const char** payload, const int *fd_to_close_in_child, const int fd_to_close_in_child_count)
{

	/* command <client IP> <client port> <event type> <event> <payload length> <payload 1> ...<payload n> */

	size_t i = 0;
	size_t len = 0;
	size_t buffer_len = 8 + payload_len;

	size_t line_buffer_len = 0;
	char* line_buffer = NULL;
	size_t line_len = 0;
	int linenr;
	bool eof_found;
	FILE *pipe_read, *pipe_write;

	char** argv = NULL;
	pid_t childpid = 0;

	int cmdres = 255;
	bool res = false;

	bool close_received = false;
	bool error_executing = false;
	bool timer_failed = false;
	bool message_line = false;

	/* command <client host name> <client IP> <client port> <event type> <event> <payload length> <payload 1> ...<payload n> */

	if (!Add_string_to_string_array (&argv, &len, &buffer_len, executable))
	{
		Free_string_array (&argv, &len, &buffer_len);
		return false;
	}

	if (!Add_string_to_string_array (&argv, &len, &buffer_len, client_host_name))
	{
		Free_string_array (&argv, &len, &buffer_len);
		return false;
	}

	if (!Add_string_to_string_array (&argv, &len, &buffer_len, client_IP))
	{
		Free_string_array (&argv, &len, &buffer_len);
		return false;
	}

	if (!Add_luint_to_string_array (&argv, &len, &buffer_len, client_port))
	{
		Free_string_array (&argv, &len, &buffer_len);
		return false;
	}

	if (!Add_luint_to_string_array (&argv, &len, &buffer_len, event_type))
	{
		Free_string_array (&argv, &len, &buffer_len);
		return false;
	}

	if (!Add_string_to_string_array (&argv, &len, &buffer_len, event))
	{
		Free_string_array (&argv, &len, &buffer_len);
		return false;
	}

	if (!Add_luint_to_string_array (&argv, &len, &buffer_len, payload_len))
	{
		Free_string_array (&argv, &len, &buffer_len);
		return false;
	}

	for (i = 0; i < payload_len; i++)
	{
		if (!Add_string_to_string_array (&argv, &len, &buffer_len, payload[i]))
		{
			Free_string_array (&argv, &len, &buffer_len);
			return false;
		}
	}

	errno = 0;

	line_buffer_len = LINE_BUFFER_SIZE;

	line_buffer = malloc (LINE_BUFFER_SIZE);

	bzero (line_buffer, LINE_BUFFER_SIZE);

	if (line_buffer == NULL)
	{
		Free_string_array (&argv, &len, &buffer_len);
		return false;
	}

	if (!popen_ext (argv[0], argv, true, &pipe_read, &pipe_write, NULL, false, false, false,
					&childpid, fd_to_close_in_child, fd_to_close_in_child_count))
	{
		Free_string_array (&argv, &len, &buffer_len);
		Free_string (&line_buffer);
		return false;
	}

	/* Set the buffering to lines for the write pipe end. */
	setlinebuf (pipe_write);

	linenr = 1;

	while (!close_received)
	{
		errno = 0;

		if (!Set_alarm_timer (EXECUTE_READ_WRITE_LINE_TIME_OUT))
		{
			timer_failed = true;
			break;
		}

		error_executing = (!Read_line (pipe_read, &line_buffer,
												&line_buffer_len, &line_len,
												&eof_found, false, false));

		if (!Set_alarm_timer (0.0))
		{
			timer_failed = true;
			break;
		}

		if (error_executing)
			break;

		if ( ( (line_len == strlen (CLOSE_MY_MSG)) &&
				(strncmp (line_buffer, CLOSE_MY_MSG, line_len) == 0)))
		{
			/* Child indicates termination. */
			close_received = true;
		}


		if (!close_received)
		{
			if (linenr == 1)
			{
				/* HELLO message expected from child. */

				if ( (line_len != strlen (HELLO_MY_MSG)) ||
						(strncmp (line_buffer, HELLO_MY_MSG, line_len) != 0))
				{
					/* Invalid HELLO message. */

					error_executing = true;
					break;
				}
			}
			else
			{
				/* PAYLOAD message expected from child, requesting a payload line. */

				if ( (line_len == strlen (PAYLOAD_MY_MSG)) &&
						(strncmp (line_buffer, PAYLOAD_MY_MSG, line_len) == 0) &&
						( (size_t) (linenr - 2) < payload_len))
				{
					if (!Set_alarm_timer (EXECUTE_READ_WRITE_LINE_TIME_OUT))
					{
						timer_failed = true;
						break;
					}

					if (!Write_line (pipe_write, payload[linenr - 2]))
					{
						error_executing = true;
						break;
					}

					if (!Set_alarm_timer (0.0))
					{
						timer_failed = true;
						break;
					}
				}
				else if (!message_line)
				{
					/* Child process sended an extra info line. */

					message_line = true;
				}
				else
				{
					/* Invalid message or no more payload lines. */

					error_executing = true;
					break;
				}
			}
		}

		Vlogit (tll_debug,
				LOG_COMMAND_OUTPUT,
				LOGLEVELNAME (tll_debug),
				PROCESS_P_C (g_daemonized, g_processor),
				getpid(), linenr, line_buffer);

		++linenr;

		if (!Set_alarm_timer (EXECUTE_READ_WRITE_LINE_TIME_OUT))
		{
			timer_failed = true;
			break;
		}
	}

	if (!Set_alarm_timer (0.0))
		timer_failed = true;

	Free_string (&line_buffer);

	if (error_executing || timer_failed)
	{
		/* The child process was executed but we failed to set a timer or
		to read from or to write to the process. */
		error_executing = true;

		/* Ask the child process to terminate. */
		kill (childpid, SIGTERM);
	}

	timer_failed = (!Set_alarm_timer (EXECUTE_WAIT_TIME_OUT));

	res = ( (!timer_failed) && pclose_ext (&pipe_read, &pipe_write, NULL, childpid, true, &cmdres));

	Set_alarm_timer (0.0);

	if (!res)
	{
		kill (childpid, SIGKILL);

		usleep (100000);

		waitpid (childpid, NULL, WNOHANG);

		if (pipe_read != NULL)
			fclose (pipe_read);

		if (pipe_write != NULL)
			fclose (pipe_write);
	}

	Free_string_array (&argv, &len, &buffer_len);

	return (!error_executing && res && (cmdres == 0));
}
Exemplo n.º 3
0
static int FUNC_FS_CPUUSAGE(struct cmd_data *data)
{
	struct fs_cpuusage *ctx = &g_cpuusage_ctx;
	int ret;

	if (!ctx->status) {
		char *cmd[256];

		//fp = popen("top -n 1", "re");
		cmd[0] = "top";
		cmd[1] = "-d";
		cmd[2] = "2";
		cmd[3] = NULL;

		ctx->stdout = FD_INVALID;

		ctx->fd = popen_ext(cmd, NULL, &ctx->stdout);
		if (ctx->fd == -1) {
			ERROR("popen top failed");
			return -1;
		}

		ctx->fpout = fdopen(ctx->stdout, "r");
		if (ctx->fpout == NULL) {
			ERROR("fdopen top failed");
			pclose_ext(ctx->fd, 1);
			ctx->fd = -1;
			return -1;
		}

		ctx->ev.data = ctx;
		ctx->ev.fd = ctx->stdout;
		ctx->ev.events = EPOLLIN;
		ctx->ev.func = fs_cpuusage_callback_func;

		ret = reactor_event_register(ctx->stdout, &ctx->ev);
		if (ret) {
			ERROR("reactor_event_register failed");
			close(ctx->fd);
			ctx->fd = -1;
			return -1;
		}

		ctx->status = 1;
	}

	//printf("CPU:   %d%% usr   %d%% sys   %d%% nic  %d%% idle\n",
	//		usr, sys, nice, idle);

	data->out_fields[0] = FIELD_FS_cpuusr;
	data->out_param[0] = (void*) ctx->usr;
	data->out_fields[1] = FIELD_FS_cpusys;
	data->out_param[1] = (void*) ctx->sys;
	data->out_fields[2] = FIELD_FS_cpunice;
	data->out_param[2] = (void*) ctx->nice;
	data->out_fields[3] = FIELD_FS_cpuidle;
	data->out_param[3] = (void*) ctx->idle;
	data->out_fields[4] = FIELD_FS_cpuio;
	data->out_param[4] = (void*) ctx->io;
	data->out_fields[5] = FIELD_FS_cpuirq;
	data->out_param[5] = (void*) ctx->irq;
	data->out_fields[6] = FIELD_FS_cpusirq;
	data->out_param[6] = (void*) ctx->sirq;
	data->out_fields[7] = END_OF_FIELD;

	return 0;
}
Exemplo n.º 4
0
static int FUNC_FS_PROCESS_START(struct cmd_data *data)
{
	struct fs_process_ctx *ctx;
	char *cmd[256], *pch;
	char tmpstr[1024];
	int ret, i = 0;

	if (data->idx < 0 || data->idx > MAX_PROCESS_CNT) {
		ERROR("index out of range %d", data->idx);
		return -1;
	}

	ctx = &g_proc_context[data->idx];

	if (ctx->status) {
		ERROR("process %d currently running", data->idx);
		return -1;
	}

	strcpy(tmpstr, data->command);

	/* break command string into tokens for popen/execv */
	pch = strtok(tmpstr, " ");
	while (pch != NULL && i < 256) {
		cmd[i++] = pch;
		pch = strtok(NULL, " ");
	}
	cmd[i] = NULL;

	ctx->stdin = FD_INVALID;
	ctx->stdout = FD_INVALID;

	if (data->in && strlen(data->in)) {
		ctx->stdin = open(data->in, O_RDWR);
		if (ctx->stdin == FD_INVALID) {
			ret = errno;
			ERROR("error opening in file %s %s", data->in, strerror(ret));
			goto exit_free;
		}
	}

	if (data->out && strlen(data->out)) {
		ctx->stdout = open(data->out, O_RDWR);
		if (ctx->stdout == FD_INVALID) {
			ret = errno;
			ERROR("error opening out file %s %s", data->out, strerror(ret));
			goto exit_free;
		}
	}

	ctx->pid = popen_ext(cmd, &ctx->stdin, &ctx->stdout);
	if (ctx->pid == -1) {
		ERROR("popen %s failed", data->command);
		return -1;
	}

	ctx->status = 1;

	return 0;

exit_free:
	pclose_ext(ctx->pid, 1);
	if (ctx->stdout != FD_INVALID)
		close(ctx->stdout);
	if (ctx->stdin != FD_INVALID)
		close(ctx->stdin);
	ctx->pid = -1;
	return ret;
}