summaryrefslogtreecommitdiffstats
path: root/src/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/util.c b/src/util.c
index 5fff55e3..4ade681a 100644
--- a/src/util.c
+++ b/src/util.c
@@ -124,3 +124,87 @@ int pa_make_tcp_socket_low_delay(int fd) {
return ret;
}
+
+ssize_t pa_loop_read(int fd, void*data, size_t size) {
+ ssize_t ret = 0;
+ assert(fd >= 0 && data && size);
+
+ while (size > 0) {
+ ssize_t r;
+
+ if ((r = read(fd, data, size)) < 0)
+ return r;
+
+ if (r == 0)
+ break;
+
+ ret += r;
+ data += r;
+ size -= r;
+ }
+
+ return ret;
+}
+
+ssize_t pa_loop_write(int fd, const void*data, size_t size) {
+ ssize_t ret = 0;
+ assert(fd >= 0 && data && size);
+
+ while (size > 0) {
+ ssize_t r;
+
+ if ((r = write(fd, data, size)) < 0)
+ return r;
+
+ if (r == 0)
+ break;
+
+ ret += r;
+ data += r;
+ size -= r;
+ }
+
+ return ret;
+}
+
+int pa_unix_socket_is_stale(const char *fn) {
+ struct sockaddr_un sa;
+ int fd = -1, ret = -1;
+
+ if ((fd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) {
+ fprintf(stderr, "socket(): %s\n", strerror(errno));
+ goto finish;
+ }
+
+ sa.sun_family = AF_LOCAL;
+ strncpy(sa.sun_path, fn, sizeof(sa.sun_path)-1);
+ sa.sun_path[sizeof(sa.sun_path) - 1] = 0;
+
+ if (connect(fd, (struct sockaddr*) &sa, sizeof(sa)) < 0) {
+ if (errno == ECONNREFUSED)
+ ret = 1;
+ } else
+ ret = 0;
+
+finish:
+ if (fd >= 0)
+ close(fd);
+
+ return ret;
+}
+
+int pa_unix_socket_remove_stale(const char *fn) {
+ int r;
+
+ if ((r = pa_unix_socket_is_stale(fn)) < 0)
+ return errno != ENOENT ? -1 : 0;
+
+ if (!r)
+ return 0;
+
+ /* Yes, here is a race condition. But who cares? */
+ if (unlink(fn) < 0)
+ return -1;
+
+ return 0;
+}