diff options
Diffstat (limited to 'src/pulse/util.c')
| -rw-r--r-- | src/pulse/util.c | 208 |
1 files changed, 130 insertions, 78 deletions
diff --git a/src/pulse/util.c b/src/pulse/util.c index b041fec8..6656bc3f 100644 --- a/src/pulse/util.c +++ b/src/pulse/util.c @@ -1,18 +1,19 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. - + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + PulseAudio 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.1 of the License, or (at your option) any later version. - + PulseAudio 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 PulseAudio; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 @@ -23,7 +24,6 @@ #include <config.h> #endif -#include <assert.h> #include <errno.h> #include <limits.h> #include <stdio.h> @@ -37,10 +37,6 @@ #include <pwd.h> #endif -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif - #ifdef HAVE_NETDB_H #include <netdb.h> #endif @@ -53,81 +49,96 @@ #include <sys/prctl.h> #endif -#include "../pulsecore/winsock.h" +#ifdef OS_IS_DARWIN +#include <libgen.h> +#include <sys/sysctl.h> +#endif + +#include <pulse/xmalloc.h> +#include <pulse/timeval.h> -#include <pulsecore/core-error.h> -#include <pulsecore/log.h> +#include <pulsecore/socket.h> #include <pulsecore/core-util.h> +#include <pulsecore/macro.h> +#include <pulsecore/usergroup.h> #include "util.h" -#ifndef OS_IS_WIN32 -#define PATH_SEP '/' -#else -#define PATH_SEP '\\' -#endif - char *pa_get_user_name(char *s, size_t l) { - char *p; + const char *p; + char *name = NULL; +#ifdef OS_IS_WIN32 char buf[1024]; +#endif #ifdef HAVE_PWD_H - struct passwd pw, *r; + struct passwd *r; #endif - assert(s && l > 0); + pa_assert(s); + pa_assert(l > 0); - if (!(p = getenv("USER")) && !(p = getenv("LOGNAME")) && !(p = getenv("USERNAME"))) { -#ifdef HAVE_PWD_H - -#ifdef HAVE_GETPWUID_R - if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) { -#else - /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X) - * that do not support getpwuid_r. */ - if ((r = getpwuid(getuid())) == NULL) { + p = NULL; +#ifdef HAVE_GETUID + p = getuid() == 0 ? "root" : NULL; #endif - snprintf(s, l, "%lu", (unsigned long) getuid()); + if (!p) p = getenv("USER"); + if (!p) p = getenv("LOGNAME"); + if (!p) p = getenv("USERNAME"); + + if (p) { + name = pa_strlcpy(s, p, l); + } else { +#ifdef HAVE_PWD_H + + if ((r = pa_getpwuid_malloc(getuid())) == NULL) { + pa_snprintf(s, l, "%lu", (unsigned long) getuid()); return s; } - - p = r->pw_name; + + name = pa_strlcpy(s, r->pw_name, l); + pa_getpwuid_free(r); #elif defined(OS_IS_WIN32) /* HAVE_PWD_H */ DWORD size = sizeof(buf); - if (!GetUserName(buf, &size)) + if (!GetUserName(buf, &size)) { + errno = ENOENT; return NULL; + } - p = buf; + name = pa_strlcpy(s, buf, l); #else /* HAVE_PWD_H */ + return NULL; #endif /* HAVE_PWD_H */ } - return pa_strlcpy(s, p, l); + return name; } char *pa_get_host_name(char *s, size_t l) { - assert(s && l > 0); - if (gethostname(s, l) < 0) { - pa_log(__FILE__": gethostname(): %s", pa_cstrerror(errno)); + + pa_assert(s); + pa_assert(l > 0); + + if (gethostname(s, l) < 0) return NULL; - } + s[l-1] = 0; return s; } char *pa_get_home_dir(char *s, size_t l) { char *e; - #ifdef HAVE_PWD_H - char buf[1024]; - struct passwd pw, *r; + char *dir; + struct passwd *r; #endif - assert(s && l); + pa_assert(s); + pa_assert(l > 0); if ((e = getenv("HOME"))) return pa_strlcpy(s, e, l); @@ -136,52 +147,65 @@ char *pa_get_home_dir(char *s, size_t l) { return pa_strlcpy(s, e, l); #ifdef HAVE_PWD_H -#ifdef HAVE_GETPWUID_R - if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) { - pa_log(__FILE__": getpwuid_r() failed"); -#else - /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X) - * that do not support getpwuid_r. */ - if ((r = getpwuid(getuid())) == NULL) { - pa_log(__FILE__": getpwuid_r() failed"); -#endif + errno = 0; + if ((r = pa_getpwuid_malloc(getuid())) == NULL) { + if (!errno) + errno = ENOENT; + return NULL; } - return pa_strlcpy(s, r->pw_dir, l); + dir = pa_strlcpy(s, r->pw_dir, l); + + pa_getpwuid_free(r); + + return dir; #else /* HAVE_PWD_H */ + + errno = ENOENT; return NULL; #endif } char *pa_get_binary_name(char *s, size_t l) { - assert(s); - assert(l); + pa_assert(s); + pa_assert(l > 0); #if defined(OS_IS_WIN32) { char path[PATH_MAX]; - + if (GetModuleFileName(NULL, path, PATH_MAX)) return pa_strlcpy(s, pa_path_get_filename(path), l); } #endif - -#ifdef HAVE_READLINK + +#ifdef __linux__ { - int i; - char path[PATH_MAX]; + char *rp; /* This works on Linux only */ - - if ((i = readlink("/proc/self/exe", path, sizeof(path)-1)) >= 0) { - path[i] = 0; - return pa_strlcpy(s, pa_path_get_filename(path), l); + + if ((rp = pa_readlink("/proc/self/exe"))) { + pa_strlcpy(s, pa_path_get_filename(rp), l); + pa_xfree(rp); + return s; + } + } +#endif + +#ifdef __FreeBSD__ + { + char *rp; + + if ((rp = pa_readlink("/proc/curproc/file"))) { + pa_strlcpy(s, pa_path_get_filename(rp), l); + pa_xfree(rp); + return s; } } - #endif - + #if defined(HAVE_SYS_PRCTL_H) && defined(PR_GET_NAME) { @@ -192,32 +216,60 @@ char *pa_get_binary_name(char *s, size_t l) { char tcomm[TASK_COMM_LEN+1]; memset(tcomm, 0, sizeof(tcomm)); - + /* This works on Linux only */ if (prctl(PR_GET_NAME, (unsigned long) tcomm, 0, 0, 0) == 0) return pa_strlcpy(s, tcomm, l); - + } #endif - + +#ifdef OS_IS_DARWIN + { + int mib[] = { CTL_KERN, KERN_PROCARGS, getpid(), 0 }; + size_t len, nmib = (sizeof(mib) / sizeof(mib[0])) - 1; + char *buf; + + sysctl(mib, nmib, NULL, &len, NULL, 0); + buf = (char *) pa_xmalloc(len); + + if (sysctl(mib, nmib, buf, &len, NULL, 0) == 0) { + pa_strlcpy(s, basename(buf), l); + pa_xfree(buf); + return s; + } + + pa_xfree(buf); + + /* fall thru */ + } +#endif /* OS_IS_DARWIN */ + + errno = ENOENT; return NULL; } -const char *pa_path_get_filename(const char *p) { +char *pa_path_get_filename(const char *p) { char *fn; - if ((fn = strrchr(p, PATH_SEP))) + if (!p) + return NULL; + + if ((fn = strrchr(p, PA_PATH_SEP_CHAR))) return fn+1; - return (const char*) p; + return (char*) p; } char *pa_get_fqdn(char *s, size_t l) { char hn[256]; -#ifdef HAVE_GETADDRINFO +#ifdef HAVE_GETADDRINFO struct addrinfo *a, hints; #endif + pa_assert(s); + pa_assert(l > 0); + if (!pa_get_host_name(hn, sizeof(hn))) return NULL; @@ -225,7 +277,7 @@ char *pa_get_fqdn(char *s, size_t l) { memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_flags = AI_CANONNAME; - + if (getaddrinfo(hn, NULL, &hints, &a) < 0 || !a || !a->ai_canonname || !*a->ai_canonname) return pa_strlcpy(s, hn, l); @@ -244,8 +296,8 @@ int pa_msleep(unsigned long t) { #elif defined(HAVE_NANOSLEEP) struct timespec ts; - ts.tv_sec = t/1000; - ts.tv_nsec = (t % 1000) * 1000000; + ts.tv_sec = (time_t) (t / PA_MSEC_PER_SEC); + ts.tv_nsec = (long) ((t % PA_MSEC_PER_SEC) * PA_NSEC_PER_MSEC); return nanosleep(&ts, NULL); #else |
