mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	ucm: implement ${sys:sysfs/path} substitution
Example:
Condition {
	Type String
	String1 "${sys:class/dmi/id/board_vendor}"
	String2 "LENOVO"
}
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
			
			
This commit is contained in:
		
							parent
							
								
									1d848ab739
								
							
						
					
					
						commit
						cb84b02702
					
				
					 1 changed files with 53 additions and 0 deletions
				
			
		| 
						 | 
					@ -25,6 +25,8 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "ucm_local.h"
 | 
					#include "ucm_local.h"
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					#include <limits.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *rval_conf_name(snd_use_case_mgr_t *uc_mgr)
 | 
					static char *rval_conf_name(snd_use_case_mgr_t *uc_mgr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -83,6 +85,56 @@ static char *rval_env(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED, const char *i
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char *rval_sysfs(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED, const char *id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char path[PATH_MAX], link[PATH_MAX + 1];
 | 
				
			||||||
 | 
						struct stat sb;
 | 
				
			||||||
 | 
						ssize_t len;
 | 
				
			||||||
 | 
						char *e;
 | 
				
			||||||
 | 
						int fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						e = getenv("SYSFS_PATH");
 | 
				
			||||||
 | 
						if (e == NULL)
 | 
				
			||||||
 | 
							e = "/sys";
 | 
				
			||||||
 | 
						if (id[0] == '/')
 | 
				
			||||||
 | 
							id++;
 | 
				
			||||||
 | 
						snprintf(path, sizeof(path), "%s/%s", e, id);
 | 
				
			||||||
 | 
						if (lstat(path, &sb) != 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (S_ISLNK(sb.st_mode)) {
 | 
				
			||||||
 | 
							len = readlink(path, link, sizeof(link) - 1);
 | 
				
			||||||
 | 
							if (len <= 0) {
 | 
				
			||||||
 | 
								uc_error("sysfs: cannot read link '%s' (%d)", path, errno);
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							link[len] = '\0';
 | 
				
			||||||
 | 
							e = strrchr(link, '/');
 | 
				
			||||||
 | 
							if (e)
 | 
				
			||||||
 | 
								return strdup(e + 1);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (S_ISDIR(sb.st_mode))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if ((sb.st_mode & S_IRUSR) == 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fd = open(path, O_RDONLY);
 | 
				
			||||||
 | 
						if (fd < 0) {
 | 
				
			||||||
 | 
							uc_error("sysfs open failed for '%s' (%d)", path, errno);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						len = read(fd, path, sizeof(path)-1);
 | 
				
			||||||
 | 
						close(fd);
 | 
				
			||||||
 | 
						if (len < 0) {
 | 
				
			||||||
 | 
							uc_error("sysfs unable to read value '%s' (%d)", path, errno);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						while (len > 0 && path[len-1] == '\n')
 | 
				
			||||||
 | 
							len--;
 | 
				
			||||||
 | 
						path[len] = '\0';
 | 
				
			||||||
 | 
						return strdup(path);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MATCH_VARIABLE(name, id, fcn)					\
 | 
					#define MATCH_VARIABLE(name, id, fcn)					\
 | 
				
			||||||
	if (strncmp((name), (id), sizeof(id) - 1) == 0) { 		\
 | 
						if (strncmp((name), (id), sizeof(id) - 1) == 0) { 		\
 | 
				
			||||||
		rval = fcn(uc_mgr);					\
 | 
							rval = fcn(uc_mgr);					\
 | 
				
			||||||
| 
						 | 
					@ -133,6 +185,7 @@ int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr,
 | 
				
			||||||
			MATCH_VARIABLE(value, "${CardLongName}", rval_card_longname);
 | 
								MATCH_VARIABLE(value, "${CardLongName}", rval_card_longname);
 | 
				
			||||||
			MATCH_VARIABLE(value, "${CardComponents}", rval_card_components);
 | 
								MATCH_VARIABLE(value, "${CardComponents}", rval_card_components);
 | 
				
			||||||
			MATCH_VARIABLE2(value, "${env:", rval_env);
 | 
								MATCH_VARIABLE2(value, "${env:", rval_env);
 | 
				
			||||||
 | 
								MATCH_VARIABLE2(value, "${sys:", rval_sysfs);
 | 
				
			||||||
			err = -EINVAL;
 | 
								err = -EINVAL;
 | 
				
			||||||
			tmp = strchr(value, '}');
 | 
								tmp = strchr(value, '}');
 | 
				
			||||||
			if (tmp) {
 | 
								if (tmp) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue