Obsolete
/
libipc-old
Archived
3
0
Fork 0
This repository has been archived on 2024-06-18. You can view files and clone it, but cannot push or open issues/pull-requests.
libipc-old/lib/communication.c

428 lines
11 KiB
C
Raw Normal View History

2016-05-26 18:27:59 +02:00
#include "communication.h"
#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-10-27 16:25:33 +02:00
int file_write (const int fd, const char *buf, const int msize)
2016-06-05 03:19:36 +02:00
{
2016-10-27 16:25:33 +02:00
// if (buf == NULL) {
// fprintf (stderr, "file_write: buf == NULL\n");
// return -1;
// }
2016-09-11 14:37:41 +02:00
// TODO debug
// printf("file_write: path to open %s\n", path);
2016-10-27 16:25:33 +02:00
// int fd = open (path, O_WRONLY);
// if (fd <= 0) {
// printf("file_write: fd < 0\n");
// perror ("file_write");
// return ER_FILE_OPEN;
// }
2016-10-03 17:30:52 +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-10-27 16:25:33 +02:00
int file_read (const int fd, char **buf)
2016-06-12 12:38:43 +02:00
{
2016-10-27 16:25:33 +02:00
// if (buf == NULL) {
// fprintf (stderr, "file_read: buf == NULL\n");
// return -1;
// }
// int fd = open (path, O_RDONLY);
// if (fd <= 0) {
// return ER_FILE_OPEN;
// }
// TODO debug
// printf("file_read: opened file %s\n", path);
2016-06-12 12:38:43 +02:00
2016-10-27 16:25:33 +02:00
// if (*buf == NULL) {
// fprintf(stderr, "file_read : *buf == NULL\n", );
// }
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-06-12 12:38:43 +02:00
2016-10-27 16:25:33 +02:00
return ret;
}
int close_socket(int fd) {
int ret;
ret = close (fd);
if (ret < 0) {
fprintf (stderr, "err: close [err: %d] %d\n", ret, fd);
perror ("closing");
}
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-06-13 09:47:19 +02:00
int srv_init (int argc, char **argv, char **env, struct service *srv, const char *sname, int (*cb)(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-06-05 20:48:13 +02:00
// gets the service path, such as /tmp/<service>
memset (srv->spath, 0, PATH_MAX);
2016-06-12 12:38:43 +02:00
strncat (srv->spath, TMPDIR, PATH_MAX -1);
strncat (srv->spath, sname, PATH_MAX -1);
2016-05-26 18:27:59 +02:00
2016-06-05 20:48:13 +02:00
srv->version = COMMUNICATION_VERSION;
srv->index = 0; // TODO
2016-06-13 09:47:19 +02:00
if (cb != NULL) {
int ret = (*cb) (argc, argv, env, srv, sname);
if (ret != 0)
return ret;
}
return 0;
2016-05-26 18:27:59 +02:00
}
2016-06-05 20:48:13 +02:00
// SERVICE
int srv_create (struct service *srv)
2016-05-26 18:27:59 +02:00
{
int ret;
2016-06-05 20:48:13 +02:00
if ((ret = mkfifo (srv->spath, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
switch (errno) {
case EACCES :
2016-06-05 20:48:13 +02:00
printf ("file %s : EACCES\n", srv->spath);
return 1;
case EEXIST :
2016-06-05 20:48:13 +02:00
printf ("file %s : EEXIST\n", srv->spath);
break;
case ENAMETOOLONG :
2016-06-05 20:48:13 +02:00
printf ("file %s : ENAMETOOLONG\n", srv->spath);
return 2;
case ENOENT :
2016-06-05 20:48:13 +02:00
printf ("file %s : ENOENT\n", srv->spath);
return 3;
case ENOSPC :
2016-06-05 20:48:13 +02:00
printf ("file %s : ENOSPC\n", srv->spath);
return 4;
case ENOTDIR :
2016-06-05 20:48:13 +02:00
printf ("file %s : ENOTDIR\n", srv->spath);
return 5;
case EROFS :
2016-06-05 20:48:13 +02:00
printf ("file %s : EROFS\n", srv->spath);
return 6;
default :
2016-06-05 20:48:13 +02:00
printf ("err file %s unknown\n", srv->spath);
return 7;
}
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-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_get_new_process (char *buf, struct process *p)
2016-05-26 18:27:59 +02:00
{
2016-10-27 16:25:33 +02:00
/*char *buf = malloc(BUFSIZ);
memset(buf, 0, BUFSIZ);
2016-10-14 17:47:08 +02:00
int ret = 0;
2016-10-27 16:25:33 +02:00
ret = file_read (fd, &buf);
2016-10-14 17:47:08 +02:00
2016-10-27 16:25:33 +02:00
if (ret < 0) {
fprintf (stderr, "err: listening on %d\n", fd);
exit (1);
} else if (ret == 0) {
perror("get new process");
}*/
2016-06-12 12:38:43 +02:00
char *token = NULL, *saveptr = NULL;
char *str = NULL;
int i = 0;
2016-05-26 18:27:59 +02:00
pid_t pid = 0;
int index = 0;
int version = 0;
2016-06-05 03:19:36 +02:00
2016-05-26 21:56:43 +02:00
for (str = buf, i = 1; ; str = NULL, i++) {
token = strtok_r(str, " ", &saveptr);
2016-05-26 18:27:59 +02:00
if (token == NULL)
break;
2016-05-26 21:56:43 +02:00
if (i == 1) {
2016-06-05 03:19:36 +02:00
pid = strtoul(token, NULL, 10);
2016-05-26 18:27:59 +02:00
}
2016-05-26 21:56:43 +02:00
else if (i == 2) {
2016-06-05 03:19:36 +02:00
index = strtoul(token, NULL, 10);
}
else if (i == 3) {
2016-06-05 03:19:36 +02:00
version = strtoul(token, NULL, 10);
2016-05-26 18:27:59 +02:00
}
}
2016-10-27 16:25:33 +02:00
//if (buf != NULL)
// free (buf);
2016-06-05 03:19:36 +02:00
srv_process_gen (p, pid, index, version);
2016-10-14 17:47:08 +02:00
return 0;
2016-06-07 11:45:21 +02:00
}
2016-10-28 13:58:04 +02:00
int srv_read (const struct service *srv, char ** buf)
{
2016-10-28 14:24:15 +02:00
//printf("---%s\n", srv->spath);
2016-10-28 13:58:04 +02:00
return file_read (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-10-28 13:58:04 +02:00
return file_write (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-10-28 13:58:04 +02:00
//Init connection with unix socket
// send the connection string to $TMP/<service>
int app_srv_connection (struct service *srv, const char *connectionstr, size_t msize)
{
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
int sfd;
struct sockaddr_un my_addr;
socklen_t peer_addr_size;
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == -1)
return -1;
memset(&my_addr, 0, sizeof(struct sockaddr_un));
// Clear structure
my_addr.sun_family = AF_UNIX;
strncpy(my_addr.sun_path, srv->spath, sizeof(my_addr.sun_path) - 1);
peer_addr_size = sizeof(struct sockaddr_un);
if(connect(sfd,(struct sockaddr *) &my_addr, peer_addr_size) == -1)
{
perror("connect()");
exit(errno);
}
srv->service_fd = sfd;
return srv_write(srv, connectionstr, msize);
2016-11-03 22:44:35 +01:00
2016-10-28 13:58:04 +02:00
}
int proc_connection(struct process *p) {
int sfd;
struct sockaddr_un my_addr;
socklen_t peer_addr_size;
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == -1)
return -1;
memset(&my_addr, 0, sizeof(struct sockaddr_un));
// Clear structure
my_addr.sun_family = AF_UNIX;
strncpy(my_addr.sun_path, p->path_proc, sizeof(my_addr.sun_path) - 1);
peer_addr_size = sizeof(struct sockaddr_un);
if(connect(sfd,(struct sockaddr *) &my_addr, peer_addr_size) == -1)
{
perror("connect()");
exit(errno);
}
p->proc_fd = sfd;
return 0;
}
2016-06-13 09:47:19 +02:00
int app_create (struct process *p, pid_t pid, int index, int version)
2016-05-26 18:27:59 +02:00
{
2016-06-13 09:47:19 +02:00
if (version == 0) {
version = COMMUNICATION_VERSION;
}
2016-06-05 03:19:36 +02:00
// then creates the structure
2016-06-13 09:47:19 +02:00
srv_process_gen (p, pid, index, version);
2016-05-26 18:27:59 +02:00
// creates the pipes
int ret;
2016-10-27 16:25:33 +02:00
// if ((ret = mkfifo (p->path_in, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))
// {
// switch (errno) {
// case EACCES :
// printf ("file %s : EACCES\n", p->path_in);
// return 1;
// case EEXIST :
// printf ("file %s : EEXIST\n", p->path_in);
// break;
// case ENAMETOOLONG :
// printf ("file %s : ENAMETOOLONG\n", p->path_in);
// return 2;
// case ENOENT :
// printf ("file %s : ENOENT\n", p->path_in);
// return 3;
// case ENOSPC :
// printf ("file %s : ENOSPC\n", p->path_in);
// return 4;
// case ENOTDIR :
// printf ("file %s : ENOTDIR\n", p->path_in);
// return 5;
// case EROFS :
// printf ("file %s : EROFS\n", p->path_in);
// return 6;
// default :
// printf ("err file %s unknown\n", p->path_in);
// return 7;
// }
// }
// if ((ret = mkfifo (p->path_out, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
// switch (errno) {
// case EACCES :
// printf ("file %s : EACCES\n", p->path_out);
// return 1;
// case EEXIST :
// printf ("file %s : EEXIST\n", p->path_out);
// break;
// case ENAMETOOLONG :
// printf ("file %s : ENAMETOOLONG\n", p->path_out);
// return 2;
// case ENOENT :
// printf ("file %s : ENOENT\n", p->path_out);
// return 3;
// case ENOSPC :
// printf ("file %s : ENOSPC\n", p->path_out);
// return 4;
// case ENOTDIR :
// printf ("file %s : ENOTDIR\n", p->path_out);
// return 5;
// case EROFS :
// printf ("file %s : EROFS\n", p->path_out);
// return 6;
// default :
// printf ("err file %s unknown\n", p->path_out);
// return 7;
// }
// }
if ((ret = mkfifo (p->path_proc, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
switch (errno) {
case EACCES :
2016-06-05 03:19:36 +02:00
printf ("file %s : EACCES\n", p->path_out);
return 1;
case EEXIST :
2016-06-05 03:19:36 +02:00
printf ("file %s : EEXIST\n", p->path_out);
break;
case ENAMETOOLONG :
2016-06-05 03:19:36 +02:00
printf ("file %s : ENAMETOOLONG\n", p->path_out);
return 2;
case ENOENT :
2016-06-05 03:19:36 +02:00
printf ("file %s : ENOENT\n", p->path_out);
return 3;
case ENOSPC :
2016-06-05 03:19:36 +02:00
printf ("file %s : ENOSPC\n", p->path_out);
return 4;
case ENOTDIR :
2016-06-05 03:19:36 +02:00
printf ("file %s : ENOTDIR\n", p->path_out);
return 5;
case EROFS :
2016-06-05 03:19:36 +02:00
printf ("file %s : EROFS\n", p->path_out);
return 6;
default :
2016-06-05 03:19:36 +02:00
printf ("err file %s unknown\n", p->path_out);
return 7;
}
2016-05-26 18:27:59 +02:00
}
return 0;
}
2016-06-05 03:19:36 +02:00
int app_destroy (struct process *p)
2016-05-26 18:27:59 +02:00
{
2016-10-27 16:25:33 +02:00
// if (unlink (p->path_in)) {
// return 1;
// }
// if (unlink (p->path_out)) {
// return 1;
// }
2016-05-26 18:27:59 +02:00
2016-10-27 16:25:33 +02:00
if (unlink (p->path_proc)) {
2016-05-26 18:27:59 +02:00
return 1;
}
return 0;
}
2016-10-27 16:25:33 +02:00
int app_read (struct process *p, char ** buf)
2016-10-28 14:24:15 +02:00
{
//printf("---%s\n", p->path_proc);
2016-10-27 16:25:33 +02:00
return file_read (p->proc_fd, buf);
2016-05-26 18:27:59 +02:00
}
2016-06-12 12:38:43 +02:00
int app_write (struct process *p, char * buf, size_t msize)
2016-05-26 18:27:59 +02:00
{
2016-10-28 14:24:15 +02:00
//printf("---%s\n", p->path_proc);
2016-10-27 16:25:33 +02:00
return file_write (p->proc_fd, buf, msize);
2016-05-26 18:27:59 +02:00
}
2016-10-28 13:58:04 +02:00
/*init a unix socket : bind, listen
*and return a socket
*/
int set_listen_socket(const char *path) {
int sfd;
struct sockaddr_un my_addr;
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == -1)
return -1;
memset(&my_addr, 0, sizeof(struct sockaddr_un));
/* Clear structure */
my_addr.sun_family = AF_UNIX;
strncpy(my_addr.sun_path, path, sizeof(my_addr.sun_path) - 1);
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;
return sfd;
}