add server shell script example

This commit is contained in:
gome 2023-09-17 12:52:37 -05:00
parent d197d53ca1
commit 8e58e189c7
6 changed files with 81 additions and 26 deletions

View File

@ -5,11 +5,6 @@ exe-flags = $(flags)
exe-src := $(wildcard src/*.c)
exe := $(exe-src:src/%.c=bin/%)
lib-src := $(wildcard lib/*.c)
lib := $(lib-src:lib/%.c=bin/%.so)
obj := $(lib-src:lib/%.c=bin/%.o)
server-src := $(wildcard src/*.c)
client-src := $(wildcard src/client/*.c)
shared-src := $(wildcard src/shared/*.c)
all: exe lib
@ -57,4 +52,4 @@ print-% : ; @echo $* = $($*)
# @printf "Compiling test executable for $< ... \n"
# @gcc $(c-flags) -o $@ $< && printf "Done.\n"
.PHONY: clean exe server-lib client-lib all
.PHONY: all clean exe lib server-lib client-lib

View File

@ -97,6 +97,7 @@ char* client_get_response() {
// }
// TODO: proper signal handling (e.g. this doesn't run when SIGINT stops the program)
void __attribute__ ((destructor)) client_clean_up(void) {
free(client_globals.response);
close(client_globals.sock_fd);

View File

@ -140,6 +140,7 @@ uid_t server_get_uid() {
// }
// TODO: proper signal handling (e.g. this doesn't run when SIGINT stops the program)
void __attribute__ ((destructor)) server_clean_up(void) {
// TODO: error handling?
close(server_globals.sock_fd);

View File

@ -34,7 +34,7 @@ So, for example, to use the server, you'd need:
You should be able to use these libraries in a variety of languages that support a C [foreign function interface (FFI)](https://en.wikipedia.org/wiki/Foreign_function_interface).
### API
#### API
I'll write up API documentation soon, but for now, look at the header files in `./include` for an idea of the API.
@ -43,7 +43,7 @@ I'll write up API documentation soon, but for now, look at the header files in `
There are subcommands for the server and the client respectively.
This part is still a WIP, so don't expect much yet!
##### Server
#### Server
```
> localserv server <socket-path>
@ -51,7 +51,9 @@ This part is still a WIP, so don't expect much yet!
The `<socket-path>` can be any file path that you have permissions to that isn't already occupied, e.g., `~/example.sock`
##### Client
The server listens for strings from clients, writes them to `stdout`, and waits for a line from `stdin` to send back to the client. This can be handled interactively, but it can also be hooked into with a script, as in the example `./server.sh`.
#### Client
```
> localserv client <socket-path> <request>
@ -59,3 +61,20 @@ The `<socket-path>` can be any file path that you have permissions to that isn't
The `<socket-path>` is the same one you specified when starting your server.
The `<request>` is just any string you want to send to the server.
### Server script example
After building with `make exe`, run the server script `./server.sh` like so:
```
> ./server.sh ~/myserver.sock
```
Leave this running, and in another terminal session, run the client against the same socket:
```
> bin/localserv client ~/myserver.sock 'my message'
MY MESSAGE
```
As shown, you should receive the capitalized version of your message from the server. In theory, this should work if other users too, if they run the client against the same socket.

31
server.sh Executable file
View File

@ -0,0 +1,31 @@
#!/bin/bash
set -euo pipefail
# NOTE: you have to build the localserv command using `make exe` before you can use this
if [[ -z "${1-}" ]]; then
echo "provide a socket path"
exit -1
fi
# set up named pipes in same place as the socket
recv="$1.recvpipe"
resp="$1.resppipe"
mkfifo $recv $resp
# they will be removed when the script exits
trap "rm -f $recv $resp" EXIT
# get input line by line (each line will be a request string)
# TODO: do note that this doesn't handle multiline requests correctly yet!
while read -r line; do
# do whatever you want with line here and just write it to stdout
# this example just capitalizes everything
# the server will send back the first full line (i.e. up to a newline) it receives
echo $line | tr a-z A-Z;
# this sets up the stdin & stdout to our pipes and
# backgrounds the process so it can run at the same time as the server
done <$recv >$resp &
# run the server, hooked up to the pipes and at the socket address the user gave
bin/localserv server $1 >$recv <$resp

View File

@ -14,25 +14,33 @@ int server(char *path) {
return error;
}
error = server_listen();
if (error) {
fprintf(stderr, "%s: listen failed: %s\n", exe_name, strerror(error));
return error;
}
while (true) {
error = server_listen();
if (error) {
fprintf(stderr, "%s: listen failed: %s\n", exe_name, strerror(error));
return error;
}
char* request = server_get_request();
printf("Request: %s\n", request);
printf("Input response: ");
char* request = server_get_request();
printf("%s\n", request);
fflush(stdout);
char* response = NULL;
size_t len = 0;
if (getline(&response, &len, stdin) == -1) {
fprintf(stderr, "%s: failed getting input: %s\n", exe_name, strerror(errno));
}
error = server_respond(response);
if (error) {
fprintf(stderr, "%s: respond failed: %s\n", exe_name, strerror(error));
return error;
char* response = NULL;
size_t len = 0;
ssize_t length = getline(&response, &len, stdin);
if (length == -1) {
fprintf(stderr, "%s: failed getting input\n", exe_name);
return -1;
}
response[length - 1] = '\0';
error = server_respond(response);
free(response);
if (error) {
fprintf(stderr, "%s: respond failed: %s\n", exe_name, strerror(error));
return error;
}
}
return 0;