Commit d2848c0b14ecf965f59017e969071e908ea0d173
1 parent
0fd281dd
add info text about file handle passing and ported more stuff from my old server structure
Showing
11 changed files
with
533 additions
and
12 deletions
FD_PASSING.txt
0 → 100644
1 | +File Descriptor Passing | ||
2 | + | ||
3 | +File descriptors can be sent from one process to another by two means. One way is by inheritance, the other is by passing through a unix domain socket. There are three reasons I know of why one might do this. The first is that on platforms that don't have a credentials passing mechanism but do have a file descriptor passing mechanism, an authentication scheme based on file system privilege demonstration could be used instead. The second is if one process has file system privileges that the other does not. The third is scenarios where a server will hand a connection's file descriptor to another already started helper process of some kind. Again this area is different from OS to OS. On Linux this is done with a socket feature known as ancillary data. | ||
4 | + | ||
5 | +It works by one side sending some data to the other (at least 1 byte) with attached ancillary data. Normally this facility is used for odd features of various underlying network protocols, such as TCP/IP's out of band data. This is accomplished with the lower level socket function sendmsg() that accepts both arrays of IO vectors and control data message objects as members of its struct msghdr parameter. Ancillary, also known as control, data in sockets takes the form of a struct cmsghdr. The members of this structure can mean different things based on what type of socket it is used with. Making it even more squirrelly is that most of these structures need to be modified with macros. Here are two example functions based on the ones available in Warren Gay's book mention at the end of this article. A socket's peer that read data sent to it by send_fd() without using recv_fd() would just get a single capital F. | ||
6 | + | ||
7 | + | ||
8 | + int send_fd(int socket, int fd_to_send) | ||
9 | + { | ||
10 | + struct msghdr socket_message; | ||
11 | + struct iovec io_vector[1]; | ||
12 | + struct cmsghdr * control_message = NULL; | ||
13 | + char message_buffer[1]; | ||
14 | + | ||
15 | + /* | ||
16 | + storage space needed for an ancillary element with | ||
17 | + a paylod of length is CMSG_SPACE(sizeof(length)) | ||
18 | + */ | ||
19 | + char ancillary_element_buffer[CMSG_SPACE(sizeof(int))]; | ||
20 | + int available_ancillary_element_buffer_space; | ||
21 | + | ||
22 | + /* at least one vector of one byte must be sent */ | ||
23 | + message_buffer[0] = 'F'; | ||
24 | + io_vector[0].iov_base = message_buffer; | ||
25 | + io_vector[0].iov_len = 1; | ||
26 | + | ||
27 | + /* initialize socket message */ | ||
28 | + memset(&socket_message, 0, sizeof(struct msghdr)); | ||
29 | + socket_message.msg_iov = io_vector; | ||
30 | + socket_message.msg_iovlen = 1; | ||
31 | + | ||
32 | + /* provide space for the ancillary data */ | ||
33 | + available_ancillary_element_buffer_space = CMSG_SPACE(sizeof(int)); | ||
34 | + memset(ancillary_element_buffer, 0, available_ancillary_element_buffer_space); | ||
35 | + socket_message.msg_control = ancillary_element_buffer; | ||
36 | + socket_message.msg_controllen = available_ancillary_element_buffer_space; | ||
37 | + | ||
38 | + /* initialize a single ancillary data element for fd passing */ | ||
39 | + control_message = CMSG_FIRSTHDR(&socket_message); | ||
40 | + control_message->cmsg_level = SOL_SOCKET; | ||
41 | + control_message->cmsg_type = SCM_RIGHTS; | ||
42 | + control_message->cmsg_len = CMSG_LEN(sizeof(int)); | ||
43 | + *((int *) CMSG_DATA(control_message)) = fd_to_send; | ||
44 | + | ||
45 | + return sendmsg(socket, &socket_message, 0); | ||
46 | + } | ||
47 | + | ||
48 | + | ||
49 | + | ||
50 | + int recv_fd(int socket) | ||
51 | + { | ||
52 | + int sent_fd, available_ancillary_element_buffer_space; | ||
53 | + struct msghdr socket_message; | ||
54 | + struct iovec io_vector[1]; | ||
55 | + struct cmsghdr *control_message = NULL; | ||
56 | + char message_buffer[1]; | ||
57 | + char ancillary_element_buffer[CMSG_SPACE(sizeof(int))]; | ||
58 | + | ||
59 | + /* start clean */ | ||
60 | + memset(&socket_message, 0, sizeof(struct msghdr)); | ||
61 | + memset(ancillary_element_buffer, 0, CMSG_SPACE(sizeof(int))); | ||
62 | + | ||
63 | + /* setup a place to fill in message contents */ | ||
64 | + io_vector[0].iov_base = message_buffer; | ||
65 | + io_vector[0].iov_len = 1; | ||
66 | + socket_message.msg_iov = io_vector; | ||
67 | + socket_message.msg_iovlen = 1; | ||
68 | + | ||
69 | + /* provide space for the ancillary data */ | ||
70 | + socket_message.msg_control = ancillary_element_buffer; | ||
71 | + socket_message.msg_controllen = CMSG_SPACE(sizeof(int)); | ||
72 | + | ||
73 | + if(recvmsg(socket, &socket_message, MSG_CMSG_CLOEXEC) < 0) | ||
74 | + return -1; | ||
75 | + | ||
76 | + if(message_buffer[0] != 'F') | ||
77 | + { | ||
78 | + /* this did not originate from the above function */ | ||
79 | + return -1; | ||
80 | + } | ||
81 | + | ||
82 | + if((socket_message.msg_flags & MSG_CTRUNC) == MSG_CTRUNC) | ||
83 | + { | ||
84 | + /* we did not provide enough space for the ancillary element array */ | ||
85 | + return -1; | ||
86 | + } | ||
87 | + | ||
88 | + /* iterate ancillary elements */ | ||
89 | + for(control_message = CMSG_FIRSTHDR(&socket_message); | ||
90 | + control_message != NULL; | ||
91 | + control_message = CMSG_NXTHDR(&socket_message, control_message)) | ||
92 | + { | ||
93 | + if( (control_message->cmsg_level == SOL_SOCKET) && | ||
94 | + (control_message->cmsg_type == SCM_RIGHTS) ) | ||
95 | + { | ||
96 | + sent_fd = *((int *) CMSG_DATA(control_message)); | ||
97 | + return sent_fd; | ||
98 | + } | ||
99 | + } | ||
100 | + | ||
101 | + return -1; | ||
102 | + } | ||
103 | + |
@@ -16,15 +16,13 @@ AC_PROG_CC | @@ -16,15 +16,13 @@ AC_PROG_CC | ||
16 | AC_PROG_CC_C99 | 16 | AC_PROG_CC_C99 |
17 | AC_PROG_LIBTOOL | 17 | AC_PROG_LIBTOOL |
18 | AM_PROG_CC_C_O | 18 | AM_PROG_CC_C_O |
19 | -AC_PROG_RANLIB | ||
20 | 19 | ||
21 | # Checks for libraries. | 20 | # Checks for libraries. |
22 | AC_CHECK_LIB([json], [json_object_new_object], [], | 21 | AC_CHECK_LIB([json], [json_object_new_object], [], |
23 | [AC_MSG_ERROR([json-c library not found], [1])]) | 22 | [AC_MSG_ERROR([json-c library not found], [1])]) |
24 | 23 | ||
25 | # Checks for header files. | 24 | # Checks for header files. |
26 | -AC_CHECK_HEADERS([stdarg.h string.h stdlib.h stdio.h unistd.h syslog.h | ||
27 | - sys/types.h json/json.h]) | 25 | +AC_CHECK_HEADERS([stdarg.h string.h stdlib.h stdio.h unistd.h syslog.h sys/types.h json/json.h]) |
28 | 26 | ||
29 | # Checks for typedefs, structures, and compiler characteristics. | 27 | # Checks for typedefs, structures, and compiler characteristics. |
30 | AC_HEADER_STDBOOL | 28 | AC_HEADER_STDBOOL |
@@ -33,8 +31,8 @@ AC_TYPE_PID_T | @@ -33,8 +31,8 @@ AC_TYPE_PID_T | ||
33 | AC_TYPE_SIZE_T | 31 | AC_TYPE_SIZE_T |
34 | 32 | ||
35 | # Checks for library functions. | 33 | # Checks for library functions. |
36 | -AC_FUNC_FORK | ||
37 | -AC_FUNC_MALLOC | 34 | +#AC_FUNC_FORK |
35 | +#AC_FUNC_MALLOC | ||
38 | AC_CHECK_FUNCS([memset]) | 36 | AC_CHECK_FUNCS([memset]) |
39 | 37 | ||
40 | AC_CONFIG_FILES([Makefile tests/Makefile]) | 38 | AC_CONFIG_FILES([Makefile tests/Makefile]) |
include/server.h
0 → 100644
1 | +#ifndef __SERVER_H__ | ||
2 | +#define __SERVER_H__ | ||
3 | + | ||
4 | +#include <stdio.h> /* for printf() and fprintf() */ | ||
5 | +#include <sys/select.h> /* for select system call and related */ | ||
6 | + | ||
7 | +#include "socket.h" | ||
8 | +#include "logger.h" | ||
9 | +#include "cclass.h" | ||
10 | + | ||
11 | + | ||
12 | +CLASS(SERVER) { | ||
13 | + LOGGER logger; | ||
14 | + SOCK sock; | ||
15 | + unsigned int max_fd; | ||
16 | + fd_set fdset; | ||
17 | + | ||
18 | + struct { | ||
19 | + SOCK sock; | ||
20 | + char * wbuf; | ||
21 | + char * rbuf; | ||
22 | + unsigned int rpos; | ||
23 | + unsigned int wpos; | ||
24 | + } conns[FD_SETSIZE]; | ||
25 | +}; | ||
26 | + | ||
27 | + | ||
28 | +void server_run(SERVER this); | ||
29 | +void server_close(SERVER this); | ||
30 | +void server_shutdown(SERVER this); | ||
31 | + | ||
32 | +#endif // __SERVER_H__ | ||
33 | + | ||
34 | +// vim: set ts=4 sw=4: |
include/socket.h
0 → 100644
1 | +#ifndef __SOCKET_H__ | ||
2 | +#define __SOCKET_H__ | ||
3 | + | ||
4 | +#include <arpa/inet.h> /* for in_port_t */ | ||
5 | + | ||
6 | +#include "logger.h" | ||
7 | +#include "cclass.h" | ||
8 | + | ||
9 | + | ||
10 | +CLASS(SOCK) { | ||
11 | + LOGGER logger; | ||
12 | + in_port_t port; | ||
13 | + struct sockaddr_in addr; | ||
14 | + int handle; /* socket handle for server */ | ||
15 | +}; | ||
16 | + | ||
17 | +void sock_initServer(SOCK this, int backlog); | ||
18 | +SOCK sock_accept(SOCK this, char remoteAddr[16]); | ||
19 | + | ||
20 | +#endif /* __SOCKET_H__ */ | ||
21 | + | ||
22 | +// vim: set ts=4 sw=4: |
src/server.c
0 → 100644
1 | +#include <sys/select.h> /* for select system call and related */ | ||
2 | +#include <string.h> /* for memset and stuff */ | ||
3 | +#include <stdlib.h> /* for getopt */ | ||
4 | + | ||
5 | +#include "server.h" | ||
6 | +#include "socket.h" | ||
7 | +#include "server.h" | ||
8 | +#include "logger.h" | ||
9 | +#include "cclass.h" | ||
10 | + | ||
11 | + | ||
12 | +INIT_CLASS(SERVER); | ||
13 | + | ||
14 | +__construct(SERVER) | ||
15 | +{ | ||
16 | + in_port_t port; | ||
17 | + unsigned int backlog; | ||
18 | + | ||
19 | + this->logger = va_arg(* params, LOGGER); | ||
20 | + port = va_arg(* params, int); | ||
21 | + backlog = va_arg(* params, unsigned int); | ||
22 | + | ||
23 | + FD_ZERO(&(this->fdset)); | ||
24 | + | ||
25 | + this->sock = new(SOCK, port); | ||
26 | + sock_initServer(this->sock, backlog); | ||
27 | + | ||
28 | + this->max_fd = this->sock->handle; | ||
29 | + FD_SET(this->sock->handle, &(this->fdset)); | ||
30 | +} | ||
31 | + | ||
32 | +__destruct(SERVER) | ||
33 | +{ | ||
34 | + int i; | ||
35 | + | ||
36 | + for (i=3; i<=this->max_fd; i++) { | ||
37 | + if (FD_ISSET(i, &(this->fdset)) && i != this->sock->handle) { | ||
38 | + /* | ||
39 | + * @TODO do some finalization...buffer handling...etc. | ||
40 | + */ | ||
41 | + delete(&(this->conns[i]).sock); | ||
42 | + FD_CLR(i, &(this->fdset)); | ||
43 | + } | ||
44 | + } | ||
45 | + | ||
46 | + delete(&this->sock); | ||
47 | +} | ||
48 | + | ||
49 | +__jsonConst(SERVER) {} | ||
50 | +__toJson(SERVER) {} | ||
51 | +__clear(SERVER) {} | ||
52 | + | ||
53 | +// vim: set ts=4 sw=4: |
src/socket.c
0 → 100644
1 | +#include <stdio.h> /* for printf() and fprintf() */ | ||
2 | +#include <sys/types.h> /* SO_REUSEADDR */ | ||
3 | +#include <sys/socket.h> /* for socket(), bind(), and connect() */ | ||
4 | +#include <arpa/inet.h> /* for sockaddr_in and inet_ntoa() */ | ||
5 | +#include <stdlib.h> /* for atoi() and exit() */ | ||
6 | +#include <string.h> /* for memset() */ | ||
7 | +#include <unistd.h> /* for close() */ | ||
8 | +#include <errno.h> /* for errno */ | ||
9 | +#include <stdarg.h> | ||
10 | + | ||
11 | +#include "logger.h" | ||
12 | +#include "cclass.h" | ||
13 | +#include "socket.h" | ||
14 | + | ||
15 | + | ||
16 | +INIT_CLASS(SOCK); | ||
17 | + | ||
18 | +__construct(SOCK) | ||
19 | +{ | ||
20 | + this->logger = va_arg(* params, struct _logger *); | ||
21 | + this->port = va_arg(* params, int); | ||
22 | +} | ||
23 | + | ||
24 | +__destruct(SOCK) | ||
25 | +{ | ||
26 | + if (0 != this->handle) { | ||
27 | + shutdown(this->handle, SHUT_RDWR); | ||
28 | + close(this->handle); | ||
29 | + } | ||
30 | +} | ||
31 | + | ||
32 | +__jsonConst(SOCK) {} | ||
33 | +__toJson(SOCK) {} | ||
34 | +__clear(SOCK) {} | ||
35 | + | ||
36 | + | ||
37 | +void | ||
38 | +sock_initServer(SOCK this, int backlog) | ||
39 | +{ | ||
40 | + struct sockaddr_in addr; /* Local address */ | ||
41 | + int reUse = 1; /* TODO: make this configurable */ | ||
42 | + | ||
43 | + /* Create socket for incoming connections */ | ||
44 | + if (-1 == (this->handle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) { | ||
45 | + logger_log(this->logger, LOGGER_CRIT, | ||
46 | + "error opening socket: %s - service terminated", | ||
47 | + strerror(errno)); | ||
48 | + exit(EXIT_FAILURE); | ||
49 | + } | ||
50 | + | ||
51 | + /* Make the socket REUSE a TIME_WAT socket */ | ||
52 | + setsockopt(this->handle, SOL_SOCKET, SO_REUSEADDR, &reUse, sizeof (reUse)); | ||
53 | + | ||
54 | + /* Construct local address structure */ | ||
55 | + memset(&addr, 0, sizeof(addr)); /* Zero out structure */ | ||
56 | + | ||
57 | + addr.sin_family = AF_INET; /* Internet address family */ | ||
58 | + addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ | ||
59 | + addr.sin_port = htons(this->port); /* Local port */ | ||
60 | + | ||
61 | + /* Bind to the local address */ | ||
62 | + if (-1 == bind(this->handle, (struct sockaddr *) &addr, sizeof(addr))) { | ||
63 | + logger_log(this->logger, LOGGER_CRIT, | ||
64 | + "error binding socket: %s - service terminated", | ||
65 | + strerror(errno)); | ||
66 | + exit(EXIT_FAILURE); | ||
67 | + } | ||
68 | + | ||
69 | + /* Mark the socket so it will listen for incoming connections */ | ||
70 | + if (-1 == listen(this->handle, backlog)) { | ||
71 | + logger_log(this->logger, LOGGER_CRIT, | ||
72 | + "error binding socket: %s - service terminated", | ||
73 | + strerror(errno)); | ||
74 | + exit(EXIT_FAILURE); | ||
75 | + } | ||
76 | +} | ||
77 | + | ||
78 | +SOCK | ||
79 | +sock_accept(SOCK this, char remoteAddr[16]) | ||
80 | +{ | ||
81 | + SOCK sock; /* Socket for client */ | ||
82 | + struct sockaddr_in addr; /* Client address */ | ||
83 | + unsigned int len; /* Length of client address data structure */ | ||
84 | + | ||
85 | + /* Set the size of the in-out parameter */ | ||
86 | + len = sizeof(addr); | ||
87 | + | ||
88 | + sock = new(SOCK, this->logger, this->port); | ||
89 | + /** | ||
90 | + * @TODO: change port to remote port on success | ||
91 | + */ | ||
92 | + | ||
93 | + /* Wait for a client to connect */ | ||
94 | + if (-1 == (sock->handle = accept(this->handle, (struct sockaddr *) &addr, &len))) { | ||
95 | + logger_log(this->logger, LOGGER_WARNING, | ||
96 | + "error acception connection: %s", strerror(errno)); | ||
97 | + } else { | ||
98 | + strncpy (remoteAddr, inet_ntoa(addr.sin_addr), sizeof(remoteAddr)-1); | ||
99 | + } | ||
100 | + | ||
101 | + /* clntSock is connected to a client! */ | ||
102 | + /** | ||
103 | + * @TODO add verbosity level to logger | ||
104 | + */ | ||
105 | +// if (0 != this->logger->verbose) { | ||
106 | + logger_log(this->logger, LOGGER_INFO, | ||
107 | + "handling client %s\n", inet_ntoa(addr.sin_addr)); | ||
108 | +// } | ||
109 | + | ||
110 | + return sock; | ||
111 | +} | ||
112 | + | ||
113 | +// vim: set ts=4 sw=4: |
1 | ACLOCAL_AMFLAGS = -I m4 | 1 | ACLOCAL_AMFLAGS = -I m4 |
2 | 2 | ||
3 | TESTS_ENVIRONMENT = valgrind --error-exitcode=123 --leak-check=full --quiet | 3 | TESTS_ENVIRONMENT = valgrind --error-exitcode=123 --leak-check=full --quiet |
4 | -TESTS = cclassTest loggerTest | ||
5 | -check_PROGRAMS = cclassTest loggerTest | 4 | +TESTS = cclassTest loggerTest socketTest serverTest |
5 | +check_PROGRAMS = cclassTest loggerTest socketTest serverTest | ||
6 | 6 | ||
7 | cclassTest_SOURCES = runtest.c cclassTest.c mock/class.c ../src/cclass.c | 7 | cclassTest_SOURCES = runtest.c cclassTest.c mock/class.c ../src/cclass.c |
8 | cclassTest_LDADD = $(LIBOBJS) | 8 | cclassTest_LDADD = $(LIBOBJS) |
@@ -12,4 +12,12 @@ loggerTest_SOURCES = runtest.c loggerTest.c ../src/cclass.c ../src/logger.c | @@ -12,4 +12,12 @@ loggerTest_SOURCES = runtest.c loggerTest.c ../src/cclass.c ../src/logger.c | ||
12 | loggerTest_LDADD = $(LIBOBJS) | 12 | loggerTest_LDADD = $(LIBOBJS) |
13 | loggerTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . | 13 | loggerTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . |
14 | 14 | ||
15 | +socketTest_SOURCES = runtest.c socketTest.c ../src/cclass.c ../src/logger.c ../src/socket.c | ||
16 | +socketTest_LDADD = $(LIBOBJS) | ||
17 | +socketTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . | ||
18 | + | ||
19 | +serverTest_SOURCES = runtest.c serverTest.c ../src/cclass.c ../src/logger.c ../src/socket.c ../src/server.c | ||
20 | +serverTest_LDADD = $(LIBOBJS) | ||
21 | +serverTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . | ||
22 | + | ||
15 | EXTRA_DIST = runtest.h mock/class.h | 23 | EXTRA_DIST = runtest.h mock/class.h |
@@ -18,14 +18,15 @@ | @@ -18,14 +18,15 @@ | ||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <stdio.h> | 20 | #include <stdio.h> |
21 | +#include <stdlib.h> | ||
21 | 22 | ||
22 | #include "runtest.h" | 23 | #include "runtest.h" |
23 | #include "cclass.h" | 24 | #include "cclass.h" |
24 | #include "logger.h" | 25 | #include "logger.h" |
25 | 26 | ||
26 | 27 | ||
27 | -int level = -1; | ||
28 | -const char * msg = NULL; | 28 | +int level = -1; |
29 | +char * msg = NULL; | ||
29 | 30 | ||
30 | static void | 31 | static void |
31 | logfnct_mock(int _level, const char * _msg) | 32 | logfnct_mock(int _level, const char * _msg) |
@@ -75,7 +76,7 @@ int (* const tearDown)() = __tearDown; | @@ -75,7 +76,7 @@ int (* const tearDown)() = __tearDown; | ||
75 | 76 | ||
76 | static | 77 | static |
77 | int | 78 | int |
78 | -testDummy() | 79 | +testLogger() |
79 | { | 80 | { |
80 | logger_log(logger, LOGGER_ERR, "foo %d %s", 123, "bar"); | 81 | logger_log(logger, LOGGER_ERR, "foo %d %s", 123, "bar"); |
81 | 82 | ||
@@ -86,7 +87,7 @@ testDummy() | @@ -86,7 +87,7 @@ testDummy() | ||
86 | } | 87 | } |
87 | 88 | ||
88 | const testfunc tests[] = { | 89 | const testfunc tests[] = { |
89 | - testDummy | 90 | + testLogger |
90 | }; | 91 | }; |
91 | const size_t count = FUNCS_COUNT(tests); | 92 | const size_t count = FUNCS_COUNT(tests); |
92 | 93 |
tests/serverTest.c
0 → 100644
1 | +#include <stdio.h> | ||
2 | +#include <stdlib.h> | ||
3 | + | ||
4 | +#include "runtest.h" | ||
5 | +#include "logger.h" | ||
6 | +#include "cclass.h" | ||
7 | +#include "server.h" | ||
8 | + | ||
9 | + | ||
10 | +#define TEST_PORT 11212 | ||
11 | + | ||
12 | + | ||
13 | +int level = -1; | ||
14 | +char * msg = NULL; | ||
15 | + | ||
16 | +static void | ||
17 | +logfnct_mock(int _level, const char * _msg) | ||
18 | +{ | ||
19 | + level = _level; | ||
20 | + msg = malloc(strlen(_msg) + 1); | ||
21 | + strcpy(msg, _msg); | ||
22 | +} | ||
23 | + | ||
24 | +const char testname[] = "serverTest"; | ||
25 | +LOGGER logger = NULL; | ||
26 | +SERVER server = NULL; | ||
27 | + | ||
28 | +static | ||
29 | +int | ||
30 | +__setUp() | ||
31 | +{ | ||
32 | + logger = new(LOGGER, NULL); | ||
33 | + logger_add(logger, logfnct_mock); | ||
34 | + | ||
35 | + server = new(SERVER, logger, TEST_PORT); | ||
36 | + | ||
37 | + ASSERT_INSTANCE_OF(SERVER, server); | ||
38 | + ASSERT_INSTANCE_OF(LOGGER, server->logger); | ||
39 | + ASSERT_INSTANCE_OF(SOCK, server->sock); | ||
40 | + ASSERT_EQUAL(TEST_PORT, server->sock->port); | ||
41 | + ASSERT_EQUAL(server->max_fd, server->sock->handle); | ||
42 | + | ||
43 | + return TEST_OK; | ||
44 | +} | ||
45 | +int (* const setUp)() = __setUp; | ||
46 | + | ||
47 | +static | ||
48 | +int | ||
49 | +__tearDown() | ||
50 | +{ | ||
51 | + level = -1; | ||
52 | + | ||
53 | + if (NULL != msg) { | ||
54 | + free(msg); | ||
55 | + msg = NULL; | ||
56 | + } | ||
57 | + | ||
58 | + if (NULL != logger) { | ||
59 | + ASSERT_OBJECT(logger); | ||
60 | + delete(&logger); | ||
61 | + } | ||
62 | + | ||
63 | + if (NULL != server) { | ||
64 | + ASSERT_OBJECT(server); | ||
65 | + delete(&server); | ||
66 | + } | ||
67 | + | ||
68 | + return TEST_OK; | ||
69 | +} | ||
70 | +int (* const tearDown)() = __tearDown; | ||
71 | + | ||
72 | +static | ||
73 | +int | ||
74 | +testDummy() | ||
75 | +{ | ||
76 | + return TEST_OK; | ||
77 | +} | ||
78 | + | ||
79 | +static | ||
80 | +int | ||
81 | +testAccept() | ||
82 | +{ | ||
83 | + /* | ||
84 | + * @TODO ... | ||
85 | + */ | ||
86 | + return TEST_OK; | ||
87 | +} | ||
88 | + | ||
89 | +const testfunc tests[] = { | ||
90 | + testDummy | ||
91 | +}; | ||
92 | +const size_t count = FUNCS_COUNT(tests); | ||
93 | + | ||
94 | +// vim: set ts=4 sw=4: |
tests/socketTest.c
0 → 100644
1 | +#include <stdio.h> | ||
2 | +#include <stdlib.h> | ||
3 | + | ||
4 | +#include "runtest.h" | ||
5 | +#include "logger.h" | ||
6 | +#include "cclass.h" | ||
7 | +#include "socket.h" | ||
8 | + | ||
9 | + | ||
10 | +#define TEST_PORT 11212 | ||
11 | + | ||
12 | + | ||
13 | +int level = -1; | ||
14 | +char * msg = NULL; | ||
15 | + | ||
16 | +static void | ||
17 | +logfnct_mock(int _level, const char * _msg) | ||
18 | +{ | ||
19 | + level = _level; | ||
20 | + msg = malloc(strlen(_msg) + 1); | ||
21 | + strcpy(msg, _msg); | ||
22 | +} | ||
23 | + | ||
24 | +const char testname[] = "socketTest"; | ||
25 | +LOGGER logger = NULL; | ||
26 | +SOCK sock = NULL; | ||
27 | + | ||
28 | +static | ||
29 | +int | ||
30 | +__setUp() | ||
31 | +{ | ||
32 | + logger = new(LOGGER, NULL); | ||
33 | + logger_add(logger, logfnct_mock); | ||
34 | + | ||
35 | + sock = new(SOCK, logger, TEST_PORT); | ||
36 | + | ||
37 | + ASSERT_INSTANCE_OF(SOCK, sock); | ||
38 | + ASSERT_INSTANCE_OF(LOGGER, sock->logger); | ||
39 | + ASSERT_EQUAL(TEST_PORT, sock->port); | ||
40 | + | ||
41 | + return TEST_OK; | ||
42 | +} | ||
43 | +int (* const setUp)() = __setUp; | ||
44 | + | ||
45 | +static | ||
46 | +int | ||
47 | +__tearDown() | ||
48 | +{ | ||
49 | + level = -1; | ||
50 | + | ||
51 | + if (NULL != msg) { | ||
52 | + free(msg); | ||
53 | + msg = NULL; | ||
54 | + } | ||
55 | + | ||
56 | + if (NULL != logger) { | ||
57 | + ASSERT_OBJECT(logger); | ||
58 | + delete(&logger); | ||
59 | + } | ||
60 | + | ||
61 | + if (NULL != sock) { | ||
62 | + ASSERT_OBJECT(sock); | ||
63 | + delete(&sock); | ||
64 | + } | ||
65 | + | ||
66 | + return TEST_OK; | ||
67 | +} | ||
68 | +int (* const tearDown)() = __tearDown; | ||
69 | + | ||
70 | +static | ||
71 | +int | ||
72 | +testInitServer() | ||
73 | +{ | ||
74 | + sock_initServer(sock, 10); | ||
75 | + | ||
76 | + ASSERT_NOT_NULL(sock->handle); | ||
77 | + | ||
78 | + return TEST_OK; | ||
79 | +} | ||
80 | + | ||
81 | +static | ||
82 | +int | ||
83 | +testAccept() | ||
84 | +{ | ||
85 | + /* | ||
86 | + * @TODO ... | ||
87 | + */ | ||
88 | +} | ||
89 | + | ||
90 | +const testfunc tests[] = { | ||
91 | + testInitServer | ||
92 | +}; | ||
93 | +const size_t count = FUNCS_COUNT(tests); | ||
94 | + | ||
95 | +// vim: set ts=4 sw=4: |
Please
register
or
login
to post a comment