X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=hotplug-dispatch.c;h=f1ece3833f235d59b321d6d9bd89ea3ef621fcd9;hb=8a60e7e066cb0b364cae13c524dce16743633b0a;hp=6a4fa68a00a56b1a9657f445bcb4d172bb7e1de6;hpb=08938fe1cbc06eeaafa39448057368391d165272;p=project%2Fprocd.git diff --git a/hotplug-dispatch.c b/hotplug-dispatch.c index 6a4fa68..f1ece38 100644 --- a/hotplug-dispatch.c +++ b/hotplug-dispatch.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -105,7 +104,11 @@ static void hotplug_exec(struct uloop_timeout *t) return; } - asprintf(&script, ". /lib/functions.sh\n. %s\n", pc->globbuf.gl_pathv[pc->cnt++]); + if (asprintf(&script, ". /lib/functions.sh\n. %s\n", pc->globbuf.gl_pathv[pc->cnt++]) == -1) { + pc->ret = ENOMEM; + return; + } + /* prepare for execve() */ exec_argv[0] = "/bin/sh"; exec_argv[1] = "-c"; @@ -120,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; } @@ -184,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)); @@ -195,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; } @@ -232,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 */ @@ -247,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; @@ -257,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) { + hotplug_free(pc); + return UBUS_STATUS_UNKNOWN_ERROR; + } + if (glob(globstr, GLOB_DOOFFS, NULL, &pc->globbuf)) { free(globstr); hotplug_free(pc); @@ -288,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[] = { @@ -302,7 +339,8 @@ static void add_subsystem(int nlen, char *newname) struct hotplug_subsys *nh = calloc(1, sizeof(struct hotplug_subsys)); char *name; - asprintf(&name, "%s%.*s", HOTPLUG_OBJECT_PREFIX, nlen, newname); + if (asprintf(&name, "%s%.*s", HOTPLUG_OBJECT_PREFIX, nlen, newname) == -1) + exit(ENOMEM); /* prepare and add ubus object */ nh->ubus.name = name; @@ -403,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); }