mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	correct autospawning
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@202 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
		
							parent
							
								
									935826f4f3
								
							
						
					
					
						commit
						8c110d904d
					
				
					 13 changed files with 187 additions and 136 deletions
				
			
		| 
						 | 
				
			
			@ -85,7 +85,7 @@ struct pa_context *pa_context_new(struct pa_mainloop_api *mainloop, const char *
 | 
			
		|||
 | 
			
		||||
    c->memblock_stat = pa_memblock_stat_new();
 | 
			
		||||
    
 | 
			
		||||
    pa_check_for_sigpipe();
 | 
			
		||||
    pa_check_signal_is_blocked(SIGPIPE);
 | 
			
		||||
    return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -365,15 +365,116 @@ static struct sockaddr *resolve_server(const char *server, size_t *len) {
 | 
			
		|||
    return sa;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pa_context_connect(struct pa_context *c, const char *server) {
 | 
			
		||||
static int is_running(void) {
 | 
			
		||||
    struct stat st;
 | 
			
		||||
    
 | 
			
		||||
    if (DEFAULT_SERVER[0] != '/')
 | 
			
		||||
        return 1;
 | 
			
		||||
 | 
			
		||||
    if (stat(DEFAULT_SERVER, &st) < 0)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int context_connect_spawn(struct pa_context *c, const struct pa_spawn_api *api) {
 | 
			
		||||
    pid_t pid;
 | 
			
		||||
    int status, r;
 | 
			
		||||
    int fds[2] = { -1, -1} ;
 | 
			
		||||
    struct pa_iochannel *io;
 | 
			
		||||
 | 
			
		||||
    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
 | 
			
		||||
        pa_log(__FILE__": socketpair() failed: %s\n", strerror(errno));
 | 
			
		||||
        pa_context_fail(c, PA_ERROR_INTERNAL);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (api && api->prefork)
 | 
			
		||||
        api->prefork();
 | 
			
		||||
 | 
			
		||||
    if ((pid = fork()) < 0) {
 | 
			
		||||
        pa_log(__FILE__": fork() failed: %s\n", strerror(errno));
 | 
			
		||||
        pa_context_fail(c, PA_ERROR_INTERNAL);
 | 
			
		||||
 | 
			
		||||
        if (api && api->postfork)
 | 
			
		||||
            api->postfork();
 | 
			
		||||
        
 | 
			
		||||
        goto fail;
 | 
			
		||||
    } else if (!pid) {
 | 
			
		||||
        char t[128];
 | 
			
		||||
        char *p;
 | 
			
		||||
        /* Child */
 | 
			
		||||
 | 
			
		||||
        close(fds[0]);
 | 
			
		||||
        
 | 
			
		||||
        if (api && api->atfork)
 | 
			
		||||
            api->atfork();
 | 
			
		||||
 | 
			
		||||
        if (!(p = getenv(ENV_DEFAULT_BINARY)))
 | 
			
		||||
            p = POLYPAUDIO_BINARY;
 | 
			
		||||
 | 
			
		||||
        snprintf(t, sizeof(t), "%s=1", ENV_AUTOSPAWNED);
 | 
			
		||||
        putenv(t); 
 | 
			
		||||
        
 | 
			
		||||
        snprintf(t, sizeof(t), "-Lmodule-native-protocol-fd fd=%i", fds[1]);
 | 
			
		||||
        execl(p, p, t, NULL);
 | 
			
		||||
        
 | 
			
		||||
        exit(1);
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
    /* Parent */
 | 
			
		||||
 | 
			
		||||
    r = waitpid(pid, &status, 0);
 | 
			
		||||
 | 
			
		||||
    if (api && api->postfork)
 | 
			
		||||
        api->postfork();
 | 
			
		||||
        
 | 
			
		||||
    if (r < 0) {
 | 
			
		||||
        pa_log(__FILE__": waitpid() failed: %s\n", strerror(errno));
 | 
			
		||||
        pa_context_fail(c, PA_ERROR_INTERNAL);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
 | 
			
		||||
        pa_context_fail(c, PA_ERROR_CONNECTIONREFUSED);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    close(fds[1]);
 | 
			
		||||
    
 | 
			
		||||
    io = pa_iochannel_new(c->mainloop, fds[0], fds[0]);
 | 
			
		||||
    setup_context(c, io);
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
    if (fds[0] != -1)
 | 
			
		||||
        close(fds[0]);
 | 
			
		||||
    if (fds[1] != -1)
 | 
			
		||||
        close(fds[1]);
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int pa_context_connect(struct pa_context *c, const char *server, int spawn, const struct pa_spawn_api *api) {
 | 
			
		||||
    int r = -1;
 | 
			
		||||
    assert(c && c->ref >= 1 && c->state == PA_CONTEXT_UNCONNECTED);
 | 
			
		||||
 | 
			
		||||
    pa_context_ref(c);
 | 
			
		||||
    
 | 
			
		||||
    if (!server)
 | 
			
		||||
        if (!(server = getenv(ENV_DEFAULT_SERVER)))
 | 
			
		||||
        if (!(server = getenv(ENV_DEFAULT_SERVER))) {
 | 
			
		||||
            if (spawn && !is_running()) {
 | 
			
		||||
                char *b;
 | 
			
		||||
                
 | 
			
		||||
                if ((b = getenv(ENV_DISABLE_AUTOSPAWN)))
 | 
			
		||||
                    if (pa_parse_boolean(b) > 1)
 | 
			
		||||
                        return -1;
 | 
			
		||||
                
 | 
			
		||||
                return context_connect_spawn(c, api);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            server = DEFAULT_SERVER;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    pa_context_ref(c);
 | 
			
		||||
 | 
			
		||||
    assert(!c->client);
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -562,94 +663,6 @@ const char* pa_get_library_version(void) {
 | 
			
		|||
    return PACKAGE_VERSION;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int is_running(void) {
 | 
			
		||||
    struct stat st;
 | 
			
		||||
    
 | 
			
		||||
    if (DEFAULT_SERVER[0] != '/')
 | 
			
		||||
        return 1;
 | 
			
		||||
 | 
			
		||||
    if (stat(DEFAULT_SERVER, &st) < 0)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pa_context_connect_spawn(struct pa_context *c, void (*atfork)(void), void (*prefork)(void), void (*postfork)(void)) {
 | 
			
		||||
    pid_t pid;
 | 
			
		||||
    int status, r;
 | 
			
		||||
    int fds[2] = { -1, -1} ;
 | 
			
		||||
    struct pa_iochannel *io;
 | 
			
		||||
    
 | 
			
		||||
    if (getenv(ENV_DEFAULT_SERVER) || is_running())
 | 
			
		||||
        return pa_context_connect(c, NULL);
 | 
			
		||||
 | 
			
		||||
    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
 | 
			
		||||
        pa_log(__FILE__": socketpair() failed: %s\n", strerror(errno));
 | 
			
		||||
        pa_context_fail(c, PA_ERROR_INTERNAL);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (prefork)
 | 
			
		||||
        prefork();
 | 
			
		||||
 | 
			
		||||
    if ((pid = fork()) < 0) {
 | 
			
		||||
        pa_log(__FILE__": fork() failed: %s\n", strerror(errno));
 | 
			
		||||
        pa_context_fail(c, PA_ERROR_INTERNAL);
 | 
			
		||||
 | 
			
		||||
        if (postfork)
 | 
			
		||||
            postfork();
 | 
			
		||||
        
 | 
			
		||||
        goto fail;
 | 
			
		||||
    } else if (!pid) {
 | 
			
		||||
        char t[64];
 | 
			
		||||
        char *p;
 | 
			
		||||
        /* Child */
 | 
			
		||||
 | 
			
		||||
        close(fds[0]);
 | 
			
		||||
        
 | 
			
		||||
        if (atfork)
 | 
			
		||||
            atfork();
 | 
			
		||||
 | 
			
		||||
        if (!(p = getenv(ENV_DEFAULT_BINARY)))
 | 
			
		||||
            p = POLYPAUDIO_BINARY;
 | 
			
		||||
        
 | 
			
		||||
        snprintf(t, sizeof(t), "-Lmodule-native-protocol-fd fd=%i", fds[1]);
 | 
			
		||||
        execl(p, p, "-r", "-D", "-lsyslog", "-X 5", t, NULL);
 | 
			
		||||
        
 | 
			
		||||
        exit(1);
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
    /* Parent */
 | 
			
		||||
 | 
			
		||||
    r = waitpid(pid, &status, 0);
 | 
			
		||||
 | 
			
		||||
    if (postfork)
 | 
			
		||||
        postfork();
 | 
			
		||||
        
 | 
			
		||||
    if (r < 0) {
 | 
			
		||||
        pa_log(__FILE__": waitpid() failed: %s\n", strerror(errno));
 | 
			
		||||
        pa_context_fail(c, PA_ERROR_INTERNAL);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
 | 
			
		||||
        pa_context_fail(c, PA_ERROR_CONNECTIONREFUSED);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    close(fds[1]);
 | 
			
		||||
    
 | 
			
		||||
    io = pa_iochannel_new(c->mainloop, fds[0], fds[0]);
 | 
			
		||||
    setup_context(c, io);
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
    if (fds[0] != -1)
 | 
			
		||||
        close(fds[0]);
 | 
			
		||||
    if (fds[1] != -1)
 | 
			
		||||
        close(fds[1]);
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct pa_operation* pa_context_set_default_sink(struct pa_context *c, const char *name, void(*cb)(struct pa_context*c, int success, void *userdata), void *userdata) {
 | 
			
		||||
    struct pa_tagstruct *t;
 | 
			
		||||
    struct pa_operation *o;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue