memset(udev, 0x00, sizeof(struct udevice));
INIT_LIST_HEAD(&udev->symlink_list);
INIT_LIST_HEAD(&udev->run_list);
+ INIT_LIST_HEAD(&udev->env_list);
if (subsystem)
strlcpy(udev->subsystem, subsystem, sizeof(udev->subsystem));
list_del(&name_loop->node);
free(name_loop);
}
+ list_for_each_entry_safe(name_loop, temp_loop, &udev->env_list, node) {
+ list_del(&name_loop->node);
+ free(name_loop);
+ }
}
int string_is_true(const char *str)
return 0;
}
-void file_unmap(char *buf, size_t bufsize)
+void file_unmap(void *buf, size_t bufsize)
{
munmap(buf, bufsize);
}
dbg("'%s' is already in the list", name);
return 0;
}
- if (sort && strcmp(loop_name->name, name) > 0)
- break;
}
+ if (sort)
+ list_for_each_entry(loop_name, name_list, node) {
+ if (sort && strcmp(loop_name->name, name) > 0)
+ break;
+ }
+
new_name = malloc(sizeof(struct name_entry));
if (new_name == NULL) {
dbg("error malloc");
}
strlcpy(new_name->name, name, sizeof(new_name->name));
+ dbg("adding '%s'", new_name->name);
+ list_add_tail(&new_name->node, &loop_name->node);
+
+ return 0;
+}
+
+int name_list_key_add(struct list_head *name_list, const char *key, const char *value)
+{
+ struct name_entry *loop_name;
+ struct name_entry *new_name;
+
+ list_for_each_entry(loop_name, name_list, node) {
+ if (strncmp(loop_name->name, key, strlen(key)) == 0) {
+ dbg("key already present '%s', replace it", loop_name->name);
+ snprintf(loop_name->name, sizeof(loop_name->name), "%s=%s", key, value);
+ loop_name->name[sizeof(loop_name->name)-1] = '\0';
+ return 0;
+ }
+ }
+
+ new_name = malloc(sizeof(struct name_entry));
+ if (new_name == NULL) {
+ dbg("error malloc");
+ return -ENOMEM;
+ }
+
+ snprintf(new_name->name, sizeof(new_name->name), "%s=%s", key, value);
+ new_name->name[sizeof(new_name->name)-1] = '\0';
+ dbg("adding '%s'", new_name->name);
list_add_tail(&new_name->node, &loop_name->node);
return 0;
return 0;
}
-int execute_command(const char *command, const char *subsystem)
+int execute_program(const char *command, const char *subsystem,
+ char *result, size_t ressize, size_t *reslen)
{
- int retval;
+ int retval = 0;
+ int count;
+ int status;
+ int pipefds[2];
pid_t pid;
- char arg[PATH_SIZE];
- char *argv[(PATH_SIZE / 2) + 1];
char *pos;
+ char arg[PATH_SIZE];
+ char *argv[(sizeof(arg) / 2) + 1];
int devnull;
int i;
+ size_t len;
strlcpy(arg, command, sizeof(arg));
i = 0;
dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]);
}
+ if (result) {
+ if (pipe(pipefds) != 0) {
+ err("pipe failed");
+ return -1;
+ }
+ }
+
pid = fork();
- switch (pid) {
+ switch(pid) {
case 0:
- /* child */
+ /* child dup2 write side of pipe to STDOUT */
devnull = open("/dev/null", O_RDWR);
if (devnull >= 0) {
dup2(devnull, STDIN_FILENO);
- dup2(devnull, STDOUT_FILENO);
+ if (!result)
+ dup2(devnull, STDOUT_FILENO);
dup2(devnull, STDERR_FILENO);
close(devnull);
}
- retval = execv(arg, argv);
- err("exec of child failed");
+ if (result)
+ dup2(pipefds[1], STDOUT_FILENO);
+ execv(arg, argv);
+ err("exec of program failed");
_exit(1);
case -1:
- dbg("fork of child failed");
- break;
+ err("fork of '%s' failed", arg);
return -1;
default:
- waitpid(pid, NULL, 0);
+ /* parent reads from pipefds[0] */
+ if (result) {
+ close(pipefds[1]);
+ len = 0;
+ while (1) {
+ count = read(pipefds[0], result + len, ressize - len-1);
+ if (count < 0) {
+ err("read failed with '%s'", strerror(errno));
+ retval = -1;
+ break;
+ }
+
+ if (count == 0)
+ break;
+
+ len += count;
+ if (len >= ressize-1) {
+ err("ressize %ld too short", (long)ressize);
+ retval = -1;
+ break;
+ }
+ }
+ result[len] = '\0';
+ close(pipefds[0]);
+ if (reslen)
+ *reslen = len;
+ }
+ waitpid(pid, &status, 0);
+
+ if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) {
+ dbg("exec program status 0x%x", status);
+ retval = -1;
+ }
}
- return 0;
+ return retval;
}