Compare commits
No commits in common. "874c2767238231d398b683f21385ffa6d3a3a458" and "b3763ff62c8eb0cdf77f8bfdb7603bddd137940b" have entirely different histories.
874c276723
...
b3763ff62c
9 changed files with 0 additions and 584 deletions
15
bitset2.c
15
bitset2.c
|
|
@ -1,15 +0,0 @@
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define BITSET_WORD_BITS (sizeof(bitset_word_t) * 8U)
|
|
||||||
#define BITSET_WORD(idx) ((uintptr_t *)(bits))[(idx) / BITSET_WORD_BITS]
|
|
||||||
#define BITSET_MASK(idx) ((uintptr_t)1 << ((idx) % BITSET_WORD_BITS))
|
|
||||||
|
|
||||||
#define BITSET_SET(bits, idx) (BITSET_WORD(idx) |= BITSET_MASK(idx))
|
|
||||||
#define BITSET_CLEAR(bits, idx) (BITSET_WORD(idx) &= ~BITSET_MASK(idx))
|
|
||||||
#define BITSET_FLIP(bits, idx) (BITSET_WORD(idx) ^= BITSET_MASK(idx))
|
|
||||||
#define BITSET_TEST(bits, idx) (!!((BITSET_WORD(idx) & BITSET_MASK(idx)))) /* forces 0/1 */
|
|
||||||
// #define BITSET_PUT(bits, idx, v) do { if (v) BITSET_SET(bits,idx); else BITSET_CLEAR(bits,idx); } while(0)
|
|
||||||
int main(void) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
188
dijk.c
188
dijk.c
|
|
@ -1,188 +0,0 @@
|
||||||
/* SPDX-License-Identifier: MIT */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imbus 2025
|
|
||||||
*
|
|
||||||
* PQ-less dijkstra in quadratic complexity
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define DIM 26
|
|
||||||
|
|
||||||
#define A 0
|
|
||||||
#define B 1
|
|
||||||
#define C 2
|
|
||||||
#define D 3
|
|
||||||
#define E 4
|
|
||||||
#define F 5
|
|
||||||
#define G 6
|
|
||||||
#define H 7
|
|
||||||
#define I 8
|
|
||||||
#define J 9
|
|
||||||
#define K 10
|
|
||||||
#define L 11
|
|
||||||
#define M 12
|
|
||||||
#define N 13
|
|
||||||
#define O 14
|
|
||||||
#define P 15
|
|
||||||
#define Q 16
|
|
||||||
#define R 17
|
|
||||||
#define S 18
|
|
||||||
#define T 19
|
|
||||||
#define U 20
|
|
||||||
#define V 21
|
|
||||||
#define W 22
|
|
||||||
#define X 23
|
|
||||||
#define Y 24
|
|
||||||
#define Z 25
|
|
||||||
|
|
||||||
/* Node to character */
|
|
||||||
#define ntoch(n) ('A' + (char)(n % 26))
|
|
||||||
|
|
||||||
/* Some helpers */
|
|
||||||
#define set_dist(from, to, d) g[((int)from)][((int)to)] = (int)d
|
|
||||||
#define get_dist(from, to) g[((int)from)][((int)to)]
|
|
||||||
|
|
||||||
/* Adjacency matrix */
|
|
||||||
int g[DIM][DIM] = {};
|
|
||||||
|
|
||||||
void printmat(int mat[DIM][DIM]) {
|
|
||||||
printf("## ");
|
|
||||||
for (int h = 0; h < DIM; h++) printf("%c ", ntoch(h));
|
|
||||||
printf("\n");
|
|
||||||
printf(" ");
|
|
||||||
for (int h = 0; h < DIM; h++) printf("%s", "__");
|
|
||||||
printf("\n");
|
|
||||||
for (int i = 0; i < DIM; i++) {
|
|
||||||
printf("%c |", ntoch(i));
|
|
||||||
for (int j = 0; j < DIM; j++) {
|
|
||||||
printf("%c ", ntoch(mat[i][j]));
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dijkstra(int mat[DIM][DIM], int prev[DIM], int dist[DIM], int s) {
|
|
||||||
int visited[DIM] = {0};
|
|
||||||
|
|
||||||
for (int i = 0; i < DIM; i++) {
|
|
||||||
dist[i] = INT_MAX;
|
|
||||||
prev[i] = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dist[s] = 0;
|
|
||||||
prev[s] = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < DIM; i++) {
|
|
||||||
// Pick first unvisited with smallest dist
|
|
||||||
int u = -1;
|
|
||||||
int min = INT_MAX;
|
|
||||||
|
|
||||||
for (int j = 0; j < DIM; j++) {
|
|
||||||
if (!visited[j] && dist[j] < min) {
|
|
||||||
min = dist[j];
|
|
||||||
u = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (u == -1)
|
|
||||||
break;
|
|
||||||
visited[u] = 1;
|
|
||||||
|
|
||||||
for (int v = 0; v < DIM; v++) {
|
|
||||||
if (get_dist(u, v) > 0 && !visited[v]) {
|
|
||||||
if (dist[u] + get_dist(u, v) < dist[v]) {
|
|
||||||
dist[v] = dist[u] + get_dist(u, v);
|
|
||||||
prev[v] = u;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void path_reconstruct(int prev[DIM], int dist[DIM], int s, int t) {
|
|
||||||
if (dist[t] == INT_MAX) {
|
|
||||||
printf("No path from %c to %c\n", ntoch(s), ntoch(t));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int path[DIM];
|
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
// Walk backwards from target to source
|
|
||||||
for (int v = t; v != -1; v = prev[v]) {
|
|
||||||
path[len++] = v;
|
|
||||||
if (v == s)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path[len - 1] != s) {
|
|
||||||
printf("No path from %c to %c\n", ntoch(s), ntoch(t));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print path in correct order
|
|
||||||
printf("Path (cost %d): ", dist[t]);
|
|
||||||
for (int i = len - 1; i >= 0; i--) {
|
|
||||||
printf("%c", ntoch(path[i]));
|
|
||||||
if (i > 0)
|
|
||||||
printf(" -> ");
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_graph(void) {
|
|
||||||
set_dist(A, B, 4);
|
|
||||||
set_dist(A, C, 9);
|
|
||||||
set_dist(B, D, 2);
|
|
||||||
set_dist(B, E, 5);
|
|
||||||
set_dist(C, B, 2);
|
|
||||||
set_dist(C, F, 7);
|
|
||||||
set_dist(D, C, 1);
|
|
||||||
set_dist(E, C, 2);
|
|
||||||
set_dist(F, G, 3);
|
|
||||||
set_dist(G, H, 6);
|
|
||||||
set_dist(H, I, 1);
|
|
||||||
set_dist(I, J, 8);
|
|
||||||
set_dist(J, K, 4);
|
|
||||||
set_dist(K, L, 5);
|
|
||||||
set_dist(L, M, 2);
|
|
||||||
set_dist(M, N, 3);
|
|
||||||
set_dist(N, O, 7);
|
|
||||||
set_dist(O, P, 1);
|
|
||||||
set_dist(P, Q, 2);
|
|
||||||
set_dist(Q, R, 6);
|
|
||||||
set_dist(R, S, 3);
|
|
||||||
set_dist(S, T, 5);
|
|
||||||
set_dist(T, U, 2);
|
|
||||||
set_dist(U, V, 1);
|
|
||||||
set_dist(V, W, 4);
|
|
||||||
set_dist(W, X, 7);
|
|
||||||
set_dist(X, Y, 2);
|
|
||||||
set_dist(Y, Z, 3);
|
|
||||||
set_dist(Z, A, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
for (int i = 0; i < DIM; i++) {
|
|
||||||
for (int j = 0; j < DIM; j++) {
|
|
||||||
g[i][j] = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init_graph();
|
|
||||||
|
|
||||||
printmat(g);
|
|
||||||
|
|
||||||
int prev[DIM] = {0};
|
|
||||||
int dist[DIM] = {0};
|
|
||||||
dijkstra(g, prev, dist, A);
|
|
||||||
|
|
||||||
for (int k = 0; k < DIM; k++) {
|
|
||||||
printf("%c prev: %c\n", ntoch(k), ntoch(prev[k]));
|
|
||||||
}
|
|
||||||
|
|
||||||
path_reconstruct(prev, dist, A, Z);
|
|
||||||
}
|
|
||||||
70
interfaces.c
70
interfaces.c
|
|
@ -1,70 +0,0 @@
|
||||||
#include <math.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
// Here's a basic interface for geometric shapes.
|
|
||||||
typedef struct {
|
|
||||||
double (*area)(void *);
|
|
||||||
double (*perim)(void *);
|
|
||||||
} geometry;
|
|
||||||
|
|
||||||
// For our example we'll implement this interface on
|
|
||||||
// `rect` and `circle` types.
|
|
||||||
typedef struct {
|
|
||||||
double width, height;
|
|
||||||
} rect;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
double radius;
|
|
||||||
} circle;
|
|
||||||
|
|
||||||
// To implement an interface in C, we need to define functions
|
|
||||||
// that match the function pointers in the interface.
|
|
||||||
// Here we implement `geometry` on `rect`s.
|
|
||||||
double rect_area(void *r) {
|
|
||||||
rect *rect_ptr = (rect *)r;
|
|
||||||
return rect_ptr->width * rect_ptr->height;
|
|
||||||
}
|
|
||||||
|
|
||||||
double rect_perim(void *r) {
|
|
||||||
rect *rect_ptr = (rect *)r;
|
|
||||||
return 2 * rect_ptr->width + 2 * rect_ptr->height;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The implementation for `circle`s.
|
|
||||||
double circle_area(void *c) {
|
|
||||||
circle *circle_ptr = (circle *)c;
|
|
||||||
return M_PI * circle_ptr->radius * circle_ptr->radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
double circle_perim(void *c) {
|
|
||||||
circle *circle_ptr = (circle *)c;
|
|
||||||
return 2 * M_PI * circle_ptr->radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a variable has an interface type, then we can call
|
|
||||||
// methods that are in the named interface. Here's a
|
|
||||||
// generic `measure` function taking advantage of this
|
|
||||||
// to work on any `geometry`.
|
|
||||||
void measure(void *g, geometry *geom) {
|
|
||||||
printf("Area: %f\n", geom->area(g));
|
|
||||||
printf("Perimeter: %f\n", geom->perim(g));
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
rect r = {.width = 3, .height = 4};
|
|
||||||
circle c = {.radius = 5};
|
|
||||||
|
|
||||||
// The `circle` and `rect` struct types both
|
|
||||||
// implement the `geometry` interface so we can use
|
|
||||||
// instances of these structs as arguments to `measure`.
|
|
||||||
geometry rect_geometry = {rect_area, rect_perim};
|
|
||||||
geometry circle_geometry = {circle_area, circle_perim};
|
|
||||||
|
|
||||||
printf("Rectangle:\n");
|
|
||||||
measure(&r, &rect_geometry);
|
|
||||||
|
|
||||||
printf("\nCircle:\n");
|
|
||||||
measure(&c, &circle_geometry);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
66
riscv-vm.c
66
riscv-vm.c
|
|
@ -1,66 +0,0 @@
|
||||||
#include <assert.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define PPN_MASK (UINT64_MAX >> 20)
|
|
||||||
|
|
||||||
#define PPN_TO_PA(PPN) ((PPN & PPN_MASK) << 12)
|
|
||||||
#define PA_TO_PPN(PA) (PA >> 12)
|
|
||||||
|
|
||||||
#define ALIGN_UP(n, align) (((n) + (align) - 1) & ~((align) - 1))
|
|
||||||
#define ALIGN_DOWN(n, align) ((n) & ~((align) - 1))
|
|
||||||
|
|
||||||
#define IS_ALIGNED(x, align) (((uintptr_t)(x) & ((uintptr_t)(align) - 1)) == 0)
|
|
||||||
#define IS_ALIGNED_ANY(x, align) (((uintptr_t)(x) % (uintptr_t)(align)) == 0)
|
|
||||||
|
|
||||||
#define IS_POWER_OF_TWO(x) (((x) != 0) && (((x) & ((x) - 1)) == 0))
|
|
||||||
#define IS_ALIGNED_POW2(x, align) \
|
|
||||||
(assert(IS_POWER_OF_TWO((uintptr_t)(align))), (((uintptr_t)(x) & ((uintptr_t)(align) - 1)) == 0))
|
|
||||||
|
|
||||||
#define VM_MODE_SV39 (2 << 64)
|
|
||||||
|
|
||||||
#define PTE_V (1 << 0)
|
|
||||||
#define PTE_R (1 << 1)
|
|
||||||
#define PTE_W (1 << 2)
|
|
||||||
#define PTE_X (1 << 3)
|
|
||||||
/* And so on... */
|
|
||||||
|
|
||||||
#define IS_LEAF(PTE) ((PTE & (PTE_R | PTE_W | PTE_X)) != 0)
|
|
||||||
|
|
||||||
#define PTE_PPN(PTE, LEVEL) (((PTE) >> (10 + ((LEVEL) * 9)) & 0x1FF))
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
assert(IS_ALIGNED(0, 1));
|
|
||||||
assert(IS_ALIGNED(8, 8));
|
|
||||||
assert(IS_ALIGNED(12, 4));
|
|
||||||
assert(!IS_ALIGNED(66, 16));
|
|
||||||
assert(!IS_ALIGNED(234, 4096));
|
|
||||||
assert(!IS_ALIGNED(4099, 4096));
|
|
||||||
|
|
||||||
assert(PPN_MASK == 0b11111111111111111111111111111111111111111111);
|
|
||||||
assert(PPN_MASK == 17592186044415);
|
|
||||||
assert(PPN_MASK == 0xFFFFFFFFFFF);
|
|
||||||
|
|
||||||
printf("%lu", PPN_TO_PA(0xAAAAAA));
|
|
||||||
assert(IS_ALIGNED(PPN_TO_PA(0xAAAAAAAAAAAA), 4096));
|
|
||||||
|
|
||||||
uint64_t pte = 0b11111111110000000001111111110000000001111111111;
|
|
||||||
|
|
||||||
assert(pte & PTE_V);
|
|
||||||
assert(pte & PTE_R);
|
|
||||||
assert(pte & PTE_W);
|
|
||||||
assert(pte & PTE_X);
|
|
||||||
|
|
||||||
assert(IS_LEAF(pte));
|
|
||||||
|
|
||||||
assert(PTE_PPN(pte, 0) == 0);
|
|
||||||
assert(PTE_PPN(pte, 1) == 0b111111111);
|
|
||||||
assert(PTE_PPN(pte, 2) == 0);
|
|
||||||
pte <<= 9;
|
|
||||||
assert(PTE_PPN(pte, 0) == 0b111111111);
|
|
||||||
assert(PTE_PPN(pte, 1) == 0);
|
|
||||||
assert(PTE_PPN(pte, 2) == 0b111111111);
|
|
||||||
|
|
||||||
assert(!IS_LEAF(pte)); // Rightmost bits are now shifted out
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
CC ?= gcc
|
|
||||||
CFLAGS ?= -Wall -g
|
|
||||||
|
|
||||||
all: server.elf client.elf
|
|
||||||
|
|
||||||
server.elf: server.c
|
|
||||||
client.elf: client.c
|
|
||||||
|
|
||||||
%.elf: %.c
|
|
||||||
@echo CC $@
|
|
||||||
@$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
|
||||||
|
|
||||||
test: all
|
|
||||||
bash test.sh
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.elf *.o
|
|
||||||
|
|
||||||
.PHONY: test clean
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <strings.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#define MAX 80
|
|
||||||
#define PORT 8080
|
|
||||||
|
|
||||||
void func(int sockfd) {
|
|
||||||
char buff[MAX];
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
char *msg = "Ping\n";
|
|
||||||
write(sockfd, msg, sizeof(buff));
|
|
||||||
|
|
||||||
bzero(buff, sizeof(buff));
|
|
||||||
read(sockfd, buff, sizeof(buff));
|
|
||||||
|
|
||||||
printf("From Server : %s", buff);
|
|
||||||
if ((strncmp(buff, "exit", 4)) == 0) {
|
|
||||||
printf("Client Exit...\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
if (sockfd == -1) {
|
|
||||||
printf("socket creation failed...\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
printf("Socket successfully created..\n");
|
|
||||||
|
|
||||||
struct sockaddr_in servaddr;
|
|
||||||
bzero(&servaddr, sizeof(servaddr));
|
|
||||||
servaddr.sin_family = AF_INET;
|
|
||||||
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
|
||||||
servaddr.sin_port = htons(PORT);
|
|
||||||
|
|
||||||
if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) {
|
|
||||||
printf("connection with the server failed...\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
func(sockfd);
|
|
||||||
close(sockfd);
|
|
||||||
}
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
#include <netdb.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#define MAX 80
|
|
||||||
#define PORT 8080
|
|
||||||
|
|
||||||
void func(int connfd) {
|
|
||||||
char buff[MAX];
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
bzero(buff, MAX);
|
|
||||||
|
|
||||||
ssize_t recv_n = recv(connfd, buff, sizeof(buff), 0);
|
|
||||||
if (recv_n >= MAX) {
|
|
||||||
/* Likely more data, realloc */
|
|
||||||
}
|
|
||||||
|
|
||||||
buff[recv_n - 1] = '\0';
|
|
||||||
printf("From client: %s\n", buff);
|
|
||||||
bzero(buff, MAX);
|
|
||||||
|
|
||||||
char *msg = "Hello!\n";
|
|
||||||
send(connfd, msg, strlen(msg), 0);
|
|
||||||
|
|
||||||
if (strncmp("exit", buff, 4) == 0) {
|
|
||||||
printf("Server Exit...\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
if (sockfd == -1) {
|
|
||||||
printf("socket creation failed...\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sockaddr_in servaddr;
|
|
||||||
bzero(&servaddr, sizeof(servaddr));
|
|
||||||
|
|
||||||
servaddr.sin_family = AF_INET;
|
|
||||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
servaddr.sin_port = htons(PORT);
|
|
||||||
|
|
||||||
if ((bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) != 0) {
|
|
||||||
printf("socket bind failed...\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((listen(sockfd, 5)) != 0) {
|
|
||||||
printf("Listen failed...\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sockaddr_in cli;
|
|
||||||
socklen_t len = sizeof(cli);
|
|
||||||
|
|
||||||
int connfd = accept(sockfd, (struct sockaddr *)&cli, &len);
|
|
||||||
if (connfd < 0) {
|
|
||||||
printf("server accept failed...\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
func(connfd);
|
|
||||||
close(sockfd);
|
|
||||||
}
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#define SOCKET_PATH "/tmp/demosocket"
|
|
||||||
#define BUF_SIZE 128
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
int server_fd, client_fd;
|
|
||||||
struct sockaddr_un addr;
|
|
||||||
char buf[BUF_SIZE];
|
|
||||||
|
|
||||||
// Clean up any leftover socket file
|
|
||||||
unlink(SOCKET_PATH);
|
|
||||||
|
|
||||||
// Create socket
|
|
||||||
server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
||||||
if (server_fd == -1) {
|
|
||||||
perror("socket");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zero out and set up the address structure
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
|
||||||
addr.sun_family = AF_UNIX;
|
|
||||||
strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);
|
|
||||||
|
|
||||||
// Bind the socket to the path
|
|
||||||
if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
|
||||||
perror("bind");
|
|
||||||
close(server_fd);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for a connection
|
|
||||||
if (listen(server_fd, 1) == -1) {
|
|
||||||
perror("listen");
|
|
||||||
close(server_fd);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Server listening on %s...\n", SOCKET_PATH);
|
|
||||||
|
|
||||||
// Accept a connection
|
|
||||||
client_fd = accept(server_fd, NULL, NULL);
|
|
||||||
if (client_fd == -1) {
|
|
||||||
perror("accept");
|
|
||||||
close(server_fd);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive a message
|
|
||||||
ssize_t received = recv(client_fd, buf, BUF_SIZE - 1, 0);
|
|
||||||
if (received > 0) {
|
|
||||||
buf[received] = '\0';
|
|
||||||
printf("Received: %s", buf);
|
|
||||||
|
|
||||||
// Send a reply
|
|
||||||
const char *reply = "Got your message!\n";
|
|
||||||
send(client_fd, reply, strlen(reply), 0);
|
|
||||||
} else {
|
|
||||||
perror("recv");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up
|
|
||||||
close(client_fd);
|
|
||||||
close(server_fd);
|
|
||||||
unlink(SOCKET_PATH);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
SOCKET_PATH="/tmp/demosocket"
|
|
||||||
|
|
||||||
# Cleanup function to be run on exit
|
|
||||||
cleanup() {
|
|
||||||
echo "Cleaning up..."
|
|
||||||
if [[ -n "$SERVER_PID" ]]; then
|
|
||||||
kill "$SERVER_PID" 2>/dev/null || true
|
|
||||||
wait "$SERVER_PID" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
rm -f "$SOCKET_PATH"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Trap EXIT to ensure cleanup runs
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
echo "Starting server..."
|
|
||||||
./server.elf &
|
|
||||||
SERVER_PID=$!
|
|
||||||
|
|
||||||
# Wait briefly for the server to start
|
|
||||||
sleep 0.2
|
|
||||||
|
|
||||||
echo "Running client..."
|
|
||||||
./client.elf
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue