Why would I want to do that? because pulseaudio isn't needed (presumably) and pulseaudio does not want to run as root. In theory I should be able to run pulseaudio --system to fix the problem, but I can't get that to work.

The issue:

root@mc: arecord -l
XDG_RUNTIME_DIR (/run/user/1000) is not owned by us (uid 0), but uid 1000! (This could e.g. happen if you try to connect to a non-root pulseAudio as a root user, over the native protocol. Don't do that.)

Well Okay but how? And why? The listed reasons are not applicable to a single user machine. Surely sox runs on alsa (AUDIODRIVER=alsa) and does not need PulseAudio. How can I tell sox to do that?

1 Answer 1


Okay so I had no success setting up a pi to run pulseaudio in system wide mode. As the aim is to use sox from within a c program that is portable, modifying the environment in complex ways is self defeating anyway.

On a pi there is a good chance it will be run single user and so malicious other users are simply a case of edge case poisoning.

Instead I have wrapped the use of the sox command in some code that checks who the user is using getuid, read who owns the directory specified by XDG_RUNTIME_DIR using stat and, if necessary, using chown to make root the owner of /run/usr/xxx directory while the program is running and then chowns the original user back at the end. Oh and used

sudo visudo /etc/sudoers

to put a '!' before the 'env_reset' so that environment variables get carried over when using sudo (thinking about it, that is not necessary but I do it for other reasons).

This is not the most cludgy thing I've ever done but...

I'd argue that irrespective of what pulseaudio people say, pis should run pulseaudio in system-wide mode by default.

The code (snippet) called before calling snprintf with the sox command and again at termination:

        char * xrd = getenv("XDG_RUNTIME_DIR");
        if(saved_uid != 0) { // put it back
                int i = chown(xrd,saved_uid,saved_uid);
                if(i !=0 ) { perror("chown"); return; }
                saved_uid = 0;
        } else {
                uid_t p_uid = getuid(); // who is running the process
                struct stat sb;
                int n = stat(xrd,&sb);
                if( n == -1) {perror("stat"); return; }
                if( p_uid == 0 && sb.st_uid != 0 ) {
                        saved_uid = sb.st_uid;
                        int i = chown(xrd,0,0);
                        if(i !=0 ) { perror("chown"); return; }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.