properly handle return codes
[project/procd.git] / plug / hotplug.c
index 07abaf8..1a98e8b 100644 (file)
@@ -22,6 +22,7 @@
 #include <libubox/blobmsg_json.h>
 #include <libubox/json_script.h>
 #include <libubox/uloop.h>
+#include <json-c/json.h>
 
 #include <fcntl.h>
 #include <unistd.h>
@@ -161,10 +162,10 @@ static void handle_firmware(struct blob_attr *msg, struct blob_attr *data)
        char *dir = blobmsg_get_string(blobmsg_data(data));
        char *file = hotplug_msg_find_var(msg, "FIRMWARE");
        char *dev = hotplug_msg_find_var(msg, "DEVPATH");
-       void *fw_data;
-       struct stat s;
+       struct stat s = { 0 };
        char *path, loadpath[256], syspath[256];
-       int fw, load, sys, len;
+       int fw, src, load, len;
+       static char buf[4096];
 
        DEBUG(2, "Firmware request for %s/%s\n", dir, file);
 
@@ -173,62 +174,62 @@ static void handle_firmware(struct blob_attr *msg, struct blob_attr *data)
                exit(-1);
        }
 
-       path = malloc(strlen(dir) + strlen(file) + 2);
-       if (!path) {
-               ERROR("Failed to allocate memory\n");
-               exit(-1);
-       }
+       path = alloca(strlen(dir) + strlen(file) + 2);
        sprintf(path, "%s/%s", dir, file);
 
        if (stat(path, &s)) {
                ERROR("Could not find firmware %s\n", path);
-               exit(-1);
-       }
-
-       fw_data = malloc(s.st_size);
-       if (!fw_data) {
-               ERROR("Failed to allocate firmware data memory\n");
-               exit(-1);
+               src = -1;
+               s.st_size = 0;
+               goto send_to_kernel;
        }
 
-       fw = open(path, O_RDONLY);
-       if (!fw) {
+       src = open(path, O_RDONLY);
+       if (src < 0) {
                ERROR("Failed to open %s\n", path);
-               exit(-1);
-       }
-       if (read(fw, fw_data, s.st_size) != s.st_size) {
-               ERROR("Failed to read firmware data\n");
-               exit(-1);
+               s.st_size = 0;
+               goto send_to_kernel;
        }
-       close(fw);
 
+send_to_kernel:
        snprintf(loadpath, sizeof(loadpath), "/sys/%s/loading", dev);
        load = open(loadpath, O_WRONLY);
        if (!load) {
                ERROR("Failed to open %s\n", loadpath);
                exit(-1);
        }
-       write(load, "1", 1);
+       if (write(load, "1", 1) == -1) {
+               ERROR("Failed to write to %s\n", loadpath);
+               exit(-1);
+       }
        close(load);
 
        snprintf(syspath, sizeof(syspath), "/sys/%s/data", dev);
-       sys = open(syspath, O_WRONLY);
-       if (!sys) {
+       fw = open(syspath, O_WRONLY);
+       if (fw < 0) {
                ERROR("Failed to open %s\n", syspath);
                exit(-1);
        }
 
        len = s.st_size;
-       while (len > 4096) {
-               write(fw, fw_data, 4096);
-               len -= 4096;
+       while (len) {
+               len = read(src, buf, sizeof(buf));
+               if (len <= 0)
+                       break;
+
+               if (write(fw, buf, len) == -1) {
+                       ERROR("failed to write firmware file %s/%s to %s\n", dir, file, dev);
+                       break;
+               }
        }
-       if (len)
-               write(fw, fw_data, len);
+
+       if (src >= 0)
+               close(src);
        close(fw);
 
        load = open(loadpath, O_WRONLY);
-       write(load, "0", 1);
+       if (write(load, "0", 1) == -1)
+               ERROR("failed to write to %s\n", loadpath);
        close(load);
 
        DEBUG(2, "Done loading %s\n", path);
@@ -342,7 +343,7 @@ rule_handle_file(struct json_script_ctx *ctx, const char *name)
        json_object *obj;
 
        obj = json_object_from_file((char*)name);
-       if (is_error(obj))
+       if (!obj)
                return NULL;
 
        blob_buf_init(&script, 0);
@@ -453,6 +454,7 @@ void hotplug_last_event(uloop_timeout_handler handler)
 void hotplug(char *rules)
 {
        struct sockaddr_nl nls;
+       int nlbufsize = 512 * 1024;
 
        rule_file = strdup(rules);
        memset(&nls,0,sizeof(struct sockaddr_nl));
@@ -469,6 +471,9 @@ void hotplug(char *rules)
                exit(1);
        }
 
+       if (setsockopt(hotplug_fd.fd, SOL_SOCKET, SO_RCVBUFFORCE, &nlbufsize, sizeof(nlbufsize)))
+               ERROR("Failed to resize receive buffer: %s\n", strerror(errno));
+
        json_script_init(&jctx);
        queue_proc.cb = queue_proc_cb;
        uloop_fd_add(&hotplug_fd, ULOOP_READ);