X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=hotplug-dispatch.c;h=cfba7d19b745725bbf0e81eadd9639055e4b45c7;hb=f5d9b14fea85e3272cac5200fb32a5c99ba7fdff;hp=0a285c9727ebf6f9fd9f4ba92150a357644d7fc3;hpb=78d5baa015105d4f1da9499a6bbb0364843083b1;p=project%2Fprocd.git diff --git a/hotplug-dispatch.c b/hotplug-dispatch.c index 0a285c9..cfba7d1 100644 --- a/hotplug-dispatch.c +++ b/hotplug-dispatch.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -124,6 +123,7 @@ static void hotplug_exec(struct uloop_timeout *t) exit(execve(exec_argv[0], exec_argv, pc->envp)); } else if (pc->process.pid < 0) { /* fork error */ + free(script); hotplug_free(pc); return; } @@ -188,6 +188,7 @@ static int hotplug_call(struct ubus_context *ctx, struct ubus_object *obj, 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)); @@ -199,10 +200,21 @@ static int hotplug_call(struct ubus_context *ctx, struct ubus_object *obj, /* 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; } @@ -236,14 +248,26 @@ static int hotplug_call(struct ubus_context *ctx, struct ubus_object *obj, 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 */ @@ -251,7 +275,8 @@ static int hotplug_call(struct ubus_context *ctx, struct ubus_object *obj, ++envz; envp = calloc(envz + 1, sizeof(char *)); - assert(envp != NULL); + if (!envp) + goto err_envle; /* populating new environment */ envz = 0; @@ -261,25 +286,22 @@ static int hotplug_call(struct ubus_context *ctx, struct ubus_object *obj, 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) { + env_free(envp); + return UBUS_STATUS_UNKNOWN_ERROR; + } + if (glob(globstr, GLOB_DOOFFS, NULL, &pc->globbuf)) { free(globstr); hotplug_free(pc); @@ -292,6 +314,17 @@ static int hotplug_call(struct ubus_context *ctx, struct ubus_object *obj, 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[] = { @@ -408,10 +441,18 @@ void ubus_init_hotplug(struct ubus_context *newctx) } 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); }