swaybar: rewrite text protocol handling
This now uses getline to correctly handle multiple or long statuses. It also removes the struct text_protocol_state and moves its members into the status_line struct.
This commit is contained in:
parent
babd9618b9
commit
70245c2cd5
|
@ -12,11 +12,6 @@ enum status_protocol {
|
||||||
PROTOCOL_I3BAR,
|
PROTOCOL_I3BAR,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct text_protocol_state {
|
|
||||||
char *buffer;
|
|
||||||
size_t buffer_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum json_node_type {
|
enum json_node_type {
|
||||||
JSON_NODE_UNKNOWN,
|
JSON_NODE_UNKNOWN,
|
||||||
JSON_NODE_ARRAY,
|
JSON_NODE_ARRAY,
|
||||||
|
@ -63,7 +58,8 @@ struct status_line {
|
||||||
const char *text;
|
const char *text;
|
||||||
struct wl_list blocks; // i3bar_block::link
|
struct wl_list blocks; // i3bar_block::link
|
||||||
|
|
||||||
struct text_protocol_state text_state;
|
char *buffer;
|
||||||
|
size_t buffer_size;
|
||||||
struct i3bar_protocol_state i3bar_state;
|
struct i3bar_protocol_state i3bar_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,27 +30,17 @@ void status_error(struct status_line *status, const char *text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool status_handle_readable(struct status_line *status) {
|
bool status_handle_readable(struct status_line *status) {
|
||||||
|
ssize_t read_bytes = 1;
|
||||||
char *line;
|
char *line;
|
||||||
switch (status->protocol) {
|
switch (status->protocol) {
|
||||||
case PROTOCOL_ERROR:
|
|
||||||
return false;
|
|
||||||
case PROTOCOL_I3BAR:
|
case PROTOCOL_I3BAR:
|
||||||
if (i3bar_handle_readable(status) > 0) {
|
if (i3bar_handle_readable(status) > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROTOCOL_TEXT:
|
|
||||||
line = read_line_buffer(status->read,
|
|
||||||
status->text_state.buffer, status->text_state.buffer_size);
|
|
||||||
if (!line) {
|
|
||||||
status_error(status, "[error reading from status command]");
|
|
||||||
} else {
|
|
||||||
status->text = line;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
case PROTOCOL_UNDEF:
|
case PROTOCOL_UNDEF:
|
||||||
line = read_line_buffer(status->read,
|
line = read_line_buffer(status->read,
|
||||||
status->text_state.buffer, status->text_state.buffer_size);
|
status->buffer, status->buffer_size);
|
||||||
if (!line) {
|
if (!line) {
|
||||||
status_error(status, "[error reading from status command]");
|
status_error(status, "[error reading from status command]");
|
||||||
return false;
|
return false;
|
||||||
|
@ -81,7 +71,7 @@ bool status_handle_readable(struct status_line *status) {
|
||||||
}
|
}
|
||||||
|
|
||||||
status->protocol = PROTOCOL_I3BAR;
|
status->protocol = PROTOCOL_I3BAR;
|
||||||
free(status->text_state.buffer);
|
free(status->buffer);
|
||||||
wl_list_init(&status->blocks);
|
wl_list_init(&status->blocks);
|
||||||
status->i3bar_state.buffer_size = 4096;
|
status->i3bar_state.buffer_size = 4096;
|
||||||
status->i3bar_state.buffer =
|
status->i3bar_state.buffer =
|
||||||
|
@ -91,14 +81,32 @@ bool status_handle_readable(struct status_line *status) {
|
||||||
status->text = line;
|
status->text = line;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
case PROTOCOL_TEXT:
|
||||||
|
errno = 0;
|
||||||
|
while (true) {
|
||||||
|
if (status->buffer[read_bytes - 1] == '\n') {
|
||||||
|
status->buffer[read_bytes - 1] = '\0';
|
||||||
|
}
|
||||||
|
read_bytes = getline(&status->buffer,
|
||||||
|
&status->buffer_size, status->read);
|
||||||
|
if (errno == EAGAIN) {
|
||||||
|
clearerr(status->read);
|
||||||
|
return true;
|
||||||
|
} else if (errno) {
|
||||||
|
status_error(status, "[error reading from status command]");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct status_line *status_line_init(char *cmd) {
|
struct status_line *status_line_init(char *cmd) {
|
||||||
struct status_line *status = calloc(1, sizeof(struct status_line));
|
struct status_line *status = calloc(1, sizeof(struct status_line));
|
||||||
status->text_state.buffer_size = 8192;
|
status->buffer_size = 8192;
|
||||||
status->text_state.buffer = malloc(status->text_state.buffer_size);
|
status->buffer = malloc(status->buffer_size);
|
||||||
|
|
||||||
int pipe_read_fd[2];
|
int pipe_read_fd[2];
|
||||||
int pipe_write_fd[2];
|
int pipe_write_fd[2];
|
||||||
|
@ -148,7 +156,7 @@ void status_line_free(struct status_line *status) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
free(status->text_state.buffer);
|
free(status->buffer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free(status);
|
free(status);
|
||||||
|
|
Loading…
Reference in a new issue