2016-05-26 18:27:59 +02:00
|
|
|
#include "communication.h"
|
2016-05-30 01:54:19 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <time.h>
|
2016-09-11 14:37:41 +02:00
|
|
|
#include <errno.h>
|
2016-10-27 16:25:33 +02:00
|
|
|
#include <sys/socket.h>
|
2016-10-28 13:58:04 +02:00
|
|
|
#include <sys/un.h>
|
|
|
|
|
|
|
|
#define LISTEN_BACKLOG 50
|
|
|
|
#define handle_error(msg) \
|
|
|
|
do { perror(msg); exit(EXIT_FAILURE); } while (0)
|
2016-05-26 18:27:59 +02:00
|
|
|
|
2016-12-14 23:17:35 +01:00
|
|
|
int msg_send (const int fd, const char *buf, const int msize)
|
2016-06-05 03:19:36 +02:00
|
|
|
{
|
2016-09-09 12:06:25 +02:00
|
|
|
int ret = 0;
|
2016-10-06 19:44:53 +02:00
|
|
|
//printf ("%ld bytes to write\n", msize);
|
2016-10-27 16:25:33 +02:00
|
|
|
ret = send (fd, buf, msize, 0);
|
2016-10-03 17:30:52 +02:00
|
|
|
if (ret <= 0) {
|
2016-10-27 16:25:33 +02:00
|
|
|
fprintf (stderr, "err: written %d\n", fd);
|
2016-09-11 14:37:41 +02:00
|
|
|
}
|
2016-06-05 03:19:36 +02:00
|
|
|
|
2016-09-09 12:06:25 +02:00
|
|
|
return ret;
|
2016-06-05 03:19:36 +02:00
|
|
|
}
|
|
|
|
|
2016-12-14 23:17:35 +01:00
|
|
|
int msg_recv (const int fd, char **buf)
|
2016-06-12 12:38:43 +02:00
|
|
|
{
|
2016-09-10 16:59:53 +02:00
|
|
|
int ret = 0;
|
2016-10-27 16:25:33 +02:00
|
|
|
ret = recv (fd, *buf, BUFSIZ, 0);
|
2016-09-14 00:27:50 +02:00
|
|
|
if (ret < 0) {
|
2016-10-27 16:25:33 +02:00
|
|
|
fprintf (stderr, "err: read %d\n", fd);
|
2016-09-10 16:59:53 +02:00
|
|
|
}
|
2016-06-12 12:38:43 +02:00
|
|
|
|
2016-10-27 16:25:33 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
int close_socket (int fd)
|
|
|
|
{
|
2016-10-27 16:25:33 +02:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = close (fd);
|
|
|
|
if (ret < 0) {
|
|
|
|
fprintf (stderr, "err: close [err: %d] %d\n", ret, fd);
|
2016-09-10 16:59:53 +02:00
|
|
|
perror ("closing");
|
2016-09-09 14:44:15 +02:00
|
|
|
}
|
2016-06-12 12:38:43 +02:00
|
|
|
|
2016-09-09 12:06:25 +02:00
|
|
|
return ret;
|
2016-06-12 12:38:43 +02:00
|
|
|
}
|
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
// SERVICE
|
|
|
|
|
|
|
|
// init unix socket + srv->spath filled
|
|
|
|
int srv_init (int argc, char **argv, char **env, struct service *srv, const char *sname)
|
2016-05-26 18:27:59 +02:00
|
|
|
{
|
2016-06-05 20:48:13 +02:00
|
|
|
if (srv == NULL)
|
2016-06-13 09:47:19 +02:00
|
|
|
return ER_PARAMS;
|
2016-05-26 18:27:59 +02:00
|
|
|
|
2016-06-12 14:41:25 +02:00
|
|
|
// TODO
|
|
|
|
// use the argc, argv and env parameters
|
|
|
|
// it will be useful to change some parameters transparently
|
|
|
|
// ex: to get resources from other machines, choosing the
|
|
|
|
// remote with environment variables
|
|
|
|
|
|
|
|
argc = argc;
|
|
|
|
argv = argv;
|
|
|
|
env = env;
|
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
// srv->version => already set
|
|
|
|
// srv->index => already set
|
|
|
|
|
|
|
|
// gets the service path, such as /tmp/ipc/<service>
|
2016-06-10 20:02:58 +02:00
|
|
|
memset (srv->spath, 0, PATH_MAX);
|
2016-12-15 00:28:42 +01:00
|
|
|
snprintf (srv->spath, PATH_MAX, "%s/%s-%d-%d"
|
|
|
|
, TMPDIR, sname, srv->index, srv->version);
|
2016-05-26 18:27:59 +02:00
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
// TODO TEST create a unix socket
|
|
|
|
int sfd;
|
|
|
|
struct sockaddr_un my_addr;
|
2016-06-13 09:47:19 +02:00
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
|
|
if (sfd == -1)
|
|
|
|
return -1;
|
2016-06-13 09:47:19 +02:00
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
// clear structure
|
|
|
|
memset(&my_addr, 0, sizeof(struct sockaddr_un));
|
2016-05-26 18:27:59 +02:00
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
my_addr.sun_family = AF_UNIX;
|
|
|
|
strncpy(my_addr.sun_path, srv->spath, strlen (srv->spath)); // TODO check size
|
2016-06-05 20:48:13 +02:00
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
// delete the unix socket if already created
|
|
|
|
// TODO FIXME
|
|
|
|
unlink(my_addr.sun_path);
|
|
|
|
if (bind(sfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_un)) == -1)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (listen(sfd, LISTEN_BACKLOG) == -1)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
srv->service_fd = sfd;
|
2016-05-26 18:27:59 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-06-05 20:48:13 +02:00
|
|
|
int srv_close (struct service *srv)
|
2016-05-26 18:27:59 +02:00
|
|
|
{
|
2016-12-15 00:28:42 +01:00
|
|
|
close_socket (srv->service_fd);
|
|
|
|
|
|
|
|
// TODO FIXME is unlink really necessary
|
2016-06-05 20:48:13 +02:00
|
|
|
if (unlink (srv->spath)) {
|
2016-05-26 18:27:59 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-10-28 13:58:04 +02:00
|
|
|
int srv_read (const struct service *srv, char ** buf)
|
2016-05-30 01:54:19 +02:00
|
|
|
{
|
2016-10-28 14:24:15 +02:00
|
|
|
//printf("---%s\n", srv->spath);
|
2016-12-14 23:17:35 +01:00
|
|
|
return msg_recv (srv->service_fd, buf);
|
2016-05-26 21:56:43 +02:00
|
|
|
}
|
|
|
|
|
2016-10-28 13:58:04 +02:00
|
|
|
int srv_write (const struct service *srv, const char * buf, size_t msize)
|
2016-05-26 21:56:43 +02:00
|
|
|
{
|
2016-10-28 14:24:15 +02:00
|
|
|
//printf("---%s\n", srv->spath);
|
2016-12-14 23:17:35 +01:00
|
|
|
return msg_send (srv->service_fd, buf, msize);
|
2016-05-26 18:27:59 +02:00
|
|
|
}
|
|
|
|
|
2016-06-05 03:19:36 +02:00
|
|
|
// APPLICATION
|
2016-05-26 18:27:59 +02:00
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
// Initialize connection with unix socket
|
2016-06-10 01:21:04 +02:00
|
|
|
// send the connection string to $TMP/<service>
|
2016-12-15 00:28:42 +01:00
|
|
|
|
|
|
|
// fill srv->spath && srv->service_fd
|
|
|
|
int app_connection (struct service *srv, const char *sname
|
|
|
|
, const char *connectionstr, size_t msize)
|
2016-06-10 01:21:04 +02:00
|
|
|
{
|
|
|
|
if (srv == NULL) {
|
2016-09-09 12:06:25 +02:00
|
|
|
return -1;
|
2016-06-12 12:38:43 +02:00
|
|
|
}
|
2016-10-28 13:58:04 +02:00
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
// srv->version => already set
|
|
|
|
// srv->index => already set
|
2016-11-03 22:44:35 +01:00
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
// gets the service path, such as /tmp/ipc/<service>
|
|
|
|
memset (srv->spath, 0, PATH_MAX);
|
|
|
|
snprintf (srv->spath, PATH_MAX, "%s/%s-%d-%d"
|
|
|
|
, TMPDIR, sname, srv->index, srv->version);
|
2016-10-28 13:58:04 +02:00
|
|
|
|
|
|
|
int sfd;
|
|
|
|
struct sockaddr_un my_addr;
|
|
|
|
socklen_t peer_addr_size;
|
|
|
|
|
|
|
|
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
|
|
if (sfd == -1)
|
|
|
|
return -1;
|
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
// clear structure
|
2016-10-28 13:58:04 +02:00
|
|
|
memset(&my_addr, 0, sizeof(struct sockaddr_un));
|
2016-12-15 00:28:42 +01:00
|
|
|
|
2016-10-28 13:58:04 +02:00
|
|
|
my_addr.sun_family = AF_UNIX;
|
2016-12-15 00:28:42 +01:00
|
|
|
strncpy(my_addr.sun_path, srv->spath, strlen (srv->spath)); // TODO check size
|
2016-10-28 13:58:04 +02:00
|
|
|
|
|
|
|
peer_addr_size = sizeof(struct sockaddr_un);
|
2016-12-15 00:28:42 +01:00
|
|
|
if(connect(sfd, (struct sockaddr *) &my_addr, peer_addr_size) == -1)
|
2016-10-28 13:58:04 +02:00
|
|
|
{
|
|
|
|
perror("connect()");
|
|
|
|
exit(errno);
|
|
|
|
}
|
2016-12-15 00:28:42 +01:00
|
|
|
srv->service_fd = sfd;
|
|
|
|
|
|
|
|
// TODO FIXME
|
|
|
|
// send connection string and receive acknowledgement
|
|
|
|
srv_write(srv, connectionstr, msize);
|
2016-10-28 13:58:04 +02:00
|
|
|
|
|
|
|
return 0;
|
2016-06-10 01:21:04 +02:00
|
|
|
}
|
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
int app_close (struct service *srv)
|
2016-05-26 18:27:59 +02:00
|
|
|
{
|
2016-12-15 00:28:42 +01:00
|
|
|
return close_socket (srv->service_fd);
|
2016-05-26 18:27:59 +02:00
|
|
|
}
|
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
int app_read (struct service *srv, char ** buf)
|
2016-10-28 14:24:15 +02:00
|
|
|
{
|
2016-12-15 00:28:42 +01:00
|
|
|
return msg_recv (srv->service_fd, buf);
|
2016-05-26 18:27:59 +02:00
|
|
|
}
|
|
|
|
|
2016-12-15 00:28:42 +01:00
|
|
|
int app_write (struct service *srv, char * buf, size_t msize)
|
2016-05-26 18:27:59 +02:00
|
|
|
{
|
2016-12-15 00:28:42 +01:00
|
|
|
return msg_send (srv->service_fd, buf, msize);
|
2016-10-28 13:58:04 +02:00
|
|
|
}
|