]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/core-util.c
add API pa_ncpus()
[pulseaudio] / src / pulsecore / core-util.c
index 3e5ea492defa1234bbf6ec220c4732c68b89ab81..e65b17968fc05f39de2f1434dc53ea857f42f2e7 100644 (file)
@@ -935,7 +935,7 @@ static int is_group(gid_t gid, const char *name) {
 #else
     n = -1;
 #endif
-    if (n < 0)
+    if (n <= 0)
         n = 512;
 
     data = pa_xmalloc((size_t) n);
@@ -959,7 +959,7 @@ finish:
      * support getgrgid_r. */
 
     errno = 0;
-    if ((result = getgrgid(gid)) == NULL) {
+    if (!(result = getgrgid(gid))) {
         pa_log("getgrgid(%u): %s", gid, pa_cstrerror(errno));
 
         if (!errno)
@@ -1026,18 +1026,35 @@ int pa_uid_in_group(uid_t uid, const char *name) {
     char **i;
     int r = -1;
 
+#ifdef _SC_GETGR_R_SIZE_MAX
     g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
+#else
+    g_n = -1;
+#endif
+    if (g_n <= 0)
+        g_n = 512;
+
     g_buf = pa_xmalloc((size_t) g_n);
 
+#ifdef _SC_GETPW_R_SIZE_MAX
     p_n = sysconf(_SC_GETPW_R_SIZE_MAX);
+#else
+    p_n = -1;
+#endif
+    if (p_n <= 0)
+        p_n = 512;
+
     p_buf = pa_xmalloc((size_t) p_n);
 
     errno = 0;
-    if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) {
-
+#ifdef HAVE_GETGRNAM_R
+    if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr)
+#else
+    if (!(gr = getgrnam(name)))
+#endif
+    {
         if (!errno)
             errno = ENOENT;
-
         goto finish;
     }
 
@@ -1045,8 +1062,11 @@ int pa_uid_in_group(uid_t uid, const char *name) {
     for (i = gr->gr_mem; *i; i++) {
         struct passwd pwbuf, *pw;
 
-        errno = 0;
+#ifdef HAVE_GETPWNAM_R
         if (getpwnam_r(*i, &pwbuf, p_buf, (size_t) p_n, &pw) != 0 || !pw)
+#else
+        if (!(pw = getpwnam(*i)))
+#endif
             continue;
 
         if (pw->pw_uid == uid) {
@@ -1069,15 +1089,25 @@ gid_t pa_get_gid_of_group(const char *name) {
     long g_n;
     struct group grbuf, *gr;
 
+#ifdef _SC_GETGR_R_SIZE_MAX
     g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
+#else
+    g_n = -1;
+#endif
+    if (g_n <= 0)
+        g_n = 512;
+
     g_buf = pa_xmalloc((size_t) g_n);
 
     errno = 0;
-    if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) {
-
+#ifdef HAVE_GETGRNAM_R
+    if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr)
+#else
+    if (!(gr = getgrnam(name)))
+#endif
+    {
         if (!errno)
             errno = ENOENT;
-
         goto finish;
     }
 
@@ -1315,31 +1345,43 @@ static char* make_random_dir(mode_t m) {
         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
         "0123456789";
 
-    char fn[24] = "/tmp/pulse-";
+    const char *tmpdir;
+    char *fn;
+    size_t pathlen;
 
-    fn[sizeof(fn)-1] = 0;
+    if (!(tmpdir = getenv("TMPDIR")))
+        if (!(tmpdir = getenv("TMP")))
+            if (!(tmpdir = getenv("TEMP")))
+                tmpdir = getenv("TEMPDIR");
+
+    if (!tmpdir || !pa_is_path_absolute(tmpdir))
+        tmpdir = "/tmp";
+
+    fn = pa_sprintf_malloc("%s/pulse-XXXXXXXXXXXX", tmpdir);
+    pathlen = strlen(fn);
 
     for (;;) {
-        unsigned i;
+        size_t i;
         int r;
         mode_t u;
         int saved_errno;
 
-        for (i = 11; i < sizeof(fn)-1; i++)
+        for (i = pathlen - 12; i < pathlen; i++)
             fn[i] = table[rand() % (sizeof(table)-1)];
 
         u = umask((~m) & 0777);
         r = mkdir(fn, m);
+
         saved_errno = errno;
         umask(u);
+        errno = saved_errno;
 
         if (r >= 0)
-            return pa_xstrdup(fn);
-
-        errno = saved_errno;
+            return fn;
 
         if (errno != EEXIST) {
             pa_log_error("Failed to create random directory %s: %s", fn, pa_cstrerror(errno));
+            pa_xfree(fn);
             return NULL;
         }
     }
@@ -1370,6 +1412,7 @@ static int make_random_dir_and_link(mode_t m, const char *k) {
 char *pa_get_runtime_dir(void) {
     char *d, *k = NULL, *p = NULL, *t = NULL, *mid;
     struct stat st;
+    mode_t m;
 
     /* The runtime directory shall contain dynamic data that needs NOT
      * to be kept accross reboots and is usuallly private to the user,
@@ -1378,10 +1421,9 @@ char *pa_get_runtime_dir(void) {
      * this directory, we link it to a random subdir in /tmp, if it
      * was not explicitly configured. */
 
-    if ((d = getenv("PULSE_RUNTIME_PATH"))) {
-        mode_t m;
+    m = pa_in_system_mode() ? 0755U : 0700U;
 
-        m = pa_in_system_mode() ? 0755U : 0700U;
+    if ((d = getenv("PULSE_RUNTIME_PATH"))) {
 
         if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0)  {
             pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
@@ -1394,6 +1436,11 @@ char *pa_get_runtime_dir(void) {
     if (!(d = get_pulse_home()))
         goto fail;
 
+    if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0)  {
+        pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
+        goto fail;
+    }
+
     if (!(mid = pa_machine_id())) {
         pa_xfree(d);
         goto fail;
@@ -2334,7 +2381,7 @@ int pa_reset_sigs(int except, ...) {
 int pa_reset_sigsv(const int except[]) {
     int sig;
 
-    for (sig = 1; sig < _NSIG; sig++) {
+    for (sig = 1; sig < NSIG; sig++) {
         pa_bool_t reset = TRUE;
 
         switch (sig) {
@@ -2455,3 +2502,54 @@ char *pa_uname_string(void) {
 
     return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);
 }
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+pa_bool_t pa_in_valgrind(void) {
+    static int b = 0;
+
+    /* To make heisenbugs a bit simpler to find we check for $VALGRIND
+     * here instead of really checking whether we run in valgrind or
+     * not. */
+
+    if (b < 1)
+        b = getenv("VALGRIND") ? 2 : 1;
+
+    return b > 1;
+}
+#endif
+
+unsigned pa_gcd(unsigned a, unsigned b) {
+
+    while (b > 0) {
+        unsigned t = b;
+        b = a % b;
+        a = t;
+    }
+
+    return a;
+}
+
+void pa_reduce(unsigned *num, unsigned *den) {
+
+    unsigned gcd = pa_gcd(*num, *den);
+
+    if (gcd <= 0)
+        return;
+
+    *num /= gcd;
+    *den /= gcd;
+
+    pa_assert(pa_gcd(*num, *den) == 1);
+}
+
+unsigned pa_ncpus(void) {
+    long ncpus;
+
+#ifdef _SC_NPROCESSORS_CONF
+    ncpus = sysconf(_SC_NPROCESSORS_CONF);
+#else
+    ncpus = 1;
+#endif
+
+    return ncpus <= 0 ? 1 : (unsigned) ncpus;
+}