Basic IPC stuff
This commit is contained in:
parent
92abc822ec
commit
3671e34d4e
|
@ -0,0 +1,48 @@
|
||||||
|
#ifndef _SFXD_COMMON_H_
|
||||||
|
#define _SFXD_COMMON_H_
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 8192
|
||||||
|
#define DAEMON_SOCKET_PATH "/tmp/sfxd-ipc"
|
||||||
|
#define CLIENT_SOCKET_PATH "/tmp/sfxd-client-%ld"
|
||||||
|
|
||||||
|
#define PANIC_FMT(FMT, ...) _panic(__LINE__, __FILE__, errno, FMT, __VA_ARGS__)
|
||||||
|
#define PANIC(TXT) _panic(__LINE__, __FILE__, errno, TXT)
|
||||||
|
#define EXPECT(CODE, CONDITION) { \
|
||||||
|
ssize_t __res = (CODE); \
|
||||||
|
if (!(__res CONDITION)) \
|
||||||
|
PANIC_FMT("%s failed condition: %zd %s", #CODE, __res, #CONDITION); \
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void _panic(int line, const char *filename, int _errno, const char *fmt, ...) {
|
||||||
|
fprintf(stderr, "Panic at %s:%d\nMessage: ", filename, line);
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vfprintf(stderr, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
fprintf(stderr, "\nerrno: %d (%s)\n", _errno, strerror(_errno));
|
||||||
|
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t adler32(const void *buf, size_t buflength) {
|
||||||
|
const uint8_t *buffer = (const uint8_t*)buf;
|
||||||
|
|
||||||
|
uint32_t s1 = 1;
|
||||||
|
uint32_t s2 = 0;
|
||||||
|
|
||||||
|
for (size_t n = 0; n < buflength; n++) {
|
||||||
|
s1 = (s1 + buffer[n]) % 65521;
|
||||||
|
s2 = (s2 + s1) % 65521;
|
||||||
|
}
|
||||||
|
return (s2 << 16) | s1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
40
src/sfxc.c
40
src/sfxc.c
|
@ -1,6 +1,40 @@
|
||||||
|
#include "common.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
int main(void) {
|
int main(int argc, char **argv) {
|
||||||
printf("Hi!\n");
|
struct sockaddr_un sa_server, sa_client;
|
||||||
|
int sock_fd;
|
||||||
|
static char buffer[BUFFER_SIZE];
|
||||||
|
|
||||||
|
EXPECT(sock_fd = socket(AF_UNIX, SOCK_DGRAM, 0), > 0);
|
||||||
|
|
||||||
|
memset(&sa_server, 0, sizeof(sa_server));
|
||||||
|
memset(&sa_client, 0, sizeof(sa_client));
|
||||||
|
|
||||||
|
sa_server.sun_family = sa_client.sun_family = AF_UNIX;
|
||||||
|
snprintf(sa_client.sun_path, sizeof(sa_client.sun_path), CLIENT_SOCKET_PATH, (long)getpid());
|
||||||
|
strncpy(sa_server.sun_path, DAEMON_SOCKET_PATH, sizeof(sa_server.sun_path) - 1);
|
||||||
|
|
||||||
|
EXPECT(bind(sock_fd, (struct sockaddr *)&sa_client, sizeof(struct sockaddr_un)), == 0);
|
||||||
|
|
||||||
|
for (int i = 1; i < argc; i++) {
|
||||||
|
strncat(buffer, argv[1], BUFFER_SIZE - strlen(buffer) - 1);
|
||||||
|
if (i != argc - 1) {
|
||||||
|
strncat(buffer, " ", BUFFER_SIZE - strlen(buffer) - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT(sendto(sock_fd, buffer, strlen(buffer), 0, (struct sockaddr *)&sa_server, sizeof(sa_server)), == strlen(buffer));
|
||||||
|
int data_len;
|
||||||
|
while ((data_len = recv(sock_fd, buffer, BUFFER_SIZE, 0)) > 0) {
|
||||||
|
printf("%.*s", data_len, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink(sa_client.sun_path);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
77
src/sfxd.c
77
src/sfxd.c
|
@ -1,6 +1,77 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
int main(void) {
|
struct msg_target {
|
||||||
printf("Hi!\n");
|
FILE *file_handle;
|
||||||
|
int sock_fd;
|
||||||
|
struct sockaddr *sock_addr;
|
||||||
|
ssize_t sock_addr_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
ssize_t send_data(struct msg_target tgt, const void *data, size_t len);
|
||||||
|
void execute_command(struct msg_target tgt, const char *command, const char *params);
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
struct sockaddr_un sa_server, sa_client;
|
||||||
|
int sock_fd;
|
||||||
|
static char buffer[BUFFER_SIZE];
|
||||||
|
|
||||||
|
char *sock_path = DAEMON_SOCKET_PATH;
|
||||||
|
|
||||||
|
EXPECT(sock_fd = socket(AF_UNIX, SOCK_DGRAM, 0), > 0);
|
||||||
|
|
||||||
|
memset(&sa_server, 0, sizeof(sa_server));
|
||||||
|
memset(&sa_client, 0, sizeof(sa_client));
|
||||||
|
|
||||||
|
sa_server.sun_family = AF_UNIX;
|
||||||
|
strncpy(sa_server.sun_path, sock_path, sizeof(sa_server.sun_path) - 1);
|
||||||
|
|
||||||
|
unlink(sa_server.sun_path);
|
||||||
|
EXPECT(bind(sock_fd, (struct sockaddr *)&sa_server, sizeof(struct sockaddr_un)), >= 0);
|
||||||
|
|
||||||
|
ssize_t data_len;
|
||||||
|
socklen_t sl_client = sizeof(sa_client);
|
||||||
|
while ((data_len = recvfrom(sock_fd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&sa_client, &sl_client)) != -1) {
|
||||||
|
buffer[data_len] = '\0';
|
||||||
|
struct sockaddr_un *sau_client = &sa_client;
|
||||||
|
char *command = buffer;
|
||||||
|
char *params = strchr(buffer, ' ');
|
||||||
|
if (params != NULL) {
|
||||||
|
*params = '\0';
|
||||||
|
params++;
|
||||||
|
}
|
||||||
|
execute_command((struct msg_target) { 0, sock_fd, (struct sockaddr *)&sa_client, sl_client }, command, params);
|
||||||
|
EXPECT(sendto(sock_fd, "OK\n", 4, 0, (struct sockaddr *)&sa_client, sl_client), == 4);
|
||||||
|
EXPECT(sendto(sock_fd, "", 0, 0, (struct sockaddr *)&sa_client, sl_client), == 0);
|
||||||
|
sl_client = sizeof(sa_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink(sa_server.sun_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t send_data(struct msg_target tgt, const void *data, size_t len) {
|
||||||
|
ssize_t written;
|
||||||
|
if (tgt.file_handle) {
|
||||||
|
if ((written = fwrite(data, 1, len, tgt.file_handle)) != len) {
|
||||||
|
PANIC_FMT("fwrite(ptr=%p, size=%zd, nmemb=%zd, stream=%p) -> %zd",
|
||||||
|
data, 1, len, tgt.file_handle, written);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((written = sendto(tgt.sock_fd, data, len, 0, tgt.sock_addr, tgt.sock_addr_size)) != len) {
|
||||||
|
PANIC_FMT("sendto(socket=%d, message=%p, length=%zd, flags=%d, dest_addr=%p, dest_len=%zd) -> %zd",
|
||||||
|
tgt.sock_fd, data, len, 0, tgt.sock_addr, tgt.sock_addr_size, written);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute_command(struct msg_target tgt, const char *command, const char *params) {
|
||||||
|
send_data(tgt, "WAAAAAAAAAAAAAA\n", 16);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue