~diwic/ubuntu/lucid/pulseaudio/bugfixes

« back to all changes in this revision

Viewing changes to src/pulsecore/core-util.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich
  • Date: 2009-05-05 14:18:20 UTC
  • mfrom: (1.2.4 upstream) (1.1.8 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090505141820-rrr2mtdd1jkllvr8
Tags: 1:0.9.15-1ubuntu1
* Merge from unreleased Debian pulseaudio git, remaining changes:
  - epoch (my stupid fault :S)
  - Don't build against, and create jack package. Jack is not in main
  - use linear resampler to work better with lack of PREEMPT in jaunty's
    -generic kernel config, also change buffer size
  - Add alsa configuration files to route alsa applications via pulseaudio
  - Move libasound2-plugins from Recommends to Depends
  - Add pm-utils sleep hook to suspend (and resume) users' pulseaudio
    daemons
  - patch to fix source/sink and suspend-on-idle race
  - Make initscript more informative in the default case of per-user
    sessions
  - create /var/run/pulse, and make restart more robust
  - add status check for system wide pulseaudio instance
  - LSB {Required-*,Should-*} should specify hal instead of dbus,
    since hal is required (and already requires dbus)
  - indicate that the system pulseaudio instance is being started from the init
    script
  - Install more upstream man pages
  - Link to pacat for parec man page
  - check whether pulseaudio is running before preloading the padsp library
  - Add DEB_OPT_FLAG = -O3 as per recommendation from
    pulseaudio-discuss/2007-December/001017.html
  - cache /usr/share/sounds/ubuntu/stereo/ wav files on pulseaudio load
  - disable glitch free (use tsched=0)
  - Generate a PO template on build
  - add special case to disable pulseaudio loading if accessibility/speech
    is being used
  - the sd wrapper script should not load pulseaudio if pulseaudio is being
    used as a system service
  - add a pulseaudio apport hook
  - fix some typos in README.Debian
  - demote paprefs to suggests
  - drop padevchooser(Recommends) and pavucontrol (Suggests)
  - drop libasyncns-dev build dependency, its in universe
* add libudev-dev as a build-dependency

Show diffs side-by-side

added added

removed removed

Lines of Context:
88
88
#include <samplerate.h>
89
89
#endif
90
90
 
 
91
#ifdef __APPLE__
 
92
#include <xlocale.h>
 
93
#endif
 
94
 
91
95
#include <pulse/xmalloc.h>
92
96
#include <pulse/util.h>
93
97
#include <pulse/utf8.h>
97
101
#include <pulsecore/log.h>
98
102
#include <pulsecore/macro.h>
99
103
#include <pulsecore/thread.h>
 
104
#include <pulsecore/strbuf.h>
100
105
 
101
106
#include "core-util.h"
102
107
 
321
326
}
322
327
 
323
328
/** Calls read() in a loop. Makes sure that as much as 'size' bytes,
324
 
 * unless EOF is reached or an error occured */
 
329
 * unless EOF is reached or an error occurred */
325
330
ssize_t pa_loop_read(int fd, void*data, size_t size, int *type) {
326
331
    ssize_t ret = 0;
327
332
    int _type;
699
704
#endif
700
705
}
701
706
 
702
 
static int match(const char *expr, const char *v) {
 
707
int pa_match(const char *expr, const char *v) {
703
708
    int k;
704
709
    regex_t re;
705
710
    int r;
739
744
    /* And then we check language dependant */
740
745
    if ((expr = nl_langinfo(YESEXPR)))
741
746
        if (expr[0])
742
 
            if ((r = match(expr, v)) > 0)
 
747
            if ((r = pa_match(expr, v)) > 0)
743
748
                return 1;
744
749
 
745
750
    if ((expr = nl_langinfo(NOEXPR)))
746
751
        if (expr[0])
747
 
            if ((r = match(expr, v)) > 0)
 
752
            if ((r = pa_match(expr, v)) > 0)
748
753
                return 0;
749
754
 
750
755
    errno = EINVAL;
935
940
#else
936
941
    n = -1;
937
942
#endif
938
 
    if (n < 0)
 
943
    if (n <= 0)
939
944
        n = 512;
940
945
 
941
946
    data = pa_xmalloc((size_t) n);
959
964
     * support getgrgid_r. */
960
965
 
961
966
    errno = 0;
962
 
    if ((result = getgrgid(gid)) == NULL) {
 
967
    if (!(result = getgrgid(gid))) {
963
968
        pa_log("getgrgid(%u): %s", gid, pa_cstrerror(errno));
964
969
 
965
970
        if (!errno)
1026
1031
    char **i;
1027
1032
    int r = -1;
1028
1033
 
 
1034
#ifdef _SC_GETGR_R_SIZE_MAX
1029
1035
    g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
 
1036
#else
 
1037
    g_n = -1;
 
1038
#endif
 
1039
    if (g_n <= 0)
 
1040
        g_n = 512;
 
1041
 
1030
1042
    g_buf = pa_xmalloc((size_t) g_n);
1031
1043
 
 
1044
#ifdef _SC_GETPW_R_SIZE_MAX
1032
1045
    p_n = sysconf(_SC_GETPW_R_SIZE_MAX);
 
1046
#else
 
1047
    p_n = -1;
 
1048
#endif
 
1049
    if (p_n <= 0)
 
1050
        p_n = 512;
 
1051
 
1033
1052
    p_buf = pa_xmalloc((size_t) p_n);
1034
1053
 
1035
1054
    errno = 0;
1036
 
    if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) {
1037
 
 
 
1055
#ifdef HAVE_GETGRNAM_R
 
1056
    if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr)
 
1057
#else
 
1058
    if (!(gr = getgrnam(name)))
 
1059
#endif
 
1060
    {
1038
1061
        if (!errno)
1039
1062
            errno = ENOENT;
1040
 
 
1041
1063
        goto finish;
1042
1064
    }
1043
1065
 
1045
1067
    for (i = gr->gr_mem; *i; i++) {
1046
1068
        struct passwd pwbuf, *pw;
1047
1069
 
1048
 
        errno = 0;
 
1070
#ifdef HAVE_GETPWNAM_R
1049
1071
        if (getpwnam_r(*i, &pwbuf, p_buf, (size_t) p_n, &pw) != 0 || !pw)
 
1072
#else
 
1073
        if (!(pw = getpwnam(*i)))
 
1074
#endif
1050
1075
            continue;
1051
1076
 
1052
1077
        if (pw->pw_uid == uid) {
1069
1094
    long g_n;
1070
1095
    struct group grbuf, *gr;
1071
1096
 
 
1097
#ifdef _SC_GETGR_R_SIZE_MAX
1072
1098
    g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
 
1099
#else
 
1100
    g_n = -1;
 
1101
#endif
 
1102
    if (g_n <= 0)
 
1103
        g_n = 512;
 
1104
 
1073
1105
    g_buf = pa_xmalloc((size_t) g_n);
1074
1106
 
1075
1107
    errno = 0;
1076
 
    if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) {
1077
 
 
 
1108
#ifdef HAVE_GETGRNAM_R
 
1109
    if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr)
 
1110
#else
 
1111
    if (!(gr = getgrnam(name)))
 
1112
#endif
 
1113
    {
1078
1114
        if (!errno)
1079
1115
            errno = ENOENT;
1080
 
 
1081
1116
        goto finish;
1082
1117
    }
1083
1118
 
1207
1242
            goto fail;
1208
1243
        }
1209
1244
 
1210
 
        /* Check wheter the file has been removed meanwhile. When yes,
 
1245
        /* Check whether the file has been removed meanwhile. When yes,
1211
1246
         * restart this loop, otherwise, we're done */
1212
1247
        if (st.st_nlink >= 1)
1213
1248
            break;
1376
1411
        return -1;
1377
1412
    }
1378
1413
 
 
1414
    pa_xfree(p);
1379
1415
    return 0;
1380
1416
}
1381
1417
 
1408
1444
 
1409
1445
    if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0)  {
1410
1446
        pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
 
1447
        pa_xfree(d);
1411
1448
        goto fail;
1412
1449
    }
1413
1450
 
2424
2461
 
2425
2462
        pa_strip_nl(ln);
2426
2463
 
2427
 
        if (ln[0])
2428
 
            return pa_xstrdup(ln);
 
2464
        if (r && ln[0])
 
2465
            return pa_utf8_filter(ln);
2429
2466
    }
2430
2467
 
2431
2468
    /* The we fall back to the host name. It supposed to be somewhat
2443
2480
                break;
2444
2481
 
2445
2482
        } else if (strlen(c) < l-1) {
 
2483
            char *u;
2446
2484
 
2447
2485
            if (*c == 0) {
2448
2486
                pa_xfree(c);
2449
2487
                break;
2450
2488
            }
2451
2489
 
2452
 
            return c;
 
2490
            u = pa_utf8_filter(c);
 
2491
            pa_xfree(c);
 
2492
            return u;
2453
2493
        }
2454
2494
 
2455
2495
        /* Hmm, the hostname is as long the space we offered the
2461
2501
    }
2462
2502
 
2463
2503
    /* If no hostname was set we use the POSIX hostid. It's usually
2464
 
     * the IPv4 address.  Mit not be that stable. */
 
2504
     * the IPv4 address.  Might not be that stable. */
2465
2505
    return pa_sprintf_malloc("%08lx", (unsigned long) gethostid);
2466
2506
}
2467
2507
 
 
2508
char *pa_session_id(void) {
 
2509
    const char *e;
 
2510
 
 
2511
    if (!(e = getenv("XDG_SESSION_COOKIE")))
 
2512
        return NULL;
 
2513
 
 
2514
    return pa_utf8_filter(e);
 
2515
}
 
2516
 
2468
2517
char *pa_uname_string(void) {
2469
2518
    struct utsname u;
2470
2519
 
2471
 
    pa_assert_se(uname(&u) == 0);
 
2520
    pa_assert_se(uname(&u) >= 0);
2472
2521
 
2473
2522
    return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);
2474
2523
}
2487
2536
    return b > 1;
2488
2537
}
2489
2538
#endif
 
2539
 
 
2540
unsigned pa_gcd(unsigned a, unsigned b) {
 
2541
 
 
2542
    while (b > 0) {
 
2543
        unsigned t = b;
 
2544
        b = a % b;
 
2545
        a = t;
 
2546
    }
 
2547
 
 
2548
    return a;
 
2549
}
 
2550
 
 
2551
void pa_reduce(unsigned *num, unsigned *den) {
 
2552
 
 
2553
    unsigned gcd = pa_gcd(*num, *den);
 
2554
 
 
2555
    if (gcd <= 0)
 
2556
        return;
 
2557
 
 
2558
    *num /= gcd;
 
2559
    *den /= gcd;
 
2560
 
 
2561
    pa_assert(pa_gcd(*num, *den) == 1);
 
2562
}
 
2563
 
 
2564
unsigned pa_ncpus(void) {
 
2565
    long ncpus;
 
2566
 
 
2567
#ifdef _SC_NPROCESSORS_CONF
 
2568
    ncpus = sysconf(_SC_NPROCESSORS_CONF);
 
2569
#else
 
2570
    ncpus = 1;
 
2571
#endif
 
2572
 
 
2573
    return ncpus <= 0 ? 1 : (unsigned) ncpus;
 
2574
}
 
2575
 
 
2576
char *pa_replace(const char*s, const char*a, const char *b) {
 
2577
    pa_strbuf *sb;
 
2578
    size_t an;
 
2579
 
 
2580
    pa_assert(s);
 
2581
    pa_assert(a);
 
2582
    pa_assert(b);
 
2583
 
 
2584
    an = strlen(a);
 
2585
    sb = pa_strbuf_new();
 
2586
 
 
2587
    for (;;) {
 
2588
        const char *p;
 
2589
 
 
2590
        if (!(p = strstr(s, a)))
 
2591
            break;
 
2592
 
 
2593
        pa_strbuf_putsn(sb, s, p-s);
 
2594
        pa_strbuf_puts(sb, b);
 
2595
        s = p + an;
 
2596
    }
 
2597
 
 
2598
    pa_strbuf_puts(sb, s);
 
2599
 
 
2600
    return pa_strbuf_tostring_free(sb);
 
2601
}
 
2602
 
 
2603
char *pa_unescape(char *p) {
 
2604
    char *s, *d;
 
2605
    pa_bool_t escaped = FALSE;
 
2606
 
 
2607
    for (s = p, d = p; *s; s++) {
 
2608
        if (!escaped && *s == '\\') {
 
2609
            escaped = TRUE;
 
2610
            continue;
 
2611
        }
 
2612
 
 
2613
        *(d++) = *s;
 
2614
        escaped = FALSE;
 
2615
    }
 
2616
 
 
2617
    *d = 0;
 
2618
 
 
2619
    return p;
 
2620
}
 
2621
 
 
2622
char *pa_realpath(const char *path) {
 
2623
    char *t;
 
2624
    pa_assert(path);
 
2625
 
 
2626
    /* We want only abolsute paths */
 
2627
    if (path[0] != '/') {
 
2628
        errno = EINVAL;
 
2629
        return NULL;
 
2630
    }
 
2631
 
 
2632
#if defined(__GLIBC__) || defined(__APPLE__)
 
2633
    {
 
2634
        char *r;
 
2635
 
 
2636
        if (!(r = realpath(path, NULL)))
 
2637
            return NULL;
 
2638
 
 
2639
        /* We copy this here in case our pa_xmalloc() is not
 
2640
         * implemented on top of libc malloc() */
 
2641
        t = pa_xstrdup(r);
 
2642
        pa_xfree(r);
 
2643
    }
 
2644
#elif defined(PATH_MAX)
 
2645
    {
 
2646
        char *path_buf;
 
2647
        path_buf = pa_xmalloc(PATH_MAX);
 
2648
 
 
2649
        if (!(t = realpath(path, path_buf))) {
 
2650
            pa_xfree(path_buf);
 
2651
            return NULL;
 
2652
        }
 
2653
    }
 
2654
#else
 
2655
#error "It's not clear whether this system supports realpath(..., NULL) like GNU libc does. If it doesn't we need a private version of realpath() here."
 
2656
#endif
 
2657
 
 
2658
    return t;
 
2659
}