From 6b2ad54284dff429f101ec45f1d12e17970e20b7 Mon Sep 17 00:00:00 2001 From: Philippe PITTOLI Date: Mon, 30 May 2016 16:30:05 +0200 Subject: [PATCH] pingpong service with test application script : working --- lib/communication.c | 60 +++++++++++++++--- lib/communication.h | 3 + pingpong/Makefile | 22 +++++++ pingpong/README.markdown | 31 ++++++++++ pingpong/pingpong.c | 88 +++++++++++++++++++++++++++ pingpong/pingpong.sh | 37 +++++++++++ service-test.c | 128 --------------------------------------- 7 files changed, 233 insertions(+), 136 deletions(-) create mode 100644 pingpong/Makefile create mode 100644 pingpong/README.markdown create mode 100644 pingpong/pingpong.c create mode 100755 pingpong/pingpong.sh delete mode 100644 service-test.c diff --git a/lib/communication.c b/lib/communication.c index 9aae555..9e5a382 100644 --- a/lib/communication.c +++ b/lib/communication.c @@ -82,8 +82,6 @@ int service_get_new_process (struct process *proc, const char * spath) bzero (buf, BUFSIZ); // read the pipe, get a process to work on - int ret; - struct timespec ts = { 0 }; struct timespec ts2 = { 0 }; @@ -307,6 +305,32 @@ int process_open_in (struct process *proc) return 0; } +int service_proc_open_in (struct process *proc) +{ + char fifopathin[PATH_MAX]; + char fifopathout[PATH_MAX]; + process_paths (fifopathin, fifopathout, proc->pid, proc->index); + + printf ("opening in %s\n", fifopathin); + proc->in = fopen (fifopathin, "wb"); + printf ("opened : %d\n", proc->in); + + return 0; +} + +int service_proc_open_out (struct process *proc) +{ + char fifopathin[PATH_MAX]; + char fifopathout[PATH_MAX]; + process_paths (fifopathin, fifopathout, proc->pid, proc->index); + + printf ("opening out %s\n", fifopathout); + proc->out = fopen (fifopathout, "rb"); + printf ("opened\n"); + + return 0; +} + int process_open_out (struct process *proc) { char fifopathin[PATH_MAX]; @@ -347,12 +371,12 @@ int process_read (struct process *proc, void * buf, size_t * msize) { int ret; if ((ret = process_open_in (proc))) { - fprintf(stdout, "error process_create %d\n", ret); + fprintf(stdout, "error process_open_in %d\n", ret); exit (1); } *msize = fread (buf, 1, *msize, proc->in); // FIXME check errors - printf ("DEBUG read, size %ld : %s\n", *msize, buf); + // printf ("DEBUG read, size %ld : %s\n", *msize, buf); if ((ret = process_close_in (proc))) { fprintf(stdout, "error process_close_in %d\n", ret); @@ -381,16 +405,36 @@ int process_write (struct process *proc, void * buf, size_t msize) int service_read (struct process *proc, void * buf, size_t * msize) { - if ((*msize = fread (buf, 1, *msize, proc->out))) - return *msize; + int ret; + if ((ret = service_proc_open_out (proc))) { + fprintf(stdout, "error process_open_out %d\n", ret); + exit (1); + } + + *msize = fread (buf, 1, *msize, proc->out); // FIXME check errors + // printf ("DEBUG read, size %ld : %s\n", *msize, buf); + + if ((ret = process_close_out (proc))) { + fprintf(stdout, "error process_close_out %d\n", ret); + exit (1); + } return 0; } int service_write (struct process *proc, void * buf, size_t msize) { - if ((msize = fwrite (buf, 1, msize, proc->in))) - return msize; + int ret; + if ((ret = service_proc_open_in (proc))) { + fprintf(stdout, "error process_open_in %d\n", ret); + exit (1); + } + fwrite (buf, 1, msize, proc->in); // FIXME check errors + + if ((ret = process_close_in (proc))) { + fprintf(stdout, "error process_close_in %d\n", ret); + exit (1); + } return 0; } diff --git a/lib/communication.h b/lib/communication.h index 2029e0b..4ab656c 100644 --- a/lib/communication.h +++ b/lib/communication.h @@ -60,4 +60,7 @@ int process_destroy (struct process *); // called by the application int process_read (struct process *, void * buf, size_t *); int process_write (struct process *, void * buf, size_t); +int service_read (struct process *, void * buf, size_t *); +int service_write (struct process *, void * buf, size_t); + #endif diff --git a/pingpong/Makefile b/pingpong/Makefile new file mode 100644 index 0000000..22d244e --- /dev/null +++ b/pingpong/Makefile @@ -0,0 +1,22 @@ +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) diff --git a/pingpong/README.markdown b/pingpong/README.markdown new file mode 100644 index 0000000..b349e7f --- /dev/null +++ b/pingpong/README.markdown @@ -0,0 +1,31 @@ +# Service ping-pong + +This service is a brain-dead application. It is only to a pedagogic end. + +The purpose is only to communicate with an application once, the application +sends a message and the service answer with the same message. + +# How it works + + * **S**: service + * **A**: application + + 1. **S** creates the named pipe /tmp/pingpong, then listens + 2. **S** opens the named pipes in & out + 3. **A** talks with the test program *pingpong.sh* + 4. **S** closes the test program named pipes + 5. **S** removes the named pipe /tmp/pingpong after 10 served applications + +# pingpong.sh + +The script *pingpong.sh* lets you test the service. + +Usage : + + pingpong.sh [NB] + # NB is the number of exchanged messages + + or + + pingpong.sh clean + # it is to clean the /tmp/ipc/ directory diff --git a/pingpong/pingpong.c b/pingpong/pingpong.c new file mode 100644 index 0000000..b6e5b6d --- /dev/null +++ b/pingpong/pingpong.c @@ -0,0 +1,88 @@ +#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; + struct process proc; + + int cnt = 10; + + while (cnt--) { + // -1 : error, 0 = no new process, 1 = new process + ret = service_get_new_process (&proc, spath); + if (ret == -1) { + fprintf (stderr, "Error service_get_new_process\n"); + exit (1); + } else if (ret == 0) { // that should not happen + continue; + } + + // printf ("before print\n"); + process_print (&proc); + // printf ("after print\n"); + + // about the message + size_t msize = BUFSIZ; + char buf[BUFSIZ]; + bzero(buf, BUFSIZ); + + // printf ("before read\n"); + if ((ret = service_read (&proc, &buf, &msize))) { + fprintf(stdout, "error service_read %d\n", ret); + exit (1); + } + // printf ("after read\n"); + printf ("read, size %ld : %s\n", msize, buf); + + // printf ("before proc write\n"); + if ((ret = service_write (&proc, &buf, msize))) { + fprintf(stdout, "error service_write %d\n", ret); + exit (1); + } + // printf ("after proc write\n"); + printf ("\033[32mStill \033[31m%d\033[32m applications to serve\n",cnt); + } +} + +/* + * service ping-pong + * + * 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, "pingpong"); + + // 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 (spath))) { + fprintf(stdout, "error service_close %d\n", ret); + exit (1); + } + + return EXIT_SUCCESS; +} diff --git a/pingpong/pingpong.sh b/pingpong/pingpong.sh new file mode 100755 index 0000000..b622dce --- /dev/null +++ b/pingpong/pingpong.sh @@ -0,0 +1,37 @@ +#!/bin/dash + +REP=/tmp/ipc/ +SERVICE="pingpong" +NB=3 + +# CLEAN UP ! +if [ $# -ne 0 ] && [ "$1" = clean ] +then + echo "clean rep ${REP}" + rm ${REP}/${SERVICE} + rm ${REP}/*-in + rm ${REP}/*-out + + exit 0 +fi + +if [ $# -ne 0 ] +then + NB=$1 +fi + +for pid in `seq 1 ${NB}` +do + # we make the application pipes + mkfifo ${REP}/${pid}-1-in 2>/dev/null + mkfifo ${REP}/${pid}-1-out 2>/dev/null + + # pid index version + echo "${pid} 1 1" > ${REP}/${SERVICE} + + # the purpose is to send something in the pipe + cat /dev/urandom | base64 | head -n 1 > ${REP}/${pid}-1-out + + # the the service will answer with our message + cat ${REP}/${pid}-1-in +done diff --git a/service-test.c b/service-test.c deleted file mode 100644 index c7ac8d1..0000000 --- a/service-test.c +++ /dev/null @@ -1,128 +0,0 @@ -#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; - struct process proc; -#if 1 - while (1) { - - // -1 : error - // 0 = no new process - // 1 = new process - ret = service_get_new_process (&proc, spath); - if (ret == -1) { - fprintf (stderr, "Error service_get_new_process\n"); - exit (1); - } else if (ret == 0) { - continue; - } - - printf ("before print\n"); - process_print (&proc); - printf ("after print\n"); - - // about the message - size_t msize = BUFSIZ; - char buf[BUFSIZ]; - bzero(buf, BUFSIZ); - - printf ("before read\n"); - if ((ret = process_read (&proc, &buf, &msize))) { - fprintf(stdout, "error process_read %d\n", ret); - exit (1); - } - printf ("after read\n"); - printf ("read, size %ld : %s\n", msize, buf); - - printf ("before proc write\n"); - if ((ret = process_write (&proc, &buf, msize))) { - fprintf(stdout, "error process_write %d\n", ret); - exit (1); - } - printf ("after proc write\n"); - } -#endif - -#if 0 - - int ret; - struct process **proc; - int nproc = 0; - while (1) { - service_get_new_processes (&proc, &nproc, spath); - - // for each process : open, read, write, close - for (int i = 0 ; i < nproc ; i++) { - printf ("before print\n"); - process_print (proc[i]); - printf ("after print, i = %d\n", i); - - // about the message - size_t msize = BUFSIZ; - char buf[BUFSIZ]; - bzero(buf, BUFSIZ); - - printf ("before read\n"); - if ((ret = process_read (proc[i], &buf, &msize))) { - fprintf(stdout, "error process_read %d\n", ret); - exit (1); - } - printf ("after read\n"); - printf ("read, size %ld : %s\n", msize, buf); - - printf ("before proc write\n"); - if ((ret = process_write (proc[i], &buf, msize))) { - fprintf(stdout, "error process_write %d\n", ret); - exit (1); - } - printf ("after proc write\n"); - } - service_free_processes (proc, nproc); - free (proc); - } -#endif -} - -/* - * 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 (spath))) { - fprintf(stdout, "error service_close %d\n", ret); - exit (1); - } - - return EXIT_SUCCESS; -}