Example #1
0
/*
 * Handle SIGUSR1 by replacing the current process's options with those
 * being passed in via IPC message. The message queue is deleted afterwards.
 */
static void remote__sig_usr1(int s)
{
	struct remote_msg msgbuf;
	struct msqid_ds qbuf;
	ssize_t got;
	int msgid;

	memset(&msgbuf, 0, sizeof(msgbuf));

	msgid = remote__msgget(remote__opts);
	if (msgid < 0) {
		return;
	}

	got =
	    msgrcv(msgid, &msgbuf, sizeof(msgbuf) - sizeof(long), getpid(),
		   IPC_NOWAIT);
	if (got < 0) {
		msgctl(msgid, IPC_RMID, &qbuf);
		return;
	}

	if (msgctl(msgid, IPC_RMID, &qbuf) == 0) {
		if (qbuf.msg_qnum < 1) {
			msgctl(msgid, IPC_RMID, &qbuf);
		}
	}

	if ((got < 1) || (remote__opts == NULL)) {
		return;
	}


	remote__opts->progress = msgbuf.progress;
	remote__opts->timer = msgbuf.timer;
	remote__opts->eta = msgbuf.eta;
	remote__opts->rate = msgbuf.rate;
	remote__opts->average_rate = msgbuf.average_rate;

	if (msgbuf.rate_limit > 0)
		remote__opts->rate_limit = msgbuf.rate_limit;
	if (msgbuf.buffer_size > 0) {
		remote__opts->buffer_size = msgbuf.buffer_size;
		pv_set_buffer_size(msgbuf.buffer_size, 1);
	}
	if (msgbuf.size > 0)
		remote__opts->size = msgbuf.size;
	if (msgbuf.interval > 0)
		remote__opts->interval = msgbuf.interval;
	if (msgbuf.width > 0)
		remote__opts->width = msgbuf.width;
	if (msgbuf.height > 0)
		remote__opts->height = msgbuf.height;
	if (msgbuf.name[0] != 0)
		remote__opts->name = strdup(msgbuf.name);
}
Example #2
0
File: remote.c Project: icetee/pv
/*
 * Check for an IPC remote handling message and, if there is one, replace
 * the current process's options with those being passed in.
 *
 * NB relies on pv_state_set_format() causing the output format to be
 * reparsed.
 */
void pv_remote_check(pvstate_t state)
{
	struct remote_msg msgbuf;
	int got;

	if (remote__msgid < 0)
		return;

	memset(&msgbuf, 0, sizeof(msgbuf));

	got =
	    msgrcv(remote__msgid, &msgbuf, sizeof(msgbuf) - sizeof(long),
		   getpid(), IPC_NOWAIT);
	if (got < 0) {
		/*
		 * If our queue had been deleted, re-create it.
		 */
		if (errno != EAGAIN && errno != ENOMSG) {
			remote__msgid = remote__msgget();
		}
	}
	if (got < 1)
		return;

	debug("%s", "received remote message");

	pv_state_format_string_set(state, NULL);
	pv_state_name_set(state, NULL);

	pv_state_set_format(state, msgbuf.progress, msgbuf.timer,
			    msgbuf.eta, msgbuf.fineta, msgbuf.rate,
			    msgbuf.average_rate,
			    msgbuf.bytes, msgbuf.bufpercent,
			    msgbuf.lastwritten,
			    0 ==
			    msgbuf.name[0] ? NULL : strdup(msgbuf.name));

	if (msgbuf.rate_limit > 0)
		pv_state_rate_limit_set(state, msgbuf.rate_limit);
	if (msgbuf.buffer_size > 0) {
		pv_state_target_buffer_size_set(state, msgbuf.buffer_size);
	}
	if (msgbuf.size > 0)
		pv_state_size_set(state, msgbuf.size);
	if (msgbuf.interval > 0)
		pv_state_interval_set(state, msgbuf.interval);
	if (msgbuf.width > 0)
		pv_state_width_set(state, msgbuf.width);
	if (msgbuf.height > 0)
		pv_state_height_set(state, msgbuf.height);
	if (msgbuf.format[0] != 0)
		pv_state_format_string_set(state, strdup(msgbuf.format));
}
Example #3
0
/*
 * Set the options of a remote process by setting up an IPC message queue,
 * sending a message containing the new options, and then sending a SIGUSR1
 * so the process knows it has a message to read.
 *
 * Returns nonzero on error.
 */
int remote_set(opts_t opts)
{
	struct remote_msg msgbuf;
	int msgid;

	memset(&msgbuf, 0, sizeof(msgbuf));
	msgbuf.mtype = opts->remote;
	msgbuf.progress = opts->progress;
	msgbuf.timer = opts->timer;
	msgbuf.eta = opts->eta;
	msgbuf.rate = opts->rate;
	msgbuf.average_rate = opts->average_rate;
	msgbuf.rate_limit = opts->rate_limit;
	msgbuf.buffer_size = opts->buffer_size;
	msgbuf.size = opts->size;
	msgbuf.interval = opts->interval;
	msgbuf.width = opts->width;
	msgbuf.height = opts->height;
	if (opts->name != NULL) {
		strncpy(msgbuf.name, opts->name, sizeof(msgbuf.name) - 1);
	}

	msgid = remote__msgget(opts);
	if (msgid < 0) {
		fprintf(stderr, "%s: %s\n", opts->program_name,
			strerror(errno));
		return 1;
	}

	if (msgsnd(msgid, &msgbuf, sizeof(msgbuf) - sizeof(long), 0) != 0) {
		fprintf(stderr, "%s: %s\n", opts->program_name,
			strerror(errno));
		return 1;
	}

	if (kill(opts->remote, SIGUSR1) != 0) {
		fprintf(stderr, "%s: %s\n", opts->program_name,
			strerror(errno));
		return 1;
	}

	return 0;
}
Example #4
0
File: remote.c Project: icetee/pv
/*
 * Set the options of a remote process by setting up an IPC message queue,
 * sending a message containing the new options, and then waiting for the
 * message to be consumed by the remote process.
 *
 * Returns nonzero on error.
 */
int pv_remote_set(opts_t opts)
{
	struct remote_msg msgbuf;
	struct msqid_ds qbuf;
	long timeout;
	int msgid;
	long initial_qnum;

	/*
	 * Check that the remote process exists.
	 */
	if (kill(opts->remote, 0) != 0) {
		fprintf(stderr, "%s: %d: %s\n", opts->program_name,
			opts->remote, strerror(errno));
		return 1;
	}

	/*
	 * Make sure parameters are within sensible bounds.
	 */
	if (opts->width < 0)
		opts->width = 80;
	if (opts->height < 0)
		opts->height = 25;
	if (opts->width > 999999)
		opts->width = 999999;
	if (opts->height > 999999)
		opts->height = 999999;
	if ((opts->interval != 0) && (opts->interval < 0.1))
		opts->interval = 0.1;
	if (opts->interval > 600)
		opts->interval = 600;

	/*
	 * Copy parameters into message buffer.
	 */
	memset(&msgbuf, 0, sizeof(msgbuf));
	msgbuf.mtype = opts->remote;
	msgbuf.progress = opts->progress;
	msgbuf.timer = opts->timer;
	msgbuf.eta = opts->eta;
	msgbuf.fineta = opts->fineta;
	msgbuf.rate = opts->rate;
	msgbuf.average_rate = opts->average_rate;
	msgbuf.bytes = opts->bytes;
	msgbuf.bufpercent = opts->bufpercent;
	msgbuf.lastwritten = opts->lastwritten;
	msgbuf.rate_limit = opts->rate_limit;
	msgbuf.buffer_size = opts->buffer_size;
	msgbuf.size = opts->size;
	msgbuf.interval = opts->interval;
	msgbuf.width = opts->width;
	msgbuf.height = opts->height;
	if (opts->name != NULL) {
		strncpy(msgbuf.name, opts->name, sizeof(msgbuf.name) - 1);
	}
	if (opts->format != NULL) {
		strncpy(msgbuf.format, opts->format,
			sizeof(msgbuf.format) - 1);
	}

	msgid = remote__msgget();
	if (msgid < 0) {
		fprintf(stderr, "%s: %s\n", opts->program_name,
			strerror(errno));
		return 1;
	}

	if (msgctl(msgid, IPC_STAT, &qbuf) < 0) {
		fprintf(stderr, "%s: %s\n", opts->program_name,
			strerror(errno));
		return 1;
	}

	initial_qnum = qbuf.msg_qnum;

	if (msgsnd(msgid, &msgbuf, sizeof(msgbuf) - sizeof(long), 0) != 0) {
		fprintf(stderr, "%s: %s\n", opts->program_name,
			strerror(errno));
		return 1;
	}

	timeout = 1100000;

	while (timeout > 10000) {
		struct timeval tv;

		tv.tv_sec = 0;
		tv.tv_usec = 10000;
		select(0, NULL, NULL, NULL, &tv);
		timeout -= 10000;

		/*
		 * If we can't stat the queue, it must have been deleted.
		 */
		if (msgctl(msgid, IPC_STAT, &qbuf) < 0)
			break;

		/*
		 * If the message count is at or below the message count
		 * before we sent our message, assume it was received.
		 */
		if (qbuf.msg_qnum <= initial_qnum) {
			return 0;
		}
	}

	/*
	 * Message not received - delete it.
	 */
	if (msgctl(msgid, IPC_STAT, &qbuf) >= 0) {
		msgrcv(msgid, &msgbuf, sizeof(msgbuf) - sizeof(long),
		       opts->remote, IPC_NOWAIT);
		/*
		 * If this leaves nothing on the queue, remove the
		 * queue, in case we created one for no reason.
		 */
		if (msgctl(msgid, IPC_STAT, &qbuf) >= 0) {
			if (qbuf.msg_qnum < 1)
				msgctl(msgid, IPC_RMID, &qbuf);
		}
	}

	fprintf(stderr, "%s: %d: %s\n", opts->program_name, opts->remote,
		_("message not received"));
	return 1;
}
Example #5
0
File: remote.c Project: icetee/pv
/*
 * Initialise remote message reception handling.
 */
void pv_remote_init(void)
{
	remote__msgid = remote__msgget();
}