Merge branch 'newapi' of JunkOS/libipc into master
This commit is contained in:
commit
75c00d229e
195
Makefile
195
Makefile
@ -11,8 +11,8 @@ MANDIR := $(SHAREDIR)/man
|
|||||||
CC := cc
|
CC := cc
|
||||||
AR := ar
|
AR := ar
|
||||||
RANLIB := ranlib
|
RANLIB := ranlib
|
||||||
CFLAGS :=
|
CFLAGS :=
|
||||||
LDFLAGS :=
|
LDFLAGS :=
|
||||||
|
|
||||||
Q := @
|
Q := @
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ libipc.clean: libipc.so.clean libipc.a.clean
|
|||||||
libipc.uninstall: libipc.so.uninstall libipc.a.uninstall
|
libipc.uninstall: libipc.so.uninstall libipc.a.uninstall
|
||||||
|
|
||||||
src/ipc.h.install: src/ipc.h
|
src/ipc.h.install: src/ipc.h
|
||||||
@echo '[01;31m IN > [01;37m$(INCLUDEDIR)/ipc.h[00m'
|
@echo ' IN > $(INCLUDEDIR)/ipc.h'
|
||||||
$(Q)mkdir -p '$(DESTDIR)$(INCLUDEDIR)'
|
$(Q)mkdir -p '$(DESTDIR)$(INCLUDEDIR)'
|
||||||
$(Q)install -m0644 src/ipc.h $(DESTDIR)$(INCLUDEDIR)/ipc.h
|
$(Q)install -m0644 src/ipc.h $(DESTDIR)$(INCLUDEDIR)/ipc.h
|
||||||
|
|
||||||
@ -36,169 +36,169 @@ src/ipc.h.clean: src/ipc.h
|
|||||||
$(Q):
|
$(Q):
|
||||||
|
|
||||||
src/ipc.h.uninstall:
|
src/ipc.h.uninstall:
|
||||||
@echo '[01;37m RM > [01;37m$(INCLUDEDIR)/ipc.h[00m'
|
@echo ' RM > $(INCLUDEDIR)/ipc.h'
|
||||||
$(Q)rm -f '$(DESTDIR)$(INCLUDEDIR)/ipc.h'
|
$(Q)rm -f '$(DESTDIR)$(INCLUDEDIR)/ipc.h'
|
||||||
|
|
||||||
man/libipc.7: man/libipc.7.md
|
man/libipc.7: man/libipc.7.md
|
||||||
@echo '[01;32m MAN > [01;37mman/libipc.7[00m'
|
@echo ' MAN > man/libipc.7'
|
||||||
$(Q)pandoc -s --from markdown --to man 'man/libipc.7.md' -o 'man/libipc.7'
|
$(Q)pandoc -s --from markdown --to man 'man/libipc.7.md' -o 'man/libipc.7'
|
||||||
|
|
||||||
|
|
||||||
man/libipc.7.install: man/libipc.7
|
man/libipc.7.install: man/libipc.7
|
||||||
@echo '[01;31m IN > [01;37m$(MANDIR)/man7/libipc.7[00m'
|
@echo ' IN > $(MANDIR)/man7/libipc.7'
|
||||||
$(Q)mkdir -p '$(DESTDIR)$(MANDIR)/man7'
|
$(Q)mkdir -p '$(DESTDIR)$(MANDIR)/man7'
|
||||||
$(Q)install -m0644 man/libipc.7 $(DESTDIR)$(MANDIR)/man7/libipc.7
|
$(Q)install -m0644 man/libipc.7 $(DESTDIR)$(MANDIR)/man7/libipc.7
|
||||||
|
|
||||||
man/libipc.7.clean:
|
man/libipc.7.clean:
|
||||||
@echo '[01;37m RM > [01;37mman/libipc.7[00m'
|
@echo ' RM > man/libipc.7'
|
||||||
$(Q)rm -f man/libipc.7
|
$(Q)rm -f man/libipc.7
|
||||||
|
|
||||||
man/libipc.7.uninstall:
|
man/libipc.7.uninstall:
|
||||||
@echo '[01;37m RM > [01;37m$(MANDIR)/man7/libipc.7[00m'
|
@echo ' RM > $(MANDIR)/man7/libipc.7'
|
||||||
$(Q)rm -f '$(DESTDIR)$(MANDIR)/man7/libipc.7'
|
$(Q)rm -f '$(DESTDIR)$(MANDIR)/man7/libipc.7'
|
||||||
|
|
||||||
libipc.so: src/client.o src/communication.o src/logger.o src/message.o src/usocket.o src/utils.o
|
libipc.so: src/communication.o src/error.o src/logger.o src/message.o src/usocket.o src/utils.o
|
||||||
@echo '[01;32m LD > [01;37mlibipc.so[00m'
|
@echo ' LD > libipc.so'
|
||||||
$(Q)$(CC) -o libipc.so -shared $(LDFLAGS) src/client.o src/communication.o src/logger.o src/message.o src/usocket.o src/utils.o
|
$(Q)$(CC) -o libipc.so -shared $(LDFLAGS) src/communication.o src/error.o src/logger.o src/message.o src/usocket.o src/utils.o
|
||||||
|
|
||||||
libipc.so.install: libipc.so
|
libipc.so.install: libipc.so
|
||||||
@echo '[01;31m IN > [01;37m$(LIBDIR)/libipc.so.0.1.0[00m'
|
@echo ' IN > $(LIBDIR)/libipc.so.0.1.0'
|
||||||
$(Q)mkdir -p '$(DESTDIR)$(LIBDIR)'
|
$(Q)mkdir -p '$(DESTDIR)$(LIBDIR)'
|
||||||
$(Q)install -m0755 libipc.so $(DESTDIR)$(LIBDIR)/libipc.so.0.1.0
|
$(Q)install -m0755 libipc.so $(DESTDIR)$(LIBDIR)/libipc.so.0.1.0
|
||||||
@echo '[01;33m LN > [01;37m$(LIBDIR)/libipc.so.0.1[00m'
|
@echo ' LN > $(LIBDIR)/libipc.so.0.1'
|
||||||
$(Q)ln -sf '$(LIBDIR)/libipc.so.0.1.0' '$(DESTDIR)/$(LIBDIR)/libipc.so.0.1'
|
$(Q)ln -sf '$(LIBDIR)/libipc.so.0.1.0' '$(DESTDIR)/$(LIBDIR)/libipc.so.0.1'
|
||||||
@echo '[01;33m LN > [01;37m$(LIBDIR)/libipc.so.0[00m'
|
@echo ' LN > $(LIBDIR)/libipc.so.0'
|
||||||
$(Q)ln -sf '$(LIBDIR)/libipc.so.0.1.0' '$(DESTDIR)/$(LIBDIR)/libipc.so.0'
|
$(Q)ln -sf '$(LIBDIR)/libipc.so.0.1.0' '$(DESTDIR)/$(LIBDIR)/libipc.so.0'
|
||||||
@echo '[01;33m LN > [01;37m$(LIBDIR)/libipc.so[00m'
|
@echo ' LN > $(LIBDIR)/libipc.so'
|
||||||
$(Q)ln -sf '$(LIBDIR)/libipc.so.0.1.0' '$(DESTDIR)/$(LIBDIR)/libipc.so'
|
$(Q)ln -sf '$(LIBDIR)/libipc.so.0.1.0' '$(DESTDIR)/$(LIBDIR)/libipc.so'
|
||||||
|
|
||||||
libipc.so.clean:
|
libipc.so.clean:
|
||||||
@echo '[01;37m RM > [01;37mlibipc.so[00m'
|
@echo ' RM > libipc.so'
|
||||||
$(Q)rm -f libipc.so
|
$(Q)rm -f libipc.so
|
||||||
|
|
||||||
libipc.so.uninstall:
|
libipc.so.uninstall:
|
||||||
@echo '[01;37m RM > [01;37m$(LIBDIR)/libipc.so.0.1.0[00m'
|
@echo ' RM > $(LIBDIR)/libipc.so.0.1.0'
|
||||||
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so.0.1.0'
|
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so.0.1.0'
|
||||||
@echo '[01;37m RM > [01;37m$(LIBDIR)/libipc.so.0.1[00m'
|
@echo ' RM > $(LIBDIR)/libipc.so.0.1'
|
||||||
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so.0.1'
|
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so.0.1'
|
||||||
@echo '[01;37m RM > [01;37m$(LIBDIR)/libipc.so.0[00m'
|
@echo ' RM > $(LIBDIR)/libipc.so.0'
|
||||||
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so.0'
|
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so.0'
|
||||||
@echo '[01;37m RM > [01;37m$(LIBDIR)/libipc.so[00m'
|
@echo ' RM > $(LIBDIR)/libipc.so'
|
||||||
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so'
|
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so'
|
||||||
|
|
||||||
libipc.a: src/client.o src/communication.o src/logger.o src/message.o src/usocket.o src/utils.o
|
libipc.a: src/communication.o src/error.o src/logger.o src/message.o src/usocket.o src/utils.o
|
||||||
@echo '[01;32m LD > [01;37mlibipc.a[00m'
|
@echo ' LD > libipc.a'
|
||||||
$(Q)$(AR) rc 'libipc.a' src/client.o src/communication.o src/logger.o src/message.o src/usocket.o src/utils.o
|
$(Q)$(AR) rc 'libipc.a' src/communication.o src/error.o src/logger.o src/message.o src/usocket.o src/utils.o
|
||||||
|
|
||||||
libipc.a.install: libipc.a
|
libipc.a.install: libipc.a
|
||||||
@echo '[01;31m IN > [01;37m$(LIBDIR)/libipc.a[00m'
|
@echo ' IN > $(LIBDIR)/libipc.a'
|
||||||
$(Q)mkdir -p '$(DESTDIR)$(LIBDIR)'
|
$(Q)mkdir -p '$(DESTDIR)$(LIBDIR)'
|
||||||
$(Q)install -m0755 libipc.a $(DESTDIR)$(LIBDIR)/libipc.a
|
$(Q)install -m0755 libipc.a $(DESTDIR)$(LIBDIR)/libipc.a
|
||||||
|
|
||||||
libipc.a.clean:
|
libipc.a.clean:
|
||||||
@echo '[01;37m RM > [01;37mlibipc.a[00m'
|
@echo ' RM > libipc.a'
|
||||||
$(Q)rm -f libipc.a
|
$(Q)rm -f libipc.a
|
||||||
|
|
||||||
libipc.a.uninstall:
|
libipc.a.uninstall:
|
||||||
@echo '[01;37m RM > [01;37m$(LIBDIR)/libipc.a[00m'
|
@echo ' RM > $(LIBDIR)/libipc.a'
|
||||||
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.a'
|
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.a'
|
||||||
|
|
||||||
src/client.o: src/client.c src/client.h
|
src/communication.o: src/communication.c src/ipc.h src/utils.h src/message.h
|
||||||
@echo '[01;34m CC > [01;37msrc/client.o[00m'
|
@echo ' CC > src/communication.o'
|
||||||
$(Q)$(CC) $(CFLAGS) -fPIC -c src/client.c -fPIC -o src/client.o
|
|
||||||
|
|
||||||
src/client.o.install:
|
|
||||||
|
|
||||||
src/client.o.clean:
|
|
||||||
@echo '[01;37m RM > [01;37msrc/client.o[00m'
|
|
||||||
$(Q)rm -f src/client.o
|
|
||||||
|
|
||||||
src/client.o.uninstall:
|
|
||||||
|
|
||||||
src/communication.o: src/communication.c src/communication.h src/utils.h src/error.h src/event.h
|
|
||||||
@echo '[01;34m CC > [01;37msrc/communication.o[00m'
|
|
||||||
$(Q)$(CC) $(CFLAGS) -fPIC -c src/communication.c -fPIC -o src/communication.o
|
$(Q)$(CC) $(CFLAGS) -fPIC -c src/communication.c -fPIC -o src/communication.o
|
||||||
|
|
||||||
src/communication.o.install:
|
src/communication.o.install:
|
||||||
|
|
||||||
src/communication.o.clean:
|
src/communication.o.clean:
|
||||||
@echo '[01;37m RM > [01;37msrc/communication.o[00m'
|
@echo ' RM > src/communication.o'
|
||||||
$(Q)rm -f src/communication.o
|
$(Q)rm -f src/communication.o
|
||||||
|
|
||||||
src/communication.o.uninstall:
|
src/communication.o.uninstall:
|
||||||
|
|
||||||
|
src/error.o: src/error.c src/ipc.h
|
||||||
|
@echo ' CC > src/error.o'
|
||||||
|
$(Q)$(CC) $(CFLAGS) -fPIC -c src/error.c -fPIC -o src/error.o
|
||||||
|
|
||||||
|
src/error.o.install:
|
||||||
|
|
||||||
|
src/error.o.clean:
|
||||||
|
@echo ' RM > src/error.o'
|
||||||
|
$(Q)rm -f src/error.o
|
||||||
|
|
||||||
|
src/error.o.uninstall:
|
||||||
|
|
||||||
src/logger.o: src/logger.c src/logger.h
|
src/logger.o: src/logger.c src/logger.h
|
||||||
@echo '[01;34m CC > [01;37msrc/logger.o[00m'
|
@echo ' CC > src/logger.o'
|
||||||
$(Q)$(CC) $(CFLAGS) -fPIC -c src/logger.c -fPIC -o src/logger.o
|
$(Q)$(CC) $(CFLAGS) -fPIC -c src/logger.c -fPIC -o src/logger.o
|
||||||
|
|
||||||
src/logger.o.install:
|
src/logger.o.install:
|
||||||
|
|
||||||
src/logger.o.clean:
|
src/logger.o.clean:
|
||||||
@echo '[01;37m RM > [01;37msrc/logger.o[00m'
|
@echo ' RM > src/logger.o'
|
||||||
$(Q)rm -f src/logger.o
|
$(Q)rm -f src/logger.o
|
||||||
|
|
||||||
src/logger.o.uninstall:
|
src/logger.o.uninstall:
|
||||||
|
|
||||||
src/message.o: src/message.c src/message.h src/error.h src/usocket.h
|
src/message.o: src/message.c src/message.h src/usocket.h
|
||||||
@echo '[01;34m CC > [01;37msrc/message.o[00m'
|
@echo ' CC > src/message.o'
|
||||||
$(Q)$(CC) $(CFLAGS) -fPIC -c src/message.c -fPIC -o src/message.o
|
$(Q)$(CC) $(CFLAGS) -fPIC -c src/message.c -fPIC -o src/message.o
|
||||||
|
|
||||||
src/message.o.install:
|
src/message.o.install:
|
||||||
|
|
||||||
src/message.o.clean:
|
src/message.o.clean:
|
||||||
@echo '[01;37m RM > [01;37msrc/message.o[00m'
|
@echo ' RM > src/message.o'
|
||||||
$(Q)rm -f src/message.o
|
$(Q)rm -f src/message.o
|
||||||
|
|
||||||
src/message.o.uninstall:
|
src/message.o.uninstall:
|
||||||
|
|
||||||
src/usocket.o: src/usocket.c src/usocket.h src/utils.h src/error.h
|
src/usocket.o: src/usocket.c src/usocket.h src/utils.h
|
||||||
@echo '[01;34m CC > [01;37msrc/usocket.o[00m'
|
@echo ' CC > src/usocket.o'
|
||||||
$(Q)$(CC) $(CFLAGS) -fPIC -c src/usocket.c -fPIC -o src/usocket.o
|
$(Q)$(CC) $(CFLAGS) -fPIC -c src/usocket.c -fPIC -o src/usocket.o
|
||||||
|
|
||||||
src/usocket.o.install:
|
src/usocket.o.install:
|
||||||
|
|
||||||
src/usocket.o.clean:
|
src/usocket.o.clean:
|
||||||
@echo '[01;37m RM > [01;37msrc/usocket.o[00m'
|
@echo ' RM > src/usocket.o'
|
||||||
$(Q)rm -f src/usocket.o
|
$(Q)rm -f src/usocket.o
|
||||||
|
|
||||||
src/usocket.o.uninstall:
|
src/usocket.o.uninstall:
|
||||||
|
|
||||||
src/utils.o: src/utils.c src/utils.h
|
src/utils.o: src/utils.c src/utils.h
|
||||||
@echo '[01;34m CC > [01;37msrc/utils.o[00m'
|
@echo ' CC > src/utils.o'
|
||||||
$(Q)$(CC) $(CFLAGS) -fPIC -c src/utils.c -fPIC -o src/utils.o
|
$(Q)$(CC) $(CFLAGS) -fPIC -c src/utils.c -fPIC -o src/utils.o
|
||||||
|
|
||||||
src/utils.o.install:
|
src/utils.o.install:
|
||||||
|
|
||||||
src/utils.o.clean:
|
src/utils.o.clean:
|
||||||
@echo '[01;37m RM > [01;37msrc/utils.o[00m'
|
@echo ' RM > src/utils.o'
|
||||||
$(Q)rm -f src/utils.o
|
$(Q)rm -f src/utils.o
|
||||||
|
|
||||||
src/utils.o.uninstall:
|
src/utils.o.uninstall:
|
||||||
|
|
||||||
$(DESTDIR)$(PREFIX):
|
$(DESTDIR)$(PREFIX):
|
||||||
@echo '[01;35m DIR > [01;37m$(PREFIX)[00m'
|
@echo ' DIR > $(PREFIX)'
|
||||||
$(Q)mkdir -p $(DESTDIR)$(PREFIX)
|
$(Q)mkdir -p $(DESTDIR)$(PREFIX)
|
||||||
$(DESTDIR)$(BINDIR):
|
$(DESTDIR)$(BINDIR):
|
||||||
@echo '[01;35m DIR > [01;37m$(BINDIR)[00m'
|
@echo ' DIR > $(BINDIR)'
|
||||||
$(Q)mkdir -p $(DESTDIR)$(BINDIR)
|
$(Q)mkdir -p $(DESTDIR)$(BINDIR)
|
||||||
$(DESTDIR)$(LIBDIR):
|
$(DESTDIR)$(LIBDIR):
|
||||||
@echo '[01;35m DIR > [01;37m$(LIBDIR)[00m'
|
@echo ' DIR > $(LIBDIR)'
|
||||||
$(Q)mkdir -p $(DESTDIR)$(LIBDIR)
|
$(Q)mkdir -p $(DESTDIR)$(LIBDIR)
|
||||||
$(DESTDIR)$(SHAREDIR):
|
$(DESTDIR)$(SHAREDIR):
|
||||||
@echo '[01;35m DIR > [01;37m$(SHAREDIR)[00m'
|
@echo ' DIR > $(SHAREDIR)'
|
||||||
$(Q)mkdir -p $(DESTDIR)$(SHAREDIR)
|
$(Q)mkdir -p $(DESTDIR)$(SHAREDIR)
|
||||||
$(DESTDIR)$(INCLUDEDIR):
|
$(DESTDIR)$(INCLUDEDIR):
|
||||||
@echo '[01;35m DIR > [01;37m$(INCLUDEDIR)[00m'
|
@echo ' DIR > $(INCLUDEDIR)'
|
||||||
$(Q)mkdir -p $(DESTDIR)$(INCLUDEDIR)
|
$(Q)mkdir -p $(DESTDIR)$(INCLUDEDIR)
|
||||||
$(DESTDIR)$(MANDIR):
|
$(DESTDIR)$(MANDIR):
|
||||||
@echo '[01;35m DIR > [01;37m$(MANDIR)[00m'
|
@echo ' DIR > $(MANDIR)'
|
||||||
$(Q)mkdir -p $(DESTDIR)$(MANDIR)
|
$(Q)mkdir -p $(DESTDIR)$(MANDIR)
|
||||||
install: subdirs.install libipc.install src/ipc.h.install man/libipc.7.install libipc.so.install libipc.a.install src/client.o.install src/communication.o.install src/logger.o.install src/message.o.install src/usocket.o.install src/utils.o.install src/client.o.install src/communication.o.install src/logger.o.install src/message.o.install src/usocket.o.install src/utils.o.install
|
install: subdirs.install libipc.install src/ipc.h.install man/libipc.7.install libipc.so.install libipc.a.install src/communication.o.install src/error.o.install src/logger.o.install src/message.o.install src/usocket.o.install src/utils.o.install src/communication.o.install src/error.o.install src/logger.o.install src/message.o.install src/usocket.o.install src/utils.o.install
|
||||||
@:
|
@:
|
||||||
|
|
||||||
subdirs.install:
|
subdirs.install:
|
||||||
|
|
||||||
uninstall: subdirs.uninstall libipc.uninstall src/ipc.h.uninstall man/libipc.7.uninstall libipc.so.uninstall libipc.a.uninstall src/client.o.uninstall src/communication.o.uninstall src/logger.o.uninstall src/message.o.uninstall src/usocket.o.uninstall src/utils.o.uninstall src/client.o.uninstall src/communication.o.uninstall src/logger.o.uninstall src/message.o.uninstall src/usocket.o.uninstall src/utils.o.uninstall
|
uninstall: subdirs.uninstall libipc.uninstall src/ipc.h.uninstall man/libipc.7.uninstall libipc.so.uninstall libipc.a.uninstall src/communication.o.uninstall src/error.o.uninstall src/logger.o.uninstall src/message.o.uninstall src/usocket.o.uninstall src/utils.o.uninstall src/communication.o.uninstall src/error.o.uninstall src/logger.o.uninstall src/message.o.uninstall src/usocket.o.uninstall src/utils.o.uninstall
|
||||||
@:
|
@:
|
||||||
|
|
||||||
subdirs.uninstall:
|
subdirs.uninstall:
|
||||||
@ -208,7 +208,7 @@ test: all subdirs subdirs.test
|
|||||||
|
|
||||||
subdirs.test:
|
subdirs.test:
|
||||||
|
|
||||||
clean: libipc.clean src/ipc.h.clean man/libipc.7.clean libipc.so.clean libipc.a.clean src/client.o.clean src/communication.o.clean src/logger.o.clean src/message.o.clean src/usocket.o.clean src/utils.o.clean src/client.o.clean src/communication.o.clean src/logger.o.clean src/message.o.clean src/usocket.o.clean src/utils.o.clean
|
clean: libipc.clean src/ipc.h.clean man/libipc.7.clean libipc.so.clean libipc.a.clean src/communication.o.clean src/error.o.clean src/logger.o.clean src/message.o.clean src/usocket.o.clean src/utils.o.clean src/communication.o.clean src/error.o.clean src/logger.o.clean src/message.o.clean src/usocket.o.clean src/utils.o.clean
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
|
|
||||||
@ -221,21 +221,18 @@ distdir:
|
|||||||
|
|
||||||
dist-gz: $(PACKAGE)-$(VERSION).tar.gz
|
dist-gz: $(PACKAGE)-$(VERSION).tar.gz
|
||||||
$(PACKAGE)-$(VERSION).tar.gz: distdir
|
$(PACKAGE)-$(VERSION).tar.gz: distdir
|
||||||
@echo '[01;33m TAR > [01;37m$(PACKAGE)-$(VERSION).tar.gz[00m'
|
@echo ' TAR > $(PACKAGE)-$(VERSION).tar.gz'
|
||||||
$(Q)tar czf $(PACKAGE)-$(VERSION).tar.gz \
|
$(Q)tar czf $(PACKAGE)-$(VERSION).tar.gz \
|
||||||
$(PACKAGE)-$(VERSION)/Makefile \
|
$(PACKAGE)-$(VERSION)/Makefile \
|
||||||
$(PACKAGE)-$(VERSION)/project.zsh \
|
$(PACKAGE)-$(VERSION)/project.zsh \
|
||||||
$(PACKAGE)-$(VERSION)/src/error.h \
|
|
||||||
$(PACKAGE)-$(VERSION)/src/ipc.h \
|
$(PACKAGE)-$(VERSION)/src/ipc.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/event.h \
|
|
||||||
$(PACKAGE)-$(VERSION)/man/libipc.7.md \
|
$(PACKAGE)-$(VERSION)/man/libipc.7.md \
|
||||||
$(PACKAGE)-$(VERSION)/src/client.c \
|
|
||||||
$(PACKAGE)-$(VERSION)/src/communication.c \
|
$(PACKAGE)-$(VERSION)/src/communication.c \
|
||||||
|
$(PACKAGE)-$(VERSION)/src/error.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/logger.c \
|
$(PACKAGE)-$(VERSION)/src/logger.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/message.c \
|
$(PACKAGE)-$(VERSION)/src/message.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/usocket.c \
|
$(PACKAGE)-$(VERSION)/src/usocket.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/utils.c \
|
$(PACKAGE)-$(VERSION)/src/utils.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/client.h \
|
|
||||||
$(PACKAGE)-$(VERSION)/src/communication.h \
|
$(PACKAGE)-$(VERSION)/src/communication.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/logger.h \
|
$(PACKAGE)-$(VERSION)/src/logger.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/message.h \
|
$(PACKAGE)-$(VERSION)/src/message.h \
|
||||||
@ -244,21 +241,18 @@ $(PACKAGE)-$(VERSION).tar.gz: distdir
|
|||||||
|
|
||||||
dist-xz: $(PACKAGE)-$(VERSION).tar.xz
|
dist-xz: $(PACKAGE)-$(VERSION).tar.xz
|
||||||
$(PACKAGE)-$(VERSION).tar.xz: distdir
|
$(PACKAGE)-$(VERSION).tar.xz: distdir
|
||||||
@echo '[01;33m TAR > [01;37m$(PACKAGE)-$(VERSION).tar.xz[00m'
|
@echo ' TAR > $(PACKAGE)-$(VERSION).tar.xz'
|
||||||
$(Q)tar cJf $(PACKAGE)-$(VERSION).tar.xz \
|
$(Q)tar cJf $(PACKAGE)-$(VERSION).tar.xz \
|
||||||
$(PACKAGE)-$(VERSION)/Makefile \
|
$(PACKAGE)-$(VERSION)/Makefile \
|
||||||
$(PACKAGE)-$(VERSION)/project.zsh \
|
$(PACKAGE)-$(VERSION)/project.zsh \
|
||||||
$(PACKAGE)-$(VERSION)/src/error.h \
|
|
||||||
$(PACKAGE)-$(VERSION)/src/ipc.h \
|
$(PACKAGE)-$(VERSION)/src/ipc.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/event.h \
|
|
||||||
$(PACKAGE)-$(VERSION)/man/libipc.7.md \
|
$(PACKAGE)-$(VERSION)/man/libipc.7.md \
|
||||||
$(PACKAGE)-$(VERSION)/src/client.c \
|
|
||||||
$(PACKAGE)-$(VERSION)/src/communication.c \
|
$(PACKAGE)-$(VERSION)/src/communication.c \
|
||||||
|
$(PACKAGE)-$(VERSION)/src/error.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/logger.c \
|
$(PACKAGE)-$(VERSION)/src/logger.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/message.c \
|
$(PACKAGE)-$(VERSION)/src/message.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/usocket.c \
|
$(PACKAGE)-$(VERSION)/src/usocket.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/utils.c \
|
$(PACKAGE)-$(VERSION)/src/utils.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/client.h \
|
|
||||||
$(PACKAGE)-$(VERSION)/src/communication.h \
|
$(PACKAGE)-$(VERSION)/src/communication.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/logger.h \
|
$(PACKAGE)-$(VERSION)/src/logger.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/message.h \
|
$(PACKAGE)-$(VERSION)/src/message.h \
|
||||||
@ -267,21 +261,18 @@ $(PACKAGE)-$(VERSION).tar.xz: distdir
|
|||||||
|
|
||||||
dist-bz2: $(PACKAGE)-$(VERSION).tar.bz2
|
dist-bz2: $(PACKAGE)-$(VERSION).tar.bz2
|
||||||
$(PACKAGE)-$(VERSION).tar.bz2: distdir
|
$(PACKAGE)-$(VERSION).tar.bz2: distdir
|
||||||
@echo '[01;33m TAR > [01;37m$(PACKAGE)-$(VERSION).tar.bz2[00m'
|
@echo ' TAR > $(PACKAGE)-$(VERSION).tar.bz2'
|
||||||
$(Q)tar cjf $(PACKAGE)-$(VERSION).tar.bz2 \
|
$(Q)tar cjf $(PACKAGE)-$(VERSION).tar.bz2 \
|
||||||
$(PACKAGE)-$(VERSION)/Makefile \
|
$(PACKAGE)-$(VERSION)/Makefile \
|
||||||
$(PACKAGE)-$(VERSION)/project.zsh \
|
$(PACKAGE)-$(VERSION)/project.zsh \
|
||||||
$(PACKAGE)-$(VERSION)/src/error.h \
|
|
||||||
$(PACKAGE)-$(VERSION)/src/ipc.h \
|
$(PACKAGE)-$(VERSION)/src/ipc.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/event.h \
|
|
||||||
$(PACKAGE)-$(VERSION)/man/libipc.7.md \
|
$(PACKAGE)-$(VERSION)/man/libipc.7.md \
|
||||||
$(PACKAGE)-$(VERSION)/src/client.c \
|
|
||||||
$(PACKAGE)-$(VERSION)/src/communication.c \
|
$(PACKAGE)-$(VERSION)/src/communication.c \
|
||||||
|
$(PACKAGE)-$(VERSION)/src/error.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/logger.c \
|
$(PACKAGE)-$(VERSION)/src/logger.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/message.c \
|
$(PACKAGE)-$(VERSION)/src/message.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/usocket.c \
|
$(PACKAGE)-$(VERSION)/src/usocket.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/utils.c \
|
$(PACKAGE)-$(VERSION)/src/utils.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/client.h \
|
|
||||||
$(PACKAGE)-$(VERSION)/src/communication.h \
|
$(PACKAGE)-$(VERSION)/src/communication.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/logger.h \
|
$(PACKAGE)-$(VERSION)/src/logger.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/message.h \
|
$(PACKAGE)-$(VERSION)/src/message.h \
|
||||||
@ -289,38 +280,38 @@ $(PACKAGE)-$(VERSION).tar.bz2: distdir
|
|||||||
$(PACKAGE)-$(VERSION)/src/utils.h
|
$(PACKAGE)-$(VERSION)/src/utils.h
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo '[01;37m :: ipc-0.1.0[00m'
|
@echo ' :: ipc-0.1.0'
|
||||||
@echo ''
|
@echo ''
|
||||||
@echo '[01;37mGeneric targets:[00m'
|
@echo 'Generic targets:'
|
||||||
@echo '[00m - [01;32mhelp [37m Prints this help message.[00m'
|
@echo ' - help Prints this help message.'
|
||||||
@echo '[00m - [01;32mall [37m Builds all targets.[00m'
|
@echo ' - all Builds all targets.'
|
||||||
@echo '[00m - [01;32mdist [37m Creates tarballs of the files of the project.[00m'
|
@echo ' - dist Creates tarballs of the files of the project.'
|
||||||
@echo '[00m - [01;32minstall [37m Installs the project.[00m'
|
@echo ' - install Installs the project.'
|
||||||
@echo '[00m - [01;32mclean [37m Removes compiled files.[00m'
|
@echo ' - clean Removes compiled files.'
|
||||||
@echo '[00m - [01;32muninstall [37m Deinstalls the project.[00m'
|
@echo ' - uninstall Deinstalls the project.'
|
||||||
@echo ''
|
@echo ''
|
||||||
@echo '[01;37mCLI-modifiable variables:[00m'
|
@echo 'CLI-modifiable variables:'
|
||||||
@echo ' - [01;34mCC [37m ${CC}[00m'
|
@echo ' - CC ${CC}'
|
||||||
@echo ' - [01;34mCFLAGS [37m ${CFLAGS}[00m'
|
@echo ' - CFLAGS ${CFLAGS}'
|
||||||
@echo ' - [01;34mLDFLAGS [37m ${LDFLAGS}[00m'
|
@echo ' - LDFLAGS ${LDFLAGS}'
|
||||||
@echo ' - [01;34mDESTDIR [37m ${DESTDIR}[00m'
|
@echo ' - DESTDIR ${DESTDIR}'
|
||||||
@echo ' - [01;34mPREFIX [37m ${PREFIX}[00m'
|
@echo ' - PREFIX ${PREFIX}'
|
||||||
@echo ' - [01;34mBINDIR [37m ${BINDIR}[00m'
|
@echo ' - BINDIR ${BINDIR}'
|
||||||
@echo ' - [01;34mLIBDIR [37m ${LIBDIR}[00m'
|
@echo ' - LIBDIR ${LIBDIR}'
|
||||||
@echo ' - [01;34mSHAREDIR [37m ${SHAREDIR}[00m'
|
@echo ' - SHAREDIR ${SHAREDIR}'
|
||||||
@echo ' - [01;34mINCLUDEDIR [37m ${INCLUDEDIR}[00m'
|
@echo ' - INCLUDEDIR ${INCLUDEDIR}'
|
||||||
@echo ' - [01;34mMANDIR [37m ${MANDIR}[00m'
|
@echo ' - MANDIR ${MANDIR}'
|
||||||
@echo ''
|
@echo ''
|
||||||
@echo '[01;37mProject targets: [00m'
|
@echo 'Project targets: '
|
||||||
@echo ' - [01;33mlibipc [37m library[00m'
|
@echo ' - libipc library'
|
||||||
@echo ' - [01;33msrc/ipc.h [37m header[00m'
|
@echo ' - src/ipc.h header'
|
||||||
@echo ' - [01;33mman/libipc.7 [37m man[00m'
|
@echo ' - man/libipc.7 man'
|
||||||
@echo ''
|
@echo ''
|
||||||
@echo '[01;37mMakefile options:[00m'
|
@echo 'Makefile options:'
|
||||||
@echo ' - gnu: false'
|
@echo ' - gnu: false'
|
||||||
@echo ' - colors: true'
|
@echo ' - colors: false'
|
||||||
@echo ''
|
@echo ''
|
||||||
@echo '[01;37mRebuild the Makefile with:[00m'
|
@echo 'Rebuild the Makefile with:'
|
||||||
@echo ' zsh ./build.zsh -c'
|
@echo ' zsh ./build.zsh'
|
||||||
.PHONY: all subdirs clean distclean dist install uninstall help
|
.PHONY: all subdirs clean distclean dist install uninstall help
|
||||||
|
|
||||||
|
14
examples/README.md
Normal file
14
examples/README.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# how to compile
|
||||||
|
|
||||||
|
./build.sh
|
||||||
|
|
||||||
|
# how to launch
|
||||||
|
|
||||||
|
export IPC_RUNDIR=/tmp
|
||||||
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../
|
||||||
|
./pongd
|
||||||
|
|
||||||
|
# in another terminal
|
||||||
|
export IPC_RUNDIR=/tmp
|
||||||
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../
|
||||||
|
./pong
|
13
examples/build.sh
Executable file
13
examples/build.sh
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
nontapmsg() {
|
||||||
|
echo $*
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in *.c
|
||||||
|
do
|
||||||
|
f=`echo $i | sed "s/.c$//"`
|
||||||
|
nontapmsg "compiling $f"
|
||||||
|
# gcc $f.c ./lib/*.o -o $f -I../src -I ./lib/ -L../ -L./lib/ -lipc -Wall -g -Wextra
|
||||||
|
gcc -Wall -g -Wextra $f.c -o $f -I../src -L../ ../src/ipc.h -lipc
|
||||||
|
done
|
166
examples/pong.c
Normal file
166
examples/pong.c
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "../src/ipc.h"
|
||||||
|
|
||||||
|
#define MSG "coucou"
|
||||||
|
#define SERVICE_NAME "pongd"
|
||||||
|
|
||||||
|
#define PRINTERR(ret,msg) {\
|
||||||
|
const char * err = ipc_errors_get (ret);\
|
||||||
|
fprintf(stderr, "error while %s: %s\n", msg, err);\
|
||||||
|
}
|
||||||
|
|
||||||
|
void non_interactive (char *env[])
|
||||||
|
{
|
||||||
|
struct ipc_message m;
|
||||||
|
memset (&m, 0, sizeof (struct ipc_message));
|
||||||
|
struct ipc_connection_info srv;
|
||||||
|
memset (&srv, 0, sizeof (struct ipc_connection_info));
|
||||||
|
|
||||||
|
// index and version should be filled
|
||||||
|
srv.index = 0;
|
||||||
|
srv.version = 0;
|
||||||
|
|
||||||
|
enum ipc_errors ret;
|
||||||
|
|
||||||
|
// init service
|
||||||
|
ret = ipc_connection (env, &srv, SERVICE_NAME);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_err("main", "ipc_application_connection < 0");
|
||||||
|
PRINTERR(ret, "application connection");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("msg to send (%ld): %.*s\n", (ssize_t) strlen(MSG) +1, (int) strlen(MSG), MSG);
|
||||||
|
ret = ipc_message_format_data (&m, MSG, (ssize_t) strlen(MSG) +1);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
PRINTERR(ret, "message format data");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf ("msg to send in the client: ");
|
||||||
|
// ipc_message_print (&m);
|
||||||
|
ret = ipc_write (&srv, &m);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_err("main", "application_write");
|
||||||
|
PRINTERR(ret, "application write");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
ipc_message_empty (&m);
|
||||||
|
|
||||||
|
ret = ipc_read (&srv, &m);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_err("main", "application_read");
|
||||||
|
PRINTERR(ret, "application read");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("msg recv: %s\n", m.payload);
|
||||||
|
ipc_message_empty (&m);
|
||||||
|
|
||||||
|
ret = ipc_close (&srv);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_err("main", "application_close");
|
||||||
|
PRINTERR(ret, "application close");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void interactive (char *env[])
|
||||||
|
{
|
||||||
|
enum ipc_errors ret;
|
||||||
|
struct ipc_connection_info srv;
|
||||||
|
memset (&srv, 0, sizeof (struct ipc_connection_info));
|
||||||
|
|
||||||
|
// index and version should be filled
|
||||||
|
srv.index = 0;
|
||||||
|
srv.version = 0;
|
||||||
|
|
||||||
|
// init service
|
||||||
|
ret = ipc_connection (env, &srv, SERVICE_NAME);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_err ("main", "ipc_application_connection < 0");
|
||||||
|
PRINTERR(ret, "application connection");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ipc_event event;
|
||||||
|
memset (&event, 0, sizeof (struct ipc_event));
|
||||||
|
|
||||||
|
struct ipc_connection_infos services;
|
||||||
|
memset (&services, 0, sizeof (struct ipc_connection_infos));
|
||||||
|
ipc_add (&services, &srv);
|
||||||
|
|
||||||
|
ipc_add_fd (&services, 0); // add STDIN
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
printf ("msg to send: ");
|
||||||
|
fflush (stdout);
|
||||||
|
ret = ipc_wait_event (&services, NULL, &event);
|
||||||
|
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_error("ipc_application_peek_event != 0");
|
||||||
|
PRINTERR(ret, "application peek event");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event.type) {
|
||||||
|
case IPC_EVENT_TYPE_EXTRA_SOCKET:
|
||||||
|
{
|
||||||
|
struct ipc_message *m = event.m;
|
||||||
|
if ( m->length == 0 || strncmp (m->payload, "exit", 4) == 0) {
|
||||||
|
|
||||||
|
ipc_message_empty (m);
|
||||||
|
free (m);
|
||||||
|
|
||||||
|
ipc_connections_free (&services);
|
||||||
|
|
||||||
|
ret = ipc_close (&srv);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_err("main", "application_close < 0");
|
||||||
|
PRINTERR(ret, "application close");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit (EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ipc_write (&srv, m);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_err("main", "application_write < 0");
|
||||||
|
PRINTERR(ret, "application write");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IPC_EVENT_TYPE_MESSAGE:
|
||||||
|
{
|
||||||
|
struct ipc_message *m = event.m;
|
||||||
|
printf ("msg recv: %.*s", m->length, m->payload);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case IPC_EVENT_TYPE_DISCONNECTION:
|
||||||
|
case IPC_EVENT_TYPE_NOT_SET:
|
||||||
|
case IPC_EVENT_TYPE_CONNECTION:
|
||||||
|
case IPC_EVENT_TYPE_ERROR:
|
||||||
|
default :
|
||||||
|
fprintf (stderr, "should not happen, event type %d\n", event.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char *argv[], char *env[])
|
||||||
|
{
|
||||||
|
argc = argc; // warnings
|
||||||
|
argv = argv; // warnings
|
||||||
|
|
||||||
|
if (argc == 1)
|
||||||
|
non_interactive (env);
|
||||||
|
else
|
||||||
|
interactive (env);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
173
examples/pongd.c
Normal file
173
examples/pongd.c
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
#include "../src/ipc.h"
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define PONGD_SERVICE_NAME "pongd"
|
||||||
|
|
||||||
|
#define PRINTERR(ret,msg) {\
|
||||||
|
const char * err = ipc_errors_get (ret);\
|
||||||
|
fprintf(stderr, "error while %s: %s\n", msg, err);\
|
||||||
|
}
|
||||||
|
|
||||||
|
int cpt = 0;
|
||||||
|
|
||||||
|
struct ipc_connection_info *srv = NULL;
|
||||||
|
struct ipc_connection_infos *clients = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
void main_loop ()
|
||||||
|
{
|
||||||
|
enum ipc_errors ret = 0;
|
||||||
|
|
||||||
|
clients = malloc (sizeof (struct ipc_connection_infos));
|
||||||
|
memset(clients, 0, sizeof(struct ipc_connection_infos));
|
||||||
|
|
||||||
|
struct ipc_event event;
|
||||||
|
memset(&event, 0, sizeof (struct ipc_event));
|
||||||
|
event.type = IPC_EVENT_TYPE_NOT_SET;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
// ipc_service_poll_event provides one event at a time
|
||||||
|
// warning: event->m is free'ed if not NULL
|
||||||
|
printf ("before poll\n"); // TODO remove
|
||||||
|
ret = ipc_wait_event (clients, srv, &event);
|
||||||
|
if (ret != IPC_ERROR_NONE && ret != IPC_ERROR_CLOSED_RECIPIENT) {
|
||||||
|
handle_error("ipc_service_poll_event != IPC_ERROR_NONE");
|
||||||
|
PRINTERR(ret,"service poll event");
|
||||||
|
|
||||||
|
// the application will shut down, and close the service
|
||||||
|
ret = ipc_server_close (srv);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_error("ipc_server_close < 0");
|
||||||
|
PRINTERR(ret,"server close");
|
||||||
|
}
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event.type) {
|
||||||
|
case IPC_EVENT_TYPE_CONNECTION:
|
||||||
|
{
|
||||||
|
cpt++;
|
||||||
|
printf ("connection: %d clients connected\n", cpt);
|
||||||
|
printf ("new client has the fd %d\n", (event.origin)->fd);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case IPC_EVENT_TYPE_DISCONNECTION:
|
||||||
|
{
|
||||||
|
cpt--;
|
||||||
|
printf ("disconnection: %d clients remaining\n", cpt);
|
||||||
|
|
||||||
|
// free the ipc_client structure
|
||||||
|
free (event.origin);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case IPC_EVENT_TYPE_MESSAGE:
|
||||||
|
{
|
||||||
|
struct ipc_message *m = event.m;
|
||||||
|
if (m->length > 0) {
|
||||||
|
printf ("message received (type %d): %.*s\n", m->type, m->length, m->payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ipc_write (event.origin, m);
|
||||||
|
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_err( "handle_new_msg", "server_write < 0");
|
||||||
|
PRINTERR(ret,"server write");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case IPC_EVENT_TYPE_ERROR:
|
||||||
|
{
|
||||||
|
fprintf (stderr, "a problem happened with client %d\n"
|
||||||
|
, (event.origin)->fd);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
{
|
||||||
|
fprintf (stderr, "there must be a problem, event not set\n");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// should never go there
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void exit_program(int signal)
|
||||||
|
{
|
||||||
|
printf("Quitting, signal: %d\n", signal);
|
||||||
|
|
||||||
|
// free remaining clients
|
||||||
|
for (int i = 0; i < clients->size ; i++) {
|
||||||
|
struct ipc_connection_info *cli = clients->cinfos[i];
|
||||||
|
if (cli != NULL) {
|
||||||
|
free (cli);
|
||||||
|
}
|
||||||
|
clients->cinfos[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ipc_connections_free (clients);
|
||||||
|
free (clients);
|
||||||
|
|
||||||
|
|
||||||
|
// the application will shut down, and close the service
|
||||||
|
enum ipc_errors ret = ipc_server_close (srv);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_error("ipc_server_close < 0");
|
||||||
|
PRINTERR(ret,"server close");
|
||||||
|
}
|
||||||
|
free (srv);
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* service ping-pong: send back everything sent by the clients
|
||||||
|
* stop the program on SIG{TERM,INT,ALRM,USR{1,2},HUP} signals
|
||||||
|
*/
|
||||||
|
|
||||||
|
int main(int argc, char * argv[], char **env)
|
||||||
|
{
|
||||||
|
argc = argc; // warnings
|
||||||
|
argv = argv; // warnings
|
||||||
|
|
||||||
|
printf ("pid = %d\n", getpid ());
|
||||||
|
|
||||||
|
srv = malloc (sizeof (struct ipc_connection_info));
|
||||||
|
if (srv == NULL) {
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
memset (srv, 0, sizeof (struct ipc_connection_info));
|
||||||
|
srv->type = '\0';
|
||||||
|
srv->index = 0;
|
||||||
|
srv->version = 0;
|
||||||
|
srv->fd = 0;
|
||||||
|
srv->spath = NULL;
|
||||||
|
|
||||||
|
enum ipc_errors ret = ipc_server_init (env, srv, PONGD_SERVICE_NAME);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_error("ipc_server_init != IPC_ERROR_NONE");
|
||||||
|
PRINTERR(ret,"server init");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
printf ("Listening on %s.\n", srv->spath);
|
||||||
|
|
||||||
|
printf("MAIN: server created\n" );
|
||||||
|
|
||||||
|
signal (SIGHUP, exit_program);
|
||||||
|
signal (SIGALRM, exit_program);
|
||||||
|
signal (SIGUSR1, exit_program);
|
||||||
|
signal (SIGUSR2, exit_program);
|
||||||
|
signal (SIGTERM, exit_program);
|
||||||
|
signal (SIGINT, exit_program);
|
||||||
|
|
||||||
|
// the service will loop until the end of time, or a signal
|
||||||
|
main_loop ();
|
||||||
|
|
||||||
|
// main_loop should not return
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
115
man/libipc.7.md
115
man/libipc.7.md
@ -10,18 +10,118 @@ section: 7
|
|||||||
|
|
||||||
libipc - Simple, easy-to-use IPC library
|
libipc - Simple, easy-to-use IPC library
|
||||||
|
|
||||||
# SYNOPSIS
|
|
||||||
|
|
||||||
**`#include <ipc.h>`**
|
|
||||||
|
|
||||||
**`...`**
|
|
||||||
|
|
||||||
# DESCRIPTION
|
# DESCRIPTION
|
||||||
|
|
||||||
**libipc** is a library that provides interprocess communication medium between applications.
|
**libipc** is a library that provides interprocess communication medium between applications.
|
||||||
It provides both client and server code.
|
It provides both client and server code.
|
||||||
|
|
||||||
# USAGE
|
# SYNOPSIS
|
||||||
|
|
||||||
|
**`#include <ipc.h>`**
|
||||||
|
|
||||||
|
## Initialization, exchanges, disconnection
|
||||||
|
|
||||||
|
// server initialization\
|
||||||
|
*enum ipc_errors* **ipc_server_init** (*char* \*\*env , *struct ipc_connection_info* \*srv, *const char* \*sname);\
|
||||||
|
// connection establishement to a server\
|
||||||
|
*enum ipc_errors* **ipc_connection** (*char* \*\*env, *struct ipc_connection_info* \*, *const char* \*);\
|
||||||
|
|
||||||
|
// closing a server\
|
||||||
|
*enum ipc_errors* **ipc_server_close** (*struct ipc_connection_info* \*srv);\
|
||||||
|
// closing a connection\
|
||||||
|
*enum ipc_errors* **ipc_close** (*struct ipc_connection_info* \*p);\
|
||||||
|
*enum ipc_errors* **ipc_accept** (*struct ipc_connection_info* \*srv, *struct ipc_connection_info* \*p);
|
||||||
|
|
||||||
|
*enum ipc_errors* **ipc_read** (*const struct ipc_connection_info* \*, *struct ipc_message* \*m);\
|
||||||
|
*enum ipc_errors* **ipc_write** (*const struct ipc_connection_info* \*, *const struct ipc_message* \*m);\
|
||||||
|
*enum ipc_errors* **ipc_wait_event** (*struct ipc_connection_infos* \*clients, *struct ipc_connection_info* \*srv, *struct ipc_event* \*event);
|
||||||
|
|
||||||
|
|
||||||
|
// store and remove only pointers on allocated structures\
|
||||||
|
*enum ipc_errors* **ipc_add** (*struct ipc_connection_infos* \*cinfos, *struct ipc_connection_info* \*cinfo);\
|
||||||
|
*enum ipc_errors* **ipc_del** (*struct ipc_connection_infos* \*cinfos, *struct ipc_connection_info* \*cinfo);
|
||||||
|
|
||||||
|
// add an arbitrary file descriptor to read\
|
||||||
|
*enum ipc_errors* **ipc_add_fd** (*struct ipc_connection_infos* \*cinfos, *int* fd);
|
||||||
|
|
||||||
|
|
||||||
|
## Message functions
|
||||||
|
|
||||||
|
// create msg structure with a certain payload length (0 for no payload memory allocation)\
|
||||||
|
*enum ipc_errors* **ipc_message_new** (*struct ipc_message* \*\*m, *ssize_t* paylen);\
|
||||||
|
// create msg structure from buffer\
|
||||||
|
*enum ipc_errors* **ipc_message_format_read** (*struct ipc_message* \*m, *const char* \*buf, *ssize_t* msize);\
|
||||||
|
// create buffer from msg structure\
|
||||||
|
*enum ipc_errors* **ipc_message_format_write** (*const struct ipc_message* \*m, *char* \*\*buf, *ssize_t* \*msize);\
|
||||||
|
|
||||||
|
// read a structure msg from fd\
|
||||||
|
*enum ipc_errors* **ipc_message_read** (*int32_t* fd, *struct ipc_message* \*m);\
|
||||||
|
// write a structure msg to fd\
|
||||||
|
*enum ipc_errors* **ipc_message_write** (*int32_t* fd, *const struct ipc_message* \*m);\
|
||||||
|
*enum ipc_errors* **ipc_message_format** (*struct ipc_message* \*m, *char* type, *const char* \*payload, *ssize_t* length);\
|
||||||
|
*enum ipc_errors* **ipc_message_format_data** (*struct ipc_message* \*m, *const char* \*payload, *ssize_t* length);\
|
||||||
|
*enum ipc_errors* **ipc_message_format_server_close** (*struct ipc_message* \*m);\
|
||||||
|
|
||||||
|
*enum ipc_errors* **ipc_message_empty** (*struct ipc_message* \*m);
|
||||||
|
|
||||||
|
|
||||||
|
# STRUCTURES
|
||||||
|
|
||||||
|
struct ipc_connection_info {
|
||||||
|
uint32_t version;
|
||||||
|
uint32_t index;
|
||||||
|
int32_t fd;
|
||||||
|
char type; // may be an arbitrary fd
|
||||||
|
char *spath; // max size: PATH_MAX, used to store unix socket path
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ipc_connection_infos {
|
||||||
|
struct ipc_connection_info ** cinfos;
|
||||||
|
int32_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ipc_message {
|
||||||
|
char type;
|
||||||
|
uint32_t length;
|
||||||
|
char *payload;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ipc_event {
|
||||||
|
enum ipc_event_type type;
|
||||||
|
void* origin; // currently used as an client or service pointer
|
||||||
|
void* m; // message pointer
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# ENUMERATIONS
|
||||||
|
|
||||||
|
enum msg_types {
|
||||||
|
MSG_TYPE_SERVER_CLOSE = 0
|
||||||
|
, MSG_TYPE_ERR
|
||||||
|
, MSG_TYPE_DATA
|
||||||
|
} message_types;
|
||||||
|
|
||||||
|
Function **ipc_wait_event** returns an *event type* structure.\
|
||||||
|
The event may be a (dis)connection, received data or an error.\
|
||||||
|
It also can be *IPC_EVENT_TYPE_EXTRA_SOCKET* since an arbitrary file descriptor can be added to the *ipc_connection_infos* structure with **ipc_add_fd**.
|
||||||
|
|
||||||
|
enum ipc_event_type {
|
||||||
|
IPC_EVENT_TYPE_NOT_SET
|
||||||
|
, IPC_EVENT_TYPE_ERROR
|
||||||
|
, IPC_EVENT_TYPE_EXTRA_SOCKET
|
||||||
|
, IPC_EVENT_TYPE_CONNECTION
|
||||||
|
, IPC_EVENT_TYPE_DISCONNECTION
|
||||||
|
, IPC_EVENT_TYPE_MESSAGE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ipc_errors {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# EXAMPLES
|
||||||
|
|
||||||
|
Examples are available in the */examples* directory.
|
||||||
|
|
||||||
# NOTES
|
# NOTES
|
||||||
|
|
||||||
@ -31,5 +131,4 @@ It provides both client and server code.
|
|||||||
|
|
||||||
- Documentation is currently limited.
|
- Documentation is currently limited.
|
||||||
- Rerouting IPC connexions through other services (for example, through a network bridge service) is currently not possible.
|
- Rerouting IPC connexions through other services (for example, through a network bridge service) is currently not possible.
|
||||||
- Errors management is currently limited, and precise errors cannot be distinguished.
|
|
||||||
|
|
||||||
|
@ -11,5 +11,5 @@ type[src/ipc.h]=header
|
|||||||
|
|
||||||
type[man/libipc.7]=man
|
type[man/libipc.7]=man
|
||||||
|
|
||||||
dist=(Makefile project.zsh src/error.h src/ipc.h src/event.h man/*.md)
|
dist=(Makefile project.zsh src/ipc.h man/*.md)
|
||||||
|
|
||||||
|
108
src/client.c
108
src/client.c
@ -1,108 +0,0 @@
|
|||||||
#include "client.h"
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
struct ipc_client * ipc_server_client_copy (const struct ipc_client *p)
|
|
||||||
{
|
|
||||||
if (p == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
struct ipc_client * copy = malloc (sizeof(struct ipc_client));
|
|
||||||
memset (copy, 0, sizeof (struct ipc_client));
|
|
||||||
memcpy (copy, p, sizeof (struct ipc_client));
|
|
||||||
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ipc_server_client_eq (const struct ipc_client *p1, const struct ipc_client *p2)
|
|
||||||
{
|
|
||||||
return (p1->version == p2->version && p1->index == p2->index
|
|
||||||
&& p1->proc_fd == p2->proc_fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ipc_server_client_gen (struct ipc_client *p
|
|
||||||
, uint32_t index, uint32_t version)
|
|
||||||
{
|
|
||||||
p->version = version;
|
|
||||||
p->index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ipc_clients_add (struct ipc_clients *clients, struct ipc_client *p)
|
|
||||||
{
|
|
||||||
assert(clients != NULL);
|
|
||||||
assert(p != NULL);
|
|
||||||
|
|
||||||
clients->size++;
|
|
||||||
clients->clients = realloc(clients->clients
|
|
||||||
, sizeof(struct ipc_client) * clients->size);
|
|
||||||
|
|
||||||
if (clients->clients == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
clients->clients[clients->size - 1] = p;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ipc_clients_del (struct ipc_clients *clients, struct ipc_client *p)
|
|
||||||
{
|
|
||||||
assert(clients != NULL);
|
|
||||||
assert(p != NULL);
|
|
||||||
|
|
||||||
if (clients->clients == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t i;
|
|
||||||
for (i = 0; i < clients->size; i++) {
|
|
||||||
if (clients->clients[i] == p) {
|
|
||||||
clients->clients[i] = clients->clients[clients->size-1];
|
|
||||||
clients->size--;
|
|
||||||
if (clients->size == 0) {
|
|
||||||
ipc_clients_free (clients);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
clients->clients = realloc(clients->clients
|
|
||||||
, sizeof(struct ipc_client) * clients->size);
|
|
||||||
|
|
||||||
if (clients->clients == NULL) {
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
void client_print (struct ipc_client *p)
|
|
||||||
{
|
|
||||||
if (p != NULL)
|
|
||||||
printf ("client %d : index %d, version %d\n"
|
|
||||||
, p->proc_fd, p->index, p->version);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ipc_clients_print (struct ipc_clients *ap)
|
|
||||||
{
|
|
||||||
int32_t i;
|
|
||||||
for (i = 0; i < ap->size; i++) {
|
|
||||||
printf("%d : ", i);
|
|
||||||
client_print(ap->clients[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ipc_clients_free (struct ipc_clients *ap)
|
|
||||||
{
|
|
||||||
if (ap->clients != NULL) {
|
|
||||||
free (ap->clients);
|
|
||||||
ap->clients = NULL;
|
|
||||||
}
|
|
||||||
ap->size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
10
src/client.h
10
src/client.h
@ -1,10 +0,0 @@
|
|||||||
#ifndef __IPC_CLIENT_H__
|
|
||||||
#define __IPC_CLIENT_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "ipc.h"
|
|
||||||
|
|
||||||
void ipc_clients_print (struct ipc_clients *);
|
|
||||||
void client_print (struct ipc_client *);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,309 +1,227 @@
|
|||||||
#include "communication.h"
|
#include "ipc.h"
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "error.h"
|
|
||||||
#include "event.h"
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h> // error numbers
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// print structures
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
|
||||||
void service_path (char *path, const char *sname, int32_t index, int32_t version)
|
void service_path (char *path, const char *sname, int32_t index, int32_t version)
|
||||||
{
|
{
|
||||||
assert (path != NULL);
|
assert (path != NULL);
|
||||||
assert (sname != NULL);
|
assert (sname != NULL);
|
||||||
|
|
||||||
memset (path, 0, PATH_MAX);
|
memset (path, 0, PATH_MAX);
|
||||||
snprintf (path, PATH_MAX, "%s/%s-%d-%d", RUNDIR, sname, index, version);
|
|
||||||
|
char * rundir = getenv ("IPC_RUNDIR");
|
||||||
|
if (rundir == NULL)
|
||||||
|
rundir = RUNDIR;
|
||||||
|
|
||||||
|
snprintf (path, PATH_MAX, "%s/%s-%d-%d", rundir, sname, index, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ipc_server_init (char **env
|
/*calculer le max filedescriptor*/
|
||||||
, struct ipc_service *srv, const char *sname)
|
static int32_t get_max_fd (struct ipc_connection_infos *cinfos)
|
||||||
{
|
{
|
||||||
|
int32_t i;
|
||||||
|
int32_t max = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < cinfos->size; i++ ) {
|
||||||
|
if (cinfos->cinfos[i]->fd > max) {
|
||||||
|
max = cinfos->cinfos[i]->fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ipc_errors ipc_server_init (char **env, struct ipc_connection_info *srv, const char *sname)
|
||||||
|
{
|
||||||
|
if (env == NULL)
|
||||||
|
return IPC_ERROR_SERVER_INIT__NO_ENVIRONMENT_PARAM;
|
||||||
|
|
||||||
if (srv == NULL)
|
if (srv == NULL)
|
||||||
return IPC_ERROR_WRONG_PARAMETERS;
|
return IPC_ERROR_SERVER_INIT__NO_SERVICE_PARAM;
|
||||||
|
|
||||||
// TODO
|
if (sname == NULL)
|
||||||
// use env parameters
|
return IPC_ERROR_SERVER_INIT__NO_SERVER_NAME_PARAM;
|
||||||
// it will be useful to change some parameters transparently
|
|
||||||
// ex: to get resources from other machines, choosing the
|
|
||||||
// remote with environment variables
|
|
||||||
|
|
||||||
|
// TODO: loop over environment variables
|
||||||
|
// any IPC_NETWORK_* should be shared with the network service
|
||||||
|
// in order to route requests over any chosen protocol stack
|
||||||
|
// ex: IPC_NETWORK_AUDIO="tor://some.example.com/"
|
||||||
env = env;
|
env = env;
|
||||||
|
|
||||||
// gets the service path
|
// gets the service path
|
||||||
service_path (srv->spath, sname, srv->index, srv->version);
|
char buf [PATH_MAX];
|
||||||
|
memset (buf, 0, PATH_MAX);
|
||||||
|
service_path (buf, sname, srv->index, srv->version);
|
||||||
|
|
||||||
int32_t ret = usock_init (&srv->service_fd, srv->spath);
|
// gets the service path
|
||||||
if (ret < 0) {
|
if (srv->spath != NULL) {
|
||||||
handle_err ("ipc_server_init", "usock_init ret < 0");
|
free (srv->spath);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
size_t s = strlen (buf);
|
||||||
}
|
srv->spath = malloc (s+1);
|
||||||
|
if (srv->spath == NULL) {
|
||||||
|
return IPC_ERROR_SERVER_INIT__MALLOC;
|
||||||
|
}
|
||||||
|
memcpy (srv->spath, buf, s);
|
||||||
|
srv->spath[s] = '\0'; // to be sure
|
||||||
|
|
||||||
int32_t ipc_server_accept (struct ipc_service *srv, struct ipc_client *p)
|
enum ipc_errors ret = usock_init (&srv->fd, srv->spath);
|
||||||
{
|
if (ret != IPC_ERROR_NONE) {
|
||||||
assert (srv != NULL);
|
handle_err ("ipc_server_init", "usock_init");
|
||||||
assert (p != NULL);
|
return ret;
|
||||||
|
|
||||||
int32_t ret = usock_accept (srv->service_fd, &p->proc_fd);
|
|
||||||
if (ret < 0) {
|
|
||||||
handle_err ("ipc_server_accept", "usock_accept < 0");
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// empty the srv structure
|
enum ipc_errors ipc_connection (char **env, struct ipc_connection_info *srv, const char *sname)
|
||||||
int32_t ipc_server_close (struct ipc_service *srv)
|
|
||||||
{
|
{
|
||||||
usock_close (srv->service_fd);
|
// TODO: loop over environment variables
|
||||||
int32_t ret = usock_remove (srv->spath);
|
// any IPC_NETWORK_* should be shared with the network service
|
||||||
ipc_service_empty (srv);
|
// in order to route requests over any chosen protocol stack
|
||||||
return ret;
|
// ex: IPC_NETWORK_AUDIO="tor://some.example.com/"
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ipc_server_close_client (struct ipc_client *p)
|
|
||||||
{
|
|
||||||
return usock_close (p->proc_fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ipc_server_read (const struct ipc_client *p, struct ipc_message *m)
|
|
||||||
{
|
|
||||||
return ipc_message_read (p->proc_fd, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ipc_server_write (const struct ipc_client *p, const struct ipc_message *m)
|
|
||||||
{
|
|
||||||
return ipc_message_write (p->proc_fd, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ipc_application_connection (char **env
|
|
||||||
, struct ipc_service *srv, const char *sname)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
// use env parameters
|
|
||||||
// it will be useful to change some parameters transparently
|
|
||||||
// ex: to get resources from other machines, choosing the
|
|
||||||
// remote with environment variables
|
|
||||||
|
|
||||||
env = env;
|
env = env;
|
||||||
|
if (env == NULL)
|
||||||
|
return IPC_ERROR_CONNECTION__NO_ENVIRONMENT_PARAM;
|
||||||
|
|
||||||
assert (srv != NULL);
|
assert (srv != NULL);
|
||||||
assert (sname != NULL);
|
assert (sname != NULL);
|
||||||
|
|
||||||
if (srv == NULL) {
|
if (srv == NULL) {
|
||||||
return -1;
|
return IPC_ERROR_CONNECTION__NO_SERVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sname == NULL) {
|
||||||
|
return IPC_ERROR_CONNECTION__NO_SERVICE_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
// gets the service path
|
// gets the service path
|
||||||
service_path (srv->spath, sname, srv->index, srv->version);
|
char buf [PATH_MAX];
|
||||||
|
memset (buf, 0, PATH_MAX);
|
||||||
|
service_path (buf, sname, srv->index, srv->version);
|
||||||
|
|
||||||
int32_t ret = usock_connect (&srv->service_fd, srv->spath);
|
enum ipc_errors ret = usock_connect (&srv->fd, buf);
|
||||||
if (ret < 0) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_err ("ipc_application_connection", "usock_connect ret <= 0");
|
handle_err ("ipc_connection", "usock_connect ret");
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// close the socket
|
enum ipc_errors ipc_server_close (struct ipc_connection_info *srv)
|
||||||
int32_t ipc_application_close (struct ipc_service *srv)
|
|
||||||
{
|
{
|
||||||
return usock_close (srv->service_fd);
|
usock_close (srv->fd);
|
||||||
|
enum ipc_errors ret = usock_remove (srv->spath);
|
||||||
|
if (srv->spath != NULL) {
|
||||||
|
free (srv->spath);
|
||||||
|
srv->spath = NULL;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ipc_application_read (struct ipc_service *srv, struct ipc_message *m)
|
enum ipc_errors ipc_close (struct ipc_connection_info *p)
|
||||||
{
|
|
||||||
return ipc_message_read (srv->service_fd, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ipc_application_write (struct ipc_service *srv, const struct ipc_message *m)
|
|
||||||
{
|
{
|
||||||
return ipc_message_write (srv->service_fd, m);
|
return usock_close (p->fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ipc_errors ipc_accept (struct ipc_connection_info *srv, struct ipc_connection_info *p)
|
||||||
/*calculer le max filedescriptor*/
|
|
||||||
static int32_t get_max_fd_from_ipc_clients_ (struct ipc_clients *clients)
|
|
||||||
{
|
{
|
||||||
int32_t i;
|
assert (srv != NULL);
|
||||||
int32_t max = 0;
|
assert (p != NULL);
|
||||||
|
|
||||||
for (i = 0; i < clients->size; i++ ) {
|
if (srv == NULL) {
|
||||||
if (clients->clients[i]->proc_fd > max) {
|
return IPC_ERROR_ACCEPT__NO_SERVICE_PARAM;
|
||||||
max = clients->clients[i]->proc_fd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t get_max_fd_from_ipc_services_ (struct ipc_services *services)
|
|
||||||
{
|
|
||||||
int32_t i;
|
|
||||||
int32_t max = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < services->size; i++ ) {
|
|
||||||
if (services->services[i]->service_fd > max) {
|
|
||||||
max = services->services[i]->service_fd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ipc_server_select prend en parametre
|
|
||||||
* * un tableau de client qu'on écoute
|
|
||||||
* * le service qui attend de nouvelles connexions
|
|
||||||
* * un tableau de client qui souhaitent parler
|
|
||||||
*
|
|
||||||
* 0 = OK
|
|
||||||
* -1 = error
|
|
||||||
*/
|
|
||||||
|
|
||||||
int32_t ipc_server_select (struct ipc_clients *clients, struct ipc_service *srv
|
|
||||||
, struct ipc_clients *active_clients, int32_t *new_connection)
|
|
||||||
{
|
|
||||||
*new_connection = 0;
|
|
||||||
assert (clients != NULL);
|
|
||||||
assert (active_clients != NULL);
|
|
||||||
|
|
||||||
// delete previous read active_clients array
|
|
||||||
ipc_clients_free (active_clients);
|
|
||||||
|
|
||||||
int32_t i, j;
|
|
||||||
/* master file descriptor list */
|
|
||||||
fd_set master;
|
|
||||||
fd_set readf;
|
|
||||||
|
|
||||||
/* maximum file descriptor number */
|
|
||||||
int32_t fdmax;
|
|
||||||
/* listening socket descriptor */
|
|
||||||
int32_t listener = srv->service_fd;
|
|
||||||
|
|
||||||
/* clear the master and temp sets */
|
|
||||||
FD_ZERO(&master);
|
|
||||||
FD_ZERO(&readf);
|
|
||||||
/* add the listener to the master set */
|
|
||||||
FD_SET(listener, &master);
|
|
||||||
|
|
||||||
for (i=0; i < clients->size; i++) {
|
|
||||||
FD_SET(clients->clients[i]->proc_fd, &master);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* keep track of the biggest file descriptor */
|
|
||||||
fdmax = get_max_fd_from_ipc_clients_ (clients) > srv->service_fd ? get_max_fd_from_ipc_clients_ (clients) : srv->service_fd;
|
|
||||||
|
|
||||||
readf = master;
|
|
||||||
if(select(fdmax+1, &readf, NULL, NULL, NULL) == -1) {
|
|
||||||
perror("select");
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i <= fdmax; i++) {
|
if (p == NULL) {
|
||||||
if (FD_ISSET(i, &readf)) {
|
return IPC_ERROR_ACCEPT__NO_CLIENT_PARAM;
|
||||||
if (i == listener) {
|
|
||||||
*new_connection = 1;
|
|
||||||
} else {
|
|
||||||
for(j = 0; j < clients->size; j++) {
|
|
||||||
if(i == clients->clients[j]->proc_fd ) {
|
|
||||||
ipc_clients_add (active_clients, clients->clients[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
enum ipc_errors ret = usock_accept (srv->fd, &p->fd);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_err ("ipc_accept", "usock_accept");
|
||||||
|
return IPC_ERROR_ACCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
enum ipc_errors ipc_read (const struct ipc_connection_info *p, struct ipc_message *m)
|
||||||
* ipc_application_select prend en parametre
|
|
||||||
* * un tableau de server qu'on écoute
|
|
||||||
* * le service qui attend de nouvelles connexions
|
|
||||||
* * un tableau de client qui souhaitent parler
|
|
||||||
*
|
|
||||||
* 0 = OK
|
|
||||||
* -1 = error
|
|
||||||
*/
|
|
||||||
|
|
||||||
int32_t ipc_application_select (struct ipc_services *services, struct ipc_services *active_services)
|
|
||||||
{
|
{
|
||||||
assert (services != NULL);
|
return ipc_message_read (p->fd, m);
|
||||||
assert (active_services != NULL);
|
|
||||||
|
|
||||||
// delete previous read active_services array
|
|
||||||
ipc_services_free (active_services);
|
|
||||||
|
|
||||||
int32_t i, j;
|
|
||||||
/* master file descriptor list */
|
|
||||||
fd_set master;
|
|
||||||
fd_set readf;
|
|
||||||
|
|
||||||
/* maximum file descriptor number */
|
|
||||||
int32_t fdmax;
|
|
||||||
|
|
||||||
/* clear the master and temp sets */
|
|
||||||
FD_ZERO(&master);
|
|
||||||
FD_ZERO(&readf);
|
|
||||||
|
|
||||||
for (i=0; i < services->size; i++) {
|
|
||||||
FD_SET(services->services[i]->service_fd, &master);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* keep track of the biggest file descriptor */
|
|
||||||
fdmax = get_max_fd_from_ipc_services_ (services);
|
|
||||||
|
|
||||||
readf = master;
|
|
||||||
if(select(fdmax+1, &readf, NULL, NULL, NULL) == -1) {
|
|
||||||
perror("select");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i <= fdmax; i++) {
|
|
||||||
if (FD_ISSET(i, &readf)) {
|
|
||||||
for(j = 0; j < services->size; j++) {
|
|
||||||
if(i == services->services[j]->service_fd ) {
|
|
||||||
ipc_services_add (active_services, services->services[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t handle_new_connection (struct ipc_service *srv
|
enum ipc_errors ipc_write (const struct ipc_connection_info *p, const struct ipc_message *m)
|
||||||
, struct ipc_clients *clients
|
|
||||||
, struct ipc_client **new_client)
|
|
||||||
{
|
{
|
||||||
*new_client = malloc(sizeof(struct ipc_client));
|
return ipc_message_write (p->fd, m);
|
||||||
memset(*new_client, 0, sizeof(struct ipc_client));
|
|
||||||
|
|
||||||
if (ipc_server_accept (srv, *new_client) < 0) {
|
|
||||||
handle_error("server_accept < 0");
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
// printf("new connection\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipc_clients_add (clients, *new_client) < 0) {
|
|
||||||
handle_error("ipc_clients_add < 0");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ipc_service_poll_event (struct ipc_clients *clients, struct ipc_service *srv
|
enum ipc_errors handle_new_connection (struct ipc_connection_info *cinfo
|
||||||
|
, struct ipc_connection_infos *cinfos
|
||||||
|
, struct ipc_connection_info **new_client)
|
||||||
|
{
|
||||||
|
if (cinfo == NULL) {
|
||||||
|
return IPC_ERROR_HANDLE_NEW_CONNECTION__NO_CINFO_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cinfos == NULL) {
|
||||||
|
return IPC_ERROR_HANDLE_NEW_CONNECTION__NO_CINFOS_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
*new_client = malloc(sizeof(struct ipc_connection_info));
|
||||||
|
if (*new_client == NULL) {
|
||||||
|
return IPC_ERROR_HANDLE_NEW_CONNECTION__MALLOC;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(*new_client, 0, sizeof(struct ipc_connection_info));
|
||||||
|
|
||||||
|
enum ipc_errors ret = ipc_accept (cinfo, *new_client);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_error("server_accept error");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ipc_add (cinfos, *new_client);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_error("ipc_clients_add error");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IPC_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: should replace
|
||||||
|
// ipc_service_poll_event
|
||||||
|
// ipc_application_poll_event
|
||||||
|
// ipc_application_peek_event
|
||||||
|
// ipc_application_poll_event_
|
||||||
|
enum ipc_errors ipc_wait_event (struct ipc_connection_infos *cinfos
|
||||||
|
, struct ipc_connection_info *cinfo // NULL for clients
|
||||||
, struct ipc_event *event)
|
, struct ipc_event *event)
|
||||||
{
|
{
|
||||||
assert (clients != NULL);
|
assert (cinfos != NULL);
|
||||||
|
|
||||||
|
if (cinfos == NULL) {
|
||||||
|
return IPC_ERROR_WAIT_EVENT__NO_CLIENTS_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event == NULL) {
|
||||||
|
return IPC_ERROR_WAIT_EVENT__NO_EVENT_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
IPC_EVENT_CLEAN(event);
|
IPC_EVENT_CLEAN(event);
|
||||||
|
|
||||||
@ -312,44 +230,55 @@ int32_t ipc_service_poll_event (struct ipc_clients *clients, struct ipc_service
|
|||||||
fd_set master;
|
fd_set master;
|
||||||
fd_set readf;
|
fd_set readf;
|
||||||
|
|
||||||
/* maximum file descriptor number */
|
|
||||||
int32_t fdmax;
|
|
||||||
/* listening socket descriptor */
|
|
||||||
int32_t listener = srv->service_fd;
|
|
||||||
|
|
||||||
/* clear the master and temp sets */
|
/* clear the master and temp sets */
|
||||||
FD_ZERO(&master);
|
FD_ZERO(&master);
|
||||||
FD_ZERO(&readf);
|
FD_ZERO(&readf);
|
||||||
/* add the listener to the master set */
|
|
||||||
FD_SET(listener, &master);
|
|
||||||
|
|
||||||
for (i=0; i < clients->size; i++) {
|
|
||||||
FD_SET(clients->clients[i]->proc_fd, &master);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* maximum file descriptor number */
|
||||||
/* keep track of the biggest file descriptor */
|
/* keep track of the biggest file descriptor */
|
||||||
fdmax = get_max_fd_from_ipc_clients_ (clients) > srv->service_fd ? get_max_fd_from_ipc_clients_ (clients) : srv->service_fd;
|
int32_t fdmax = get_max_fd (cinfos);
|
||||||
|
|
||||||
|
/* listening socket descriptor */
|
||||||
|
int32_t listener;
|
||||||
|
if (cinfo != NULL) {
|
||||||
|
listener = cinfo->fd;
|
||||||
|
|
||||||
|
/* add the listener to the master set */
|
||||||
|
FD_SET(listener, &master);
|
||||||
|
|
||||||
|
// if listener is max fd
|
||||||
|
if (fdmax < listener)
|
||||||
|
fdmax = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < cinfos->size; i++) {
|
||||||
|
FD_SET(cinfos->cinfos[i]->fd, &master);
|
||||||
|
}
|
||||||
|
|
||||||
readf = master;
|
readf = master;
|
||||||
if(select(fdmax+1, &readf, NULL, NULL, NULL) == -1) {
|
if(select(fdmax+1, &readf, NULL, NULL, NULL) == -1) {
|
||||||
perror("select");
|
perror("select");
|
||||||
return -1;
|
return IPC_ERROR_WAIT_EVENT__SELECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i <= fdmax; i++) {
|
for (i = 0; i <= fdmax; i++) {
|
||||||
if (FD_ISSET(i, &readf)) {
|
if (FD_ISSET(i, &readf)) {
|
||||||
if (i == listener) {
|
if (cinfo != NULL && i == listener) {
|
||||||
// connection
|
// connection
|
||||||
struct ipc_client *new_client = NULL;
|
struct ipc_connection_info *new_client = NULL;
|
||||||
handle_new_connection (srv, clients, &new_client);
|
enum ipc_errors ret = handle_new_connection (cinfo, cinfos, &new_client);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
// TODO: quit the program
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_CONNECTION, NULL, new_client);
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_CONNECTION, NULL, new_client);
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
} else {
|
} else {
|
||||||
for(j = 0; j < clients->size; j++) {
|
for(j = 0; j < cinfos->size; j++) {
|
||||||
if(i == clients->clients[j]->proc_fd ) {
|
if(i == cinfos->cinfos[j]->fd ) {
|
||||||
// listen to what they have to say (disconnection or message)
|
// listen to what they have to say (disconnection or message)
|
||||||
// then add a client to `event`, the ipc_event structure
|
// then add a client to `event`, the ipc_event structure
|
||||||
int32_t ret = 0;
|
enum ipc_errors ret;
|
||||||
struct ipc_message *m = NULL;
|
struct ipc_message *m = NULL;
|
||||||
m = malloc (sizeof(struct ipc_message));
|
m = malloc (sizeof(struct ipc_message));
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
@ -358,24 +287,27 @@ int32_t ipc_service_poll_event (struct ipc_clients *clients, struct ipc_service
|
|||||||
memset (m, 0, sizeof (struct ipc_message));
|
memset (m, 0, sizeof (struct ipc_message));
|
||||||
|
|
||||||
// current talking client
|
// current talking client
|
||||||
struct ipc_client *pc = clients->clients[j];
|
struct ipc_connection_info *pc = cinfos->cinfos[j];
|
||||||
ret = ipc_server_read (pc, m);
|
ret = ipc_read (pc, m);
|
||||||
if (ret < 0) {
|
if (ret != IPC_ERROR_NONE && ret != IPC_ERROR_CLOSED_RECIPIENT) {
|
||||||
handle_err ("ipc_service_poll_event", "ipc_server_read < 0");
|
handle_err ("ipc_wait_event", "ipc_read");
|
||||||
ipc_message_empty (m);
|
ipc_message_empty (m);
|
||||||
free (m);
|
free (m);
|
||||||
|
|
||||||
IPC_EVENT_SET(event, IPC_EVENT_TYPE_ERROR, NULL, pc);
|
IPC_EVENT_SET(event, IPC_EVENT_TYPE_ERROR, NULL, pc);
|
||||||
return IPC_ERROR_READ;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// disconnection: close the client then delete it from clients
|
// disconnection: close the client then delete it from cinfos
|
||||||
if (ret == 1) {
|
if (ret == IPC_ERROR_CLOSED_RECIPIENT) {
|
||||||
if (ipc_server_close_client (pc) < 0) {
|
ret = ipc_close (pc);
|
||||||
handle_err( "ipc_service_poll_event", "ipc_server_close_client < 0");
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_err( "ipc_wait_event", "ipc_close");
|
||||||
}
|
}
|
||||||
if (ipc_clients_del (clients, pc) < 0) {
|
|
||||||
handle_err( "ipc_service_poll_event", "ipc_clients_del < 0");
|
ret = ipc_del (cinfos, pc);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_err( "ipc_wait_event", "ipc_del");
|
||||||
}
|
}
|
||||||
ipc_message_empty (m);
|
ipc_message_empty (m);
|
||||||
free (m);
|
free (m);
|
||||||
@ -383,131 +315,178 @@ int32_t ipc_service_poll_event (struct ipc_clients *clients, struct ipc_service
|
|||||||
IPC_EVENT_SET(event, IPC_EVENT_TYPE_DISCONNECTION, NULL, pc);
|
IPC_EVENT_SET(event, IPC_EVENT_TYPE_DISCONNECTION, NULL, pc);
|
||||||
|
|
||||||
// warning: do not forget to free the ipc_client structure
|
// warning: do not forget to free the ipc_client structure
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we received a new message from a client
|
// we received a new message
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_MESSAGE, m, pc);
|
// from a client
|
||||||
return 0;
|
if (pc->type == 'a') {
|
||||||
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_EXTRA_SOCKET, m, pc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_MESSAGE, m, pc);
|
||||||
|
}
|
||||||
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ipc_application_poll_event_ (struct ipc_services *services, struct ipc_event *event, int32_t interactive)
|
// store and remove only pointers on allocated structures
|
||||||
|
enum ipc_errors ipc_add (struct ipc_connection_infos *cinfos, struct ipc_connection_info *p)
|
||||||
{
|
{
|
||||||
assert (services != NULL);
|
assert(cinfos != NULL);
|
||||||
|
assert(p != NULL);
|
||||||
|
|
||||||
IPC_EVENT_CLEAN(event);
|
if (cinfos == NULL) {
|
||||||
|
return IPC_ERROR_ADD__NO_PARAM_CLIENTS;
|
||||||
int32_t i, j;
|
|
||||||
/* master file descriptor list */
|
|
||||||
fd_set master;
|
|
||||||
fd_set readf;
|
|
||||||
|
|
||||||
/* maximum file descriptor number */
|
|
||||||
int32_t fdmax;
|
|
||||||
|
|
||||||
/* clear the master and temp sets */
|
|
||||||
FD_ZERO(&master);
|
|
||||||
FD_ZERO(&readf);
|
|
||||||
|
|
||||||
if (interactive) {
|
|
||||||
FD_SET(0, &master);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i < services->size; i++) {
|
|
||||||
FD_SET(services->services[i]->service_fd, &master);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* keep track of the biggest file descriptor */
|
if (p == NULL) {
|
||||||
fdmax = get_max_fd_from_ipc_services_ (services);
|
return IPC_ERROR_ADD__NO_PARAM_CLIENT;
|
||||||
|
}
|
||||||
|
|
||||||
readf = master;
|
cinfos->size++;
|
||||||
if(select(fdmax+1, &readf, NULL, NULL, NULL) == -1) {
|
cinfos->cinfos = realloc(cinfos->cinfos, sizeof(struct ipc_connection_info) * cinfos->size);
|
||||||
perror("select");
|
|
||||||
return -1;
|
if (cinfos->cinfos == NULL) {
|
||||||
|
return IPC_ERROR_ADD__EMPTY_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
cinfos->cinfos[cinfos->size - 1] = p;
|
||||||
|
return IPC_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ipc_errors ipc_del (struct ipc_connection_infos *cinfos, struct ipc_connection_info *p)
|
||||||
|
{
|
||||||
|
assert(cinfos != NULL);
|
||||||
|
assert(p != NULL);
|
||||||
|
|
||||||
|
if (cinfos == NULL) {
|
||||||
|
return IPC_ERROR_DEL__NO_CLIENTS_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == NULL) {
|
||||||
|
return IPC_ERROR_DEL__NO_CLIENT_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cinfos->cinfos == NULL) {
|
||||||
|
return IPC_ERROR_DEL__EMPTY_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t i;
|
||||||
|
for (i = 0; i < cinfos->size; i++) {
|
||||||
|
if (cinfos->cinfos[i] == p) {
|
||||||
|
cinfos->cinfos[i] = cinfos->cinfos[cinfos->size-1];
|
||||||
|
cinfos->size--;
|
||||||
|
if (cinfos->size == 0) {
|
||||||
|
ipc_connections_free (cinfos);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cinfos->cinfos = realloc(cinfos->cinfos, sizeof(struct ipc_connection_info) * cinfos->size);
|
||||||
|
|
||||||
|
if (cinfos->cinfos == NULL) {
|
||||||
|
return IPC_ERROR_DEL__EMPTIED_LIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IPC_ERROR_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IPC_ERROR_DEL__CANNOT_FIND_CLIENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipc_connections_free (struct ipc_connection_infos *cinfos)
|
||||||
|
{
|
||||||
|
if (cinfos->cinfos != NULL) {
|
||||||
|
free (cinfos->cinfos);
|
||||||
|
cinfos->cinfos = NULL;
|
||||||
|
}
|
||||||
|
cinfos->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: should replace ipc_client_server_copy and ipc_server_client_copy
|
||||||
|
struct ipc_connection_info * ipc_connection_copy (const struct ipc_connection_info *p)
|
||||||
|
{
|
||||||
|
if (p == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct ipc_connection_info * copy = malloc (sizeof(struct ipc_connection_info));
|
||||||
|
|
||||||
|
if (copy == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memset (copy, 0, sizeof (struct ipc_connection_info));
|
||||||
|
memcpy (copy, p, sizeof (struct ipc_connection_info));
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: should replace ipc_server_client_eq, ipc_service_eq
|
||||||
|
int8_t ipc_connection_eq (const struct ipc_connection_info *p1, const struct ipc_connection_info *p2)
|
||||||
|
{
|
||||||
|
return (p1->type == p2->type && p1->version == p2->version && p1->index == p2->index && p1->fd == p2->fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the client service structure
|
||||||
|
// TODO: should replace ipc_client_server_gen, ipc_server_client_gen
|
||||||
|
enum ipc_errors ipc_connection_gen (struct ipc_connection_info *cinfo
|
||||||
|
, uint32_t index, uint32_t version, int fd, char type)
|
||||||
|
{
|
||||||
|
if (cinfo == NULL) {
|
||||||
|
return IPC_ERROR_CONNECTION_GEN__NO_CINFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i <= fdmax; i++) {
|
cinfo->type = type;
|
||||||
if (FD_ISSET(i, &readf)) {
|
cinfo->version = version;
|
||||||
|
cinfo->index = index;
|
||||||
|
cinfo->fd = fd;
|
||||||
|
|
||||||
// interactive: input on stdin
|
return IPC_ERROR_NONE;
|
||||||
if (i == 0) {
|
}
|
||||||
// XXX: by default, message type is 0
|
|
||||||
struct ipc_message *m = malloc (sizeof (struct ipc_message));
|
|
||||||
if (m == NULL) {
|
|
||||||
return IPC_ERROR_NOT_ENOUGH_MEMORY;
|
|
||||||
}
|
|
||||||
memset (m, 0, sizeof (struct ipc_message));
|
|
||||||
m->payload = malloc (IPC_MAX_MESSAGE_SIZE);
|
|
||||||
|
|
||||||
m->length = read(0, m->payload , IPC_MAX_MESSAGE_SIZE);
|
// add an arbitrary file descriptor to read
|
||||||
IPC_EVENT_SET(event, IPC_EVENT_TYPE_STDIN, m, NULL);
|
enum ipc_errors ipc_add_fd (struct ipc_connection_infos *cinfos, int fd)
|
||||||
return 0;
|
{
|
||||||
}
|
if (cinfos == NULL) {
|
||||||
|
return IPC_ERROR_ADD_FD__NO_PARAM_CINFOS;
|
||||||
for(j = 0; j < services->size; j++) {
|
|
||||||
if(i == services->services[j]->service_fd ) {
|
|
||||||
// listen to what they have to say (disconnection or message)
|
|
||||||
// then add a client to `event`, the ipc_event structure
|
|
||||||
int32_t ret = 0;
|
|
||||||
struct ipc_message *m = NULL;
|
|
||||||
m = malloc (sizeof(struct ipc_message));
|
|
||||||
if (m == NULL) {
|
|
||||||
return IPC_ERROR_NOT_ENOUGH_MEMORY;
|
|
||||||
}
|
|
||||||
memset (m, 0, sizeof (struct ipc_message));
|
|
||||||
|
|
||||||
// current talking client
|
|
||||||
struct ipc_service *ps = services->services[j];
|
|
||||||
ret = ipc_application_read (ps, m);
|
|
||||||
if (ret < 0) {
|
|
||||||
handle_err ("ipc_application_poll_event", "ipc_application_read < 0");
|
|
||||||
ipc_message_empty (m);
|
|
||||||
free (m);
|
|
||||||
|
|
||||||
IPC_EVENT_SET(event, IPC_EVENT_TYPE_ERROR, NULL, ps);
|
|
||||||
return IPC_ERROR_READ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// disconnection: close the service
|
|
||||||
if (ret == 1) {
|
|
||||||
if (ipc_application_close (ps) < 0) {
|
|
||||||
handle_err( "ipc_application_poll_event", "ipc_application_close < 0");
|
|
||||||
}
|
|
||||||
if (ipc_services_del (services, ps) < 0) {
|
|
||||||
handle_err( "ipc_application_poll_event", "ipc_services_del < 0");
|
|
||||||
}
|
|
||||||
ipc_message_empty (m);
|
|
||||||
free (m);
|
|
||||||
|
|
||||||
IPC_EVENT_SET(event, IPC_EVENT_TYPE_DISCONNECTION, NULL, ps);
|
|
||||||
|
|
||||||
// warning: do not forget to free the ipc_client structure
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we received a new message from a client
|
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_MESSAGE, m, ps);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
struct ipc_connection_info *cinfo;
|
||||||
|
|
||||||
|
enum ipc_errors ret;
|
||||||
|
ret = ipc_connection_gen (cinfo, 0, 0, fd, 'a');
|
||||||
|
|
||||||
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ipc_application_poll_event (struct ipc_services *services, struct ipc_event *event) {
|
void ipc_connection_print (struct ipc_connection_info *cinfo)
|
||||||
return ipc_application_poll_event_ (services, event, 0);
|
{
|
||||||
|
if (cinfo == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("fd %d: index %d, version %d, type %c"
|
||||||
|
, cinfo->fd, cinfo->index, cinfo->version, cinfo->type);
|
||||||
|
|
||||||
|
if (cinfo->spath != NULL) {
|
||||||
|
printf (", path %s\n", cinfo->spath);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ipc_application_peek_event (struct ipc_services *services, struct ipc_event *event) {
|
void ipc_connections_print (struct ipc_connection_infos *cinfos)
|
||||||
return ipc_application_poll_event_ (services, event, 1);
|
{
|
||||||
|
int32_t i;
|
||||||
|
for (i = 0; i < cinfos->size; i++) {
|
||||||
|
printf("[%d] : ", i);
|
||||||
|
ipc_connection_print(cinfos->cinfos[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,4 @@
|
|||||||
#ifndef __IPC_COMMUNICATION_H__
|
#ifndef __IPC_COMMUNICATION_H__
|
||||||
#define __IPC_COMMUNICATION_H__
|
#define __IPC_COMMUNICATION_H__
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h> // error numbers
|
|
||||||
|
|
||||||
|
|
||||||
#include "ipc.h"
|
|
||||||
#include "client.h"
|
|
||||||
#include "event.h"
|
|
||||||
#include "message.h"
|
|
||||||
|
|
||||||
#define IPC_WITH_UNIX_SOCKETS
|
|
||||||
#ifdef IPC_WITH_UNIX_SOCKETS
|
|
||||||
#include "usocket.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
113
src/error.c
Normal file
113
src/error.c
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
#include "ipc.h"
|
||||||
|
|
||||||
|
#define NTAB(t) ((int) (sizeof (t) / sizeof (t)[0]))
|
||||||
|
|
||||||
|
struct ipc_errors_verbose {
|
||||||
|
enum ipc_errors error_code;
|
||||||
|
char * explanation_string;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ipc_errors_verbose ipc_errors_verbose [] = {
|
||||||
|
|
||||||
|
/* general errors */
|
||||||
|
IPC_ERROR_NONE, "no error"
|
||||||
|
, IPC_ERROR_NOT_ENOUGH_MEMORY, "not enough memory"
|
||||||
|
, IPC_ERROR_CLOSED_RECIPIENT, "closed recipient"
|
||||||
|
|
||||||
|
, IPC_ERROR_SERVER_INIT__NO_ENVIRONMENT_PARAM, "ipc_server_init: no environment param"
|
||||||
|
, IPC_ERROR_SERVER_INIT__NO_SERVICE_PARAM, "ipc_server_init: no service param"
|
||||||
|
, IPC_ERROR_SERVER_INIT__NO_SERVER_NAME_PARAM, "ipc_server_init: no server name param"
|
||||||
|
, IPC_ERROR_SERVER_INIT__MALLOC, "ipc_server_init: error on malloc function"
|
||||||
|
|
||||||
|
, IPC_ERROR_CONNECTION__NO_SERVER, "ipc_connection: no server parameter"
|
||||||
|
, IPC_ERROR_CONNECTION__NO_SERVICE_NAME, "ipc_connection: no service name parameter"
|
||||||
|
, IPC_ERROR_CONNECTION__NO_ENVIRONMENT_PARAM, "ipc_connection: no environment param"
|
||||||
|
|
||||||
|
, IPC_ERROR_CONNECTION_GEN__NO_CINFO, "ipc_connection_gen: no cinfo"
|
||||||
|
|
||||||
|
, IPC_ERROR_ACCEPT__NO_SERVICE_PARAM, "ipc_accept: no service param"
|
||||||
|
, IPC_ERROR_ACCEPT__NO_CLIENT_PARAM, "ipc_accept: no client param"
|
||||||
|
, IPC_ERROR_ACCEPT, "ipc_accept: error on accept function"
|
||||||
|
|
||||||
|
, IPC_ERROR_HANDLE_NEW_CONNECTION__NO_CINFO_PARAM, "ipc_handle_new_connection: no cinfo param"
|
||||||
|
, IPC_ERROR_HANDLE_NEW_CONNECTION__NO_CINFOS_PARAM, "ipc_handle_new_connection: no cinfos param"
|
||||||
|
|
||||||
|
, IPC_ERROR_WAIT_EVENT__SELECT, "ipc_wait_event: error on the select function"
|
||||||
|
, IPC_ERROR_WAIT_EVENT__NO_CLIENTS_PARAM, "ipc_wait_event: no clients param"
|
||||||
|
, IPC_ERROR_WAIT_EVENT__NO_EVENT_PARAM, "ipc_wait_event: no event param"
|
||||||
|
|
||||||
|
, IPC_ERROR_HANDLE_NEW_CONNECTION__MALLOC, "ipc_handle_new_connection: error on malloc function"
|
||||||
|
|
||||||
|
, IPC_ERROR_ADD__EMPTY_LIST, "ipc_clients_add: empty list: realloc failed"
|
||||||
|
, IPC_ERROR_ADD__NO_PARAM_CLIENTS, "ipc_clients_add: no param client list"
|
||||||
|
, IPC_ERROR_ADD__NO_PARAM_CLIENT, "ipc_clients_add: no param client"
|
||||||
|
|
||||||
|
, IPC_ERROR_ADD_FD__NO_PARAM_CINFOS, "ipc_add_fd: no cinfos param"
|
||||||
|
|
||||||
|
, IPC_ERROR_DEL__EMPTY_LIST, "ipc_clients_del: empty list"
|
||||||
|
, IPC_ERROR_DEL__EMPTIED_LIST, "ipc_clients_del: cannot realloc"
|
||||||
|
, IPC_ERROR_DEL__CANNOT_FIND_CLIENT, "ipc_clients_del: cannot find client"
|
||||||
|
, IPC_ERROR_DEL__NO_CLIENTS_PARAM, "ipc_clients_del: no clients param"
|
||||||
|
, IPC_ERROR_DEL__NO_CLIENT_PARAM, "ipc_clients_del: no client param"
|
||||||
|
|
||||||
|
|
||||||
|
/* unix socket */
|
||||||
|
|
||||||
|
, IPC_ERROR_USOCK_SEND, "usock_send: cannot send message"
|
||||||
|
|
||||||
|
, IPC_ERROR_USOCK_CONNECT__SOCKET, "usock_connect: error on socket function"
|
||||||
|
, IPC_ERROR_USOCK_CONNECT__WRONG_FILE_DESCRIPTOR, "usock_connect: wrong file descriptor"
|
||||||
|
, IPC_ERROR_USOCK_CONNECT__EMPTY_PATH, "usock_connect: empty path"
|
||||||
|
|
||||||
|
, IPC_ERROR_USOCK_CLOSE, "usock_close: close function"
|
||||||
|
|
||||||
|
, IPC_ERROR_USOCK_REMOVE__UNLINK, "usock_remove: unlink function"
|
||||||
|
, IPC_ERROR_USOCK_REMOVE__NO_FILE, "usock_remove: file not found"
|
||||||
|
|
||||||
|
, IPC_ERROR_USOCK_INIT__EMPTY_FILE_DESCRIPTOR, "usock_init: no file descriptor"
|
||||||
|
, IPC_ERROR_USOCK_INIT__WRONG_FILE_DESCRIPTOR, "usock_init: wrong file descriptor"
|
||||||
|
, IPC_ERROR_USOCK_INIT__EMPTY_PATH, "usock_init: empty path"
|
||||||
|
, IPC_ERROR_USOCK_INIT__BIND, "usock_init: error on bind function"
|
||||||
|
, IPC_ERROR_USOCK_INIT__LISTEN, "usock_init: error on listen function"
|
||||||
|
|
||||||
|
, IPC_ERROR_USOCK_ACCEPT__PATH_FILE_DESCRIPTOR, "ipc_usock_accept: no path file descriptor"
|
||||||
|
, IPC_ERROR_USOCK_ACCEPT, "ipc_usock_accept: error on accept function"
|
||||||
|
|
||||||
|
, IPC_ERROR_USOCK_RECV__NO_BUFFER, "ipc_usock_recv: no buffer in usock_recv"
|
||||||
|
, IPC_ERROR_USOCK_RECV__NO_LENGTH, "ipc_usock_recv: no length in usock_recv"
|
||||||
|
, IPC_ERROR_USOCK_RECV, "ipc_usock_recv: cannot receive message in usock_recv"
|
||||||
|
|
||||||
|
|
||||||
|
/* message function errors */
|
||||||
|
|
||||||
|
, IPC_ERROR_MESSAGE_NEW__NO_MESSAGE_PARAM, "ipc_message_new: no message param"
|
||||||
|
, IPC_ERROR_MESSAGE_READ__NO_MESSAGE_PARAM, "ipc_message_read: no message param"
|
||||||
|
|
||||||
|
, IPC_ERROR_MESSAGE_WRITE__NO_MESSAGE_PARAM, "ipc_message_write: no message param"
|
||||||
|
, IPC_ERROR_MESSAGE_WRITE__NOT_ENOUGH_DATA, "ipc_message_write: no enough data sent"
|
||||||
|
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT__NO_MESSAGE_PARAM, "ipc_message_format: no message param"
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT__INCONSISTENT_PARAMS, "ipc_message_format: inconsistent params"
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT__LENGTH, "ipc_message_format: length param > maximum allowed"
|
||||||
|
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_MESSAGE, "ipc_message_format_write: empty message"
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_MSIZE, "ipc_message_format_write: empty message size"
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_BUFFER, "ipc_message_format_write: empty buffer"
|
||||||
|
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT_READ__EMPTY_MESSAGE, "ipc_message_format_read: empty message"
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT_READ__EMPTY_BUFFER, "ipc_message_format_read: empty buffer"
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT_READ__MESSAGE_SIZE, "ipc_message_format_read: message size > maximum allowed"
|
||||||
|
|
||||||
|
, IPC_ERROR_MESSAGE_EMPTY__EMPTY_MESSAGE_LIST, "ipc_message_empty: empty message list"
|
||||||
|
};
|
||||||
|
|
||||||
|
const char * ipc_errors_get (enum ipc_errors e)
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < NTAB(ipc_errors_verbose) ; i++) {
|
||||||
|
if (ipc_errors_verbose[i].error_code == e) {
|
||||||
|
return ipc_errors_verbose[i].explanation_string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
18
src/error.h
18
src/error.h
@ -1,18 +0,0 @@
|
|||||||
#ifndef __IPC_ERROR_H__
|
|
||||||
#define __IPC_ERROR_H__
|
|
||||||
|
|
||||||
// #define IPC_WITH_ERRORS 3
|
|
||||||
|
|
||||||
#ifdef IPC_WITH_ERRORS
|
|
||||||
#include "logger.h"
|
|
||||||
#define handle_error(msg) \
|
|
||||||
do { log_error (msg); exit(EXIT_FAILURE); } while (0)
|
|
||||||
|
|
||||||
#define handle_err(fun,msg)\
|
|
||||||
do { log_error ("%s: file %s line %d %s", fun, __FILE__, __LINE__, msg); } while (0)
|
|
||||||
#else
|
|
||||||
#define handle_error(msg)
|
|
||||||
#define handle_err(fun,msg)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
22
src/event.h
22
src/event.h
@ -1,22 +0,0 @@
|
|||||||
#ifndef __IPC_EVENT__
|
|
||||||
#define __IPC_EVENT__
|
|
||||||
|
|
||||||
#include "ipc.h"
|
|
||||||
#include "message.h"
|
|
||||||
|
|
||||||
#define IPC_EVENT_SET(pevent,type_,message_,origin_) {\
|
|
||||||
pevent->type = type_; \
|
|
||||||
pevent->m = message_; \
|
|
||||||
pevent->origin = origin_; \
|
|
||||||
};
|
|
||||||
|
|
||||||
#define IPC_EVENT_CLEAN(pevent) {\
|
|
||||||
pevent->type = IPC_EVENT_TYPE_NOT_SET;\
|
|
||||||
if (pevent->m != NULL) {\
|
|
||||||
ipc_message_empty (pevent->m);\
|
|
||||||
free(pevent->m);\
|
|
||||||
pevent->m = NULL;\
|
|
||||||
}\
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
278
src/ipc.h
278
src/ipc.h
@ -28,40 +28,121 @@ enum msg_types {
|
|||||||
enum ipc_event_type {
|
enum ipc_event_type {
|
||||||
IPC_EVENT_TYPE_NOT_SET
|
IPC_EVENT_TYPE_NOT_SET
|
||||||
, IPC_EVENT_TYPE_ERROR
|
, IPC_EVENT_TYPE_ERROR
|
||||||
, IPC_EVENT_TYPE_STDIN
|
|
||||||
|
, IPC_EVENT_TYPE_EXTRA_SOCKET
|
||||||
|
|
||||||
, IPC_EVENT_TYPE_CONNECTION
|
, IPC_EVENT_TYPE_CONNECTION
|
||||||
, IPC_EVENT_TYPE_DISCONNECTION
|
, IPC_EVENT_TYPE_DISCONNECTION
|
||||||
, IPC_EVENT_TYPE_MESSAGE
|
, IPC_EVENT_TYPE_MESSAGE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ipc_errors {
|
enum ipc_errors {
|
||||||
IPC_ERROR_NOT_ENOUGH_MEMORY
|
/* general errors */
|
||||||
, IPC_ERROR_WRONG_PARAMETERS
|
IPC_ERROR_NONE
|
||||||
, IPC_ERROR_READ
|
, IPC_ERROR_NOT_ENOUGH_MEMORY
|
||||||
|
, IPC_ERROR_CLOSED_RECIPIENT
|
||||||
|
|
||||||
|
, IPC_ERROR_SERVER_INIT__NO_ENVIRONMENT_PARAM
|
||||||
|
, IPC_ERROR_SERVER_INIT__NO_SERVICE_PARAM
|
||||||
|
, IPC_ERROR_SERVER_INIT__NO_SERVER_NAME_PARAM
|
||||||
|
, IPC_ERROR_SERVER_INIT__MALLOC
|
||||||
|
|
||||||
|
, IPC_ERROR_CONNECTION__NO_SERVER
|
||||||
|
, IPC_ERROR_CONNECTION__NO_SERVICE_NAME
|
||||||
|
, IPC_ERROR_CONNECTION__NO_ENVIRONMENT_PARAM
|
||||||
|
|
||||||
|
, IPC_ERROR_CONNECTION_GEN__NO_CINFO
|
||||||
|
|
||||||
|
, IPC_ERROR_ACCEPT__NO_SERVICE_PARAM
|
||||||
|
, IPC_ERROR_ACCEPT__NO_CLIENT_PARAM
|
||||||
|
, IPC_ERROR_ACCEPT
|
||||||
|
|
||||||
|
, IPC_ERROR_HANDLE_NEW_CONNECTION__NO_CINFO_PARAM
|
||||||
|
, IPC_ERROR_HANDLE_NEW_CONNECTION__NO_CINFOS_PARAM
|
||||||
|
|
||||||
|
, IPC_ERROR_WAIT_EVENT__SELECT
|
||||||
|
, IPC_ERROR_WAIT_EVENT__NO_CLIENTS_PARAM
|
||||||
|
, IPC_ERROR_WAIT_EVENT__NO_EVENT_PARAM
|
||||||
|
|
||||||
|
, IPC_ERROR_HANDLE_NEW_CONNECTION__MALLOC
|
||||||
|
|
||||||
|
, IPC_ERROR_ADD__EMPTY_LIST
|
||||||
|
, IPC_ERROR_ADD__NO_PARAM_CLIENTS
|
||||||
|
, IPC_ERROR_ADD__NO_PARAM_CLIENT
|
||||||
|
|
||||||
|
, IPC_ERROR_ADD_FD__NO_PARAM_CINFOS
|
||||||
|
|
||||||
|
, IPC_ERROR_DEL__EMPTY_LIST
|
||||||
|
, IPC_ERROR_DEL__EMPTIED_LIST
|
||||||
|
, IPC_ERROR_DEL__CANNOT_FIND_CLIENT
|
||||||
|
, IPC_ERROR_DEL__NO_CLIENTS_PARAM
|
||||||
|
, IPC_ERROR_DEL__NO_CLIENT_PARAM
|
||||||
|
|
||||||
|
|
||||||
|
/* unix socket */
|
||||||
|
|
||||||
|
, IPC_ERROR_USOCK_SEND
|
||||||
|
|
||||||
|
, IPC_ERROR_USOCK_CONNECT__SOCKET
|
||||||
|
, IPC_ERROR_USOCK_CONNECT__WRONG_FILE_DESCRIPTOR
|
||||||
|
, IPC_ERROR_USOCK_CONNECT__EMPTY_PATH
|
||||||
|
|
||||||
|
, IPC_ERROR_USOCK_CLOSE
|
||||||
|
|
||||||
|
, IPC_ERROR_USOCK_REMOVE__UNLINK
|
||||||
|
, IPC_ERROR_USOCK_REMOVE__NO_FILE
|
||||||
|
|
||||||
|
, IPC_ERROR_USOCK_INIT__EMPTY_FILE_DESCRIPTOR
|
||||||
|
, IPC_ERROR_USOCK_INIT__WRONG_FILE_DESCRIPTOR
|
||||||
|
, IPC_ERROR_USOCK_INIT__EMPTY_PATH
|
||||||
|
, IPC_ERROR_USOCK_INIT__BIND
|
||||||
|
, IPC_ERROR_USOCK_INIT__LISTEN
|
||||||
|
|
||||||
|
, IPC_ERROR_USOCK_ACCEPT__PATH_FILE_DESCRIPTOR
|
||||||
|
, IPC_ERROR_USOCK_ACCEPT
|
||||||
|
|
||||||
|
, IPC_ERROR_USOCK_RECV__NO_BUFFER
|
||||||
|
, IPC_ERROR_USOCK_RECV__NO_LENGTH
|
||||||
|
, IPC_ERROR_USOCK_RECV
|
||||||
|
|
||||||
|
|
||||||
|
/* message function errors */
|
||||||
|
|
||||||
|
, IPC_ERROR_MESSAGE_NEW__NO_MESSAGE_PARAM
|
||||||
|
, IPC_ERROR_MESSAGE_READ__NO_MESSAGE_PARAM
|
||||||
|
|
||||||
|
, IPC_ERROR_MESSAGE_WRITE__NO_MESSAGE_PARAM
|
||||||
|
, IPC_ERROR_MESSAGE_WRITE__NOT_ENOUGH_DATA
|
||||||
|
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT__NO_MESSAGE_PARAM
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT__INCONSISTENT_PARAMS
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT__LENGTH
|
||||||
|
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_MESSAGE
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_MSIZE
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_BUFFER
|
||||||
|
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT_READ__EMPTY_MESSAGE
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT_READ__EMPTY_BUFFER
|
||||||
|
, IPC_ERROR_MESSAGE_FORMAT_READ__MESSAGE_SIZE
|
||||||
|
|
||||||
|
, IPC_ERROR_MESSAGE_EMPTY__EMPTY_MESSAGE_LIST
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ipc_service {
|
|
||||||
|
struct ipc_connection_info {
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
char spath[PATH_MAX];
|
int32_t fd;
|
||||||
int32_t service_fd;
|
char type; // server, client, arbitrary fd
|
||||||
|
char *spath; // max size: PATH_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ipc_services {
|
struct ipc_connection_infos {
|
||||||
struct ipc_service ** services;
|
struct ipc_connection_info ** cinfos;
|
||||||
int32_t size;
|
int32_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ipc_client {
|
|
||||||
uint32_t version;
|
|
||||||
uint32_t index;
|
|
||||||
int32_t proc_fd;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ipc_clients {
|
|
||||||
struct ipc_client **clients;
|
|
||||||
int32_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ipc_message {
|
struct ipc_message {
|
||||||
char type;
|
char type;
|
||||||
@ -71,111 +152,122 @@ struct ipc_message {
|
|||||||
|
|
||||||
struct ipc_event {
|
struct ipc_event {
|
||||||
enum ipc_event_type type;
|
enum ipc_event_type type;
|
||||||
void* origin; // currently used as an client or service pointer
|
struct ipc_connection_info *origin;
|
||||||
void* m; // message pointer
|
void* m; // message pointer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
/*
|
* MACROS
|
||||||
* SERVICE
|
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
// srv->version and srv->index must be already set
|
// #define IPC_WITH_ERRORS 3
|
||||||
// init unix socket + fill srv->spath
|
|
||||||
int32_t ipc_server_init (char **env , struct ipc_service *srv, const char *sname);
|
|
||||||
int32_t ipc_server_close (struct ipc_service *srv);
|
|
||||||
int32_t ipc_server_close_client (struct ipc_client *p);
|
|
||||||
int32_t ipc_server_accept (struct ipc_service *srv, struct ipc_client *p);
|
|
||||||
|
|
||||||
// 1 on a recipient socket close
|
#ifdef IPC_WITH_ERRORS
|
||||||
int32_t ipc_server_read (const struct ipc_client *, struct ipc_message *m);
|
#include "logger.h"
|
||||||
int32_t ipc_server_write (const struct ipc_client *, const struct ipc_message *m);
|
#define handle_error(msg) \
|
||||||
|
do { log_error (msg); exit(EXIT_FAILURE); } while (0)
|
||||||
|
|
||||||
int32_t ipc_server_select (struct ipc_clients * clients, struct ipc_service *srv
|
#define handle_err(fun,msg)\
|
||||||
, struct ipc_clients *active_clients, int32_t *new_connection);
|
do { log_error ("%s: file %s line %d %s", fun, __FILE__, __LINE__, msg); } while (0)
|
||||||
|
#else
|
||||||
|
#define handle_error(msg)
|
||||||
|
#define handle_err(fun,msg)
|
||||||
|
#endif
|
||||||
|
|
||||||
int32_t ipc_service_poll_event (struct ipc_clients *clients, struct ipc_service *srv
|
#define IPC_EVENT_SET(pevent,type_,message_,origin_) {\
|
||||||
, struct ipc_event *event);
|
pevent->type = type_; \
|
||||||
|
pevent->m = message_; \
|
||||||
|
pevent->origin = origin_; \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define IPC_EVENT_CLEAN(pevent) {\
|
||||||
|
pevent->type = IPC_EVENT_TYPE_NOT_SET;\
|
||||||
|
if (pevent->m != NULL) {\
|
||||||
|
ipc_message_empty (pevent->m);\
|
||||||
|
free(pevent->m);\
|
||||||
|
pevent->m = NULL;\
|
||||||
|
}\
|
||||||
|
};
|
||||||
|
|
||||||
|
#define IPC_WITH_UNIX_SOCKETS
|
||||||
|
#ifdef IPC_WITH_UNIX_SOCKETS
|
||||||
|
#include "usocket.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define LOG
|
||||||
|
|
||||||
|
void log_error (const char* message, ...);
|
||||||
|
void log_info (const char* message, ...);
|
||||||
|
void log_debug (const char* message, ...);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SERVICES
|
* main public functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
enum ipc_errors ipc_server_init (char **env, struct ipc_connection_info *srv, const char *sname);
|
||||||
|
enum ipc_errors ipc_connection (char **env, struct ipc_connection_info *srv, const char *sname);
|
||||||
|
|
||||||
|
enum ipc_errors ipc_server_close (struct ipc_connection_info *srv);
|
||||||
|
enum ipc_errors ipc_close (struct ipc_connection_info *p);
|
||||||
|
enum ipc_errors ipc_accept (struct ipc_connection_info *srv, struct ipc_connection_info *p);
|
||||||
|
|
||||||
|
enum ipc_errors ipc_read (const struct ipc_connection_info *, struct ipc_message *m);
|
||||||
|
enum ipc_errors ipc_write (const struct ipc_connection_info *, const struct ipc_message *m);
|
||||||
|
|
||||||
|
enum ipc_errors ipc_wait_event (struct ipc_connection_infos *clients
|
||||||
|
, struct ipc_connection_info *srv
|
||||||
|
, struct ipc_event *event);
|
||||||
|
|
||||||
// store and remove only pointers on allocated structures
|
// store and remove only pointers on allocated structures
|
||||||
int32_t ipc_services_add (struct ipc_services *, struct ipc_service *);
|
enum ipc_errors ipc_add (struct ipc_connection_infos *, struct ipc_connection_info *);
|
||||||
int32_t ipc_services_del (struct ipc_services *, struct ipc_service *);
|
enum ipc_errors ipc_del (struct ipc_connection_infos *, struct ipc_connection_info *);
|
||||||
|
|
||||||
void ipc_services_free (struct ipc_services *);
|
// add an arbitrary file descriptor to read
|
||||||
|
enum ipc_errors ipc_add_fd (struct ipc_connection_infos *cinfos, int fd);
|
||||||
|
|
||||||
struct ipc_service * ipc_client_server_copy (const struct ipc_service *p);
|
void ipc_connections_free (struct ipc_connection_infos *);
|
||||||
int32_t ipc_service_eq (const struct ipc_service *p1, const struct ipc_service *p2);
|
|
||||||
|
|
||||||
|
struct ipc_connection_info * ipc_connection_copy (const struct ipc_connection_info *p);
|
||||||
|
int8_t ipc_connection_eq (const struct ipc_connection_info *p1, const struct ipc_connection_info *p2);
|
||||||
// create the client service structure
|
// create the client service structure
|
||||||
void ipc_client_server_gen (struct ipc_service *p, uint32_t index, uint32_t version);
|
enum ipc_errors ipc_connection_gen (struct ipc_connection_info *cinfo
|
||||||
|
, uint32_t index, uint32_t version, int fd, char type);
|
||||||
|
|
||||||
static inline int32_t ipc_service_empty (struct ipc_service *srv) { srv = srv; return 0 ;};
|
void ipc_connection_print (struct ipc_connection_info *cinfo);
|
||||||
|
void ipc_connections_print (struct ipc_connection_infos *cinfos);
|
||||||
|
|
||||||
|
// get explanation about an error
|
||||||
|
const char * ipc_errors_get (enum ipc_errors e);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* APPLICATION
|
* message functions
|
||||||
*
|
|
||||||
**/
|
|
||||||
|
|
||||||
// Initialize connection with unix socket
|
|
||||||
// send the connection string to $TMP/<service>
|
|
||||||
// fill srv->spath && srv->service_fd
|
|
||||||
int32_t ipc_application_connection (char **env, struct ipc_service *, const char *);
|
|
||||||
int32_t ipc_application_close (struct ipc_service *);
|
|
||||||
|
|
||||||
// 1 on a recipient socket close
|
|
||||||
int32_t ipc_application_read (struct ipc_service *srv, struct ipc_message *m);
|
|
||||||
int32_t ipc_application_write (struct ipc_service *, const struct ipc_message *m);
|
|
||||||
|
|
||||||
int32_t ipc_application_select (struct ipc_services *services, struct ipc_services *active_services);
|
|
||||||
int32_t ipc_application_poll_event (struct ipc_services *services, struct ipc_event *event);
|
|
||||||
int32_t ipc_application_peek_event (struct ipc_services *services, struct ipc_event *event);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MESSAGE
|
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
// used to create msg structure with a certain payload length (0 for no payload memory allocation)
|
||||||
|
enum ipc_errors ipc_message_new (struct ipc_message **m, ssize_t paylen);
|
||||||
// used to create msg structure from buffer
|
// used to create msg structure from buffer
|
||||||
int32_t ipc_message_format_read (struct ipc_message *m, const char *buf, ssize_t msize);
|
enum ipc_errors ipc_message_format_read (struct ipc_message *m, const char *buf, ssize_t msize);
|
||||||
// used to create buffer from msg structure
|
// used to create buffer from msg structure
|
||||||
int32_t ipc_message_format_write (const struct ipc_message *m, char **buf, ssize_t *msize);
|
enum ipc_errors ipc_message_format_write (const struct ipc_message *m, char **buf, ssize_t *msize);
|
||||||
|
|
||||||
// read a structure msg from fd
|
// read a structure msg from fd
|
||||||
int32_t ipc_message_read (int32_t fd, struct ipc_message *m);
|
enum ipc_errors ipc_message_read (int32_t fd, struct ipc_message *m);
|
||||||
// write a structure msg to fd
|
// write a structure msg to fd
|
||||||
int32_t ipc_message_write (int32_t fd, const struct ipc_message *m);
|
enum ipc_errors ipc_message_write (int32_t fd, const struct ipc_message *m);
|
||||||
|
|
||||||
int32_t ipc_message_format (struct ipc_message *m, char type, const char *payload, ssize_t length);
|
enum ipc_errors ipc_message_format (struct ipc_message *m, char type, const char *payload, ssize_t length);
|
||||||
int32_t ipc_message_format_data (struct ipc_message *m, const char *payload, ssize_t length);
|
enum ipc_errors ipc_message_format_data (struct ipc_message *m, const char *payload, ssize_t length);
|
||||||
int32_t ipc_message_format_server_close (struct ipc_message *m);
|
enum ipc_errors ipc_message_format_server_close (struct ipc_message *m);
|
||||||
|
|
||||||
int32_t ipc_message_empty (struct ipc_message *m);
|
enum ipc_errors ipc_message_empty (struct ipc_message *m);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
// non public functions
|
||||||
* CLIENT
|
void service_path (char *path, const char *sname, int32_t index, int32_t version);
|
||||||
*
|
|
||||||
**/
|
|
||||||
|
|
||||||
// store and remove only pointers on allocated structures
|
|
||||||
int32_t ipc_clients_add (struct ipc_clients *, struct ipc_client *);
|
|
||||||
int32_t ipc_clients_del (struct ipc_clients *, struct ipc_client *);
|
|
||||||
|
|
||||||
void ipc_clients_free (struct ipc_clients *);
|
|
||||||
|
|
||||||
struct ipc_client * ipc_server_client_copy (const struct ipc_client *p);
|
|
||||||
int32_t ipc_server_client_eq (const struct ipc_client *p1, const struct ipc_client *p2);
|
|
||||||
// create the service client structure
|
|
||||||
void ipc_server_client_gen (struct ipc_client *p, uint32_t index, uint32_t version);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,15 +1,9 @@
|
|||||||
#ifndef __IPC_LOGGER_H__
|
#ifndef __IPC_LOGGER_H__
|
||||||
#define __IPC_LOGGER_H__
|
#define __IPC_LOGGER_H__
|
||||||
|
|
||||||
#define LOG
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
void log_error (const char* message, ...);
|
// print log, format: date:tag: message
|
||||||
void log_info (const char* message, ...);
|
|
||||||
void log_debug (const char* message, ...);
|
|
||||||
|
|
||||||
// please use previous functions
|
|
||||||
void log_format (const char* tag, const char* message, va_list args);
|
void log_format (const char* tag, const char* message, va_list args);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
156
src/message.c
156
src/message.c
@ -1,5 +1,10 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "error.h"
|
|
||||||
#include "usocket.h"
|
#include "usocket.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -12,14 +17,44 @@ void ipc_message_print (const struct ipc_message *m)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ipc_message_format_read (struct ipc_message *m, const char *buf, ssize_t msize)
|
|
||||||
|
enum ipc_errors ipc_message_new (struct ipc_message **m, ssize_t paylen)
|
||||||
|
{
|
||||||
|
m = malloc (sizeof(struct ipc_message));
|
||||||
|
if (m == NULL) {
|
||||||
|
return IPC_ERROR_MESSAGE_NEW__NO_MESSAGE_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (*m, 0, sizeof (struct ipc_message));
|
||||||
|
|
||||||
|
if (paylen != 0) {
|
||||||
|
((struct ipc_message *)m)->payload = malloc (paylen);
|
||||||
|
if (((struct ipc_message *)m)->payload == NULL) {
|
||||||
|
free (*m);
|
||||||
|
return IPC_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IPC_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ipc_errors ipc_message_format_read (struct ipc_message *m, const char *buf, ssize_t msize)
|
||||||
{
|
{
|
||||||
assert (m != NULL);
|
assert (m != NULL);
|
||||||
assert (buf != NULL);
|
assert (buf != NULL);
|
||||||
assert (msize <= IPC_MAX_MESSAGE_SIZE);
|
assert (msize <= IPC_MAX_MESSAGE_SIZE);
|
||||||
|
|
||||||
if (m == NULL)
|
if (m == NULL) {
|
||||||
return -1;
|
return IPC_ERROR_MESSAGE_FORMAT_READ__EMPTY_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf == NULL) {
|
||||||
|
return IPC_ERROR_MESSAGE_FORMAT_READ__EMPTY_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msize > IPC_MAX_MESSAGE_SIZE) {
|
||||||
|
return IPC_ERROR_MESSAGE_FORMAT_READ__MESSAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
m->type = buf[0];
|
m->type = buf[0];
|
||||||
memcpy (&m->length, buf+1, sizeof m->length);
|
memcpy (&m->length, buf+1, sizeof m->length);
|
||||||
@ -40,24 +75,27 @@ int32_t ipc_message_format_read (struct ipc_message *m, const char *buf, ssize_t
|
|||||||
memcpy (m->payload, buf+IPC_HEADER_SIZE, m->length);
|
memcpy (m->payload, buf+IPC_HEADER_SIZE, m->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ipc_message_format_write (const struct ipc_message *m, char **buf, ssize_t *msize)
|
enum ipc_errors ipc_message_format_write (const struct ipc_message *m, char **buf, ssize_t *msize)
|
||||||
{
|
{
|
||||||
assert (m != NULL);
|
assert (m != NULL);
|
||||||
assert (buf != NULL);
|
assert (buf != NULL);
|
||||||
assert (msize != NULL);
|
assert (msize != NULL);
|
||||||
assert (m->length <= IPC_MAX_MESSAGE_SIZE);
|
assert (m->length <= IPC_MAX_MESSAGE_SIZE);
|
||||||
|
|
||||||
if (m == NULL)
|
if (m == NULL) {
|
||||||
return -1;
|
return IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
if (buf == NULL)
|
if (buf == NULL) {
|
||||||
return -2;
|
return IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
if (msize == NULL)
|
if (msize == NULL) {
|
||||||
return -3;
|
return IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_MSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
if (*buf == NULL) {
|
if (*buf == NULL) {
|
||||||
*buf = malloc (IPC_HEADER_SIZE + m->length);
|
*buf = malloc (IPC_HEADER_SIZE + m->length);
|
||||||
@ -78,82 +116,93 @@ int32_t ipc_message_format_write (const struct ipc_message *m, char **buf, ssize
|
|||||||
printf ("sending msg: type %u, size %d, msize %ld\n", m->type, m->length, *msize);
|
printf ("sending msg: type %u, size %d, msize %ld\n", m->type, m->length, *msize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 on a recipient socket close
|
// IPC_ERROR_CLOSED_RECIPIENT on closed recipient
|
||||||
int32_t ipc_message_read (int32_t fd, struct ipc_message *m)
|
enum ipc_errors ipc_message_read (int32_t fd, struct ipc_message *m)
|
||||||
{
|
{
|
||||||
assert (m != NULL);
|
assert (m != NULL);
|
||||||
|
|
||||||
|
if (m == NULL) {
|
||||||
|
return IPC_ERROR_MESSAGE_READ__NO_MESSAGE_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
ssize_t msize = IPC_MAX_MESSAGE_SIZE;
|
ssize_t msize = IPC_MAX_MESSAGE_SIZE;
|
||||||
|
|
||||||
int32_t ret = usock_recv (fd, &buf, &msize);
|
enum ipc_errors ret = usock_recv (fd, &buf, &msize);
|
||||||
if (ret < 0) {
|
if (ret != IPC_ERROR_NONE && ret != IPC_ERROR_CLOSED_RECIPIENT) {
|
||||||
// on error, buffer already freed
|
if (buf != NULL)
|
||||||
|
free (buf);
|
||||||
handle_err ("msg_read", "usock_recv");
|
handle_err ("msg_read", "usock_recv");
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// closed recipient, buffer already freed
|
// closed recipient, buffer already freed
|
||||||
if (ret == 1) {
|
if (ret == IPC_ERROR_CLOSED_RECIPIENT) {
|
||||||
return 1;
|
if (buf != NULL)
|
||||||
|
free (buf);
|
||||||
|
return IPC_ERROR_CLOSED_RECIPIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ipc_message_format_read (m, buf, msize) < 0) {
|
ret = ipc_message_format_read (m, buf, msize);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
free (buf);
|
free (buf);
|
||||||
|
return ret; // propagates ipc_message_format return
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ipc_message_write (int32_t fd, const struct ipc_message *m)
|
enum ipc_errors ipc_message_write (int32_t fd, const struct ipc_message *m)
|
||||||
{
|
{
|
||||||
assert (m != NULL);
|
assert (m != NULL);
|
||||||
|
|
||||||
|
if (m == NULL) {
|
||||||
|
return IPC_ERROR_MESSAGE_WRITE__NO_MESSAGE_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
ssize_t msize = 0;
|
ssize_t msize = 0;
|
||||||
ipc_message_format_write (m, &buf, &msize);
|
ipc_message_format_write (m, &buf, &msize);
|
||||||
|
|
||||||
ssize_t nbytes_sent = 0;
|
ssize_t nbytes_sent = 0;
|
||||||
int32_t ret = usock_send (fd, buf, msize, &nbytes_sent);
|
enum ipc_errors ret = usock_send (fd, buf, msize, &nbytes_sent);
|
||||||
if (ret < 0) {
|
if (buf != NULL) {
|
||||||
if (buf != NULL) {
|
free (buf);
|
||||||
free (buf);
|
}
|
||||||
}
|
|
||||||
handle_err ("msg_write", "usock_send ret < 0");
|
if (ret != IPC_ERROR_NONE) {
|
||||||
return -1;
|
handle_err ("msg_write", "usock_send");
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// what was sent != what should have been sent
|
// what was sent != what should have been sent
|
||||||
if (nbytes_sent != msize) {
|
if (nbytes_sent != msize) {
|
||||||
if (buf != NULL) {
|
|
||||||
free (buf);
|
|
||||||
}
|
|
||||||
handle_err ("msg_write", "usock_send did not send enough data");
|
handle_err ("msg_write", "usock_send did not send enough data");
|
||||||
return -1;
|
return IPC_ERROR_MESSAGE_WRITE__NOT_ENOUGH_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf != NULL) {
|
return IPC_ERROR_NONE;
|
||||||
free (buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MSG FORMAT
|
// MSG FORMAT
|
||||||
|
|
||||||
int32_t ipc_message_format (struct ipc_message *m, char type, const char *payload, ssize_t length)
|
enum ipc_errors ipc_message_format (struct ipc_message *m, char type, const char *payload, ssize_t length)
|
||||||
{
|
{
|
||||||
assert (m != NULL);
|
assert (m != NULL);
|
||||||
assert (length <= IPC_MAX_MESSAGE_SIZE);
|
assert (length <= IPC_MAX_MESSAGE_SIZE);
|
||||||
assert ((length == 0 && payload == NULL) || (length > 0 && payload != NULL));
|
assert ((length == 0 && payload == NULL) || (length > 0 && payload != NULL));
|
||||||
|
|
||||||
|
if (m == NULL) {
|
||||||
|
return IPC_ERROR_MESSAGE_FORMAT__NO_MESSAGE_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((length == 0 && payload != NULL) || (length > 0 && payload == NULL)) {
|
||||||
|
return IPC_ERROR_MESSAGE_FORMAT__INCONSISTENT_PARAMS;
|
||||||
|
}
|
||||||
|
|
||||||
if (length > IPC_MAX_MESSAGE_SIZE) {
|
if (length > IPC_MAX_MESSAGE_SIZE) {
|
||||||
handle_err ("msg_format_con", "msgsize > BUFSIZ");
|
handle_err ("msg_format_con", "msgsize > BUFSIZ");
|
||||||
return -1;
|
printf ("msg to format: %ld B)\n", length);
|
||||||
|
return IPC_ERROR_MESSAGE_FORMAT__LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
m->type = type;
|
m->type = type;
|
||||||
@ -174,25 +223,26 @@ int32_t ipc_message_format (struct ipc_message *m, char type, const char *payloa
|
|||||||
if (payload != NULL) {
|
if (payload != NULL) {
|
||||||
memcpy (m->payload, payload, length);
|
memcpy (m->payload, payload, length);
|
||||||
}
|
}
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ipc_message_format_data (struct ipc_message *m, const char *payload, ssize_t length)
|
enum ipc_errors ipc_message_format_data (struct ipc_message *m, const char *payload, ssize_t length)
|
||||||
{
|
{
|
||||||
return ipc_message_format (m, MSG_TYPE_DATA, payload, length);
|
return ipc_message_format (m, MSG_TYPE_DATA, payload, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ipc_message_format_server_close (struct ipc_message *m)
|
enum ipc_errors ipc_message_format_server_close (struct ipc_message *m)
|
||||||
{
|
{
|
||||||
return ipc_message_format (m, MSG_TYPE_SERVER_CLOSE, NULL, 0);
|
return ipc_message_format (m, MSG_TYPE_SERVER_CLOSE, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ipc_message_empty (struct ipc_message *m)
|
enum ipc_errors ipc_message_empty (struct ipc_message *m)
|
||||||
{
|
{
|
||||||
assert (m != NULL);
|
assert (m != NULL);
|
||||||
|
|
||||||
if (m == NULL)
|
if (m == NULL) {
|
||||||
return -1;
|
return IPC_ERROR_MESSAGE_EMPTY__EMPTY_MESSAGE_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
if (m->payload != NULL) {
|
if (m->payload != NULL) {
|
||||||
free (m->payload);
|
free (m->payload);
|
||||||
@ -201,5 +251,5 @@ int32_t ipc_message_empty (struct ipc_message *m)
|
|||||||
|
|
||||||
m->length = 0;
|
m->length = 0;
|
||||||
|
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,6 @@
|
|||||||
#ifndef __IPC_MSG_H__
|
#ifndef __IPC_MSG_H__
|
||||||
#define __IPC_MSG_H__
|
#define __IPC_MSG_H__
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
void ipc_message_print (const struct ipc_message *m);
|
void ipc_message_print (const struct ipc_message *m);
|
||||||
|
|
||||||
|
194
src/usocket.c
194
src/usocket.c
@ -1,6 +1,9 @@
|
|||||||
#include "usocket.h"
|
#include <time.h>
|
||||||
#include "utils.h"
|
#include <sys/socket.h>
|
||||||
#include "error.h"
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -8,20 +11,23 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
int32_t usock_send (const int32_t fd, const char *buf, ssize_t len, ssize_t *sent)
|
#include "usocket.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
enum ipc_errors usock_send (const int32_t fd, const char *buf, ssize_t len, ssize_t *sent)
|
||||||
{
|
{
|
||||||
ssize_t ret = 0;
|
ssize_t ret = 0;
|
||||||
ret = send (fd, buf, len, MSG_NOSIGNAL);
|
ret = send (fd, buf, len, MSG_NOSIGNAL);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
handle_err ("usock_send", "send ret <= 0");
|
handle_err ("usock_send", "send ret <= 0");
|
||||||
return -1;
|
return IPC_ERROR_USOCK_SEND;
|
||||||
}
|
}
|
||||||
*sent = ret;
|
*sent = ret;
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// *len is changed to the total message size read (header + payload)
|
// *len is changed to the total message size read (header + payload)
|
||||||
int32_t usock_recv (const int32_t fd, char **buf, ssize_t *len)
|
enum ipc_errors usock_recv (const int32_t fd, char **buf, ssize_t *len)
|
||||||
{
|
{
|
||||||
assert(buf != NULL);
|
assert(buf != NULL);
|
||||||
assert(len != NULL);
|
assert(len != NULL);
|
||||||
@ -30,12 +36,12 @@ int32_t usock_recv (const int32_t fd, char **buf, ssize_t *len)
|
|||||||
|
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
handle_err ("usock_recv", "buf == NULL");
|
handle_err ("usock_recv", "buf == NULL");
|
||||||
return -1;
|
return IPC_ERROR_USOCK_RECV__NO_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == NULL) {
|
if (len == NULL) {
|
||||||
handle_err ("usock_recv", "len == NULL");
|
handle_err ("usock_recv", "len == NULL");
|
||||||
return -1;
|
return IPC_ERROR_USOCK_RECV__NO_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*buf == NULL) {
|
if (*buf == NULL) {
|
||||||
@ -116,7 +122,7 @@ int32_t usock_recv (const int32_t fd, char **buf, ssize_t *len)
|
|||||||
handle_err ("usock_recv", "unsupported error");
|
handle_err ("usock_recv", "unsupported error");
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
return -1;
|
return IPC_ERROR_USOCK_RECV;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(IPC_WITH_ERRORS) && IPC_WITH_ERRORS > 2
|
#if defined(IPC_WITH_ERRORS) && IPC_WITH_ERRORS > 2
|
||||||
@ -132,27 +138,27 @@ int32_t usock_recv (const int32_t fd, char **buf, ssize_t *len)
|
|||||||
free (*buf);
|
free (*buf);
|
||||||
*buf = NULL;
|
*buf = NULL;
|
||||||
}
|
}
|
||||||
return 1;
|
return IPC_ERROR_CLOSED_RECIPIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// print_hexa ("msg recv", (uint8_t *)*buf, *len);
|
// print_hexa ("msg recv", (uint8_t *)*buf, *len);
|
||||||
// fflush(stdout);
|
// fflush(stdout);
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t usock_connect (int32_t *fd, const char *path)
|
enum ipc_errors usock_connect (int32_t *fd, const char *path)
|
||||||
{
|
{
|
||||||
assert (fd != NULL);
|
assert (fd != NULL);
|
||||||
assert (path != NULL);
|
assert (path != NULL);
|
||||||
|
|
||||||
if (fd == NULL) {
|
if (fd == NULL) {
|
||||||
handle_err ("usock_connect", "fd == NULL");
|
handle_err ("usock_connect", "fd == NULL");
|
||||||
return -1;
|
return IPC_ERROR_USOCK_CONNECT__WRONG_FILE_DESCRIPTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path == NULL) {
|
if (path == NULL) {
|
||||||
handle_err ("usock_connect", "path == NULL");
|
handle_err ("usock_connect", "path == NULL");
|
||||||
return -1;
|
return IPC_ERROR_USOCK_CONNECT__EMPTY_PATH;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t sfd;
|
int32_t sfd;
|
||||||
@ -162,7 +168,7 @@ int32_t usock_connect (int32_t *fd, const char *path)
|
|||||||
sfd = socket (AF_UNIX, SOCK_STREAM, 0);
|
sfd = socket (AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (sfd == -1) {
|
if (sfd == -1) {
|
||||||
handle_err ("usock_connect", "sfd == -1");
|
handle_err ("usock_connect", "sfd == -1");
|
||||||
return -1;
|
return IPC_ERROR_USOCK_CONNECT__SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear structure
|
// clear structure
|
||||||
@ -180,22 +186,22 @@ int32_t usock_connect (int32_t *fd, const char *path)
|
|||||||
|
|
||||||
*fd = sfd;
|
*fd = sfd;
|
||||||
|
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t usock_init (int32_t *fd, const char *path)
|
enum ipc_errors usock_init (int32_t *fd, const char *path)
|
||||||
{
|
{
|
||||||
assert (fd != NULL);
|
assert (fd != NULL);
|
||||||
assert (path != NULL);
|
assert (path != NULL);
|
||||||
|
|
||||||
if (fd == NULL) {
|
if (fd == NULL) {
|
||||||
handle_err ("usock_init", "fd == NULL");
|
handle_err ("usock_init", "fd == NULL");
|
||||||
return -1;
|
return IPC_ERROR_USOCK_INIT__EMPTY_FILE_DESCRIPTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path == NULL) {
|
if (path == NULL) {
|
||||||
handle_err ("usock_init", "path == NULL");
|
handle_err ("usock_init", "path == NULL");
|
||||||
return -1;
|
return IPC_ERROR_USOCK_INIT__EMPTY_PATH;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t sfd;
|
int32_t sfd;
|
||||||
@ -205,7 +211,7 @@ int32_t usock_init (int32_t *fd, const char *path)
|
|||||||
sfd = socket (AF_UNIX, SOCK_STREAM, 0);
|
sfd = socket (AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (sfd == -1) {
|
if (sfd == -1) {
|
||||||
handle_err ("usock_init", "sfd == -1");
|
handle_err ("usock_init", "sfd == -1");
|
||||||
return -1;
|
return IPC_ERROR_USOCK_INIT__WRONG_FILE_DESCRIPTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear structure
|
// clear structure
|
||||||
@ -214,35 +220,36 @@ int32_t usock_init (int32_t *fd, const char *path)
|
|||||||
my_addr.sun_family = AF_UNIX;
|
my_addr.sun_family = AF_UNIX;
|
||||||
strncpy(my_addr.sun_path, path, strlen (path));
|
strncpy(my_addr.sun_path, path, strlen (path));
|
||||||
|
|
||||||
// TODO FIXME
|
// delete the unix socket if already created
|
||||||
// delete the unix socket if already created
|
// ignore otherwise
|
||||||
|
usock_remove (path);
|
||||||
|
|
||||||
peer_addr_size = sizeof(struct sockaddr_un);
|
peer_addr_size = sizeof(struct sockaddr_un);
|
||||||
|
|
||||||
if (bind (sfd, (struct sockaddr *) &my_addr, peer_addr_size) == -1) {
|
if (bind (sfd, (struct sockaddr *) &my_addr, peer_addr_size) == -1) {
|
||||||
handle_err ("usock_init", "bind == -1");
|
handle_err ("usock_init", "bind == -1");
|
||||||
perror("bind");
|
perror("bind");
|
||||||
return -1;
|
return IPC_ERROR_USOCK_INIT__BIND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen (sfd, LISTEN_BACKLOG) == -1) {
|
if (listen (sfd, LISTEN_BACKLOG) == -1) {
|
||||||
handle_err ("usock_init", "listen == -1");
|
handle_err ("usock_init", "listen == -1");
|
||||||
perror("listen");
|
perror("listen");
|
||||||
return -1;
|
return IPC_ERROR_USOCK_INIT__LISTEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
*fd = sfd;
|
*fd = sfd;
|
||||||
|
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t usock_accept (int32_t fd, int32_t *pfd)
|
enum ipc_errors usock_accept (int32_t fd, int32_t *pfd)
|
||||||
{
|
{
|
||||||
assert (pfd != NULL);
|
assert (pfd != NULL);
|
||||||
|
|
||||||
if (pfd == NULL) {
|
if (pfd == NULL) {
|
||||||
handle_err ("usock_accept", "pfd == NULL");
|
handle_err ("usock_accept", "pfd == NULL");
|
||||||
return -1;
|
return IPC_ERROR_USOCK_ACCEPT__PATH_FILE_DESCRIPTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sockaddr_un peer_addr;
|
struct sockaddr_un peer_addr;
|
||||||
@ -253,13 +260,13 @@ int32_t usock_accept (int32_t fd, int32_t *pfd)
|
|||||||
if (*pfd < 0) {
|
if (*pfd < 0) {
|
||||||
handle_err ("usock_accept", "accept < 0");
|
handle_err ("usock_accept", "accept < 0");
|
||||||
perror("listen");
|
perror("listen");
|
||||||
return -1;
|
return IPC_ERROR_USOCK_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t usock_close (int32_t fd)
|
enum ipc_errors usock_close (int32_t fd)
|
||||||
{
|
{
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
|
|
||||||
@ -267,116 +274,25 @@ int32_t usock_close (int32_t fd)
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
handle_err ("usock_close", "close ret < 0");
|
handle_err ("usock_close", "close ret < 0");
|
||||||
perror ("closing");
|
perror ("closing");
|
||||||
return -1;
|
return IPC_ERROR_USOCK_CLOSE;
|
||||||
}
|
}
|
||||||
return 0;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t usock_remove (const char *path)
|
enum ipc_errors usock_remove (const char *path)
|
||||||
{
|
{
|
||||||
return unlink (path);
|
struct stat file_state;
|
||||||
}
|
memset (&file_state, 0, sizeof (struct stat));
|
||||||
|
|
||||||
|
// if file exists, remove it
|
||||||
// TODO: ipc_services functions
|
int ret = stat (path, &file_state);
|
||||||
|
if (ret == 0) {
|
||||||
struct ipc_service * ipc_client_server_copy (const struct ipc_service *p)
|
ret = unlink (path);
|
||||||
{
|
if (ret != 0) {
|
||||||
if (p == NULL)
|
return IPC_ERROR_USOCK_REMOVE__UNLINK;
|
||||||
return NULL;
|
}
|
||||||
|
return IPC_ERROR_NONE;
|
||||||
struct ipc_service * copy = malloc (sizeof(struct ipc_service));
|
}
|
||||||
memset (copy, 0, sizeof (struct ipc_service));
|
|
||||||
memcpy (copy, p, sizeof (struct ipc_service));
|
return IPC_ERROR_USOCK_REMOVE__NO_FILE;
|
||||||
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ipc_client_server_eq (const struct ipc_service *p1, const struct ipc_service *p2)
|
|
||||||
{
|
|
||||||
return (p1->version == p2->version && p1->index == p2->index
|
|
||||||
&& p1->service_fd == p2->service_fd && memcmp(p1->spath, p1->spath, PATH_MAX) == 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
void ipc_client_server_gen (struct ipc_service *p
|
|
||||||
, uint32_t index, uint32_t version)
|
|
||||||
{
|
|
||||||
p->version = version;
|
|
||||||
p->index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ipc_services_add (struct ipc_services *services, struct ipc_service *p)
|
|
||||||
{
|
|
||||||
assert(services != NULL);
|
|
||||||
assert(p != NULL);
|
|
||||||
|
|
||||||
services->size++;
|
|
||||||
services->services = realloc(services->services
|
|
||||||
, sizeof(struct ipc_service) * services->size);
|
|
||||||
|
|
||||||
if (services->services == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
services->services[services->size - 1] = p;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ipc_services_del (struct ipc_services *services, struct ipc_service *p)
|
|
||||||
{
|
|
||||||
assert(services != NULL);
|
|
||||||
assert(p != NULL);
|
|
||||||
|
|
||||||
if (services->services == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t i;
|
|
||||||
for (i = 0; i < services->size; i++) {
|
|
||||||
if (services->services[i] == p) {
|
|
||||||
|
|
||||||
services->services[i] = services->services[services->size-1];
|
|
||||||
services->size--;
|
|
||||||
if (services->size == 0) {
|
|
||||||
ipc_services_free (services);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
services->services = realloc(services->services
|
|
||||||
, sizeof(struct ipc_service) * services->size);
|
|
||||||
|
|
||||||
if (services->services == NULL) {
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
void service_print (struct ipc_service *p)
|
|
||||||
{
|
|
||||||
if (p != NULL)
|
|
||||||
printf ("client %d : index %d, version %d\n"
|
|
||||||
, p->service_fd, p->index, p->version);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ipc_services_print (struct ipc_services *ap)
|
|
||||||
{
|
|
||||||
int32_t i;
|
|
||||||
for (i = 0; i < ap->size; i++) {
|
|
||||||
printf("%d : ", i);
|
|
||||||
service_print(ap->services[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ipc_services_free (struct ipc_services *ap)
|
|
||||||
{
|
|
||||||
if (ap->services != NULL) {
|
|
||||||
free (ap->services);
|
|
||||||
ap->services = NULL;
|
|
||||||
}
|
|
||||||
ap->size = 0;
|
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,13 @@
|
|||||||
#ifndef __IPC_USOCKET_H__
|
#ifndef __IPC_USOCKET_H__
|
||||||
#define __IPC_USOCKET_H__
|
#define __IPC_USOCKET_H__
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
|
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define LISTEN_BACKLOG 128
|
#define LISTEN_BACKLOG 128
|
||||||
|
|
||||||
/**
|
|
||||||
* for all functions: 0 ok, < 0 not ok
|
|
||||||
*/
|
|
||||||
|
|
||||||
// input: len = max buf size
|
// input: len = max buf size
|
||||||
// output: *sent = nb received bytes
|
// output: *sent = nb received bytes
|
||||||
int32_t usock_send (const int32_t fd, const char *buf, ssize_t len, ssize_t *sent);
|
enum ipc_errors usock_send (const int32_t fd, const char *buf, ssize_t len, ssize_t *sent);
|
||||||
|
|
||||||
// -1 on msize == NULL or buf == NULL
|
// -1 on msize == NULL or buf == NULL
|
||||||
// -1 on unsupported errors from read(2)
|
// -1 on unsupported errors from read(2)
|
||||||
@ -25,23 +16,20 @@ int32_t usock_send (const int32_t fd, const char *buf, ssize_t len, ssize_t *sen
|
|||||||
// allocation of *len bytes on *buf == NULL
|
// allocation of *len bytes on *buf == NULL
|
||||||
//
|
//
|
||||||
// output: *len = nb sent bytes
|
// output: *len = nb sent bytes
|
||||||
int32_t usock_recv (int32_t fd, char **buf, ssize_t *len);
|
enum ipc_errors usock_recv (int32_t fd, char **buf, ssize_t *len);
|
||||||
|
|
||||||
// -1 on close(2) < 0
|
// -1 on close(2) < 0
|
||||||
int32_t usock_close (int32_t fd);
|
enum ipc_errors usock_close (int32_t fd);
|
||||||
|
|
||||||
// same as connect(2)
|
// same as connect(2)
|
||||||
// -1 on fd == NULL
|
// -1 on fd == NULL
|
||||||
int32_t usock_connect (int32_t *fd, const char *path);
|
enum ipc_errors usock_connect (int32_t *fd, const char *path);
|
||||||
|
|
||||||
int32_t usock_init (int32_t *fd, const char *path);
|
enum ipc_errors usock_init (int32_t *fd, const char *path);
|
||||||
|
|
||||||
int32_t usock_accept (int32_t fd, int32_t *pfd);
|
enum ipc_errors usock_accept (int32_t fd, int32_t *pfd);
|
||||||
|
|
||||||
// same as unlink(2)
|
// same as unlink(2)
|
||||||
int32_t usock_remove (const char *path);
|
enum ipc_errors usock_remove (const char *path);
|
||||||
|
|
||||||
void ipc_services_print (struct ipc_services *);
|
|
||||||
void service_print (struct ipc_service *);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user