mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	pw-cli: support arbitrary large params and commands
Use a memstream to collect the arguments so that it can dynamically allocate as much memory as necessary. Use a dynamic pod builder to construct the pods so that they can be of arbitrary size. Fixes #4166
This commit is contained in:
		
							parent
							
								
									86287760a0
								
							
						
					
					
						commit
						7ceca29970
					
				
					 1 changed files with 21 additions and 14 deletions
				
			
		| 
						 | 
					@ -32,7 +32,7 @@
 | 
				
			||||||
#include <spa/debug/pod.h>
 | 
					#include <spa/debug/pod.h>
 | 
				
			||||||
#include <spa/utils/keys.h>
 | 
					#include <spa/utils/keys.h>
 | 
				
			||||||
#include <spa/utils/json-pod.h>
 | 
					#include <spa/utils/json-pod.h>
 | 
				
			||||||
#include <spa/pod/builder.h>
 | 
					#include <spa/pod/dynamic.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <pipewire/impl.h>
 | 
					#include <pipewire/impl.h>
 | 
				
			||||||
#include <pipewire/i18n.h>
 | 
					#include <pipewire/i18n.h>
 | 
				
			||||||
| 
						 | 
					@ -1777,10 +1777,12 @@ static bool do_set_param(struct data *data, const char *cmd, char *args, char **
 | 
				
			||||||
	uint32_t param_id;
 | 
						uint32_t param_id;
 | 
				
			||||||
	struct global *global;
 | 
						struct global *global;
 | 
				
			||||||
	uint8_t buffer[1024];
 | 
						uint8_t buffer[1024];
 | 
				
			||||||
	struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
 | 
						spa_auto(spa_pod_dynamic_builder) b = { 0 };
 | 
				
			||||||
	const struct spa_type_info *ti;
 | 
						const struct spa_type_info *ti;
 | 
				
			||||||
	struct spa_pod *pod;
 | 
						struct spa_pod *pod;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	n = pw_split_ip(args, WHITESPACE, 3, a);
 | 
						n = pw_split_ip(args, WHITESPACE, 3, a);
 | 
				
			||||||
	if (n < 3) {
 | 
						if (n < 3) {
 | 
				
			||||||
		*error = spa_aprintf("%s <object-id> <param-id> <param-json>", cmd);
 | 
							*error = spa_aprintf("%s <object-id> <param-id> <param-json>", cmd);
 | 
				
			||||||
| 
						 | 
					@ -1802,11 +1804,11 @@ static bool do_set_param(struct data *data, const char *cmd, char *args, char **
 | 
				
			||||||
		*error = spa_aprintf("%s: unknown param type: %s", cmd, a[1]);
 | 
							*error = spa_aprintf("%s: unknown param type: %s", cmd, a[1]);
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ((res = spa_json_to_pod(&b, 0, ti, a[2], strlen(a[2]))) < 0) {
 | 
						if ((res = spa_json_to_pod(&b.b, 0, ti, a[2], strlen(a[2]))) < 0) {
 | 
				
			||||||
		*error = spa_aprintf("%s: can't make pod: %s", cmd, spa_strerror(res));
 | 
							*error = spa_aprintf("%s: can't make pod: %s", cmd, spa_strerror(res));
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ((pod = spa_pod_builder_deref(&b, 0)) == NULL) {
 | 
						if ((pod = spa_pod_builder_deref(&b.b, 0)) == NULL) {
 | 
				
			||||||
		*error = spa_aprintf("%s: can't make pod", cmd);
 | 
							*error = spa_aprintf("%s: can't make pod", cmd);
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1911,10 +1913,12 @@ static bool do_send_command(struct data *data, const char *cmd, char *args, char
 | 
				
			||||||
	int res, n;
 | 
						int res, n;
 | 
				
			||||||
	struct global *global;
 | 
						struct global *global;
 | 
				
			||||||
	uint8_t buffer[1024];
 | 
						uint8_t buffer[1024];
 | 
				
			||||||
	struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
 | 
						spa_auto(spa_pod_dynamic_builder) b = { 0 };
 | 
				
			||||||
	const struct spa_type_info *ti;
 | 
						const struct spa_type_info *ti;
 | 
				
			||||||
	struct spa_pod *pod;
 | 
						struct spa_pod *pod;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	n = pw_split_ip(args, WHITESPACE, 3, a);
 | 
						n = pw_split_ip(args, WHITESPACE, 3, a);
 | 
				
			||||||
	if (n < 3) {
 | 
						if (n < 3) {
 | 
				
			||||||
		*error = spa_aprintf("%s <object-id> <command-id> <command-json>", cmd);
 | 
							*error = spa_aprintf("%s <object-id> <command-id> <command-json>", cmd);
 | 
				
			||||||
| 
						 | 
					@ -1943,11 +1947,11 @@ static bool do_send_command(struct data *data, const char *cmd, char *args, char
 | 
				
			||||||
		*error = spa_aprintf("%s: unknown node command type: %s", cmd, a[1]);
 | 
							*error = spa_aprintf("%s: unknown node command type: %s", cmd, a[1]);
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ((res = spa_json_to_pod(&b, 0, ti, a[2], strlen(a[2]))) < 0) {
 | 
						if ((res = spa_json_to_pod(&b.b, 0, ti, a[2], strlen(a[2]))) < 0) {
 | 
				
			||||||
		*error = spa_aprintf("%s: can't make pod: %s", cmd, spa_strerror(res));
 | 
							*error = spa_aprintf("%s: can't make pod: %s", cmd, spa_strerror(res));
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ((pod = spa_pod_builder_deref(&b, 0)) == NULL) {
 | 
						if ((pod = spa_pod_builder_deref(&b.b, 0)) == NULL) {
 | 
				
			||||||
		*error = spa_aprintf("%s: can't make pod", cmd);
 | 
							*error = spa_aprintf("%s: can't make pod", cmd);
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -2387,23 +2391,26 @@ int main(int argc, char *argv[])
 | 
				
			||||||
		readline_cleanup();
 | 
							readline_cleanup();
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		char buf[4096], *p, *error;
 | 
							FILE *buf;
 | 
				
			||||||
 | 
							char *error, *ptr;
 | 
				
			||||||
 | 
							size_t size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		p = buf;
 | 
							buf = open_memstream(&ptr, &size);
 | 
				
			||||||
		for (i = optind; i < argc; i++) {
 | 
							for (i = optind; i < argc; i++)
 | 
				
			||||||
			p = stpcpy(p, argv[i]);
 | 
								fprintf(buf, "%s%s", i == optind ? "" : " ", argv[i]);
 | 
				
			||||||
			p = stpcpy(p, " ");
 | 
							fclose(buf);
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// If we're monitoring, surface info changes as well
 | 
							// If we're monitoring, surface info changes as well
 | 
				
			||||||
		data.monitoring_info = monitor;
 | 
							data.monitoring_info = monitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pw_main_loop_run(data.loop);
 | 
							pw_main_loop_run(data.loop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!parse(&data, buf, &error)) {
 | 
							if (!parse(&data, ptr, &error)) {
 | 
				
			||||||
			fprintf(stderr, "Error: \"%s\"\n", error);
 | 
								fprintf(stderr, "Error: \"%s\"\n", error);
 | 
				
			||||||
			free(error);
 | 
								free(error);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							free(ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (data.current != NULL)
 | 
							if (data.current != NULL)
 | 
				
			||||||
			data.current->prompt_pending = pw_core_sync(data.current->core, 0, 0);
 | 
								data.current->prompt_pending = pw_core_sync(data.current->core, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue