mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	ucm: add exec sequence command
This change renames the original exec command to shell which is more appropriate. Implement a light version of the exec command which calls directly the specified executable without the shell interaction (man 3 system). Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
		
							parent
							
								
									a468505c96
								
							
						
					
					
						commit
						590df3a5b1
					
				
					 6 changed files with 312 additions and 7 deletions
				
			
		| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
EXTRA_LTLIBRARIES = libucm.la
 | 
					EXTRA_LTLIBRARIES = libucm.la
 | 
				
			||||||
 | 
					
 | 
				
			||||||
libucm_la_SOURCES = utils.c parser.c ucm_cond.c ucm_subs.c ucm_include.c \
 | 
					libucm_la_SOURCES = utils.c parser.c ucm_cond.c ucm_subs.c ucm_include.c \
 | 
				
			||||||
		    ucm_regex.c main.c
 | 
							    ucm_regex.c ucm_exec.c main.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
noinst_HEADERS = ucm_local.h
 | 
					noinst_HEADERS = ucm_local.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -717,6 +717,14 @@ static int execute_sequence(snd_use_case_mgr_t *uc_mgr,
 | 
				
			||||||
			usleep(s->data.sleep);
 | 
								usleep(s->data.sleep);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case SEQUENCE_ELEMENT_TYPE_EXEC:
 | 
							case SEQUENCE_ELEMENT_TYPE_EXEC:
 | 
				
			||||||
 | 
								err = uc_mgr_exec(s->data.exec);
 | 
				
			||||||
 | 
								if (err != 0) {
 | 
				
			||||||
 | 
									uc_error("exec '%s' failed (exit code %d)", s->data.exec, err);
 | 
				
			||||||
 | 
									goto __fail;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SEQUENCE_ELEMENT_TYPE_SHELL:
 | 
				
			||||||
 | 
					shell_retry:
 | 
				
			||||||
			err = system(s->data.exec);
 | 
								err = system(s->data.exec);
 | 
				
			||||||
			if (WIFSIGNALED(err)) {
 | 
								if (WIFSIGNALED(err)) {
 | 
				
			||||||
				err = -EINTR;
 | 
									err = -EINTR;
 | 
				
			||||||
| 
						 | 
					@ -727,6 +735,8 @@ static int execute_sequence(snd_use_case_mgr_t *uc_mgr,
 | 
				
			||||||
					goto __fail;
 | 
										goto __fail;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else if (err < 0) {
 | 
								} else if (err < 0) {
 | 
				
			||||||
 | 
									if (errno == EAGAIN)
 | 
				
			||||||
 | 
										goto shell_retry;
 | 
				
			||||||
				err = -errno;
 | 
									err = -errno;
 | 
				
			||||||
				goto __fail;
 | 
									goto __fail;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -910,6 +910,7 @@ cset:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (strcmp(cmd, "exec") == 0) {
 | 
							if (strcmp(cmd, "exec") == 0) {
 | 
				
			||||||
			curr->type = SEQUENCE_ELEMENT_TYPE_EXEC;
 | 
								curr->type = SEQUENCE_ELEMENT_TYPE_EXEC;
 | 
				
			||||||
 | 
					exec:
 | 
				
			||||||
			err = parse_string_substitute3(uc_mgr, n, &curr->data.exec);
 | 
								err = parse_string_substitute3(uc_mgr, n, &curr->data.exec);
 | 
				
			||||||
			if (err < 0) {
 | 
								if (err < 0) {
 | 
				
			||||||
				uc_error("error: exec requires a string!");
 | 
									uc_error("error: exec requires a string!");
 | 
				
			||||||
| 
						 | 
					@ -918,6 +919,11 @@ cset:
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (strcmp(cmd, "shell") == 0) {
 | 
				
			||||||
 | 
								curr->type = SEQUENCE_ELEMENT_TYPE_SHELL;
 | 
				
			||||||
 | 
								goto exec;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (strcmp(cmd, "comment") == 0)
 | 
							if (strcmp(cmd, "comment") == 0)
 | 
				
			||||||
			goto skip;
 | 
								goto skip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										285
									
								
								src/ucm/ucm_exec.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										285
									
								
								src/ucm/ucm_exec.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,285 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  Exec an external program
 | 
				
			||||||
 | 
					 *  Copyright (C) 2021 Jaroslav Kysela
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 *  modify it under the terms of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 *  License as published by the Free Software Foundation; either
 | 
				
			||||||
 | 
					 *  version 2 of the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  This library is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 *  Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 *  License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Support for the verb/device/modifier core logic and API,
 | 
				
			||||||
 | 
					 *  command line tool and file parser was kindly sponsored by
 | 
				
			||||||
 | 
					 *  Texas Instruments Inc.
 | 
				
			||||||
 | 
					 *  Support for multiple active modifiers and devices,
 | 
				
			||||||
 | 
					 *  transition sequences, multiple client access and user defined use
 | 
				
			||||||
 | 
					 *  cases was kindly sponsored by Wolfson Microelectronics PLC.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Copyright (C) 2021 Red Hat Inc.
 | 
				
			||||||
 | 
					 *  Authors: Jaroslav Kysela <perex@perex.cz>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ucm_local.h"
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					#include <sys/wait.h>
 | 
				
			||||||
 | 
					#include <dirent.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static pthread_mutex_t fork_lock = PTHREAD_MUTEX_INITIALIZER;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Search PATH for executable
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int find_exec(const char *name, char *out, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret = 0;
 | 
				
			||||||
 | 
						char bin[PATH_MAX];
 | 
				
			||||||
 | 
						char *path, *tmp, *tmp2 = NULL;
 | 
				
			||||||
 | 
						DIR *dir;
 | 
				
			||||||
 | 
						struct dirent *de;
 | 
				
			||||||
 | 
						struct stat st;
 | 
				
			||||||
 | 
						if (name[0] == '/') {
 | 
				
			||||||
 | 
							if (lstat(name, &st))
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							if (!S_ISREG(st.st_mode) || !(st.st_mode & S_IEXEC))
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							snd_strlcpy(out, name, len);
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!(tmp = getenv("PATH")))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						path = alloca(strlen(tmp) + 1);
 | 
				
			||||||
 | 
						if (!path)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						strcpy(path, tmp);
 | 
				
			||||||
 | 
						tmp = strtok_r(path, ":", &tmp2);
 | 
				
			||||||
 | 
						while (tmp && !ret) {
 | 
				
			||||||
 | 
							if ((dir = opendir(tmp))) {
 | 
				
			||||||
 | 
								while ((de = readdir(dir))) {
 | 
				
			||||||
 | 
									if (strstr(de->d_name, name) != de->d_name)
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									snprintf(bin, sizeof(bin), "%s/%s", tmp,
 | 
				
			||||||
 | 
										 de->d_name);
 | 
				
			||||||
 | 
									if (lstat(bin, &st))
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									if (!S_ISREG(st.st_mode)
 | 
				
			||||||
 | 
									    || !(st.st_mode & S_IEXEC))
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									snd_strlcpy(out, bin, len);
 | 
				
			||||||
 | 
									return 1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								closedir(dir);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							tmp = strtok_r(NULL, ":", &tmp2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void free_args(char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char **a;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (a = argv; *a; a++)
 | 
				
			||||||
 | 
							free(*a);
 | 
				
			||||||
 | 
						free(argv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int parse_args(char ***argv, int argc, const char *cmd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *s, *f;
 | 
				
			||||||
 | 
						int i = 0, l, eow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!argv || !cmd)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s = alloca(strlen(cmd) + 1);
 | 
				
			||||||
 | 
						if (!s)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						strcpy(s, cmd);
 | 
				
			||||||
 | 
						*argv = calloc(argc, sizeof(char *));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (*s && i < argc - 1) {
 | 
				
			||||||
 | 
							while (*s == ' ')
 | 
				
			||||||
 | 
								s++;
 | 
				
			||||||
 | 
							f = s;
 | 
				
			||||||
 | 
							eow = 0;
 | 
				
			||||||
 | 
							while (*s) {
 | 
				
			||||||
 | 
								if (*s == '\\') {
 | 
				
			||||||
 | 
									l = *(s + 1);
 | 
				
			||||||
 | 
									if (l == 'b')
 | 
				
			||||||
 | 
										l = '\b';
 | 
				
			||||||
 | 
									else if (l == 'f')
 | 
				
			||||||
 | 
										l = '\f';
 | 
				
			||||||
 | 
									else if (l == 'n')
 | 
				
			||||||
 | 
										l = '\n';
 | 
				
			||||||
 | 
									else if (l == 'r')
 | 
				
			||||||
 | 
										l = '\r';
 | 
				
			||||||
 | 
									else if (l == 't')
 | 
				
			||||||
 | 
										l = '\t';
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										l = 0;
 | 
				
			||||||
 | 
									if (l) {
 | 
				
			||||||
 | 
										*s++ = l;
 | 
				
			||||||
 | 
										memmove(s, s + 1, strlen(s));
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										memmove(s, s + 1, strlen(s));
 | 
				
			||||||
 | 
										if (*s)
 | 
				
			||||||
 | 
											s++;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else if (eow) {
 | 
				
			||||||
 | 
									if (*s == eow) {
 | 
				
			||||||
 | 
										memmove(s, s + 1, strlen(s));
 | 
				
			||||||
 | 
										eow = 0;
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										s++;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else if (*s == '\'' || *s == '"') {
 | 
				
			||||||
 | 
									eow = *s;
 | 
				
			||||||
 | 
									memmove(s, s + 1, strlen(s));
 | 
				
			||||||
 | 
								} else if (*s == ' ') {
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									s++;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (f != s) {
 | 
				
			||||||
 | 
								if (*s) {
 | 
				
			||||||
 | 
									*(char *)s = '\0';
 | 
				
			||||||
 | 
									s++;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								(*argv)[i] = strdup(f);
 | 
				
			||||||
 | 
								if ((*argv)[i] == NULL) {
 | 
				
			||||||
 | 
									free_args(*argv);
 | 
				
			||||||
 | 
									return -ENOMEM;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								i++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						(*argv)[i] = NULL;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * execute a binary file
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int uc_mgr_exec(const char *prog)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						pid_t p, f, maxfd;
 | 
				
			||||||
 | 
						int err = 0, status;
 | 
				
			||||||
 | 
						char bin[PATH_MAX];
 | 
				
			||||||
 | 
						struct sigaction sa;
 | 
				
			||||||
 | 
						struct sigaction intr, quit;
 | 
				
			||||||
 | 
						sigset_t omask;
 | 
				
			||||||
 | 
						char **argv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (parse_args(&argv, 32, prog))
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						prog = argv[0];
 | 
				
			||||||
 | 
						if (argv[0][0] != '/' && argv[0][0] != '.') {
 | 
				
			||||||
 | 
							if (!find_exec(argv[0], bin, sizeof(bin))) {
 | 
				
			||||||
 | 
								err = -ENOEXEC;
 | 
				
			||||||
 | 
								goto __error;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							prog = bin;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						maxfd = sysconf(_SC_OPEN_MAX);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * block SIGCHLD signal
 | 
				
			||||||
 | 
						 * ignore SIGINT and SIGQUIT in parent
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(&sa, 0, sizeof(sa));
 | 
				
			||||||
 | 
						sa.sa_handler = SIG_IGN;
 | 
				
			||||||
 | 
						sigemptyset(&sa.sa_mask);
 | 
				
			||||||
 | 
						sigaddset(&sa.sa_mask, SIGCHLD);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pthread_mutex_lock(&fork_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sigprocmask(SIG_BLOCK, &sa.sa_mask, &omask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sigaction(SIGINT, &sa, &intr);
 | 
				
			||||||
 | 
						sigaction(SIGQUIT, &sa, &quit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p = fork();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (p == -1) {
 | 
				
			||||||
 | 
							err = -errno;
 | 
				
			||||||
 | 
							pthread_mutex_unlock(&fork_lock);
 | 
				
			||||||
 | 
							uc_error("Unable to fork() for \"%s\" -- %s", prog,
 | 
				
			||||||
 | 
								 strerror(errno));
 | 
				
			||||||
 | 
							goto __error;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (p == 0) {
 | 
				
			||||||
 | 
							f = open("/dev/null", O_RDWR);
 | 
				
			||||||
 | 
							if (f == -1) {
 | 
				
			||||||
 | 
								uc_error("pid %d cannot open /dev/null for redirect %s -- %s",
 | 
				
			||||||
 | 
									 getpid(), prog, strerror(errno));
 | 
				
			||||||
 | 
								exit(1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							close(0);
 | 
				
			||||||
 | 
							close(1);
 | 
				
			||||||
 | 
							close(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							dup2(f, 0);
 | 
				
			||||||
 | 
							dup2(f, 1);
 | 
				
			||||||
 | 
							dup2(f, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							close(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (f = 3; f < maxfd; f++)
 | 
				
			||||||
 | 
								close(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* install default handlers for the forked process */
 | 
				
			||||||
 | 
							signal(SIGINT, SIG_DFL);
 | 
				
			||||||
 | 
							signal(SIGQUIT, SIG_DFL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							execve(prog, argv, environ);
 | 
				
			||||||
 | 
							exit(1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sigaction(SIGINT, &intr, NULL);
 | 
				
			||||||
 | 
						sigaction(SIGQUIT, &quit, NULL);
 | 
				
			||||||
 | 
						sigprocmask(SIG_SETMASK, &omask, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pthread_mutex_unlock(&fork_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* make the spawned process a session leader so killing the
 | 
				
			||||||
 | 
						   process group recursively kills any child process that
 | 
				
			||||||
 | 
						   might have been spawned */
 | 
				
			||||||
 | 
						setpgid(p, p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (1) {
 | 
				
			||||||
 | 
							f = waitpid(p, &status, 0);
 | 
				
			||||||
 | 
							if (f == -1) {
 | 
				
			||||||
 | 
								if (errno == EAGAIN)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								err = -errno;
 | 
				
			||||||
 | 
								goto __error;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (WIFSIGNALED(status)) {
 | 
				
			||||||
 | 
								err = -EINTR;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (WIFEXITED(status)) {
 | 
				
			||||||
 | 
								err = WEXITSTATUS(status);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 __error:
 | 
				
			||||||
 | 
						free_args(argv);
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -49,12 +49,13 @@
 | 
				
			||||||
#define SEQUENCE_ELEMENT_TYPE_CSET		2
 | 
					#define SEQUENCE_ELEMENT_TYPE_CSET		2
 | 
				
			||||||
#define SEQUENCE_ELEMENT_TYPE_SLEEP		3
 | 
					#define SEQUENCE_ELEMENT_TYPE_SLEEP		3
 | 
				
			||||||
#define SEQUENCE_ELEMENT_TYPE_EXEC		4
 | 
					#define SEQUENCE_ELEMENT_TYPE_EXEC		4
 | 
				
			||||||
#define SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE	5
 | 
					#define SEQUENCE_ELEMENT_TYPE_SHELL		5
 | 
				
			||||||
#define SEQUENCE_ELEMENT_TYPE_CSET_TLV		6
 | 
					#define SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE	6
 | 
				
			||||||
#define SEQUENCE_ELEMENT_TYPE_CSET_NEW		7
 | 
					#define SEQUENCE_ELEMENT_TYPE_CSET_TLV		7
 | 
				
			||||||
#define SEQUENCE_ELEMENT_TYPE_CTL_REMOVE	8
 | 
					#define SEQUENCE_ELEMENT_TYPE_CSET_NEW		8
 | 
				
			||||||
#define SEQUENCE_ELEMENT_TYPE_CMPT_SEQ		9
 | 
					#define SEQUENCE_ELEMENT_TYPE_CTL_REMOVE	9
 | 
				
			||||||
#define SEQUENCE_ELEMENT_TYPE_SYSSET		10
 | 
					#define SEQUENCE_ELEMENT_TYPE_CMPT_SEQ		10
 | 
				
			||||||
 | 
					#define SEQUENCE_ELEMENT_TYPE_SYSSET		11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ucm_value {
 | 
					struct ucm_value {
 | 
				
			||||||
        struct list_head list;
 | 
					        struct list_head list;
 | 
				
			||||||
| 
						 | 
					@ -356,6 +357,8 @@ int uc_mgr_define_regex(snd_use_case_mgr_t *uc_mgr,
 | 
				
			||||||
			const char *name,
 | 
								const char *name,
 | 
				
			||||||
			snd_config_t *eval);
 | 
								snd_config_t *eval);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int uc_mgr_exec(const char *prog);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** The name of the environment variable containing the UCM directory */
 | 
					/** The name of the environment variable containing the UCM directory */
 | 
				
			||||||
#define ALSA_CONFIG_UCM_VAR "ALSA_CONFIG_UCM"
 | 
					#define ALSA_CONFIG_UCM_VAR "ALSA_CONFIG_UCM"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -509,6 +509,7 @@ void uc_mgr_free_sequence_element(struct sequence_element *seq)
 | 
				
			||||||
		free(seq->data.sysw);
 | 
							free(seq->data.sysw);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SEQUENCE_ELEMENT_TYPE_EXEC:
 | 
						case SEQUENCE_ELEMENT_TYPE_EXEC:
 | 
				
			||||||
 | 
						case SEQUENCE_ELEMENT_TYPE_SHELL:
 | 
				
			||||||
		free(seq->data.exec);
 | 
							free(seq->data.exec);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue