commit da51d3ef3df48260243428732fac196dcfc7c755 Author: Philippe PITTOLI Date: Thu May 26 18:27:59 2016 +0200 core : lib com ++ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5311fd5 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +CC=gcc +CFLAGS=-Wall -g +LDFLAGS= +CFILES=$(wildcard *.c) # CFILES => recompiles everything on a C file change +EXEC=$(basename $(wildcard *.c)) +SOURCES=$(wildcard lib/*.c) +OBJECTS=$(SOURCES:.c=.o) +TESTS=$(addsuffix .test, $(EXEC)) + +all: $(SOURCES) $(EXEC) + +$(EXEC): $(OBJECTS) $(CFILES) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $@.c -o $@ + +.c.o: + $(CC) -c $(CFLAGS) $< -o $@ + +clean: + -rm $(OBJECTS) + +mrproper: clean + rm $(EXEC) + +# to test a binary "prog" : make prog.test + +$(TESTS): + valgrind --leak-check=full -v --track-origins=yes ./$(basename $@) + +test: all $(TESTS) diff --git a/README.markdown b/README.markdown new file mode 100644 index 0000000..3b671af --- /dev/null +++ b/README.markdown @@ -0,0 +1,41 @@ +# connection init (draft) + +## what the programs should do and how they interact + + * service : application providing a feature to others (windows, audio, …) + * program : specific application (browser, instant messaging, …) + + * : service name + * : process index in the program point of view + * : process index in the service point of view + + 1. the service creates a pipe, named /tmp/ + 2. the program creates pipes named /tmp/$pid--{in,out} + 3. the program prints in the pipe /tmp/ : $pid- version + 4. depending on the configuration and service type, the service will + * thread, to spare resources + * fork, not to compromise the security + 5. the service prints in /tmp/$pid--in + +## pure "networking" view (what should go in the pipes) + + 1. the program prints in the pipe /tmp/ : $pid- version + 2. the service prints in /tmp/$pid--in + +# messages format + +QUESTION : no CBOR for 1 & 2, or CBOR everywhere ? + +## overview + + : value + + will be a simple byte : + + * <0 - 15> : control, meta data + * <16 - 127> : later use + * <128 - 255> : application specific (windowing system, audio system, …) + +## CBOR table (draft) + +index | semantic diff --git a/init-connection.c b/init-connection.c new file mode 100644 index 0000000..bb1868d --- /dev/null +++ b/init-connection.c @@ -0,0 +1,43 @@ +#include "lib/communication.h" + +/* + * pipes creation and removal test program + * + * 1. to create the named pipe /tmp/ + * 2. to create the named pipes in & out + * 3. to remove the named pipes in & out + * 4. to remove the named pipe /tmp/ + */ + +int main(int argc, char * argv[]) +{ + // service path (/tmp/) + char spath[PATH_MAX]; + service_path (spath, "windows"); + + int ret; + if ((ret = service_create (spath))) { + fprintf(stdout, "error service_create %d\n", ret); + exit (1); + } + + struct process proc; + if ((ret = process_create (&proc, 0))) { + fprintf(stdout, "error process_create %d\n", ret); + exit (1); + } + + /* specific code, talks between applications */ + + if ((ret = process_destroy (&proc))) { + fprintf(stdout, "error process_destroy %d\n", ret); + exit (1); + } + + if ((ret = service_close (spath))) { + fprintf(stdout, "error service_close %d\n", ret); + exit (1); + } + + return EXIT_SUCCESS; +} diff --git a/lib/communication.c b/lib/communication.c new file mode 100644 index 0000000..87cf5a3 --- /dev/null +++ b/lib/communication.c @@ -0,0 +1,177 @@ +#include "communication.h" + +int service_path (char *buf, const char *sname) +{ + if (buf == NULL) { + return 1; + } + + // already done in mkfifo + if (strlen(TMPDIR) + strlen(sname) > PATH_MAX) { + return 2; + } + + bzero (buf, PATH_MAX); + strncat (buf, TMPDIR, PATH_MAX); + strncat (buf, sname, PATH_MAX); + + return 0; +} + +void process_paths (char *in, char *out, pid_t pid, int index) +{ + bzero (in, PATH_MAX); + bzero (out, PATH_MAX); + snprintf(in , PATH_MAX, "%s/%d-%d-in" , TMPDIR, pid, index); + snprintf(out, PATH_MAX, "%s/%d-%d-out", TMPDIR, pid, index); +} + +int service_create (const char *fifopath) +{ + int ret; + if ((ret = mkfifo (fifopath, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) { + return 1; + } + + return 0; +} + +int service_close (const char *fifopath) +{ + if (unlink (fifopath)) { + return 1; + } + + return 0; +} + +void service_get_new_processes (struct process **proc, int *nproc, int sfifo) +{ + char buf[BUFSIZ]; + bzero (buf, BUFSIZ); + read (sfifo, buf, BUFSIZ); + + // TODO +#if 0 + unsigned long long int val = strtoull(s, NULL, 10); + + char *token, *saveptr; + char *str; + int i, j; + + // printf("%d fields :: ", f->nbfields); + // for( i = 0 ; i < f->nbfields ; i++) { + // printf("%u, ", f->fields[i]); + // } + // printf("\n"); + + for (str = s, i = 1; ; str = NULL, i++) { + token = strtok_r(str, delim, &saveptr); + if (token == NULL) + break; + + // check if we need to print the current token humanized + int found = 0; + + for (j = 0 ; j < f->nbfields && found == 0; j++ ) { + if( i == f->fields[j] ) { + print_token_to_human(token); + found = 1; + } + } + + // print the current token not humanized + if (found == 0) { + printf("%s ", token); + } + } +#endif +} + +void gen_process_structure (struct process *p + , pid_t pid, unsigned int index, unsigned int version) +{ + p->pid = pid; + p->version = version; + p->index = index; +} + + +int process_create (struct process *p, int index) +{ + pid_t pid = getpid(); + char fifopathin[PATH_MAX]; + char fifopathout[PATH_MAX]; + process_paths (fifopathin, fifopathout, pid, index); + + // creates the pipes + int ret; + if ((ret = mkfifo (fifopathin, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) { + return 1; + } + + if ((ret = mkfifo (fifopathout, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) { + return 1; + } + + // then creates the structure + gen_process_structure (p, pid, index, COMMUNICATION_VERSION); + + return 0; +} + +int process_destroy (struct process *p) +{ + char fifopathin[PATH_MAX]; + char fifopathout[PATH_MAX]; + process_paths (fifopathin, fifopathout, p->pid, p->index); + + if (unlink (fifopathin)) { + return 1; + } + + if (unlink (fifopathout)) { + return 1; + } + + return 0; +} + + +int process_open (struct process *proc) +{ + char fifopathin[PATH_MAX]; + char fifopathout[PATH_MAX]; + process_paths (fifopathin, fifopathout, proc->pid, proc->index); + + proc->in = open (fifopathin, S_IRUSR); + proc->out = open (fifopathout, S_IRUSR); + + return 0; +} + +int process_close (struct process *proc) +{ + if (proc->in != 0) { + close (proc->in); + proc->in = 0; + } + + if (proc->out != 0) { + close (proc->out); + proc->out = 0; + } + + return 0; +} + + +int process_read (struct process *proc, void * buf, size_t * msize) +{ + return 0; +} + +int process_write (struct process *proc, void * buf, size_t msize) +{ + return 0; +} diff --git a/lib/communication.h b/lib/communication.h new file mode 100644 index 0000000..aec6da6 --- /dev/null +++ b/lib/communication.h @@ -0,0 +1,56 @@ +#ifndef __COMMUNICATION_H__ +#define __COMMUNICATION_H__ + +#include +#include +#include + +#include // unlink + +#include // mkfifo +#include // mkfifo +#include // open + +#define TMPDIR "/tmp/" + +#define COMMUNICATION_VERSION 1 + +// TODO to check the right length for a path +#define PATH_MAX BUFSIZ + +struct process { + pid_t pid; + unsigned int version; + unsigned int index; + int in, out; +}; + +// TODO create the service process structure + +int service_path (char *buf, const char *sname); + +void gen_process_structure (struct process *p + , pid_t pid, unsigned int index, unsigned int version); + +/* + * returns + * 0 : ok + * 1 : no service name + * 2 : service name too long + * 3 : unable to create fifo + */ +int service_create (const char *sname); +int service_close (const char *sname); + +void service_get_new_processes (struct process **, int *nproc, int sfifo); + +int process_create (struct process *, int index); // called by the application +int process_destroy (struct process *); // called by the application + +int process_open (struct process *); // called by the service & application +int process_close (struct process *); // called by the service & application + +int process_read (struct process *, void * buf, size_t *); +int process_write (struct process *, void * buf, size_t); + +#endif diff --git a/service-test.c b/service-test.c new file mode 100644 index 0000000..dca4865 --- /dev/null +++ b/service-test.c @@ -0,0 +1,89 @@ +#include "lib/communication.h" + +/* + * main loop + * + * opens the application pipes, + * reads then writes the same message, + * then closes the pipes + */ + +void main_loop (const char *spath) +{ + int ret; + int sfifo = open (spath, S_IRUSR); // opens the service named pipe + + struct process *proc; + int nproc = 0; + + do { + service_get_new_processes (&proc, &nproc, sfifo); + + // for each process : open, read, write, close + for (int i = 0 ; i < nproc ; i++) { + printf ("new connected process : %d, version %d, index %d\n" + , proc[i].pid, proc[i].version, proc[i].index); + + if ((ret = process_open (&proc[i]))) { + fprintf(stdout, "error process_create %d\n", ret); + exit (1); + } + + // about the message + size_t msize; + char *buf; + + if ((ret = process_read (&proc[i], &buf, &msize))) { + fprintf(stdout, "error process_read %d\n", ret); + exit (1); + } + + if ((ret = process_write (&proc[i], &buf, msize))) { + fprintf(stdout, "error process_read %d\n", ret); + exit (1); + } + + if ((ret = process_close (&proc[i]))) { + fprintf(stdout, "error process_destroy %d\n", ret); + exit (1); + } + } + } while (0); // it's a test, we only do it once + + close (sfifo); // closes the service named pipe +} + +/* + * service test + * + * 1. creates the named pipe /tmp/, then listens + * 2. opens the named pipes in & out + * 3. talks with the (test) program + * 4. closes the test program named pipes + * 5. removes the named pipe /tmp/ + */ + +int main(int argc, char * argv[]) +{ + // gets the service path, such as /tmp/ + char spath[PATH_MAX]; + service_path (spath, "windows"); + + // creates the service named pipe, that listens to client applications + int ret; + if ((ret = service_create (spath))) { + fprintf(stdout, "error service_create %d\n", ret); + exit (1); + } + + // the service will loop until the end of time, a specific message, a signal + main_loop (spath); + + // the application will shut down, and remove the service named pipe + if ((ret = service_close ("windows"))) { + fprintf(stdout, "error service_close %d\n", ret); + exit (1); + } + + return EXIT_SUCCESS; +}