#include <sys/inotify.h>
#include <sys/types.h>
-#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <glob.h>
exit(execve(exec_argv[0], exec_argv, pc->envp));
} else if (pc->process.pid < 0) {
/* fork error */
+ free(script);
hotplug_free(pc);
return;
}
size_t envz = 0;
struct hotplug_process *pc;
bool async = true;
+ int err = UBUS_STATUS_UNKNOWN_ERROR;
blobmsg_parse(hotplug_policy, __HOTPLUG_MAX, tb, blobmsg_data(msg), blobmsg_len(msg));
/* first adding existing environment to avl_tree */
while (*tmpenv) {
envle = calloc(1, sizeof(struct envlist));
- assert(envle != NULL);
+ if (!envle)
+ goto err_envle;
+
envle->env = strdup(*tmpenv);
+ if (!envle->env) {
+ free(envle);
+ goto err_envle;
+ }
envle->avl.key = envle->env;
- avl_insert(&env, &envle->avl);
+ if (avl_insert(&env, &envle->avl) == -1) {
+ free(envle->env);
+ free(envle);
+ goto err_envle;
+ }
+
++tmpenv;
}
async = false;
envle = calloc(1, sizeof(struct envlist));
- assert(envle != NULL);
+ if (!envle)
+ goto err_envle;
+
envle->env = strdup(enve);
+ if (!envle->env) {
+ free(envle);
+ goto err_envle;
+ }
envle->avl.key = envle->env;
if (avl_insert(&env, &envle->avl)) {
+ /* do not override existing env values, just skip */
free((void*)envle->env);
free(envle);
}
- ++tmpenv;
+ }
+
+ /* synchronous calls are unsupported for now */
+ if (!async) {
+ err = UBUS_STATUS_NOT_SUPPORTED;
+ goto err_envle;
}
/* allocating new environment */
++envz;
envp = calloc(envz + 1, sizeof(char *));
- assert(envp != NULL);
+ if (!envp)
+ goto err_envle;
/* populating new environment */
envz = 0;
free(envle);
}
- /* glob'ing for hotplug scripts */
- if (asprintf(&globstr, "%s/%s/*", HOTPLUG_BASEDIR, subsys) == -1) {
+ pc = calloc(1, sizeof(struct hotplug_process));
+ if (!pc) {
env_free(envp);
return UBUS_STATUS_UNKNOWN_ERROR;
}
-
- /* synchronous calls are unsupported for now */
- if (!async) {
- env_free(envp);
- return UBUS_STATUS_NOT_SUPPORTED;
- }
-
- pc = calloc(1, sizeof(struct hotplug_process));
- assert(pc != NULL);
pc->timeout.cb = hotplug_exec;
pc->envp = envp;
pc->cnt = 0;
pc->ubus = obj;
+ /* glob'ing for hotplug scripts */
+ if (asprintf(&globstr, "%s/%s/*", HOTPLUG_BASEDIR, subsys) == -1) {
+ hotplug_free(pc);
+ return UBUS_STATUS_UNKNOWN_ERROR;
+ }
+
if (glob(globstr, GLOB_DOOFFS, NULL, &pc->globbuf)) {
free(globstr);
hotplug_free(pc);
uloop_timeout_set(&pc->timeout, 50);
return UBUS_STATUS_OK;
+
+err_envle:
+ avl_for_each_element_safe(&env, envle, avl, p) {
+ if (envle->env)
+ free(envle->env);
+
+ avl_delete(&env, &envle->avl);
+ free(envle);
+ }
+
+ return err;
}
static const struct ubus_method hotplug_methods[] = {
}
fd_inotify_read.fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
fd_inotify_read.cb = inotify_read_handler;
- assert(fd_inotify_read.fd != -1);
+ if (fd_inotify_read.fd == -1) {
+ printf("failed to initialize inotify handler for %s\n", HOTPLUG_BASEDIR);
+ return;
+ }
inotify_buffer = calloc(1, INOTIFY_SZ);
- assert(inotify_buffer != NULL);
- inotify_add_watch(fd_inotify_read.fd, HOTPLUG_BASEDIR, IN_CREATE | IN_MOVED_TO | IN_DELETE | IN_MOVED_FROM | IN_ONLYDIR);
+ if (!inotify_buffer)
+ return;
+
+ if (inotify_add_watch(fd_inotify_read.fd, HOTPLUG_BASEDIR,
+ IN_CREATE | IN_MOVED_TO | IN_DELETE | IN_MOVED_FROM | IN_ONLYDIR) == -1)
+ return;
+
uloop_fd_add(&fd_inotify_read, ULOOP_READ);
}