summaryrefslogtreecommitdiff
path: root/src/fsckd/fsckd.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-03-09 18:45:50 +0100
committerLennart Poettering <lennart@poettering.net>2015-03-09 18:45:50 +0100
commit7046313698e449415ab76c96af4ac0b0fdbf473c (patch)
treeb7e1a8b101a7f625d7b63e88421ac5bd26adec20 /src/fsckd/fsckd.c
parente9d2527ff4b9a907cb8a4a035be646d3dd443abc (diff)
fsckd: rework plymouth connection management
- the even source should not be freed before the fd for it is closed - read() returns an ssize_t and we need to handle it as such - properly handle errors from read() - reuse on_plymouth_disconnect() whenever we disconnect from plymouth, and rename it plymouth_disconnect hence()
Diffstat (limited to 'src/fsckd/fsckd.c')
-rw-r--r--src/fsckd/fsckd.c53
1 files changed, 34 insertions, 19 deletions
diff --git a/src/fsckd/fsckd.c b/src/fsckd/fsckd.c
index 4ff8eeaecc..757b9f1143 100644
--- a/src/fsckd/fsckd.c
+++ b/src/fsckd/fsckd.c
@@ -72,7 +72,10 @@ typedef struct Manager {
FILE *console;
double percent;
int numdevices;
+
int plymouth_fd;
+ sd_event_source *plymouth_event_source;
+
bool plymouth_cancel_sent;
bool cancel_requested;
} Manager;
@@ -126,7 +129,10 @@ static void remove_client(Client **first, Client *item) {
free(item);
}
-static void on_plymouth_disconnect(Manager *m) {
+static void plymouth_disconnect(Manager *m) {
+ assert(m);
+
+ m->plymouth_event_source = sd_event_source_unref(m->plymouth_event_source);
m->plymouth_fd = safe_close(m->plymouth_fd);
m->plymouth_cancel_sent = false;
}
@@ -135,24 +141,31 @@ static int plymouth_feedback_handler(sd_event_source *s, int fd, uint32_t revent
Manager *m = userdata;
Client *current;
char buffer[6];
- int r;
+ ssize_t l;
assert(m);
- r = read(m->plymouth_fd, buffer, sizeof(buffer));
- if (r <= 0)
- on_plymouth_disconnect(m);
- else {
- if (buffer[0] == '\15')
- log_error("Message update to plymouth wasn't delivered successfully");
-
- /* the only answer support type we requested is a key interruption */
- if (buffer[0] == '\2' && buffer[5] == '\3') {
- m->cancel_requested = true;
- /* cancel all connected clients */
- LIST_FOREACH(clients, current, m->clients)
- request_cancel_client(current);
- }
+ l = read(m->plymouth_fd, buffer, sizeof(buffer));
+ if (l < 0) {
+ log_warning_errno(errno, "Got error while reading from plymouth: %m");
+ plymouth_disconnect(m);
+ return -errno;
+ }
+ if (l == 0) {
+ plymouth_disconnect(m);
+ return 0;
+ }
+
+ if (buffer[0] == '\15')
+ log_error("Message update to plymouth wasn't delivered successfully");
+
+ /* the only answer support type we requested is a key interruption */
+ if (buffer[0] == '\2' && buffer[5] == '\3') {
+ m->cancel_requested = true;
+
+ /* cancel all connected clients */
+ LIST_FOREACH(clients, current, m->clients)
+ request_cancel_client(current);
}
return 0;
@@ -276,7 +289,7 @@ static int connect_plymouth(Manager *m) {
goto fail;
}
- r = sd_event_add_io(m->event, NULL, m->plymouth_fd, EPOLLIN, plymouth_feedback_handler, m);
+ r = sd_event_add_io(m->event, &m->plymouth_event_source, m->plymouth_fd, EPOLLIN, plymouth_feedback_handler, m);
if (r < 0) {
log_warning_errno(r, "Can't listen to plymouth socket: %m");
goto fail;
@@ -285,7 +298,7 @@ static int connect_plymouth(Manager *m) {
return 0;
fail:
- on_plymouth_disconnect(m);
+ plymouth_disconnect(m);
return r;
}
@@ -395,8 +408,10 @@ static void manager_free(Manager *m) {
fflush(m->console);
}
+ plymouth_disconnect(m);
+
safe_close(m->connection_fd);
- safe_close(m->plymouth_fd);
+
if (m->console)
fclose(m->console);