improve error handling
This commit is contained in:
parent
27a8487583
commit
8a218a7ac2
3 changed files with 44 additions and 14 deletions
4
main.c
4
main.c
|
@ -1,6 +1,8 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
const char *arg_shift(int *argc, char ***argv) {
|
const char *arg_shift(int *argc, char ***argv) {
|
||||||
|
@ -30,7 +32,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (jb_server_turn(srv) < 0) {
|
if (jb_server_turn(srv) < 0) {
|
||||||
fprintf(stderr, "server_turn failed\n");
|
fprintf(stderr, "server_turn failed (errno=%d, strerror=%s)\n", errno, strerror(errno));
|
||||||
jb_server_free(srv);
|
jb_server_free(srv);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
37
server.c
37
server.c
|
@ -403,6 +403,12 @@ void jb_server_free(struct jb_server *s)
|
||||||
{
|
{
|
||||||
if (!s) return;
|
if (!s) return;
|
||||||
if (s->sock_fd) close(s->sock_fd);
|
if (s->sock_fd) close(s->sock_fd);
|
||||||
|
// names are allocated on the heap
|
||||||
|
for (int i = 0; i < JB_MAX_NAMES; i++) {
|
||||||
|
if (s->names[i].name) {
|
||||||
|
free(s->names[i].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,6 +478,27 @@ int jb_server_turn(struct jb_server *s)
|
||||||
|
|
||||||
for (int i = 0; i < s->fd_num; i++) {
|
for (int i = 0; i < s->fd_num; i++) {
|
||||||
int fd = s->fds[i].fd;
|
int fd = s->fds[i].fd;
|
||||||
|
if (s->fds[i].revents & POLLNVAL) {
|
||||||
|
fprintf(stderr, "jb_server_turn: error: got POLLNVAL for fds[%d]. This is considered a bug in the server implementation.\n", i);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (s->fds[i].revents & POLLERR) {
|
||||||
|
if (fd == s->sock_fd) {
|
||||||
|
fprintf(stderr, "jb_server_turn: error: got POLLERR for sock_fd\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "jb_server_turn: warn: got POLLERR for fds[%d], removing...\n", i);
|
||||||
|
jb_server_client_remove(s, i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (s->fds[i].revents & POLLHUP) {
|
||||||
|
if (fd == s->sock_fd) {
|
||||||
|
fprintf(stderr, "jb_server_turn: error: got POLLHUP for sock_fd\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
jb_server_client_remove(s, i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (s->fds[i].revents & POLLIN) {
|
if (s->fds[i].revents & POLLIN) {
|
||||||
// file descriptor ready for reading
|
// file descriptor ready for reading
|
||||||
|
|
||||||
|
@ -488,15 +515,9 @@ int jb_server_turn(struct jb_server *s)
|
||||||
char data[data_buffer_len];
|
char data[data_buffer_len];
|
||||||
memset(data, 0, sizeof(data));
|
memset(data, 0, sizeof(data));
|
||||||
ssize_t bytes = recv(fd, data, sizeof(data) - 1, 0);
|
ssize_t bytes = recv(fd, data, sizeof(data) - 1, 0);
|
||||||
if (bytes < 0) {
|
if (bytes <= 0) {
|
||||||
// error during recv(), disconnect the client
|
// error during recv() OR client disconnected, disconnect the client
|
||||||
// TODO: should we actually do this?
|
// TODO: should we actually do this?
|
||||||
close(fd);
|
|
||||||
jb_server_client_remove(s, i);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (bytes == 0) {
|
|
||||||
// client disconnected
|
|
||||||
jb_server_client_remove(s, i);
|
jb_server_client_remove(s, i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
17
wire.c
17
wire.c
|
@ -3,6 +3,13 @@
|
||||||
#include "try.h"
|
#include "try.h"
|
||||||
#include "wire.h"
|
#include "wire.h"
|
||||||
|
|
||||||
|
#define WIRE_ENABLE_VERBOSE 0
|
||||||
|
#if WIRE_ENABLE_VERBOSE
|
||||||
|
#define WIRE_VERBOSE printf
|
||||||
|
#else
|
||||||
|
#define WIRE_VERBOSE(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
bool wire_align(wire_context_t *c, uint32_t alignment)
|
bool wire_align(wire_context_t *c, uint32_t alignment)
|
||||||
{
|
{
|
||||||
if ((c->byte_cursor % alignment) == 0) {
|
if ((c->byte_cursor % alignment) == 0) {
|
||||||
|
@ -130,7 +137,7 @@ int wire_parse_message(wire_context_t *c, wire_message_t *msg)
|
||||||
|
|
||||||
size_t header_fields_end = c->byte_cursor + msg->header_fields_length;
|
size_t header_fields_end = c->byte_cursor + msg->header_fields_length;
|
||||||
|
|
||||||
printf("start parse message: type=%d\n", msg->type);
|
WIRE_VERBOSE("start parse message: type=%d\n", msg->type);
|
||||||
|
|
||||||
while (c->byte_cursor < header_fields_end) {
|
while (c->byte_cursor < header_fields_end) {
|
||||||
uint8_t field_code = *(uint8_t*)TRYPTR(wire_get_u8(c));
|
uint8_t field_code = *(uint8_t*)TRYPTR(wire_get_u8(c));
|
||||||
|
@ -142,17 +149,17 @@ int wire_parse_message(wire_context_t *c, wire_message_t *msg)
|
||||||
case DBUS_HEADER_FIELD_MEMBER: /* through */
|
case DBUS_HEADER_FIELD_MEMBER: /* through */
|
||||||
case DBUS_HEADER_FIELD_DESTINATION: {
|
case DBUS_HEADER_FIELD_DESTINATION: {
|
||||||
char *str = TRYPTR(wire_get_string(c, NULL));
|
char *str = TRYPTR(wire_get_string(c, NULL));
|
||||||
printf("field: %s\n", str);
|
WIRE_VERBOSE("field: %s\n", str);
|
||||||
msg->fields[field_code].t.str = str;
|
msg->fields[field_code].t.str = str;
|
||||||
} break;
|
} break;
|
||||||
case DBUS_HEADER_FIELD_SIGNATURE: {
|
case DBUS_HEADER_FIELD_SIGNATURE: {
|
||||||
char *str = TRYPTR(wire_get_signature(c, NULL));
|
char *str = TRYPTR(wire_get_signature(c, NULL));
|
||||||
printf("field: %s\n", str);
|
WIRE_VERBOSE("field: %s\n", str);
|
||||||
msg->fields[field_code].t.str = str;
|
msg->fields[field_code].t.str = str;
|
||||||
} break;
|
} break;
|
||||||
case DBUS_HEADER_FIELD_REPLY_SERIAL: {
|
case DBUS_HEADER_FIELD_REPLY_SERIAL: {
|
||||||
uint32_t u = *(uint32_t*)TRYPTR(wire_get_u32(c));
|
uint32_t u = *(uint32_t*)TRYPTR(wire_get_u32(c));
|
||||||
printf("field: %d\n", u);
|
WIRE_VERBOSE("field: %d\n", u);
|
||||||
msg->fields[field_code].t.u32 = u;
|
msg->fields[field_code].t.u32 = u;
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
|
@ -171,7 +178,7 @@ int wire_parse_message(wire_context_t *c, wire_message_t *msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("end parse message\n");
|
WIRE_VERBOSE("end parse message\n");
|
||||||
|
|
||||||
/* header ends at 8 byte boundry */
|
/* header ends at 8 byte boundry */
|
||||||
TRYPTR(wire_align(c, 8));
|
TRYPTR(wire_align(c, 8));
|
||||||
|
|
Loading…
Reference in a new issue