ipc_recv_message: store message_type, don’t compare. add distinct EOF retval
Also use ELOG, which requires i3-msg to provide logging functions.
This commit is contained in:
parent
e8fa3eeebd
commit
dcb8ac84f8
|
@ -36,6 +36,26 @@
|
|||
|
||||
static char *socket_path;
|
||||
|
||||
/*
|
||||
* Having verboselog() and errorlog() is necessary when using libi3.
|
||||
*
|
||||
*/
|
||||
void verboselog(char *fmt, ...) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vfprintf(stdout, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void errorlog(char *fmt, ...) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
socket_path = getenv("I3SOCK");
|
||||
int o, option_index = 0;
|
||||
|
@ -135,13 +155,16 @@ int main(int argc, char *argv[]) {
|
|||
return 0;
|
||||
|
||||
uint32_t reply_length;
|
||||
uint32_t reply_type;
|
||||
uint8_t *reply;
|
||||
int ret;
|
||||
if ((ret = ipc_recv_message(sockfd, message_type, &reply_length, &reply)) != 0) {
|
||||
if ((ret = ipc_recv_message(sockfd, &reply_type, &reply_length, &reply)) != 0) {
|
||||
if (ret == -1)
|
||||
err(EXIT_FAILURE, "IPC: read()");
|
||||
exit(1);
|
||||
}
|
||||
if (reply_type != message_type)
|
||||
errx(EXIT_FAILURE, "IPC: Received reply of type %d but expected %d", reply_type, message_type);
|
||||
printf("%.*s\n", reply_length, reply);
|
||||
free(reply);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* vim:ts=4:sw=4:expandtab
|
||||
*
|
||||
* i3 - an improved dynamic tiling window manager
|
||||
* © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
|
||||
* © 2009-2013 Michael Stapelberg and contributors (see also: LICENSE)
|
||||
*
|
||||
* libi3: contains functions which are used by i3 *and* accompanying tools such
|
||||
* as i3-msg, i3-config-wizard, …
|
||||
|
@ -216,7 +216,7 @@ int ipc_send_message(int sockfd, const uint32_t message_size,
|
|||
* Returns 0 on success.
|
||||
*
|
||||
*/
|
||||
int ipc_recv_message(int sockfd, uint32_t message_type,
|
||||
int ipc_recv_message(int sockfd, uint32_t *message_type,
|
||||
uint32_t *reply_length, uint8_t **reply);
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* vim:ts=4:sw=4:expandtab
|
||||
*
|
||||
* i3 - an improved dynamic tiling window manager
|
||||
* © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
|
||||
* © 2009-2013 Michael Stapelberg and contributors (see also: LICENSE)
|
||||
*
|
||||
*/
|
||||
#include <string.h>
|
||||
|
@ -10,6 +10,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <i3/ipc.h>
|
||||
|
||||
|
@ -20,57 +21,56 @@
|
|||
* (reply_length) as well as a pointer to its contents (reply).
|
||||
*
|
||||
* Returns -1 when read() fails, errno will remain.
|
||||
* Returns -2 when the IPC protocol is violated (invalid magic, unexpected
|
||||
* Returns -2 on EOF.
|
||||
* Returns -3 when the IPC protocol is violated (invalid magic, unexpected
|
||||
* message type, EOF instead of a message). Additionally, the error will be
|
||||
* printed to stderr.
|
||||
* Returns 0 on success.
|
||||
*
|
||||
*/
|
||||
int ipc_recv_message(int sockfd, uint32_t message_type,
|
||||
int ipc_recv_message(int sockfd, uint32_t *message_type,
|
||||
uint32_t *reply_length, uint8_t **reply) {
|
||||
/* Read the message header first */
|
||||
uint32_t to_read = strlen(I3_IPC_MAGIC) + sizeof(uint32_t) + sizeof(uint32_t);
|
||||
const uint32_t to_read = strlen(I3_IPC_MAGIC) + sizeof(uint32_t) + sizeof(uint32_t);
|
||||
char msg[to_read];
|
||||
char *walk = msg;
|
||||
|
||||
uint32_t read_bytes = 0;
|
||||
while (read_bytes < to_read) {
|
||||
int n = read(sockfd, msg + read_bytes, to_read);
|
||||
int n = read(sockfd, msg + read_bytes, to_read - read_bytes);
|
||||
if (n == -1)
|
||||
return -1;
|
||||
if (n == 0) {
|
||||
fprintf(stderr, "IPC: received EOF instead of reply\n");
|
||||
ELOG("IPC: received EOF instead of reply\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
read_bytes += n;
|
||||
to_read -= n;
|
||||
}
|
||||
|
||||
if (memcmp(walk, I3_IPC_MAGIC, strlen(I3_IPC_MAGIC)) != 0) {
|
||||
fprintf(stderr, "IPC: invalid magic in reply\n");
|
||||
return -2;
|
||||
ELOG("IPC: invalid magic in reply\n");
|
||||
return -3;
|
||||
}
|
||||
|
||||
walk += strlen(I3_IPC_MAGIC);
|
||||
*reply_length = *((uint32_t*)walk);
|
||||
walk += sizeof(uint32_t);
|
||||
if (*((uint32_t*)walk) != message_type) {
|
||||
fprintf(stderr, "IPC: unexpected reply type (got %d, expected %d)\n", *((uint32_t*)walk), message_type);
|
||||
return -2;
|
||||
}
|
||||
if (message_type != NULL)
|
||||
*message_type = *((uint32_t*)walk);
|
||||
|
||||
*reply = smalloc(*reply_length);
|
||||
|
||||
to_read = *reply_length;
|
||||
read_bytes = 0;
|
||||
while (read_bytes < to_read) {
|
||||
int n = read(sockfd, *reply + read_bytes, to_read);
|
||||
if (n == -1)
|
||||
int n;
|
||||
while (read_bytes < *reply_length) {
|
||||
if ((n = read(sockfd, *reply + read_bytes, *reply_length - read_bytes)) == -1) {
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
continue;
|
||||
return -1;
|
||||
}
|
||||
|
||||
read_bytes += n;
|
||||
to_read -= n;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -101,15 +101,18 @@ void display_running_version(void) {
|
|||
err(EXIT_FAILURE, "IPC: write()");
|
||||
|
||||
uint32_t reply_length;
|
||||
uint32_t reply_type;
|
||||
uint8_t *reply;
|
||||
int ret;
|
||||
if ((ret = ipc_recv_message(sockfd, I3_IPC_MESSAGE_TYPE_GET_VERSION,
|
||||
&reply_length, &reply)) != 0) {
|
||||
if ((ret = ipc_recv_message(sockfd, &reply_type, &reply_length, &reply)) != 0) {
|
||||
if (ret == -1)
|
||||
err(EXIT_FAILURE, "IPC: read()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (reply_type != I3_IPC_MESSAGE_TYPE_GET_VERSION)
|
||||
errx(EXIT_FAILURE, "Got reply type %d, but expected %d (GET_VERSION)", reply_type, I3_IPC_MESSAGE_TYPE_GET_VERSION);
|
||||
|
||||
#if YAJL_MAJOR >= 2
|
||||
yajl_handle handle = yajl_alloc(&version_callbacks, NULL, NULL);
|
||||
#else
|
||||
|
|
|
@ -460,14 +460,16 @@ int main(int argc, char *argv[]) {
|
|||
err(EXIT_FAILURE, "IPC: write()");
|
||||
|
||||
uint32_t reply_length;
|
||||
uint32_t reply_type;
|
||||
uint8_t *reply;
|
||||
int ret;
|
||||
if ((ret = ipc_recv_message(sockfd, I3_IPC_MESSAGE_TYPE_COMMAND,
|
||||
&reply_length, &reply)) != 0) {
|
||||
if ((ret = ipc_recv_message(sockfd, &reply_type, &reply_length, &reply)) != 0) {
|
||||
if (ret == -1)
|
||||
err(EXIT_FAILURE, "IPC: read()");
|
||||
return 1;
|
||||
}
|
||||
if (reply_type != I3_IPC_MESSAGE_TYPE_COMMAND)
|
||||
errx(EXIT_FAILURE, "IPC: received reply of type %d but expected %d (COMMAND)", reply_type, I3_IPC_MESSAGE_TYPE_COMMAND);
|
||||
printf("%.*s\n", reply_length, reply);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue