[pulseaudio-commits] 4 commits - src/pulsecore src/utils

Arun Raghavan arun at kemper.freedesktop.org
Mon Oct 22 23:50:57 PDT 2012


 src/pulsecore/core-error.c |    5 +++--
 src/pulsecore/core-util.c  |   36 ++++++++++++++++++++++++++++++++----
 src/utils/pacat.c          |   12 +++++++++---
 3 files changed, 44 insertions(+), 9 deletions(-)

New commits:
commit 9f3bba8bd4c5c5bfeaf22d2d314efba2f3f0b065
Author: Thomas Martitz <kugel at rockbox.org>
Date:   Mon Aug 20 23:50:39 2012 +0200

    core: Slightly more helpful pa_cstrerror for unknown errors
    
    On Windows, strerror can actually return "Unknown Error"
    (e.g. for large errnums). The code assumes the return value to be helpful.
    Make it slightly more helpful by catching the message and appending the
    errnum.

diff --git a/src/pulsecore/core-error.c b/src/pulsecore/core-error.c
index 4d930a0..a1aee0e 100644
--- a/src/pulsecore/core-error.c
+++ b/src/pulsecore/core-error.c
@@ -63,8 +63,9 @@ const char* pa_cstrerror(int errnum) {
     original = strerror(errnum);
 #endif
 
-    if (!original) {
-        pa_snprintf(errbuf, sizeof(errbuf), "Unknown error %i", errnum);
+    /* The second condition is a Windows-ism */
+    if (!original || !strcasecmp(original, "Unknown error")) {
+        pa_snprintf(errbuf, sizeof(errbuf), "Unknown error %d", errnum);
         original = errbuf;
     }
 

commit b342daded9f3eed967637bc32ae066bce827c81d
Author: Thomas Martitz <kugel at rockbox.org>
Date:   Mon Aug 20 23:50:38 2012 +0200

    pacat: Replace read(), write() with pa_* equivalent.
    
    Calling pa_read() and pa_write() seems more appropriate since they deal better
    with platform specific issues. This doesn't actually fix any open issue since
    only stdio is affected but it seems more future proof.

diff --git a/src/utils/pacat.c b/src/utils/pacat.c
index 734017c..2cd8aa5 100644
--- a/src/utils/pacat.c
+++ b/src/utils/pacat.c
@@ -539,7 +539,7 @@ static void stdin_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_even
 
     buffer = pa_xmalloc(l);
 
-    if ((r = read(fd, buffer, l)) <= 0) {
+    if ((r = pa_read(fd, buffer, l, userdata)) <= 0) {
         if (r == 0) {
             if (verbose)
                 pa_log(_("Got EOF."));
@@ -578,7 +578,7 @@ static void stdout_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_eve
 
     pa_assert(buffer_length);
 
-    if ((r = write(fd, (uint8_t*) buffer+buffer_index, buffer_length)) <= 0) {
+    if ((r = pa_write(fd, (uint8_t*) buffer+buffer_index, buffer_length, userdata)) <= 0) {
         pa_log(_("write() failed: %s"), strerror(errno));
         quit(1);
 
@@ -718,6 +718,8 @@ int main(int argc, char *argv[]) {
     char *bn, *server = NULL;
     pa_time_event *time_event = NULL;
     const char *filename = NULL;
+    /* type for pa_read/_write. passed as userdata to the callbacks */
+    unsigned long type = 0;
 
     static const struct option long_options[] = {
         {"record",       0, NULL, 'r'},
@@ -1136,7 +1138,7 @@ int main(int argc, char *argv[]) {
         if (!(stdio_event = mainloop_api->io_new(mainloop_api,
                                                  mode == PLAYBACK ? STDIN_FILENO : STDOUT_FILENO,
                                                  mode == PLAYBACK ? PA_IO_EVENT_INPUT : PA_IO_EVENT_OUTPUT,
-                                                 mode == PLAYBACK ? stdin_callback : stdout_callback, NULL))) {
+                                                 mode == PLAYBACK ? stdin_callback : stdout_callback, &type))) {
             pa_log(_("io_new() failed."));
             goto quit;
         }

commit c327850d9e4479a0572b7baaf8dafd737586e5a1
Author: Thomas Martitz <kugel at rockbox.org>
Date:   Mon Aug 20 23:50:37 2012 +0200

    core: Transparently handle non-blocking sockets on Windows
    
    On Windows, fdsem.c:flush() fails because sockets are set to non-blocking
    mode, since pa_read() returns -1 (and errno == EWOULDBLOCK). I guess pa_read()
    is expected to block in this case so make it actually block by calling poll().

diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 1e40ba0..710c9dc 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -150,6 +150,8 @@ static pa_strlist *recorded_env = NULL;
 
 #ifdef OS_IS_WIN32
 
+#include "poll.h"
+
 /* Returns the directory of the current DLL, with '/bin/' removed if it is the last component */
 char *pa_win32_get_toplevel(HANDLE handle) {
     static char *toplevel = NULL;
@@ -368,13 +370,26 @@ ssize_t pa_read(int fd, void *buf, size_t count, int *type) {
 #ifdef OS_IS_WIN32
 
     if (!type || *type == 0) {
+        int err;
         ssize_t r;
 
+retry:
         if ((r = recv(fd, buf, count, 0)) >= 0)
             return r;
 
-        if (WSAGetLastError() != WSAENOTSOCK) {
-            errno = WSAGetLastError();
+        err = WSAGetLastError();
+        if (err != WSAENOTSOCK) {
+            /* transparently handle non-blocking sockets, by waiting
+             * for readiness */
+            if (err == WSAEWOULDBLOCK) {
+                struct pollfd pfd;
+                pfd.fd = fd;
+                pfd.events = POLLIN;
+                if (pa_poll(&pfd, 1, -1) >= 0) {
+                    goto retry;
+                }
+            }
+            errno = err;
             return r;
         }
 
@@ -400,7 +415,9 @@ ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
 
     if (!type || *type == 0) {
         ssize_t r;
+        int err;
 
+retry:
         for (;;) {
             if ((r = send(fd, buf, count, MSG_NOSIGNAL)) < 0) {
 
@@ -414,8 +431,19 @@ ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
         }
 
 #ifdef OS_IS_WIN32
-        if (WSAGetLastError() != WSAENOTSOCK) {
-            errno = WSAGetLastError();
+        err = WSAGetLastError();
+        if (err != WSAENOTSOCK) {
+            /* transparently handle non-blocking sockets, by waiting
+             * for readiness */
+            if (err == WSAEWOULDBLOCK) {
+                struct pollfd pfd;
+                pfd.fd = fd;
+                pfd.events = POLLOUT;
+                if (pa_poll(&pfd, 1, -1) >= 0) {
+                    goto retry;
+                }
+            }
+            errno = err;
             return r;
         }
 #else

commit c1637652eaf3682dc2b5aa8c87b45552a8e1cf67
Author: Thomas Martitz <kugel at rockbox.org>
Date:   Mon Aug 20 23:50:35 2012 +0200

    pacat: Enable binary mode on Windows.
    
    Without this reading from stdin will eventually end with EOF (if there happens
    to be a newline sign in the stream), because read() returns 0.
    
    This patch fixes raw data input and piping to pacat on Windows.

diff --git a/src/utils/pacat.c b/src/utils/pacat.c
index ec360f7..734017c 100644
--- a/src/utils/pacat.c
+++ b/src/utils/pacat.c
@@ -1129,6 +1129,10 @@ int main(int argc, char *argv[]) {
     pa_disable_sigpipe();
 
     if (raw) {
+#ifdef OS_IS_WIN32
+        /* need to turn on binary mode for stdio io. Windows, meh */
+        setmode(mode == PLAYBACK ? STDIN_FILENO : STDOUT_FILENO, O_BINARY);
+#endif
         if (!(stdio_event = mainloop_api->io_new(mainloop_api,
                                                  mode == PLAYBACK ? STDIN_FILENO : STDOUT_FILENO,
                                                  mode == PLAYBACK ? PA_IO_EVENT_INPUT : PA_IO_EVENT_OUTPUT,



More information about the pulseaudio-commits mailing list