mirror of
https://github.com/vale981/ray
synced 2025-03-06 10:31:39 -05:00
Make it possible to read and write data that is not null-terminated (#9)
* Make it possible to read and write data that is not null-terminated * formating
This commit is contained in:
parent
ff11ee21ef
commit
b18f214d55
6 changed files with 87 additions and 58 deletions
12
Makefile
12
Makefile
|
@ -9,11 +9,11 @@ CFLAGS += -Wmissing-declarations
|
|||
$(BUILD)/db_tests: hiredis test/db_tests.c thirdparty/greatest.h event_loop.c state/redis.c common.c
|
||||
$(CC) -o $@ test/db_tests.c event_loop.c state/redis.c common.c thirdparty/hiredis/libhiredis.a $(CFLAGS) -I. -Ithirdparty
|
||||
|
||||
$(BUILD)/socket_tests: test/socket_tests.c thirdparty/greatest.h sockets.c
|
||||
$(CC) -o $@ test/socket_tests.c sockets.c $(CFLAGS) -I. -Ithirdparty
|
||||
$(BUILD)/io_tests: test/io_tests.c thirdparty/greatest.h io.c
|
||||
$(CC) -o $@ test/io_tests.c io.c $(CFLAGS) -I. -Ithirdparty
|
||||
|
||||
$(BUILD)/task_tests: test/task_tests.c task.c sockets.c common.h
|
||||
$(CC) -o $@ test/task_tests.c task.c sockets.c $(CFLAGS) -I. -Ithirdparty
|
||||
$(BUILD)/task_tests: test/task_tests.c task.c io.c common.h
|
||||
$(CC) -o $@ test/task_tests.c task.c io.c $(CFLAGS) -I. -Ithirdparty
|
||||
|
||||
clean:
|
||||
rm -r $(BUILD)/*
|
||||
|
@ -24,8 +24,8 @@ redis:
|
|||
hiredis:
|
||||
git submodule update --init --recursive -- "thirdparty/hiredis" ; cd thirdparty/hiredis ; make
|
||||
|
||||
test: hiredis redis $(BUILD)/db_tests $(BUILD)/socket_tests $(BUILD)/task_tests FORCE
|
||||
test: hiredis redis $(BUILD)/db_tests $(BUILD)/io_tests $(BUILD)/task_tests FORCE
|
||||
./thirdparty/redis-3.2.3/src/redis-server &
|
||||
sleep 1s ; ./build/db_tests ; ./build/socket_tests ; ./build/task_tests
|
||||
sleep 1s ; ./build/db_tests ; ./build/io_tests ; ./build/task_tests
|
||||
|
||||
FORCE:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "sockets.h"
|
||||
#include "io.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
@ -6,6 +6,7 @@
|
|||
#include <sys/un.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
@ -74,22 +75,6 @@ int connect_ipc_sock(const char *socket_pathname) {
|
|||
return socket_fd;
|
||||
}
|
||||
|
||||
/* Sends a message on the given socket file descriptor. */
|
||||
void send_ipc_sock(int socket_fd, char *message) {
|
||||
int length = strlen(message);
|
||||
int nbytes;
|
||||
nbytes = write(socket_fd, (char *) &length, sizeof(length));
|
||||
if (nbytes == -1) {
|
||||
LOG_ERR("Error sending to socket.\n");
|
||||
return;
|
||||
}
|
||||
nbytes = write(socket_fd, (char *) message, length * sizeof(char));
|
||||
if (nbytes == -1) {
|
||||
LOG_ERR("Error sending to socket.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Accept a new client connection on the given socket
|
||||
* descriptor. Returns a descriptor for the new socket. */
|
||||
int accept_client(int socket_fd) {
|
||||
|
@ -105,25 +90,52 @@ int accept_client(int socket_fd) {
|
|||
return client_fd;
|
||||
}
|
||||
|
||||
/* Receives a message on the given socket file descriptor. Allocates and
|
||||
* returns a pointer to the message.
|
||||
* NOTE: Caller must free the message! */
|
||||
char *recv_ipc_sock(int socket_fd) {
|
||||
int length;
|
||||
int nbytes;
|
||||
nbytes = read(socket_fd, &length, sizeof(length));
|
||||
if (nbytes < 0) {
|
||||
LOG_ERR("Error reading length of message from socket.");
|
||||
return NULL;
|
||||
/* Write a sequence of bytes on a file descriptor. */
|
||||
void write_bytes(int fd, uint8_t *bytes, int64_t length) {
|
||||
ssize_t nbytes = write(fd, (char *) &length, sizeof(length));
|
||||
if (nbytes == -1) {
|
||||
LOG_ERR("Error sending to socket.\n");
|
||||
return;
|
||||
}
|
||||
nbytes = write(fd, (char *) bytes, length * sizeof(char));
|
||||
if (nbytes == -1) {
|
||||
LOG_ERR("Error sending to socket.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
char *message = malloc((length + 1) * sizeof(char));
|
||||
nbytes = read(socket_fd, message, length);
|
||||
/* Read a sequence of bytes written by write_bytes from a file descriptor.
|
||||
* Allocates and returns a pointer to the bytes.
|
||||
* NOTE: Caller must free the memory! */
|
||||
void read_bytes(int fd, uint8_t **bytes, int64_t *length) {
|
||||
ssize_t nbytes = read(fd, length, sizeof(int64_t));
|
||||
if (nbytes < 0) {
|
||||
LOG_ERR("Error reading length of message from socket.");
|
||||
*bytes = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
*bytes = malloc(*length * sizeof(uint8_t));
|
||||
nbytes = read(fd, *bytes, *length);
|
||||
if (nbytes < 0) {
|
||||
LOG_ERR("Error reading message from socket.");
|
||||
free(message);
|
||||
return NULL;
|
||||
free(*bytes);
|
||||
*bytes = NULL;
|
||||
}
|
||||
message[length] = '\0';
|
||||
return message;
|
||||
}
|
||||
|
||||
/* Write a null-terminated string to a file descriptor. */
|
||||
void write_string(int fd, char *message) {
|
||||
/* Account for the \0 at the end of the string. */
|
||||
write_bytes(fd, (uint8_t *) message, strlen(message) + 1);
|
||||
}
|
||||
|
||||
/* Reads a null-terminated string from the file descriptor that has been
|
||||
* written by write_string. Allocates and returns a pointer to the string.
|
||||
* NOTE: Caller must free the memory! */
|
||||
char *read_string(int fd) {
|
||||
uint8_t *bytes;
|
||||
int64_t length;
|
||||
read_bytes(fd, &bytes, &length);
|
||||
return (char *) bytes;
|
||||
}
|
21
io.h
Normal file
21
io.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef IO_H
|
||||
#define IO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Helper functions for socket communication. */
|
||||
|
||||
int bind_ipc_sock(const char *socket_pathname);
|
||||
int connect_ipc_sock(const char *socket_pathname);
|
||||
|
||||
int accept_client(int socket_fd);
|
||||
|
||||
/* Reading and writing data */
|
||||
|
||||
void write_bytes(int fd, uint8_t *bytes, int64_t length);
|
||||
void read_bytes(int fd, uint8_t **bytes, int64_t *length);
|
||||
|
||||
void write_string(int fd, char *message);
|
||||
char *read_string(int fd);
|
||||
|
||||
#endif
|
11
sockets.h
11
sockets.h
|
@ -1,11 +0,0 @@
|
|||
#ifndef SOCKETS_H
|
||||
#define SOCKETS_H
|
||||
|
||||
/* Helper functions for socket communication. */
|
||||
int bind_ipc_sock(const char* socket_pathname);
|
||||
int connect_ipc_sock(const char* socket_pathname);
|
||||
void send_ipc_sock(int socket_fd, char* message);
|
||||
int accept_client(int socket_fd);
|
||||
char* recv_ipc_sock(int socket_fd);
|
||||
|
||||
#endif
|
2
task.c
2
task.c
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "task.h"
|
||||
#include "common.h"
|
||||
#include "sockets.h"
|
||||
#include "io.h"
|
||||
|
||||
/* Tasks are stored in a consecutive chunk of memory, the first
|
||||
* sizeof(task_spec) bytes are arranged according to the struct
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "sockets.h"
|
||||
#include "io.h"
|
||||
|
||||
SUITE(socket_tests);
|
||||
SUITE(io_tests);
|
||||
|
||||
TEST ipc_socket_test(void) {
|
||||
const char *socket_pathname = "test-socket";
|
||||
|
@ -13,21 +14,27 @@ TEST ipc_socket_test(void) {
|
|||
ASSERT(socket_fd >= 0);
|
||||
|
||||
char *test_string = "hello world";
|
||||
char *test_bytes = "another string";
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
close(socket_fd);
|
||||
socket_fd = connect_ipc_sock(socket_pathname);
|
||||
ASSERT(socket_fd >= 0);
|
||||
send_ipc_sock(socket_fd, test_string);
|
||||
write_string(socket_fd, test_string);
|
||||
write_bytes(socket_fd, (uint8_t *) test_bytes, strlen(test_bytes));
|
||||
close(socket_fd);
|
||||
exit(0);
|
||||
} else {
|
||||
int client_fd = accept_client(socket_fd);
|
||||
ASSERT(client_fd >= 0);
|
||||
char* message = recv_ipc_sock(client_fd);
|
||||
char *message = read_string(client_fd);
|
||||
ASSERT(message != NULL);
|
||||
ASSERT_STR_EQ(test_string, message);
|
||||
free(message);
|
||||
int64_t len;
|
||||
uint8_t *bytes;
|
||||
read_bytes(client_fd, &bytes, &len);
|
||||
ASSERT(memcmp(test_bytes, bytes, len) == 0);
|
||||
close(client_fd);
|
||||
close(socket_fd);
|
||||
unlink(socket_pathname);
|
||||
|
@ -36,7 +43,7 @@ TEST ipc_socket_test(void) {
|
|||
PASS();
|
||||
}
|
||||
|
||||
SUITE(socket_tests) {
|
||||
SUITE(io_tests) {
|
||||
RUN_TEST(ipc_socket_test);
|
||||
}
|
||||
|
||||
|
@ -44,6 +51,6 @@ GREATEST_MAIN_DEFS();
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
GREATEST_MAIN_BEGIN();
|
||||
RUN_SUITE(socket_tests);
|
||||
RUN_SUITE(io_tests);
|
||||
GREATEST_MAIN_END();
|
||||
}
|
Loading…
Add table
Reference in a new issue