GROS CHANTIER
parent
ea882d37dc
commit
6df133c2c1
|
@ -0,0 +1,3 @@
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
*.swp
|
|
@ -72,6 +72,23 @@ int service_close (const char *fifopath)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct process * srv_process_copy (const struct process *p)
|
||||||
|
{
|
||||||
|
if (p == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct process * copy = malloc (sizeof(struct process));
|
||||||
|
memcpy (copy, p, sizeof (struct process));
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srv_process_eq (const struct process *p1, const struct process *p2)
|
||||||
|
{
|
||||||
|
return (p1->pid == p2->pid && p1>version == p2->version
|
||||||
|
&& p1->index == p2->index);
|
||||||
|
}
|
||||||
|
|
||||||
int service_get_new_process (struct process *proc, const char * spath)
|
int service_get_new_process (struct process *proc, const char * spath)
|
||||||
{
|
{
|
||||||
if (spath == NULL) {
|
if (spath == NULL) {
|
||||||
|
|
|
@ -36,6 +36,10 @@ struct service {
|
||||||
|
|
||||||
int service_path (char *buf, const char *sname);
|
int service_path (char *buf, const char *sname);
|
||||||
|
|
||||||
|
struct process * srv_process_copy (struct process *p);
|
||||||
|
|
||||||
|
int srv_process_eq (const struct process *p1, const struct process *p2);
|
||||||
|
|
||||||
void gen_process_structure (struct process *p
|
void gen_process_structure (struct process *p
|
||||||
, pid_t pid, unsigned int index, unsigned int version);
|
, pid_t pid, unsigned int index, unsigned int version);
|
||||||
|
|
||||||
|
@ -53,6 +57,7 @@ int service_get_new_process (struct process *proc, const char * spath);
|
||||||
void service_get_new_processes (struct process ***, int *nproc, char *spath);
|
void service_get_new_processes (struct process ***, int *nproc, char *spath);
|
||||||
void service_free_processes (struct process **, int nproc);
|
void service_free_processes (struct process **, int nproc);
|
||||||
|
|
||||||
|
|
||||||
void process_print (struct process *);
|
void process_print (struct process *);
|
||||||
int process_create (struct process *, int index); // called by the application
|
int process_create (struct process *, int index); // called by the application
|
||||||
int process_destroy (struct process *); // called by the application
|
int process_destroy (struct process *); // called by the application
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,171 @@
|
||||||
|
/* $OpenBSD: queue.h,v 1.43 2015/12/28 19:38:40 millert Exp $ */
|
||||||
|
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1991, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SYS_QUEUE_H_
|
||||||
|
#define _SYS_QUEUE_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file defines five types of data structures: singly-linked lists,
|
||||||
|
* lists, simple queues, tail queues and XOR simple queues.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* A singly-linked list is headed by a single forward pointer. The elements
|
||||||
|
* are singly linked for minimum space and pointer manipulation overhead at
|
||||||
|
* the expense of O(n) removal for arbitrary elements. New elements can be
|
||||||
|
* added to the list after an existing element or at the head of the list.
|
||||||
|
* Elements being removed from the head of the list should use the explicit
|
||||||
|
* macro for this purpose for optimum efficiency. A singly-linked list may
|
||||||
|
* only be traversed in the forward direction. Singly-linked lists are ideal
|
||||||
|
* for applications with large datasets and few or no removals or for
|
||||||
|
* implementing a LIFO queue.
|
||||||
|
*
|
||||||
|
* A list is headed by a single forward pointer (or an array of forward
|
||||||
|
* pointers for a hash table header). The elements are doubly linked
|
||||||
|
* so that an arbitrary element can be removed without a need to
|
||||||
|
* traverse the list. New elements can be added to the list before
|
||||||
|
* or after an existing element or at the head of the list. A list
|
||||||
|
* may only be traversed in the forward direction.
|
||||||
|
*
|
||||||
|
* A simple queue is headed by a pair of pointers, one to the head of the
|
||||||
|
* list and the other to the tail of the list. The elements are singly
|
||||||
|
* linked to save space, so elements can only be removed from the
|
||||||
|
* head of the list. New elements can be added to the list before or after
|
||||||
|
* an existing element, at the head of the list, or at the end of the
|
||||||
|
* list. A simple queue may only be traversed in the forward direction.
|
||||||
|
*
|
||||||
|
* A tail queue is headed by a pair of pointers, one to the head of the
|
||||||
|
* list and the other to the tail of the list. The elements are doubly
|
||||||
|
* linked so that an arbitrary element can be removed without a need to
|
||||||
|
* traverse the list. New elements can be added to the list before or
|
||||||
|
* after an existing element, at the head of the list, or at the end of
|
||||||
|
* the list. A tail queue may be traversed in either direction.
|
||||||
|
*
|
||||||
|
* An XOR simple queue is used in the same way as a regular simple queue.
|
||||||
|
* The difference is that the head structure also includes a "cookie" that
|
||||||
|
* is XOR'd with the queue pointer (first, last or next) to generate the
|
||||||
|
* real pointer value.
|
||||||
|
*
|
||||||
|
* For details on the use of these macros, see the queue(3) manual page.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
|
||||||
|
#define _Q_INVALIDATE(a) (a) = ((void *)-1)
|
||||||
|
#else
|
||||||
|
#define _Q_INVALIDATE(a)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List definitions.
|
||||||
|
*/
|
||||||
|
#define LIST_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *lh_first; /* first element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LIST_HEAD_INITIALIZER(head) \
|
||||||
|
{ NULL }
|
||||||
|
|
||||||
|
#define LIST_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *le_next; /* next element */ \
|
||||||
|
struct type **le_prev; /* address of previous next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List access methods.
|
||||||
|
*/
|
||||||
|
#define LIST_FIRST(head) ((head)->lh_first)
|
||||||
|
#define LIST_END(head) NULL
|
||||||
|
#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
|
||||||
|
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||||
|
|
||||||
|
#define LIST_FOREACH(var, head, field) \
|
||||||
|
for((var) = LIST_FIRST(head); \
|
||||||
|
(var)!= LIST_END(head); \
|
||||||
|
(var) = LIST_NEXT(var, field))
|
||||||
|
|
||||||
|
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
|
||||||
|
for ((var) = LIST_FIRST(head); \
|
||||||
|
(var) && ((tvar) = LIST_NEXT(var, field), 1); \
|
||||||
|
(var) = (tvar))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List functions.
|
||||||
|
*/
|
||||||
|
#define LIST_INIT(head) do { \
|
||||||
|
LIST_FIRST(head) = LIST_END(head); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
||||||
|
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
|
||||||
|
(listelm)->field.le_next->field.le_prev = \
|
||||||
|
&(elm)->field.le_next; \
|
||||||
|
(listelm)->field.le_next = (elm); \
|
||||||
|
(elm)->field.le_prev = &(listelm)->field.le_next; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
||||||
|
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||||
|
(elm)->field.le_next = (listelm); \
|
||||||
|
*(listelm)->field.le_prev = (elm); \
|
||||||
|
(listelm)->field.le_prev = &(elm)->field.le_next; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
|
||||||
|
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
|
||||||
|
(head)->lh_first = (elm); \
|
||||||
|
(elm)->field.le_prev = &(head)->lh_first; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_REMOVE(elm, field) do { \
|
||||||
|
if ((elm)->field.le_next != NULL) \
|
||||||
|
(elm)->field.le_next->field.le_prev = \
|
||||||
|
(elm)->field.le_prev; \
|
||||||
|
*(elm)->field.le_prev = (elm)->field.le_next; \
|
||||||
|
_Q_INVALIDATE((elm)->field.le_prev); \
|
||||||
|
_Q_INVALIDATE((elm)->field.le_next); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_REPLACE(elm, elm2, field) do { \
|
||||||
|
if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
|
||||||
|
(elm2)->field.le_next->field.le_prev = \
|
||||||
|
&(elm2)->field.le_next; \
|
||||||
|
(elm2)->field.le_prev = (elm)->field.le_prev; \
|
||||||
|
*(elm2)->field.le_prev = (elm2); \
|
||||||
|
_Q_INVALIDATE((elm)->field.le_prev); \
|
||||||
|
_Q_INVALIDATE((elm)->field.le_next); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif /* _SYS_QUEUE_H_ */
|
|
@ -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)
|
|
@ -1,48 +0,0 @@
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "list.h"
|
|
||||||
|
|
||||||
List*
|
|
||||||
list_new(size_t element_size)
|
|
||||||
{
|
|
||||||
List* l = malloc(sizeof(*l));
|
|
||||||
|
|
||||||
l->element_size = element_size;
|
|
||||||
l->head = NULL;
|
|
||||||
l->tail = NULL;
|
|
||||||
l->length = 0;
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
void*
|
|
||||||
list_append(List* l)
|
|
||||||
{
|
|
||||||
struct link* link = malloc(sizeof(*link) + l->element_size);
|
|
||||||
|
|
||||||
link->next = l->tail;
|
|
||||||
l->tail = link;
|
|
||||||
|
|
||||||
if (!l->head)
|
|
||||||
l->tail = link;
|
|
||||||
|
|
||||||
l->length++;
|
|
||||||
|
|
||||||
return (void*) link->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
list_free(List* l)
|
|
||||||
{
|
|
||||||
struct link* next;
|
|
||||||
struct link* link;
|
|
||||||
|
|
||||||
for (link = l->head; link; link = next) {
|
|
||||||
next = link->next;
|
|
||||||
|
|
||||||
free(link);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(l);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
|
|
||||||
#ifndef LIST_H
|
|
||||||
#define LIST_H
|
|
||||||
|
|
||||||
struct link {
|
|
||||||
struct link* next;
|
|
||||||
char value[];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct link* head;
|
|
||||||
struct link* tail;
|
|
||||||
size_t element_size;
|
|
||||||
size_t length;
|
|
||||||
} List;
|
|
||||||
|
|
||||||
List* list_new(size_t);
|
|
||||||
void* list_append(List*);
|
|
||||||
void list_remove(List*, size_t);
|
|
||||||
void list_free(List*);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
254
pubsub/pubsubd.c
254
pubsub/pubsubd.c
|
@ -1,91 +1,191 @@
|
||||||
|
#include "../lib/communication.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <communication.h>
|
|
||||||
|
|
||||||
#include "list.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int test;
|
|
||||||
} Publisher;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int test;
|
|
||||||
} Subscriber;
|
|
||||||
|
|
||||||
const char* service_name = "pubsub";
|
const char* service_name = "pubsub";
|
||||||
|
|
||||||
void
|
void
|
||||||
ohshit(int rvalue, const char* str) {
|
ohshit(int rvalue, const char* str) {
|
||||||
fprintf(stderr, "%s\n", str);
|
fprintf(stderr, "%s\n", str);
|
||||||
|
exit(rvalue);
|
||||||
exit(rvalue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init lists
|
||||||
|
void pubsubd_channels_init (struct channels *chans) { LIST_INIT(chans); }
|
||||||
|
void pubsubd_subscriber_init (struct app_list *al) { LIST_INIT(al); }
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char* argv[])
|
pubsubd_channels_eq (const struct channel *c1, const struct channel *c2)
|
||||||
{
|
{
|
||||||
List* subscribers;
|
return (strncmp (c1->chan, c2->chan, c1->chanlen) == 0);
|
||||||
List* publishers;
|
}
|
||||||
int r;
|
struct channels * pubsubd_channels_copy (struct channels *c);
|
||||||
char s_path[PATH_MAX];
|
|
||||||
int s_pipe;
|
|
||||||
|
|
||||||
(void) argc;
|
void
|
||||||
(void) argv;
|
pubsubd_channels_add (struct channels *chans, struct channels *c)
|
||||||
|
{
|
||||||
|
if(!chans || !c)
|
||||||
|
return;
|
||||||
|
|
||||||
service_path(s_path, service_name);
|
struct process *n = pubsubd_channels_copy (c);
|
||||||
|
LIST_INSERT_HEAD(al, n, entries);
|
||||||
printf("Listening on %s.\n", s_path);
|
|
||||||
|
|
||||||
if ((r = service_create(s_path)))
|
|
||||||
ohshit(1, "service_create error");
|
|
||||||
|
|
||||||
publishers = list_new(sizeof(Publisher));
|
|
||||||
subscribers = list_new(sizeof(Subscriber));
|
|
||||||
|
|
||||||
if (!publishers && !subscribers)
|
|
||||||
ohshit(1, "out of memory, already...");
|
|
||||||
|
|
||||||
/* ?!?!?!?!? */
|
|
||||||
mkfifo(s_path, S_IRUSR);
|
|
||||||
|
|
||||||
s_pipe = open(s_path, S_IRUSR);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
struct process* proc;
|
|
||||||
int proc_count, i;
|
|
||||||
|
|
||||||
service_get_new_processes(&proc, &proc_count, s_pipe);
|
|
||||||
|
|
||||||
printf("> %i proc\n", proc_count);
|
|
||||||
|
|
||||||
for (i = 0; i < proc_count; i++) {
|
|
||||||
size_t message_size = BUFSIZ;
|
|
||||||
char buffer[BUFSIZ];
|
|
||||||
|
|
||||||
process_print(proc + i);
|
|
||||||
|
|
||||||
if ((r = process_read(&proc[i], &buffer, &message_size))) {
|
|
||||||
ohshit(1, "process_read error");
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(": %s\n", buffer);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
service_free_processes(&proc, proc_count);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(s_pipe);
|
|
||||||
|
|
||||||
list_free(publishers);
|
|
||||||
list_free(subscribers);
|
|
||||||
|
|
||||||
service_close(s_path);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pubsubd_subscriber_del (struct app_list *al, struct process *p)
|
||||||
|
{
|
||||||
|
struct process *todel = srv_subscriber_get (al, p);
|
||||||
|
if(todel != NULL) {
|
||||||
|
LIST_REMOVE(todel, entries);
|
||||||
|
srv_process_free (mfree, todel);
|
||||||
|
mfree (todel);
|
||||||
|
todel = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pubsubd_subscriber_add (struct app_list *al, struct process *p)
|
||||||
|
{
|
||||||
|
if(!al || !p)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct process *n = srv_process_copy (p);
|
||||||
|
LIST_INSERT_HEAD(al, n, entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct process *
|
||||||
|
pubsubd_subscriber_get (const struct app_list *al
|
||||||
|
, const struct process *p)
|
||||||
|
{
|
||||||
|
struct process *np, *res = NULL;
|
||||||
|
LIST_FOREACH(np, al, entries) {
|
||||||
|
if(srv_process_eq (np, p)) {
|
||||||
|
res = np;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pubsubd_subscriber_del (struct app_list *al, struct process *p)
|
||||||
|
{
|
||||||
|
struct process *todel = srv_subscriber_get (al, p);
|
||||||
|
if(todel != NULL) {
|
||||||
|
LIST_REMOVE(todel, entries);
|
||||||
|
srv_process_free (mfree, todel);
|
||||||
|
mfree (todel);
|
||||||
|
todel = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pubsubd_msg_send (struct service *s, struct message * m, struct process *p)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void pubsubd_msg_recv (struct service *s, struct message * m, struct process *p)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void pubsub_msg_send (struct service *s, struct message * m)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void pubsub_msg_recv (struct service *s, struct message * m)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
// gets the service path, such as /tmp/<service>
|
||||||
|
char s_path[PATH_MAX];
|
||||||
|
service_path (s_path, service_name);
|
||||||
|
printf ("Listening on %s.\n", s_path);
|
||||||
|
|
||||||
|
// creates the service named pipe, that listens to client applications
|
||||||
|
if (service_create (s_path))
|
||||||
|
ohshit(1, "service_create error");
|
||||||
|
|
||||||
|
struct channels chans;
|
||||||
|
pubsubd_channels_init (&chans);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
struct process proc;
|
||||||
|
int proc_count, i;
|
||||||
|
|
||||||
|
service_get_new_process (&proc, s_path);
|
||||||
|
|
||||||
|
printf("> %i proc\n", proc_count);
|
||||||
|
|
||||||
|
for (i = 0; i < proc_count; i++) {
|
||||||
|
size_t message_size = BUFSIZ;
|
||||||
|
char buffer[BUFSIZ];
|
||||||
|
|
||||||
|
process_print(proc + i);
|
||||||
|
|
||||||
|
if (process_read (&proc[i], &buffer, &message_size))
|
||||||
|
ohshit(1, "process_read error");
|
||||||
|
|
||||||
|
printf(": %s\n", buffer);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
service_free_processes(&proc, proc_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the application will shut down, and remove the service named pipe
|
||||||
|
if (service_close (s_path))
|
||||||
|
ohshit(1, "service_close error");
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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");
|
||||||
|
continue;
|
||||||
|
} 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);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 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);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// printf ("after proc write\n");
|
||||||
|
printf ("\033[32mStill \033[31m%d\033[32m applications to serve\n",cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef __PUBSUBD_H__
|
||||||
|
#define __PUBSUBD_H__
|
||||||
|
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
struct message {
|
||||||
|
unsigned char *chan;
|
||||||
|
size_t chanlen;
|
||||||
|
unsigned char *data;
|
||||||
|
size_t datalen;
|
||||||
|
unsigned char type; // message type : alert, notification, …
|
||||||
|
};
|
||||||
|
|
||||||
|
struct channel {
|
||||||
|
unsigned char *chan;
|
||||||
|
size_t chanlen;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct channels {
|
||||||
|
struct channel *chan;
|
||||||
|
LIST_ENTRY(channels) entries;
|
||||||
|
};
|
||||||
|
|
||||||
|
int pubsubd_channels_eq (const struct channels *c1, const struct channels *c2);
|
||||||
|
|
||||||
|
struct app_list {
|
||||||
|
struct process *p;
|
||||||
|
LIST_ENTRY(app_list) entries;
|
||||||
|
};
|
||||||
|
|
||||||
|
void pubsubd_msg_send (struct service *, struct message *msg, struct process *p);
|
||||||
|
void pubsubd_msg_recv (struct service *, struct message *msg, struct process *p);
|
||||||
|
|
||||||
|
struct process * pubsubd_subscriber_get (const struct app_list *
|
||||||
|
, const struct process *);
|
||||||
|
void pubsubd_subscriber_del (struct app_list *al, struct process *p);
|
||||||
|
|
||||||
|
void pubsub_msg_send (struct service *, struct message *msg);
|
||||||
|
void pubsub_msg_recv (struct service *, struct message *msg);
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue