add server shell script example
This commit is contained in:
parent
d197d53ca1
commit
8e58e189c7
7
Makefile
7
Makefile
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
25
readme.md
25
readme.md
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue