1 // Copyright © Tavian Barnes <tavianator@tavianator.com>
2 // SPDX-License-Identifier: 0BSD
5 * There's no standard Unix utility that creates a socket file, so this small
6 * program does the job.
9 #include "../src/bfstd.h"
14 #include <sys/socket.h>
19 * Print an error message.
21 static void errmsg(const char *cmd, const char *path) {
22 fprintf(stderr, "%s: '%s': %s.\n", cmd, path, xstrerror(errno));
26 * struct sockaddr_un::sun_path is very short, so we chdir() into the target
27 * directory before creating sockets in case the full path is too long but the
30 static int chdir_parent(const char *path) {
31 char *dir = xdirname(path);
42 * Initialize a struct sockaddr_un with the right filename.
44 static int init_sun(struct sockaddr_un *sock, const char *path) {
45 size_t len = strlen(path);
46 if (len == 0 || path[len - 1] == '/') {
51 char *base = xbasename(path);
57 if (len >= sizeof(sock->sun_path)) {
63 sock->sun_family = AF_UNIX;
64 memcpy(sock->sun_path, base, len + 1);
69 int main(int argc, char *argv[]) {
70 const char *cmd = argc > 0 ? argv[0] : "mksock";
73 fprintf(stderr, "Usage: %s NAME\n", cmd);
77 const char *path = argv[1];
79 if (chdir_parent(path) != 0) {
84 struct sockaddr_un sock;
85 if (init_sun(&sock, path) != 0) {
90 int fd = socket(AF_UNIX, SOCK_STREAM, 0);
96 int ret = EXIT_SUCCESS;
98 if (bind(fd, (struct sockaddr *)&sock, sizeof(sock)) != 0) {
103 if (xclose(fd) != 0) {