-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Socket methods to be used by an event loop * Git ignore build files * File renames * Some fixes * Fixes * Fixes * Memory leakage fix
- Loading branch information
Showing
6 changed files
with
175 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,3 +33,6 @@ | |
# Debug files | ||
*.dSYM/ | ||
*.su | ||
|
||
# Build files | ||
build/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
#include "sockets.h" | ||
|
||
#include <stdlib.h> | ||
#include <unistd.h> | ||
#include <sys/socket.h> | ||
#include <sys/un.h> | ||
#include <string.h> | ||
#include <stdio.h> | ||
|
||
#include "common.h" | ||
|
||
/* Binds to a Unix domain datagram socket at the given | ||
* pathname. Removes any existing file at the pathname. Returns | ||
* a file descriptor for the socket, or -1 if an error | ||
* occurred. */ | ||
int bind_ipc_sock(const char *socket_pathname) { | ||
struct sockaddr_un socket_address; | ||
int socket_fd; | ||
|
||
socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0); | ||
if (socket_fd < 0) { | ||
LOG_ERR("socket() failed for pathname %s.", socket_pathname); | ||
return -1; | ||
} | ||
|
||
unlink(socket_pathname); | ||
memset(&socket_address, 0, sizeof(struct sockaddr_un)); | ||
socket_address.sun_family = AF_UNIX; | ||
if (strlen(socket_pathname) + 1 > sizeof(socket_address.sun_path)) { | ||
LOG_ERR("Socket pathname is too long."); | ||
return -1; | ||
} | ||
strncpy(socket_address.sun_path, socket_pathname, | ||
strlen(socket_pathname) + 1); | ||
|
||
if (bind(socket_fd, (struct sockaddr *) &socket_address, | ||
sizeof(struct sockaddr_un)) != 0) { | ||
LOG_ERR("Bind failed for pathname %s.", socket_pathname); | ||
return -1; | ||
} | ||
|
||
return socket_fd; | ||
} | ||
|
||
/* Connects to a Unix domain datagram socket at the given | ||
* pathname. Returns a file descriptor for the socket, or -1 if | ||
* an error occurred. */ | ||
int connect_ipc_sock(const char *socket_pathname) { | ||
struct sockaddr_un socket_address; | ||
int socket_fd; | ||
|
||
socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0); | ||
if (socket_fd < 0) { | ||
LOG_ERR("socket() failed for pathname %s.", socket_pathname); | ||
return -1; | ||
} | ||
|
||
memset(&socket_address, 0, sizeof(struct sockaddr_un)); | ||
socket_address.sun_family = AF_UNIX; | ||
if (strlen(socket_pathname) + 1 > sizeof(socket_address.sun_path)) { | ||
LOG_ERR("Socket pathname is too long."); | ||
return -1; | ||
} | ||
strncpy(socket_address.sun_path, socket_pathname, | ||
strlen(socket_pathname) + 1); | ||
|
||
if (connect(socket_fd, (struct sockaddr *) &socket_address, | ||
sizeof(struct sockaddr_un)) != 0) { | ||
LOG_ERR("Connection to socket failed for pathname %s.", socket_pathname); | ||
return -1; | ||
} | ||
|
||
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 = send(socket_fd, (char *) &length, sizeof(length), 0); | ||
if (nbytes == -1) { | ||
fprintf(stderr, "Error sending to socket.\n"); | ||
return; | ||
} | ||
nbytes = send(socket_fd, (char *) message, length * sizeof(char), 0); | ||
if (nbytes == -1) { | ||
fprintf(stderr, "Error sending to socket.\n"); | ||
return; | ||
} | ||
} | ||
|
||
/* 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 = recv(socket_fd, &length, sizeof(length), 0); | ||
if (nbytes == -1) { | ||
fprintf(stderr, "Error receiving from socket.\n"); | ||
return NULL; | ||
} | ||
char *message = malloc((length + 1) * sizeof(char)); | ||
nbytes = recv(socket_fd, message, length * sizeof(char), 0); | ||
if (nbytes == -1) { | ||
fprintf(stderr, "Error receiving from socket.\n"); | ||
return NULL; | ||
} | ||
message[length] = '\0'; | ||
return message; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#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); | ||
char* recv_ipc_sock(int socket_fd); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#include "greatest.h" | ||
|
||
#include <assert.h> | ||
#include <unistd.h> | ||
|
||
#include "sockets.h" | ||
|
||
SUITE(event_loop_tests); | ||
|
||
TEST ipc_socket_test(void) { | ||
const char* socket_pathname = "test-socket"; | ||
int socket_fd = bind_ipc_sock(socket_pathname); | ||
ASSERT(socket_fd >= 0); | ||
|
||
char* test_string = "hello world"; | ||
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); | ||
close(socket_fd); | ||
} else { | ||
char* message = recv_ipc_sock(socket_fd); | ||
ASSERT(message != NULL); | ||
ASSERT_STR_EQ(test_string, message); | ||
free(message); | ||
close(socket_fd); | ||
unlink(socket_pathname); | ||
} | ||
|
||
PASS(); | ||
} | ||
|
||
SUITE(event_loop_tests) { | ||
RUN_TEST(ipc_socket_test); | ||
} | ||
|
||
GREATEST_MAIN_DEFS(); | ||
|
||
int main(int argc, char** argv) { | ||
GREATEST_MAIN_BEGIN(); | ||
RUN_SUITE(event_loop_tests); | ||
GREATEST_MAIN_END(); | ||
} |