private_stream_manager_t *this)
{
remove_stream(this, stream_create_unix);
+ remove_service(this, stream_service_create_unix);
this->streams->destroy(this->streams);
this->services->destroy(this->services);
);
add_stream(this, "unix://", stream_create_unix);
+ add_service(this, "unix://", stream_service_create_unix);
return &this->public;
}
#include <threading/thread.h>
#include <processing/jobs/callback_job.h>
+#include <errno.h>
#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
typedef struct private_stream_service_t private_stream_service_t;
return &this->public;
}
+
+/**
+ * See header
+ */
+stream_service_t *stream_service_create_unix(char *uri)
+{
+ struct sockaddr_un addr;
+ mode_t old;
+ int fd, len;
+
+ len = stream_parse_uri_unix(uri, &addr);
+ if (len == -1)
+ {
+ DBG1(DBG_NET, "invalid stream URI: '%s'", uri);
+ return NULL;
+ }
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ DBG1(DBG_NET, "opening socket '%s' failed: %s", uri, strerror(errno));
+ return NULL;
+ }
+ unlink(addr.sun_path);
+
+ old = umask(~(S_IRWXU | S_IRWXG));
+ if (bind(fd, (struct sockaddr*)&addr, len) < 0)
+ {
+ DBG1(DBG_NET, "binding socket '%s' failed: %s", uri, strerror(errno));
+ close(fd);
+ return NULL;
+ }
+ umask(old);
+ if (chown(addr.sun_path, lib->caps->get_uid(lib->caps),
+ lib->caps->get_gid(lib->caps)) != 0)
+ {
+ DBG1(DBG_NET, "changing socket permissions for '%s' failed: %s",
+ uri, strerror(errno));
+ }
+ if (listen(fd, 5) < 0)
+ {
+ DBG1(DBG_NET, "listen on socket '%s' failed: %s", uri, strerror(errno));
+ unlink(addr.sun_path);
+ close(fd);
+ return NULL;
+ }
+ return stream_service_create_from_fd(fd);
+}
*/
stream_service_t *stream_service_create_from_fd(int fd);
+/**
+ * Create a service instance for UNIX sockets.
+ *
+ * @param uri UNIX socket specific URI, must start with "unix://"
+ * @return stream_service instance, NULL on failure
+ */
+stream_service_t *stream_service_create_unix(char *uri);
+
#endif /** STREAM_SERVICE_H_ @}*/