error bugfix in read function, correct msg length exchange, networkd draft
This commit is contained in:
parent
a8d0a82adf
commit
b9054b557e
141
Makefile
141
Makefile
@ -11,7 +11,7 @@ MANDIR := $(SHAREDIR)/man
|
|||||||
CC := cc
|
CC := cc
|
||||||
AR := ar
|
AR := ar
|
||||||
RANLIB := ranlib
|
RANLIB := ranlib
|
||||||
CFLAGS :=
|
CFLAGS := -g
|
||||||
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 ' IN > $(INCLUDEDIR)/ipc.h'
|
@echo '[01;31m IN > [01;37m$(INCLUDEDIR)/ipc.h[00m'
|
||||||
$(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,162 +36,162 @@ src/ipc.h.clean: src/ipc.h
|
|||||||
$(Q):
|
$(Q):
|
||||||
|
|
||||||
src/ipc.h.uninstall:
|
src/ipc.h.uninstall:
|
||||||
@echo ' RM > $(INCLUDEDIR)/ipc.h'
|
@echo '[01;37m RM > [01;37m$(INCLUDEDIR)/ipc.h[00m'
|
||||||
$(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 ' MAN > man/libipc.7'
|
@echo '[01;32m MAN > [01;37mman/libipc.7[00m'
|
||||||
$(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 ' IN > $(MANDIR)/man7/libipc.7'
|
@echo '[01;31m IN > [01;37m$(MANDIR)/man7/libipc.7[00m'
|
||||||
$(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 ' RM > man/libipc.7'
|
@echo '[01;37m RM > [01;37mman/libipc.7[00m'
|
||||||
$(Q)rm -f man/libipc.7
|
$(Q)rm -f man/libipc.7
|
||||||
|
|
||||||
man/libipc.7.uninstall:
|
man/libipc.7.uninstall:
|
||||||
@echo ' RM > $(MANDIR)/man7/libipc.7'
|
@echo '[01;37m RM > [01;37m$(MANDIR)/man7/libipc.7[00m'
|
||||||
$(Q)rm -f '$(DESTDIR)$(MANDIR)/man7/libipc.7'
|
$(Q)rm -f '$(DESTDIR)$(MANDIR)/man7/libipc.7'
|
||||||
|
|
||||||
libipc.so: src/communication.o src/error.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 ' LD > libipc.so'
|
@echo '[01;32m LD > [01;37mlibipc.so[00m'
|
||||||
$(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
|
$(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 ' IN > $(LIBDIR)/libipc.so.0.1.0'
|
@echo '[01;31m IN > [01;37m$(LIBDIR)/libipc.so.0.1.0[00m'
|
||||||
$(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 ' LN > $(LIBDIR)/libipc.so.0.1'
|
@echo '[01;33m LN > [01;37m$(LIBDIR)/libipc.so.0.1[00m'
|
||||||
$(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 ' LN > $(LIBDIR)/libipc.so.0'
|
@echo '[01;33m LN > [01;37m$(LIBDIR)/libipc.so.0[00m'
|
||||||
$(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 ' LN > $(LIBDIR)/libipc.so'
|
@echo '[01;33m LN > [01;37m$(LIBDIR)/libipc.so[00m'
|
||||||
$(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 ' RM > libipc.so'
|
@echo '[01;37m RM > [01;37mlibipc.so[00m'
|
||||||
$(Q)rm -f libipc.so
|
$(Q)rm -f libipc.so
|
||||||
|
|
||||||
libipc.so.uninstall:
|
libipc.so.uninstall:
|
||||||
@echo ' RM > $(LIBDIR)/libipc.so.0.1.0'
|
@echo '[01;37m RM > [01;37m$(LIBDIR)/libipc.so.0.1.0[00m'
|
||||||
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so.0.1.0'
|
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so.0.1.0'
|
||||||
@echo ' RM > $(LIBDIR)/libipc.so.0.1'
|
@echo '[01;37m RM > [01;37m$(LIBDIR)/libipc.so.0.1[00m'
|
||||||
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so.0.1'
|
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so.0.1'
|
||||||
@echo ' RM > $(LIBDIR)/libipc.so.0'
|
@echo '[01;37m RM > [01;37m$(LIBDIR)/libipc.so.0[00m'
|
||||||
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so.0'
|
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so.0'
|
||||||
@echo ' RM > $(LIBDIR)/libipc.so'
|
@echo '[01;37m RM > [01;37m$(LIBDIR)/libipc.so[00m'
|
||||||
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so'
|
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so'
|
||||||
|
|
||||||
libipc.a: src/communication.o src/error.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 ' LD > libipc.a'
|
@echo '[01;32m LD > [01;37mlibipc.a[00m'
|
||||||
$(Q)$(AR) rc 'libipc.a' src/communication.o src/error.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 ' IN > $(LIBDIR)/libipc.a'
|
@echo '[01;31m IN > [01;37m$(LIBDIR)/libipc.a[00m'
|
||||||
$(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 ' RM > libipc.a'
|
@echo '[01;37m RM > [01;37mlibipc.a[00m'
|
||||||
$(Q)rm -f libipc.a
|
$(Q)rm -f libipc.a
|
||||||
|
|
||||||
libipc.a.uninstall:
|
libipc.a.uninstall:
|
||||||
@echo ' RM > $(LIBDIR)/libipc.a'
|
@echo '[01;37m RM > [01;37m$(LIBDIR)/libipc.a[00m'
|
||||||
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.a'
|
$(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.a'
|
||||||
|
|
||||||
src/communication.o: src/communication.c src/ipc.h src/utils.h src/message.h
|
src/communication.o: src/communication.c src/ipc.h src/utils.h src/message.h
|
||||||
@echo ' CC > src/communication.o'
|
@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 ' RM > src/communication.o'
|
@echo '[01;37m RM > [01;37msrc/communication.o[00m'
|
||||||
$(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
|
src/error.o: src/error.c src/ipc.h
|
||||||
@echo ' CC > src/error.o'
|
@echo '[01;34m CC > [01;37msrc/error.o[00m'
|
||||||
$(Q)$(CC) $(CFLAGS) -fPIC -c src/error.c -fPIC -o src/error.o
|
$(Q)$(CC) $(CFLAGS) -fPIC -c src/error.c -fPIC -o src/error.o
|
||||||
|
|
||||||
src/error.o.install:
|
src/error.o.install:
|
||||||
|
|
||||||
src/error.o.clean:
|
src/error.o.clean:
|
||||||
@echo ' RM > src/error.o'
|
@echo '[01;37m RM > [01;37msrc/error.o[00m'
|
||||||
$(Q)rm -f src/error.o
|
$(Q)rm -f src/error.o
|
||||||
|
|
||||||
src/error.o.uninstall:
|
src/error.o.uninstall:
|
||||||
|
|
||||||
src/logger.o: src/logger.c src/logger.h
|
src/logger.o: src/logger.c src/logger.h
|
||||||
@echo ' CC > src/logger.o'
|
@echo '[01;34m CC > [01;37msrc/logger.o[00m'
|
||||||
$(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 ' RM > src/logger.o'
|
@echo '[01;37m RM > [01;37msrc/logger.o[00m'
|
||||||
$(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/usocket.h
|
src/message.o: src/message.c src/message.h src/usocket.h
|
||||||
@echo ' CC > src/message.o'
|
@echo '[01;34m CC > [01;37msrc/message.o[00m'
|
||||||
$(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 ' RM > src/message.o'
|
@echo '[01;37m RM > [01;37msrc/message.o[00m'
|
||||||
$(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/usocket.o: src/usocket.c src/usocket.h src/utils.h
|
||||||
@echo ' CC > src/usocket.o'
|
@echo '[01;34m CC > [01;37msrc/usocket.o[00m'
|
||||||
$(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 ' RM > src/usocket.o'
|
@echo '[01;37m RM > [01;37msrc/usocket.o[00m'
|
||||||
$(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 ' CC > src/utils.o'
|
@echo '[01;34m CC > [01;37msrc/utils.o[00m'
|
||||||
$(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 ' RM > src/utils.o'
|
@echo '[01;37m RM > [01;37msrc/utils.o[00m'
|
||||||
$(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 ' DIR > $(PREFIX)'
|
@echo '[01;35m DIR > [01;37m$(PREFIX)[00m'
|
||||||
$(Q)mkdir -p $(DESTDIR)$(PREFIX)
|
$(Q)mkdir -p $(DESTDIR)$(PREFIX)
|
||||||
$(DESTDIR)$(BINDIR):
|
$(DESTDIR)$(BINDIR):
|
||||||
@echo ' DIR > $(BINDIR)'
|
@echo '[01;35m DIR > [01;37m$(BINDIR)[00m'
|
||||||
$(Q)mkdir -p $(DESTDIR)$(BINDIR)
|
$(Q)mkdir -p $(DESTDIR)$(BINDIR)
|
||||||
$(DESTDIR)$(LIBDIR):
|
$(DESTDIR)$(LIBDIR):
|
||||||
@echo ' DIR > $(LIBDIR)'
|
@echo '[01;35m DIR > [01;37m$(LIBDIR)[00m'
|
||||||
$(Q)mkdir -p $(DESTDIR)$(LIBDIR)
|
$(Q)mkdir -p $(DESTDIR)$(LIBDIR)
|
||||||
$(DESTDIR)$(SHAREDIR):
|
$(DESTDIR)$(SHAREDIR):
|
||||||
@echo ' DIR > $(SHAREDIR)'
|
@echo '[01;35m DIR > [01;37m$(SHAREDIR)[00m'
|
||||||
$(Q)mkdir -p $(DESTDIR)$(SHAREDIR)
|
$(Q)mkdir -p $(DESTDIR)$(SHAREDIR)
|
||||||
$(DESTDIR)$(INCLUDEDIR):
|
$(DESTDIR)$(INCLUDEDIR):
|
||||||
@echo ' DIR > $(INCLUDEDIR)'
|
@echo '[01;35m DIR > [01;37m$(INCLUDEDIR)[00m'
|
||||||
$(Q)mkdir -p $(DESTDIR)$(INCLUDEDIR)
|
$(Q)mkdir -p $(DESTDIR)$(INCLUDEDIR)
|
||||||
$(DESTDIR)$(MANDIR):
|
$(DESTDIR)$(MANDIR):
|
||||||
@echo ' DIR > $(MANDIR)'
|
@echo '[01;35m DIR > [01;37m$(MANDIR)[00m'
|
||||||
$(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/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
|
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
|
||||||
@:
|
@:
|
||||||
@ -221,7 +221,7 @@ distdir:
|
|||||||
|
|
||||||
dist-gz: $(PACKAGE)-$(VERSION).tar.gz
|
dist-gz: $(PACKAGE)-$(VERSION).tar.gz
|
||||||
$(PACKAGE)-$(VERSION).tar.gz: distdir
|
$(PACKAGE)-$(VERSION).tar.gz: distdir
|
||||||
@echo ' TAR > $(PACKAGE)-$(VERSION).tar.gz'
|
@echo '[01;33m TAR > [01;37m$(PACKAGE)-$(VERSION).tar.gz[00m'
|
||||||
$(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 \
|
||||||
@ -233,7 +233,6 @@ $(PACKAGE)-$(VERSION).tar.gz: distdir
|
|||||||
$(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/communication.h \
|
|
||||||
$(PACKAGE)-$(VERSION)/src/logger.h \
|
$(PACKAGE)-$(VERSION)/src/logger.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/message.h \
|
$(PACKAGE)-$(VERSION)/src/message.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/usocket.h \
|
$(PACKAGE)-$(VERSION)/src/usocket.h \
|
||||||
@ -241,7 +240,7 @@ $(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 ' TAR > $(PACKAGE)-$(VERSION).tar.xz'
|
@echo '[01;33m TAR > [01;37m$(PACKAGE)-$(VERSION).tar.xz[00m'
|
||||||
$(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 \
|
||||||
@ -253,7 +252,6 @@ $(PACKAGE)-$(VERSION).tar.xz: distdir
|
|||||||
$(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/communication.h \
|
|
||||||
$(PACKAGE)-$(VERSION)/src/logger.h \
|
$(PACKAGE)-$(VERSION)/src/logger.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/message.h \
|
$(PACKAGE)-$(VERSION)/src/message.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/usocket.h \
|
$(PACKAGE)-$(VERSION)/src/usocket.h \
|
||||||
@ -261,7 +259,7 @@ $(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 ' TAR > $(PACKAGE)-$(VERSION).tar.bz2'
|
@echo '[01;33m TAR > [01;37m$(PACKAGE)-$(VERSION).tar.bz2[00m'
|
||||||
$(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 \
|
||||||
@ -273,45 +271,44 @@ $(PACKAGE)-$(VERSION).tar.bz2: distdir
|
|||||||
$(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/communication.h \
|
|
||||||
$(PACKAGE)-$(VERSION)/src/logger.h \
|
$(PACKAGE)-$(VERSION)/src/logger.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/message.h \
|
$(PACKAGE)-$(VERSION)/src/message.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/usocket.h \
|
$(PACKAGE)-$(VERSION)/src/usocket.h \
|
||||||
$(PACKAGE)-$(VERSION)/src/utils.h
|
$(PACKAGE)-$(VERSION)/src/utils.h
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo ' :: ipc-0.1.0'
|
@echo '[01;37m :: ipc-0.1.0[00m'
|
||||||
@echo ''
|
@echo ''
|
||||||
@echo 'Generic targets:'
|
@echo '[01;37mGeneric targets:[00m'
|
||||||
@echo ' - help Prints this help message.'
|
@echo '[00m - [01;32mhelp [37m Prints this help message.[00m'
|
||||||
@echo ' - all Builds all targets.'
|
@echo '[00m - [01;32mall [37m Builds all targets.[00m'
|
||||||
@echo ' - dist Creates tarballs of the files of the project.'
|
@echo '[00m - [01;32mdist [37m Creates tarballs of the files of the project.[00m'
|
||||||
@echo ' - install Installs the project.'
|
@echo '[00m - [01;32minstall [37m Installs the project.[00m'
|
||||||
@echo ' - clean Removes compiled files.'
|
@echo '[00m - [01;32mclean [37m Removes compiled files.[00m'
|
||||||
@echo ' - uninstall Deinstalls the project.'
|
@echo '[00m - [01;32muninstall [37m Deinstalls the project.[00m'
|
||||||
@echo ''
|
@echo ''
|
||||||
@echo 'CLI-modifiable variables:'
|
@echo '[01;37mCLI-modifiable variables:[00m'
|
||||||
@echo ' - CC ${CC}'
|
@echo ' - [01;34mCC [37m ${CC}[00m'
|
||||||
@echo ' - CFLAGS ${CFLAGS}'
|
@echo ' - [01;34mCFLAGS [37m ${CFLAGS}[00m'
|
||||||
@echo ' - LDFLAGS ${LDFLAGS}'
|
@echo ' - [01;34mLDFLAGS [37m ${LDFLAGS}[00m'
|
||||||
@echo ' - DESTDIR ${DESTDIR}'
|
@echo ' - [01;34mDESTDIR [37m ${DESTDIR}[00m'
|
||||||
@echo ' - PREFIX ${PREFIX}'
|
@echo ' - [01;34mPREFIX [37m ${PREFIX}[00m'
|
||||||
@echo ' - BINDIR ${BINDIR}'
|
@echo ' - [01;34mBINDIR [37m ${BINDIR}[00m'
|
||||||
@echo ' - LIBDIR ${LIBDIR}'
|
@echo ' - [01;34mLIBDIR [37m ${LIBDIR}[00m'
|
||||||
@echo ' - SHAREDIR ${SHAREDIR}'
|
@echo ' - [01;34mSHAREDIR [37m ${SHAREDIR}[00m'
|
||||||
@echo ' - INCLUDEDIR ${INCLUDEDIR}'
|
@echo ' - [01;34mINCLUDEDIR [37m ${INCLUDEDIR}[00m'
|
||||||
@echo ' - MANDIR ${MANDIR}'
|
@echo ' - [01;34mMANDIR [37m ${MANDIR}[00m'
|
||||||
@echo ''
|
@echo ''
|
||||||
@echo 'Project targets: '
|
@echo '[01;37mProject targets: [00m'
|
||||||
@echo ' - libipc library'
|
@echo ' - [01;33mlibipc [37m library[00m'
|
||||||
@echo ' - src/ipc.h header'
|
@echo ' - [01;33msrc/ipc.h [37m header[00m'
|
||||||
@echo ' - man/libipc.7 man'
|
@echo ' - [01;33mman/libipc.7 [37m man[00m'
|
||||||
@echo ''
|
@echo ''
|
||||||
@echo 'Makefile options:'
|
@echo '[01;37mMakefile options:[00m'
|
||||||
@echo ' - gnu: false'
|
@echo ' - gnu: false'
|
||||||
@echo ' - colors: false'
|
@echo ' - colors: true'
|
||||||
@echo ''
|
@echo ''
|
||||||
@echo 'Rebuild the Makefile with:'
|
@echo '[01;37mRebuild the Makefile with:[00m'
|
||||||
@echo ' zsh ./build.zsh'
|
@echo ' zsh ./build.zsh -c'
|
||||||
.PHONY: all subdirs clean distclean dist install uninstall help
|
.PHONY: all subdirs clean distclean dist install uninstall help
|
||||||
|
|
||||||
|
@ -6,28 +6,24 @@
|
|||||||
#include "../src/ipc.h"
|
#include "../src/ipc.h"
|
||||||
|
|
||||||
#define MSG "coucou"
|
#define MSG "coucou"
|
||||||
#define SERVICE_NAME "pongd"
|
#define SERVICE_NAME "pong"
|
||||||
|
|
||||||
#define PRINTERR(ret,msg) {\
|
#define PRINTERR(ret,msg) {\
|
||||||
const char * err = ipc_errors_get (ret);\
|
const char * err = ipc_errors_get (ret);\
|
||||||
fprintf(stderr, "error while %s: %s\n", msg, err);\
|
fprintf(stderr, "error while %s: %s\n", msg, err);\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ipc_connection_info *srv;
|
||||||
|
|
||||||
void non_interactive (char *env[])
|
void non_interactive (char *env[])
|
||||||
{
|
{
|
||||||
struct ipc_message m;
|
struct ipc_message m;
|
||||||
memset (&m, 0, sizeof (struct ipc_message));
|
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;
|
enum ipc_errors ret;
|
||||||
|
|
||||||
// init service
|
// init service
|
||||||
ret = ipc_connection (env, &srv, SERVICE_NAME);
|
ret = ipc_connection (env, srv, SERVICE_NAME);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_err("main", "ipc_application_connection < 0");
|
handle_err("main", "ipc_application_connection < 0");
|
||||||
PRINTERR(ret, "application connection");
|
PRINTERR(ret, "application connection");
|
||||||
@ -43,7 +39,7 @@ void non_interactive (char *env[])
|
|||||||
|
|
||||||
// printf ("msg to send in the client: ");
|
// printf ("msg to send in the client: ");
|
||||||
// ipc_message_print (&m);
|
// ipc_message_print (&m);
|
||||||
ret = ipc_write (&srv, &m);
|
ret = ipc_write (srv, &m);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_err("main", "application_write");
|
handle_err("main", "application_write");
|
||||||
PRINTERR(ret, "application write");
|
PRINTERR(ret, "application write");
|
||||||
@ -51,7 +47,7 @@ void non_interactive (char *env[])
|
|||||||
}
|
}
|
||||||
ipc_message_empty (&m);
|
ipc_message_empty (&m);
|
||||||
|
|
||||||
ret = ipc_read (&srv, &m);
|
ret = ipc_read (srv, &m);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_err("main", "application_read");
|
handle_err("main", "application_read");
|
||||||
PRINTERR(ret, "application read");
|
PRINTERR(ret, "application read");
|
||||||
@ -61,7 +57,7 @@ void non_interactive (char *env[])
|
|||||||
printf ("msg recv (type: %u): %s\n", m.user_type, m.payload);
|
printf ("msg recv (type: %u): %s\n", m.user_type, m.payload);
|
||||||
ipc_message_empty (&m);
|
ipc_message_empty (&m);
|
||||||
|
|
||||||
ret = ipc_close (&srv);
|
ret = ipc_close (srv);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_err("main", "application_close");
|
handle_err("main", "application_close");
|
||||||
PRINTERR(ret, "application close");
|
PRINTERR(ret, "application close");
|
||||||
@ -72,15 +68,9 @@ void non_interactive (char *env[])
|
|||||||
void interactive (char *env[])
|
void interactive (char *env[])
|
||||||
{
|
{
|
||||||
enum ipc_errors ret;
|
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
|
// init service
|
||||||
ret = ipc_connection (env, &srv, SERVICE_NAME);
|
ret = ipc_connection (env, srv, SERVICE_NAME);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_err ("main", "ipc_application_connection < 0");
|
handle_err ("main", "ipc_application_connection < 0");
|
||||||
PRINTERR(ret, "application connection");
|
PRINTERR(ret, "application connection");
|
||||||
@ -92,48 +82,66 @@ void interactive (char *env[])
|
|||||||
|
|
||||||
struct ipc_connection_infos services;
|
struct ipc_connection_infos services;
|
||||||
memset (&services, 0, sizeof (struct ipc_connection_infos));
|
memset (&services, 0, sizeof (struct ipc_connection_infos));
|
||||||
ipc_add (&services, &srv);
|
ipc_add (&services, srv);
|
||||||
|
|
||||||
ipc_add_fd (&services, 0); // add STDIN
|
ipc_add_fd (&services, 0); // add STDIN
|
||||||
|
|
||||||
|
ipc_connections_print(&services);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
printf ("msg to send: ");
|
printf ("msg to send: ");
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
ret = ipc_wait_event (&services, NULL, &event);
|
ret = ipc_wait_event (&services, NULL, &event);
|
||||||
|
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_error("ipc_application_peek_event != 0");
|
PRINTERR(ret, "wait event");
|
||||||
PRINTERR(ret, "application peek event");
|
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case IPC_EVENT_TYPE_EXTRA_SOCKET:
|
case IPC_EVENT_TYPE_EXTRA_SOCKET:
|
||||||
{
|
{
|
||||||
struct ipc_message *m = event.m;
|
// structure not read, should read the message here
|
||||||
if ( m->length == 0 || strncmp (m->payload, "exit", 4) == 0) {
|
|
||||||
|
|
||||||
ipc_message_empty (m);
|
ssize_t len;
|
||||||
free (m);
|
char buf[4096];
|
||||||
|
memset(buf, 0, 4096);
|
||||||
|
|
||||||
ipc_connections_free (&services);
|
len = read (event.origin->fd, buf, 4096);
|
||||||
|
|
||||||
ret = ipc_close (&srv);
|
buf[100] = '\0';
|
||||||
|
|
||||||
|
// in case we want to quit the program
|
||||||
|
if ( len == 0
|
||||||
|
|| strncmp (buf, "quit", 4) == 0
|
||||||
|
|| strncmp (buf, "exit", 4) == 0) {
|
||||||
|
|
||||||
|
ret = ipc_close (srv);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_err("main", "application_close < 0");
|
handle_err("main", "ipc_close");
|
||||||
PRINTERR(ret, "application close");
|
PRINTERR(ret, "application close");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ipc_connections_free (&services);
|
||||||
|
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ipc_write (&srv, m);
|
// send the message read on STDIN
|
||||||
|
struct ipc_message *m = NULL;
|
||||||
|
m = malloc (sizeof (struct ipc_message));
|
||||||
|
memset (m, 0, sizeof (struct ipc_message));
|
||||||
|
|
||||||
|
ret = ipc_write (srv, m);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_err("main", "application_write < 0");
|
handle_err("main", "ipc_write");
|
||||||
PRINTERR(ret, "application write");
|
PRINTERR(ret, "ipc_write");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ipc_message_empty (m);
|
||||||
|
free (m);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IPC_EVENT_TYPE_MESSAGE:
|
case IPC_EVENT_TYPE_MESSAGE:
|
||||||
@ -157,6 +165,13 @@ int main (int argc, char *argv[], char *env[])
|
|||||||
argc = argc; // warnings
|
argc = argc; // warnings
|
||||||
argv = argv; // warnings
|
argv = argv; // warnings
|
||||||
|
|
||||||
|
srv = malloc (sizeof (struct ipc_connection_info));
|
||||||
|
memset (srv, 0, sizeof (struct ipc_connection_info));
|
||||||
|
|
||||||
|
// index and version should be filled
|
||||||
|
srv->index = 0;
|
||||||
|
srv->version = 0;
|
||||||
|
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
non_interactive (env);
|
non_interactive (env);
|
||||||
else
|
else
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define PONGD_SERVICE_NAME "pongd"
|
#define PONGD_SERVICE_NAME "pong"
|
||||||
|
#define PONGD_VERBOSE
|
||||||
|
|
||||||
#define PRINTERR(ret,msg) {\
|
#define PRINTERR(ret,msg) {\
|
||||||
const char * err = ipc_errors_get (ret);\
|
const char * err = ipc_errors_get (ret);\
|
||||||
@ -32,16 +33,15 @@ void main_loop ()
|
|||||||
while(1) {
|
while(1) {
|
||||||
// ipc_service_poll_event provides one event at a time
|
// ipc_service_poll_event provides one event at a time
|
||||||
// warning: event->m is free'ed if not NULL
|
// warning: event->m is free'ed if not NULL
|
||||||
printf ("before poll\n"); // TODO remove
|
// printf ("before wait event\n"); // TODO remove
|
||||||
ret = ipc_wait_event (clients, srv, &event);
|
ret = ipc_wait_event (clients, srv, &event);
|
||||||
|
// printf ("after wait event\n"); // TODO remove
|
||||||
if (ret != IPC_ERROR_NONE && ret != IPC_ERROR_CLOSED_RECIPIENT) {
|
if (ret != IPC_ERROR_NONE && ret != IPC_ERROR_CLOSED_RECIPIENT) {
|
||||||
handle_error("ipc_service_poll_event != IPC_ERROR_NONE");
|
|
||||||
PRINTERR(ret,"service poll event");
|
PRINTERR(ret,"service poll event");
|
||||||
|
|
||||||
// the application will shut down, and close the service
|
// the application will shut down, and close the service
|
||||||
ret = ipc_server_close (srv);
|
ret = ipc_server_close (srv);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_error("ipc_server_close < 0");
|
|
||||||
PRINTERR(ret,"server close");
|
PRINTERR(ret,"server close");
|
||||||
}
|
}
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
@ -51,14 +51,18 @@ void main_loop ()
|
|||||||
case IPC_EVENT_TYPE_CONNECTION:
|
case IPC_EVENT_TYPE_CONNECTION:
|
||||||
{
|
{
|
||||||
cpt++;
|
cpt++;
|
||||||
printf ("connection: %d clients connected\n", cpt);
|
#ifdef PONGD_VERBOSE
|
||||||
printf ("new client has the fd %d\n", (event.origin)->fd);
|
printf ("connection: %d clients connected, new client is %d\n"
|
||||||
|
, cpt, (event.origin)->fd);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case IPC_EVENT_TYPE_DISCONNECTION:
|
case IPC_EVENT_TYPE_DISCONNECTION:
|
||||||
{
|
{
|
||||||
cpt--;
|
cpt--;
|
||||||
|
#ifdef PONGD_VERBOSE
|
||||||
printf ("disconnection: %d clients remaining\n", cpt);
|
printf ("disconnection: %d clients remaining\n", cpt);
|
||||||
|
#endif
|
||||||
|
|
||||||
// free the ipc_client structure
|
// free the ipc_client structure
|
||||||
free (event.origin);
|
free (event.origin);
|
||||||
@ -68,21 +72,25 @@ void main_loop ()
|
|||||||
{
|
{
|
||||||
struct ipc_message *m = event.m;
|
struct ipc_message *m = event.m;
|
||||||
if (m->length > 0) {
|
if (m->length > 0) {
|
||||||
|
#ifdef PONGD_VERBOSE
|
||||||
printf ("message received (type %d): %.*s\n", m->type, m->length, m->payload);
|
printf ("message received (type %d): %.*s\n", m->type, m->length, m->payload);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ipc_write (event.origin, m);
|
ret = ipc_write (event.origin, m);
|
||||||
|
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_err( "handle_new_msg", "server_write < 0");
|
|
||||||
PRINTERR(ret,"server write");
|
PRINTERR(ret,"server write");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case IPC_EVENT_TYPE_ERROR:
|
case IPC_EVENT_TYPE_ERROR:
|
||||||
{
|
{
|
||||||
fprintf (stderr, "a problem happened with client %d\n"
|
cpt--;
|
||||||
, (event.origin)->fd);
|
fprintf (stderr, "a problem happened with client %d (now disconnected)", (event.origin)->fd);
|
||||||
|
fprintf (stderr, ", %d clients remaining\n", cpt);
|
||||||
|
|
||||||
|
// free the ipc_client structure
|
||||||
|
free (event.origin);
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
@ -117,7 +125,6 @@ void exit_program(int signal)
|
|||||||
// the application will shut down, and close the service
|
// the application will shut down, and close the service
|
||||||
enum ipc_errors ret = ipc_server_close (srv);
|
enum ipc_errors ret = ipc_server_close (srv);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_error("ipc_server_close < 0");
|
|
||||||
PRINTERR(ret,"server close");
|
PRINTERR(ret,"server close");
|
||||||
}
|
}
|
||||||
free (srv);
|
free (srv);
|
||||||
@ -150,7 +157,6 @@ int main(int argc, char * argv[], char **env)
|
|||||||
|
|
||||||
enum ipc_errors ret = ipc_server_init (env, srv, PONGD_SERVICE_NAME);
|
enum ipc_errors ret = ipc_server_init (env, srv, PONGD_SERVICE_NAME);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_error("ipc_server_init != IPC_ERROR_NONE");
|
|
||||||
PRINTERR(ret,"server init");
|
PRINTERR(ret,"server init");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
160
examples/simple-tcp-client.c
Normal file
160
examples/simple-tcp-client.c
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "../src/ipc.h"
|
||||||
|
#include "../src/utils.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tcp connection to localhost port argv[1]
|
||||||
|
* message 1: pong
|
||||||
|
* message 2: echo with libipc format
|
||||||
|
*
|
||||||
|
* [messagetype | len | usertype | payload ]
|
||||||
|
* 1 B | 4 B | 1 B | ]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
int connection(int port)
|
||||||
|
{
|
||||||
|
int sockfd;
|
||||||
|
struct sockaddr_in server;
|
||||||
|
socklen_t addrlen;
|
||||||
|
|
||||||
|
// socket factory
|
||||||
|
if((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
|
||||||
|
{
|
||||||
|
perror("socket");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// init remote addr structure and other params
|
||||||
|
server.sin_family = AF_INET;
|
||||||
|
server.sin_port = htons(port);
|
||||||
|
addrlen = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
|
// get addr from command line and convert it
|
||||||
|
if(inet_pton(AF_INET, "127.0.0.1", &server.sin_addr) <= 0)
|
||||||
|
{
|
||||||
|
perror("inet_pton");
|
||||||
|
close(sockfd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Trying to connect to the remote host\n");
|
||||||
|
if(connect(sockfd, (struct sockaddr *) &server, addrlen) == -1)
|
||||||
|
{
|
||||||
|
perror("connect");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Connection OK\n");
|
||||||
|
|
||||||
|
return sockfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void send_receive (int sockfd) {
|
||||||
|
unsigned char buf[BUFSIZ];
|
||||||
|
memset (buf, 0, BUFSIZ);
|
||||||
|
|
||||||
|
// first, send service name "pong"
|
||||||
|
// send string
|
||||||
|
if(send(sockfd, "pong", 4, 0) == -1) {
|
||||||
|
perror("send pong");
|
||||||
|
close(sockfd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
printf ("message 'pong' sent\n");
|
||||||
|
|
||||||
|
memset (buf, 0, BUFSIZ);
|
||||||
|
|
||||||
|
int paylen;
|
||||||
|
paylen = recv(sockfd, buf, BUFSIZ, 0);
|
||||||
|
if (paylen <= 0) {
|
||||||
|
printf ("cannot connect to networkd\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
printf ("should receive 'OK': %*.s\n", paylen, buf);
|
||||||
|
|
||||||
|
memset (buf, 0, BUFSIZ);
|
||||||
|
|
||||||
|
buf[0] = MSG_TYPE_DATA;
|
||||||
|
|
||||||
|
// uint32_t v = htonl(6);
|
||||||
|
// memcpy (buf+1, &v, sizeof (uint32_t));
|
||||||
|
|
||||||
|
uint32_t v = 6;
|
||||||
|
uint32_t net_paylen = htonl (v);
|
||||||
|
memcpy (buf+1, &net_paylen, sizeof (uint32_t));
|
||||||
|
|
||||||
|
buf[5] = 0;
|
||||||
|
memcpy (buf+6, "coucou", 6);
|
||||||
|
|
||||||
|
print_hexa ("SENT MESSAGE", buf, 12);
|
||||||
|
|
||||||
|
// 2 | 6 | 0 | "coucou"
|
||||||
|
// 1 B | 4 B | 1 | 6 B
|
||||||
|
|
||||||
|
if(send(sockfd, buf, 12, 0) == -1) {
|
||||||
|
perror("send coucou");
|
||||||
|
close(sockfd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
printf ("message 'coucou' sent\n");
|
||||||
|
|
||||||
|
memset (buf, 0, BUFSIZ);
|
||||||
|
|
||||||
|
paylen = recv (sockfd, buf, BUFSIZ, 0);
|
||||||
|
if(paylen < 0) {
|
||||||
|
perror("recv a message");
|
||||||
|
close(sockfd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (paylen > 0) {
|
||||||
|
print_hexa ("RECEIVED MESSAGE", buf, paylen);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf (stderr, "error: disconnection from the server\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// send string
|
||||||
|
if(sendto(sockfd, , ), 0) == -1)
|
||||||
|
{
|
||||||
|
perror("sendto");
|
||||||
|
close(sockfd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
int port = 9000;
|
||||||
|
if (argc > 1) {
|
||||||
|
port = atoi (argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sockfd = connection (port);
|
||||||
|
|
||||||
|
send_receive (sockfd);
|
||||||
|
|
||||||
|
printf("Disconnection\n");
|
||||||
|
|
||||||
|
// close the socket
|
||||||
|
close(sockfd);
|
||||||
|
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
463
examples/simple-tcpd.c
Normal file
463
examples/simple-tcpd.c
Normal file
@ -0,0 +1,463 @@
|
|||||||
|
#include "../src/ipc.h"
|
||||||
|
#include "../src/utils.h"
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define NTAB(t) ((int) (sizeof (t) / sizeof (t)[0]))
|
||||||
|
#define SECURE_BUFFER_DECLARATION(type,name,size) type name[size]; memset(&name, 0, sizeof(type) * size);
|
||||||
|
// print error string
|
||||||
|
#define PRINT_ERR_STR(code) const char *estr = ipc_errors_get (code); fprintf (stderr, "%s", estr);
|
||||||
|
// Test Print Quit
|
||||||
|
#define T_P_Q(f,err,q) { ret = f; if (ret != IPC_ERROR_NONE) { fprintf (stderr, err); PRINT_ERR_STR(ret); exit (q); } }
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* TODO:
|
||||||
|
* This program is under heavy developement.
|
||||||
|
* Still many things to do.
|
||||||
|
* NOT READY FOR PRODUCTION.
|
||||||
|
*
|
||||||
|
Server side:
|
||||||
|
1. sock_tcp = tcp socket
|
||||||
|
2. ipc_server_init
|
||||||
|
3. ipc_add (ipc_server, sock_tcp)
|
||||||
|
4. wait_event
|
||||||
|
if reading on extra socket
|
||||||
|
if reading on sock_tcp
|
||||||
|
sock_client = accept
|
||||||
|
ipc_add_fd sock_client
|
||||||
|
elif reading on sock_client
|
||||||
|
TODO (first draft): print messages
|
||||||
|
else
|
||||||
|
lolwat shouldn't happen :(
|
||||||
|
elif reading on usual socket
|
||||||
|
do something
|
||||||
|
**/
|
||||||
|
|
||||||
|
#define SERVICE_NAME "simpletcp"
|
||||||
|
|
||||||
|
#define PRINTERR(ret,msg) {\
|
||||||
|
const char * err = ipc_errors_get (ret);\
|
||||||
|
fprintf(stderr, "error while %s: %s\n", msg, err);\
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ipc_switching {
|
||||||
|
int orig;
|
||||||
|
int dest;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ipc_switchings {
|
||||||
|
struct ipc_switching *collection;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct networkd {
|
||||||
|
int cpt;
|
||||||
|
struct ipc_connection_info *srv;
|
||||||
|
struct ipc_connection_infos *clients;
|
||||||
|
struct ipc_switchings * TCP_TO_IPC;
|
||||||
|
struct ipc_switchings * IPC_TO_TCP;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct networkd * ctx;
|
||||||
|
|
||||||
|
|
||||||
|
void ipc_switching_add (struct ipc_switchings *is, int orig, int dest)
|
||||||
|
{
|
||||||
|
is->collection = realloc(is->collection, sizeof(struct ipc_switching) * (is->size+1));
|
||||||
|
if (is->collection == NULL) {
|
||||||
|
printf ("error realloc\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
is->size++;
|
||||||
|
|
||||||
|
is->collection[is->size-1].orig = orig;
|
||||||
|
is->collection[is->size-1].dest = dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipc_switching_del (struct ipc_switchings *is, int orig)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < is->size; i++) {
|
||||||
|
if (is->collection[i].orig == orig) {
|
||||||
|
is->collection[i].orig = is->collection[is->size-1].orig;
|
||||||
|
int ret = is->collection[i].dest;
|
||||||
|
is->collection[i].dest = is->collection[is->size-1].dest;
|
||||||
|
|
||||||
|
size_t s = (is->size - 1) > 0 ? (is->size - 1) : 1;
|
||||||
|
|
||||||
|
is->collection = realloc(is->collection, sizeof(struct ipc_switching) * s);
|
||||||
|
if (is->collection == NULL) {
|
||||||
|
printf ("error realloc\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
is->size--;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipc_switching_get (struct ipc_switchings *is, int orig) {
|
||||||
|
for (size_t i = 0; i < is->size; i++) {
|
||||||
|
if (is->collection[i].orig == orig) {
|
||||||
|
return is->collection[i].dest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipc_switching_print (struct ipc_switchings *is) {
|
||||||
|
printf ("print!\n");
|
||||||
|
for (size_t i = 0; i < is->size; i++)
|
||||||
|
{
|
||||||
|
printf ("client %d - %d\n", is->collection[i].orig, is->collection[i].dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tcp_connection (char **env, int fd, char * buf, int len)
|
||||||
|
{
|
||||||
|
printf ("tcp client %d is not already connected to a service\n", fd);
|
||||||
|
buf[len] = '\0';
|
||||||
|
|
||||||
|
// for testing purposes
|
||||||
|
size_t last_char = strlen ((const char*)buf) -1;
|
||||||
|
if (buf[last_char] == '\n') {
|
||||||
|
buf[last_char] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("read something: where to connect %s\n", buf);
|
||||||
|
printf ("sending ok\n");
|
||||||
|
|
||||||
|
// TODO: tests
|
||||||
|
if (send (fd, "OK", 2, 0) <= 0) {
|
||||||
|
fprintf (stderr, "error: cannot send message\n");
|
||||||
|
perror("send");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SECURE_DECLARATION (struct ipc_connection_info, tcp_to_ipc_ci);
|
||||||
|
|
||||||
|
enum ipc_errors ret = 0;
|
||||||
|
T_P_Q (ipc_connection (env, &tcp_to_ipc_ci, buf), "cannot connect to the service\n", EXIT_FAILURE);
|
||||||
|
|
||||||
|
ipc_switching_add (ctx->TCP_TO_IPC, fd, tcp_to_ipc_ci.fd);
|
||||||
|
ipc_switching_add (ctx->IPC_TO_TCP, tcp_to_ipc_ci.fd, fd);
|
||||||
|
ipc_add_fd (ctx->clients, tcp_to_ipc_ci.fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_extra_socket (struct ipc_event event, int sockfd, char **env)
|
||||||
|
{
|
||||||
|
SECURE_DECLARATION (struct sockaddr_in, client);
|
||||||
|
socklen_t addrlen = 0;
|
||||||
|
|
||||||
|
printf ("something comes from somewhere: fd %d\n", event.origin->fd);
|
||||||
|
|
||||||
|
// NEW CLIENT
|
||||||
|
if (event.origin->fd == sockfd) {
|
||||||
|
int sock_fd_client;
|
||||||
|
if((sock_fd_client = accept(sockfd, (struct sockaddr *) &client, &addrlen)) == -1) {
|
||||||
|
perror("accept");
|
||||||
|
close(sockfd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
printf ("after accept\n");
|
||||||
|
// adding a client
|
||||||
|
ipc_add_fd (ctx->clients, sock_fd_client);
|
||||||
|
printf ("after ipc_add_fd, TCP client: %d\n", sock_fd_client);
|
||||||
|
}
|
||||||
|
// CLIENT IS TALKING
|
||||||
|
else {
|
||||||
|
SECURE_BUFFER_DECLARATION(char, buf, 4096);
|
||||||
|
|
||||||
|
ssize_t len = recv (event.origin->fd, buf, 4096, 0);
|
||||||
|
if (len > 0) {
|
||||||
|
|
||||||
|
print_hexa ("RECEIVED", (unsigned char*) buf, len);
|
||||||
|
|
||||||
|
// TODO: check if the message comes from an external IPC
|
||||||
|
int fd = ipc_switching_get (ctx->IPC_TO_TCP, event.origin->fd);
|
||||||
|
|
||||||
|
if (fd >= 0) {
|
||||||
|
printf ("SWITCH: ipc service %d sent a message for %d\n", event.origin->fd, fd);
|
||||||
|
int sent_len = send (fd, buf, len, 0);
|
||||||
|
if (sent_len < 0) {
|
||||||
|
perror ("write to ipc");
|
||||||
|
}
|
||||||
|
else if (sent_len != len) {
|
||||||
|
fprintf (stderr, "write NOT ENOUGH to tcp client\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fd = ipc_switching_get (ctx->TCP_TO_IPC, event.origin->fd);
|
||||||
|
if (fd >= 0) {
|
||||||
|
printf ("SWITCH: client %d sent a message for %d\n", event.origin->fd, fd);
|
||||||
|
int sent_len = send (fd, buf, len, 0);
|
||||||
|
if (sent_len < 0) {
|
||||||
|
perror ("write to ipc");
|
||||||
|
}
|
||||||
|
else if (sent_len != len) {
|
||||||
|
fprintf (stderr, "write NOT ENOUGH to ipc\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tcp_connection (env, event.origin->fd, buf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (len == 0) {
|
||||||
|
// disconnection
|
||||||
|
printf ("close connection\n");
|
||||||
|
|
||||||
|
int delfd = ipc_switching_del (ctx->TCP_TO_IPC, event.origin->fd);
|
||||||
|
if (delfd >= 0) {
|
||||||
|
close (delfd);
|
||||||
|
ipc_del_fd (ctx->clients, delfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
delfd = ipc_switching_del (ctx->IPC_TO_TCP, event.origin->fd);
|
||||||
|
if (delfd >= 0) {
|
||||||
|
close (delfd);
|
||||||
|
ipc_del_fd (ctx->clients, delfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
close (event.origin->fd);
|
||||||
|
ipc_del_fd (ctx->clients, event.origin->fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main_loop (int argc, char **argv, char **env)
|
||||||
|
{
|
||||||
|
argc = argc; // FIXME: useless
|
||||||
|
int sockfd;
|
||||||
|
|
||||||
|
struct sockaddr_in my_addr;
|
||||||
|
socklen_t addrlen;
|
||||||
|
|
||||||
|
// socket factory
|
||||||
|
if((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
|
||||||
|
{
|
||||||
|
perror("socket");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int yes = 1;
|
||||||
|
|
||||||
|
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
|
||||||
|
perror ("setsockopt");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// init local addr structure and other params
|
||||||
|
my_addr.sin_family = AF_INET;
|
||||||
|
my_addr.sin_port = htons(atoi(argv[1]));
|
||||||
|
my_addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
addrlen = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
|
// bind addr structure with socket
|
||||||
|
if(bind(sockfd, (struct sockaddr *) &my_addr, addrlen) == -1)
|
||||||
|
{
|
||||||
|
perror("bind");
|
||||||
|
close(sockfd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the socket in passive mode (only used for accept())
|
||||||
|
// and set the list size for pending connection
|
||||||
|
if(listen(sockfd, 5) == -1)
|
||||||
|
{
|
||||||
|
perror("listen");
|
||||||
|
close(sockfd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Waiting for incomming connection\n");
|
||||||
|
|
||||||
|
|
||||||
|
enum ipc_errors ret = 0;
|
||||||
|
|
||||||
|
ctx->clients = malloc (sizeof (struct ipc_connection_infos));
|
||||||
|
memset(ctx->clients, 0, sizeof(struct ipc_connection_infos));
|
||||||
|
|
||||||
|
struct ipc_event event;
|
||||||
|
memset(&event, 0, sizeof (struct ipc_event));
|
||||||
|
printf ("adding sockfd to ctx->clients\n");
|
||||||
|
ipc_add_fd (ctx->clients, sockfd);
|
||||||
|
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
// ipc_service_poll_event provides one event at a time
|
||||||
|
// warning: event->m is free'ed if not NULL
|
||||||
|
// printf ("before wait event\n"); // TODO remove
|
||||||
|
ret = ipc_wait_event (ctx->clients, ctx->srv, &event);
|
||||||
|
// printf ("after wait event\n"); // TODO remove
|
||||||
|
if (ret != IPC_ERROR_NONE && ret != IPC_ERROR_CLOSED_RECIPIENT) {
|
||||||
|
PRINTERR(ret,"wait event");
|
||||||
|
|
||||||
|
// the application will shut down, and close the service
|
||||||
|
ret = ipc_server_close (ctx->srv);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
PRINTERR(ret,"server close");
|
||||||
|
}
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event.type) {
|
||||||
|
case IPC_EVENT_TYPE_EXTRA_SOCKET:
|
||||||
|
{
|
||||||
|
handle_extra_socket (event, sockfd, env);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPC_EVENT_TYPE_CONNECTION:
|
||||||
|
{
|
||||||
|
ctx->cpt++;
|
||||||
|
printf ("connection: %d clients connected\n", ctx->cpt);
|
||||||
|
printf ("new client has the fd %d\n", (event.origin)->fd);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case IPC_EVENT_TYPE_DISCONNECTION:
|
||||||
|
{
|
||||||
|
ctx->cpt--;
|
||||||
|
printf ("disconnection: %d clients remaining\n", ctx->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 < ctx->clients->size ; i++) {
|
||||||
|
struct ipc_connection_info *cli = ctx->clients->cinfos[i];
|
||||||
|
if (cli != NULL) {
|
||||||
|
free (cli);
|
||||||
|
}
|
||||||
|
ctx->clients->cinfos[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ipc_connections_free (ctx->clients);
|
||||||
|
free (ctx->clients);
|
||||||
|
|
||||||
|
|
||||||
|
// the application will shut down, and close the service
|
||||||
|
enum ipc_errors ret = ipc_server_close (ctx->srv);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
PRINTERR(ret,"server close");
|
||||||
|
}
|
||||||
|
free (ctx->srv);
|
||||||
|
|
||||||
|
free (ctx->TCP_TO_IPC->collection);
|
||||||
|
free (ctx->TCP_TO_IPC);
|
||||||
|
free (ctx->IPC_TO_TCP->collection);
|
||||||
|
free (ctx->IPC_TO_TCP);
|
||||||
|
free (ctx);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
// check the number of args on command line
|
||||||
|
if(argc != 2)
|
||||||
|
{
|
||||||
|
printf("USAGE: %s port_num\n", argv[0]);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("pid = %d\n", getpid ());
|
||||||
|
|
||||||
|
ctx = malloc (sizeof (struct networkd));
|
||||||
|
memset (ctx, 0, sizeof (struct networkd));
|
||||||
|
|
||||||
|
|
||||||
|
ctx->TCP_TO_IPC = malloc(sizeof(struct ipc_switchings));
|
||||||
|
memset (ctx->TCP_TO_IPC, 0, sizeof(struct ipc_switchings));
|
||||||
|
ctx->TCP_TO_IPC->collection = malloc(sizeof(struct ipc_switching));
|
||||||
|
ctx->IPC_TO_TCP = malloc(sizeof(struct ipc_switchings));
|
||||||
|
memset (ctx->IPC_TO_TCP, 0, sizeof(struct ipc_switchings));
|
||||||
|
ctx->IPC_TO_TCP->collection = malloc(sizeof(struct ipc_switching));
|
||||||
|
|
||||||
|
ctx->srv = malloc (sizeof (struct ipc_connection_info));
|
||||||
|
if (ctx->srv == NULL) {
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
memset (ctx->srv, 0, sizeof (struct ipc_connection_info));
|
||||||
|
ctx->srv->type = '\0';
|
||||||
|
ctx->srv->index = 0;
|
||||||
|
ctx->srv->version = 0;
|
||||||
|
ctx->srv->fd = 0;
|
||||||
|
ctx->srv->spath = NULL;
|
||||||
|
|
||||||
|
enum ipc_errors ret = ipc_server_init (env, ctx->srv, SERVICE_NAME);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
PRINTERR(ret,"server init");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
printf ("Listening on %s.\n", ctx->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 (argc, argv, env);
|
||||||
|
|
||||||
|
// main_loop should not return
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
@ -14,6 +14,9 @@
|
|||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define IPC_CONNECTION_TYPE_IPC 'i'
|
||||||
|
#define IPC_CONNECTION_TYPE_EXTERNAL 'a'
|
||||||
|
|
||||||
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);
|
||||||
@ -25,7 +28,7 @@ void service_path (char *path, const char *sname, int32_t index, int32_t version
|
|||||||
if (rundir == NULL)
|
if (rundir == NULL)
|
||||||
rundir = RUNDIR;
|
rundir = RUNDIR;
|
||||||
|
|
||||||
snprintf (path, PATH_MAX, "%s/%s-%d-%d", rundir, sname, index, version);
|
snprintf (path, PATH_MAX-1, "%s/%s-%d-%d", rundir, sname, index, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*calculer le max filedescriptor*/
|
/*calculer le max filedescriptor*/
|
||||||
@ -68,6 +71,7 @@ enum ipc_errors ipc_server_init (char **env, struct ipc_connection_info *srv, co
|
|||||||
// gets the service path
|
// gets the service path
|
||||||
if (srv->spath != NULL) {
|
if (srv->spath != NULL) {
|
||||||
free (srv->spath);
|
free (srv->spath);
|
||||||
|
srv->spath = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t s = strlen (buf);
|
size_t s = strlen (buf);
|
||||||
@ -157,6 +161,8 @@ enum ipc_errors ipc_accept (struct ipc_connection_info *srv, struct ipc_connecti
|
|||||||
return IPC_ERROR_ACCEPT;
|
return IPC_ERROR_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p->type = IPC_CONNECTION_TYPE_IPC;
|
||||||
|
|
||||||
return IPC_ERROR_NONE;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,33 +188,25 @@ enum ipc_errors handle_new_connection (struct ipc_connection_info *cinfo
|
|||||||
return IPC_ERROR_HANDLE_NEW_CONNECTION__NO_CINFOS_PARAM;
|
return IPC_ERROR_HANDLE_NEW_CONNECTION__NO_CINFOS_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
*new_client = malloc(sizeof(struct ipc_connection_info));
|
*new_client = malloc (sizeof(struct ipc_connection_info));
|
||||||
if (*new_client == NULL) {
|
if (*new_client == NULL) {
|
||||||
return IPC_ERROR_HANDLE_NEW_CONNECTION__MALLOC;
|
return IPC_ERROR_HANDLE_NEW_CONNECTION__MALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(*new_client, 0, sizeof(struct ipc_connection_info));
|
memset(*new_client, 0, sizeof(struct ipc_connection_info));
|
||||||
|
|
||||||
enum ipc_errors ret = ipc_accept (cinfo, *new_client);
|
enum ipc_errors ret = ipc_accept (cinfo, *new_client);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_error("server_accept error");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ipc_add (cinfos, *new_client);
|
ret = ipc_add (cinfos, *new_client);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
handle_error("ipc_clients_add error");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return IPC_ERROR_NONE;
|
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
|
enum ipc_errors ipc_wait_event (struct ipc_connection_infos *cinfos
|
||||||
, struct ipc_connection_info *cinfo // NULL for clients
|
, struct ipc_connection_info *cinfo // NULL for clients
|
||||||
, struct ipc_event *event)
|
, struct ipc_event *event)
|
||||||
@ -276,6 +274,15 @@ enum ipc_errors ipc_wait_event (struct ipc_connection_infos *cinfos
|
|||||||
} else {
|
} else {
|
||||||
for(j = 0; j < cinfos->size; j++) {
|
for(j = 0; j < cinfos->size; j++) {
|
||||||
if(i == cinfos->cinfos[j]->fd ) {
|
if(i == cinfos->cinfos[j]->fd ) {
|
||||||
|
|
||||||
|
struct ipc_connection_info *pc = cinfos->cinfos[j];
|
||||||
|
|
||||||
|
// no treatment of the socket if external socket
|
||||||
|
if (pc->type == IPC_CONNECTION_TYPE_EXTERNAL) {
|
||||||
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_EXTRA_SOCKET, NULL, pc);
|
||||||
|
return IPC_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
||||||
enum ipc_errors ret;
|
enum ipc_errors ret;
|
||||||
@ -287,13 +294,23 @@ enum ipc_errors ipc_wait_event (struct ipc_connection_infos *cinfos
|
|||||||
memset (m, 0, sizeof (struct ipc_message));
|
memset (m, 0, sizeof (struct ipc_message));
|
||||||
|
|
||||||
// current talking client
|
// current talking client
|
||||||
struct ipc_connection_info *pc = cinfos->cinfos[j];
|
|
||||||
ret = ipc_read (pc, m);
|
ret = ipc_read (pc, m);
|
||||||
if (ret != IPC_ERROR_NONE && ret != IPC_ERROR_CLOSED_RECIPIENT) {
|
if (ret != IPC_ERROR_NONE && ret != IPC_ERROR_CLOSED_RECIPIENT) {
|
||||||
handle_err ("ipc_wait_event", "ipc_read");
|
handle_err ("ipc_wait_event", "ipc_read");
|
||||||
ipc_message_empty (m);
|
ipc_message_empty (m);
|
||||||
free (m);
|
free (m);
|
||||||
|
|
||||||
|
// if there is a problem, just remove the client
|
||||||
|
ret = ipc_close (pc);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_err( "ipc_wait_event", "ipc_close");
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ipc_del (cinfos, pc);
|
||||||
|
if (ret != IPC_ERROR_NONE) {
|
||||||
|
handle_err( "ipc_wait_event", "ipc_del");
|
||||||
|
}
|
||||||
|
|
||||||
IPC_EVENT_SET(event, IPC_EVENT_TYPE_ERROR, NULL, pc);
|
IPC_EVENT_SET(event, IPC_EVENT_TYPE_ERROR, NULL, pc);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -318,14 +335,7 @@ enum ipc_errors ipc_wait_event (struct ipc_connection_infos *cinfos
|
|||||||
return IPC_ERROR_NONE;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we received a new message
|
|
||||||
// from a client
|
|
||||||
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);
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_MESSAGE, m, pc);
|
||||||
}
|
|
||||||
return IPC_ERROR_NONE;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -351,7 +361,14 @@ enum ipc_errors ipc_add (struct ipc_connection_infos *cinfos, struct ipc_connect
|
|||||||
}
|
}
|
||||||
|
|
||||||
cinfos->size++;
|
cinfos->size++;
|
||||||
|
if (cinfos->size == 1 && cinfos->cinfos == NULL) {
|
||||||
|
// first allocation
|
||||||
|
cinfos->cinfos = malloc (sizeof(struct ipc_connection_info));
|
||||||
|
}
|
||||||
|
else {
|
||||||
cinfos->cinfos = realloc(cinfos->cinfos, sizeof(struct ipc_connection_info) * cinfos->size);
|
cinfos->cinfos = realloc(cinfos->cinfos, sizeof(struct ipc_connection_info) * cinfos->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (cinfos->cinfos == NULL) {
|
if (cinfos->cinfos == NULL) {
|
||||||
return IPC_ERROR_ADD__EMPTY_LIST;
|
return IPC_ERROR_ADD__EMPTY_LIST;
|
||||||
@ -381,6 +398,7 @@ enum ipc_errors ipc_del (struct ipc_connection_infos *cinfos, struct ipc_connect
|
|||||||
int32_t i;
|
int32_t i;
|
||||||
for (i = 0; i < cinfos->size; i++) {
|
for (i = 0; i < cinfos->size; i++) {
|
||||||
if (cinfos->cinfos[i] == p) {
|
if (cinfos->cinfos[i] == p) {
|
||||||
|
// TODO: possible memory leak if the ipc_connection_info is not free'ed
|
||||||
cinfos->cinfos[i] = cinfos->cinfos[cinfos->size-1];
|
cinfos->cinfos[i] = cinfos->cinfos[cinfos->size-1];
|
||||||
cinfos->size--;
|
cinfos->size--;
|
||||||
if (cinfos->size == 0) {
|
if (cinfos->size == 0) {
|
||||||
@ -404,13 +422,15 @@ enum ipc_errors ipc_del (struct ipc_connection_infos *cinfos, struct ipc_connect
|
|||||||
void ipc_connections_free (struct ipc_connection_infos *cinfos)
|
void ipc_connections_free (struct ipc_connection_infos *cinfos)
|
||||||
{
|
{
|
||||||
if (cinfos->cinfos != NULL) {
|
if (cinfos->cinfos != NULL) {
|
||||||
|
for (size_t i = 0; i < cinfos->size ; i++) {
|
||||||
|
free (cinfos->cinfos[i]);
|
||||||
|
}
|
||||||
free (cinfos->cinfos);
|
free (cinfos->cinfos);
|
||||||
cinfos->cinfos = NULL;
|
cinfos->cinfos = NULL;
|
||||||
}
|
}
|
||||||
cinfos->size = 0;
|
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)
|
struct ipc_connection_info * ipc_connection_copy (const struct ipc_connection_info *p)
|
||||||
{
|
{
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
@ -427,14 +447,12 @@ struct ipc_connection_info * ipc_connection_copy (const struct ipc_connection_in
|
|||||||
return copy;
|
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)
|
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);
|
return (p1->type == p2->type && p1->version == p2->version && p1->index == p2->index && p1->fd == p2->fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the client service structure
|
// 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
|
enum ipc_errors ipc_connection_gen (struct ipc_connection_info *cinfo
|
||||||
, uint32_t index, uint32_t version, int fd, char type)
|
, uint32_t index, uint32_t version, int fd, char type)
|
||||||
{
|
{
|
||||||
@ -457,12 +475,55 @@ enum ipc_errors ipc_add_fd (struct ipc_connection_infos *cinfos, int fd)
|
|||||||
return IPC_ERROR_ADD_FD__NO_PARAM_CINFOS;
|
return IPC_ERROR_ADD_FD__NO_PARAM_CINFOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ipc_connection_info *cinfo;
|
struct ipc_connection_info *cinfo = NULL;
|
||||||
|
|
||||||
|
cinfo = malloc (sizeof(struct ipc_connection_info));
|
||||||
|
if (cinfo == NULL) {
|
||||||
|
return IPC_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
memset (cinfo, 0, sizeof(struct ipc_connection_info));
|
||||||
|
|
||||||
enum ipc_errors ret;
|
enum ipc_errors ret;
|
||||||
ret = ipc_connection_gen (cinfo, 0, 0, fd, 'a');
|
ipc_connection_gen (cinfo, 0, 0, fd, IPC_CONNECTION_TYPE_EXTERNAL);
|
||||||
|
|
||||||
|
return ipc_add (cinfos, cinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove a connection from its file descriptor
|
||||||
|
enum ipc_errors ipc_del_fd (struct ipc_connection_infos *cinfos, int fd)
|
||||||
|
{
|
||||||
|
assert(cinfos != NULL);
|
||||||
|
if (cinfos == NULL) {
|
||||||
|
return IPC_ERROR_DEL_FD__NO_PARAM_CINFOS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cinfos->cinfos == NULL) {
|
||||||
|
return IPC_ERROR_DEL_FD__EMPTY_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t i;
|
||||||
|
for (i = 0; i < cinfos->size; i++) {
|
||||||
|
if (cinfos->cinfos[i]->fd == fd) {
|
||||||
|
free (cinfos->cinfos[i]);
|
||||||
|
cinfos->size--;
|
||||||
|
if (cinfos->size == 0) {
|
||||||
|
// free cinfos->cinfos
|
||||||
|
ipc_connections_free (cinfos);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cinfos->cinfos[i] = cinfos->cinfos[cinfos->size];
|
||||||
|
cinfos->cinfos = realloc(cinfos->cinfos, sizeof(struct ipc_connection_info) * cinfos->size);
|
||||||
|
|
||||||
|
if (cinfos->cinfos == NULL) {
|
||||||
|
return IPC_ERROR_DEL_FD__EMPTIED_LIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return IPC_ERROR_NONE;
|
return IPC_ERROR_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IPC_ERROR_DEL_FD__CANNOT_FIND_CLIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ipc_connection_print (struct ipc_connection_info *cinfo)
|
void ipc_connection_print (struct ipc_connection_info *cinfo)
|
||||||
|
@ -22,6 +22,7 @@ static struct ipc_errors_verbose ipc_errors_verbose [] = {
|
|||||||
, IPC_ERROR_CONNECTION__NO_SERVER, "ipc_connection: no server parameter"
|
, 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_SERVICE_NAME, "ipc_connection: no service name parameter"
|
||||||
, IPC_ERROR_CONNECTION__NO_ENVIRONMENT_PARAM, "ipc_connection: no environment param"
|
, IPC_ERROR_CONNECTION__NO_ENVIRONMENT_PARAM, "ipc_connection: no environment param"
|
||||||
|
, IPC_ERROR_USOCK_CONNECT__CONNECT, "ipc_connection: error on the connect function"
|
||||||
|
|
||||||
, IPC_ERROR_CONNECTION_GEN__NO_CINFO, "ipc_connection_gen: no cinfo"
|
, IPC_ERROR_CONNECTION_GEN__NO_CINFO, "ipc_connection_gen: no cinfo"
|
||||||
|
|
||||||
@ -43,6 +44,12 @@ static struct ipc_errors_verbose ipc_errors_verbose [] = {
|
|||||||
, IPC_ERROR_ADD__NO_PARAM_CLIENT, "ipc_clients_add: no param client"
|
, 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_ADD_FD__NO_PARAM_CINFOS, "ipc_add_fd: no cinfos param"
|
||||||
|
, IPC_ERROR_ADD_FD__EMPTY_LIST, "ipc_add_fd: empty list after realloc (memory problem)"
|
||||||
|
|
||||||
|
, IPC_ERROR_DEL_FD__NO_PARAM_CINFOS, "ipc_del_fd: no cinfos param"
|
||||||
|
, IPC_ERROR_DEL_FD__EMPTIED_LIST, "ipc_del_fd: empty list after realloc (memory problem)"
|
||||||
|
, IPC_ERROR_DEL_FD__EMPTY_LIST, "ipc_del_fd: empty list"
|
||||||
|
, IPC_ERROR_DEL_FD__CANNOT_FIND_CLIENT, "ipc_del_fd: cannot find user"
|
||||||
|
|
||||||
, IPC_ERROR_DEL__EMPTY_LIST, "ipc_clients_del: empty list"
|
, IPC_ERROR_DEL__EMPTY_LIST, "ipc_clients_del: empty list"
|
||||||
, IPC_ERROR_DEL__EMPTIED_LIST, "ipc_clients_del: cannot realloc"
|
, IPC_ERROR_DEL__EMPTIED_LIST, "ipc_clients_del: cannot realloc"
|
||||||
|
13
src/ipc.h
13
src/ipc.h
@ -16,6 +16,8 @@
|
|||||||
// #define IPC_MAX_MESSAGE_SIZE 100-IPC_HEADER_SIZE
|
// #define IPC_MAX_MESSAGE_SIZE 100-IPC_HEADER_SIZE
|
||||||
// #include "queue.h"
|
// #include "queue.h"
|
||||||
|
|
||||||
|
#define SECURE_DECLARATION(t,v) t v; memset(&v,0,sizeof(t));
|
||||||
|
|
||||||
#define IPC_VERSION 1
|
#define IPC_VERSION 1
|
||||||
|
|
||||||
|
|
||||||
@ -71,6 +73,12 @@ enum ipc_errors {
|
|||||||
, IPC_ERROR_ADD__NO_PARAM_CLIENT
|
, IPC_ERROR_ADD__NO_PARAM_CLIENT
|
||||||
|
|
||||||
, IPC_ERROR_ADD_FD__NO_PARAM_CINFOS
|
, IPC_ERROR_ADD_FD__NO_PARAM_CINFOS
|
||||||
|
, IPC_ERROR_ADD_FD__EMPTY_LIST
|
||||||
|
|
||||||
|
, IPC_ERROR_DEL_FD__NO_PARAM_CINFOS
|
||||||
|
, IPC_ERROR_DEL_FD__EMPTIED_LIST
|
||||||
|
, IPC_ERROR_DEL_FD__EMPTY_LIST
|
||||||
|
, IPC_ERROR_DEL_FD__CANNOT_FIND_CLIENT
|
||||||
|
|
||||||
, IPC_ERROR_DEL__EMPTY_LIST
|
, IPC_ERROR_DEL__EMPTY_LIST
|
||||||
, IPC_ERROR_DEL__EMPTIED_LIST
|
, IPC_ERROR_DEL__EMPTIED_LIST
|
||||||
@ -86,6 +94,7 @@ enum ipc_errors {
|
|||||||
, IPC_ERROR_USOCK_CONNECT__SOCKET
|
, IPC_ERROR_USOCK_CONNECT__SOCKET
|
||||||
, IPC_ERROR_USOCK_CONNECT__WRONG_FILE_DESCRIPTOR
|
, IPC_ERROR_USOCK_CONNECT__WRONG_FILE_DESCRIPTOR
|
||||||
, IPC_ERROR_USOCK_CONNECT__EMPTY_PATH
|
, IPC_ERROR_USOCK_CONNECT__EMPTY_PATH
|
||||||
|
, IPC_ERROR_USOCK_CONNECT__CONNECT
|
||||||
|
|
||||||
, IPC_ERROR_USOCK_CLOSE
|
, IPC_ERROR_USOCK_CLOSE
|
||||||
|
|
||||||
@ -166,13 +175,10 @@ struct ipc_event {
|
|||||||
|
|
||||||
#ifdef IPC_WITH_ERRORS
|
#ifdef IPC_WITH_ERRORS
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#define handle_error(msg) \
|
|
||||||
do { log_error (msg); exit(EXIT_FAILURE); } while (0)
|
|
||||||
|
|
||||||
#define handle_err(fun,msg)\
|
#define handle_err(fun,msg)\
|
||||||
do { log_error ("%s: file %s line %d %s", fun, __FILE__, __LINE__, msg); } while (0)
|
do { log_error ("%s: file %s line %d %s", fun, __FILE__, __LINE__, msg); } while (0)
|
||||||
#else
|
#else
|
||||||
#define handle_error(msg)
|
|
||||||
#define handle_err(fun,msg)
|
#define handle_err(fun,msg)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -226,6 +232,7 @@ enum ipc_errors ipc_del (struct ipc_connection_infos *, struct ipc_connection_in
|
|||||||
|
|
||||||
// add an arbitrary file descriptor to read
|
// add an arbitrary file descriptor to read
|
||||||
enum ipc_errors ipc_add_fd (struct ipc_connection_infos *cinfos, int fd);
|
enum ipc_errors ipc_add_fd (struct ipc_connection_infos *cinfos, int fd);
|
||||||
|
enum ipc_errors ipc_del_fd (struct ipc_connection_infos *cinfos, int fd);
|
||||||
|
|
||||||
void ipc_connections_free (struct ipc_connection_infos *);
|
void ipc_connections_free (struct ipc_connection_infos *);
|
||||||
|
|
||||||
|
@ -4,11 +4,15 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "usocket.h"
|
#include "usocket.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define IPC_WITH_ERRORS 3
|
||||||
|
|
||||||
void ipc_message_print (const struct ipc_message *m)
|
void ipc_message_print (const struct ipc_message *m)
|
||||||
{
|
{
|
||||||
assert (m != NULL);
|
assert (m != NULL);
|
||||||
@ -59,12 +63,14 @@ enum ipc_errors ipc_message_format_read (struct ipc_message *m, const char *buf,
|
|||||||
// message format:
|
// message format:
|
||||||
// Type (1 B) | Length (4 B) | UserType (1 B) | Payload (Length B)
|
// Type (1 B) | Length (4 B) | UserType (1 B) | Payload (Length B)
|
||||||
m->type = buf[0];
|
m->type = buf[0];
|
||||||
memcpy (&m->length, buf+1, sizeof m->length);
|
size_t unformated_size = 0;
|
||||||
|
memcpy (&unformated_size, buf+1, sizeof(size_t));
|
||||||
|
m->length = ntohl (unformated_size);
|
||||||
m->user_type = buf[1 + sizeof m->length];
|
m->user_type = buf[1 + sizeof m->length];
|
||||||
|
|
||||||
assert (m->length <= IPC_MAX_MESSAGE_SIZE);
|
assert (m->length <= IPC_MAX_MESSAGE_SIZE);
|
||||||
#if defined(IPC_WITH_ERRORS) && IPC_WITH_ERRORS > 2
|
#if defined(IPC_WITH_ERRORS) && IPC_WITH_ERRORS > 2
|
||||||
printf ("type %d, paylen = %u, total = %lu\n", m->type, m->length, msize);
|
printf ("receiving msg:\ttype %d, paylen %u, total %lu\n", m->type, m->length, msize);
|
||||||
#endif
|
#endif
|
||||||
assert (m->length == msize - IPC_HEADER_SIZE || m->length == 0);
|
assert (m->length == msize - IPC_HEADER_SIZE || m->length == 0);
|
||||||
|
|
||||||
@ -77,6 +83,9 @@ enum ipc_errors ipc_message_format_read (struct ipc_message *m, const char *buf,
|
|||||||
m->payload = malloc (m->length);
|
m->payload = malloc (m->length);
|
||||||
memcpy (m->payload, buf+IPC_HEADER_SIZE, m->length);
|
memcpy (m->payload, buf+IPC_HEADER_SIZE, m->length);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
m->payload = malloc (1);
|
||||||
|
}
|
||||||
|
|
||||||
return IPC_ERROR_NONE;
|
return IPC_ERROR_NONE;
|
||||||
}
|
}
|
||||||
@ -106,18 +115,20 @@ enum ipc_errors ipc_message_format_write (const struct ipc_message *m, char **bu
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *buffer = *buf;
|
char *buffer = *buf;
|
||||||
|
uint32_t paylen = htonl(m->length);
|
||||||
|
|
||||||
buffer[0] = m->type;
|
buffer[0] = m->type;
|
||||||
memcpy (buffer + 1, &m->length, sizeof m->length);
|
uint32_t net_paylen = htonl(m->length);
|
||||||
|
memcpy (buffer + 1, &net_paylen, sizeof(uint32_t));
|
||||||
buffer[1 + sizeof m->length] = m->user_type;
|
buffer[1 + sizeof m->length] = m->user_type;
|
||||||
if (m->payload != NULL) {
|
if (m->payload != NULL && m->length > 0) {
|
||||||
memcpy (buffer + IPC_HEADER_SIZE, m->payload, m->length);
|
memcpy (buffer + IPC_HEADER_SIZE, m->payload, m->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
*msize = IPC_HEADER_SIZE + m->length;
|
*msize = IPC_HEADER_SIZE + m->length;
|
||||||
|
|
||||||
#if defined(IPC_WITH_ERRORS) && IPC_WITH_ERRORS > 2
|
#if defined(IPC_WITH_ERRORS) && IPC_WITH_ERRORS > 2
|
||||||
printf ("sending msg: type %u, size %d, msize %ld\n", m->type, m->length, *msize);
|
printf ("sending msg:\ttype %u, paylen %u, msize %lu\n", m->type, m->length, *msize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return IPC_ERROR_NONE;
|
return IPC_ERROR_NONE;
|
||||||
@ -137,21 +148,19 @@ enum ipc_errors ipc_message_read (int32_t fd, struct ipc_message *m)
|
|||||||
|
|
||||||
enum ipc_errors ret = usock_recv (fd, &buf, &msize);
|
enum ipc_errors ret = usock_recv (fd, &buf, &msize);
|
||||||
if (ret != IPC_ERROR_NONE && ret != IPC_ERROR_CLOSED_RECIPIENT) {
|
if (ret != IPC_ERROR_NONE && ret != IPC_ERROR_CLOSED_RECIPIENT) {
|
||||||
if (buf != NULL)
|
|
||||||
free (buf);
|
|
||||||
handle_err ("msg_read", "usock_recv");
|
handle_err ("msg_read", "usock_recv");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// closed recipient, buffer already freed
|
// closed recipient, buffer already freed
|
||||||
if (ret == IPC_ERROR_CLOSED_RECIPIENT) {
|
if (ret == IPC_ERROR_CLOSED_RECIPIENT) {
|
||||||
if (buf != NULL)
|
|
||||||
free (buf);
|
|
||||||
return IPC_ERROR_CLOSED_RECIPIENT;
|
return IPC_ERROR_CLOSED_RECIPIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (buf != NULL) {
|
||||||
ret = ipc_message_format_read (m, buf, msize);
|
ret = ipc_message_format_read (m, buf, msize);
|
||||||
free (buf);
|
free (buf);
|
||||||
|
}
|
||||||
return ret; // propagates ipc_message_format return
|
return ret; // propagates ipc_message_format return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,9 +11,20 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include "usocket.h"
|
#include "usocket.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define IPC_DEBUG
|
||||||
|
|
||||||
|
#undef handle_err
|
||||||
|
#define handle_err(a,b) fprintf (stderr, "FUNCTION %s LINE %d ERROR %s\n", a, __LINE__, b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: non blocking read
|
||||||
|
*/
|
||||||
|
|
||||||
enum ipc_errors 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)
|
||||||
{
|
{
|
||||||
ssize_t ret = 0;
|
ssize_t ret = 0;
|
||||||
@ -32,7 +43,7 @@ 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);
|
||||||
|
|
||||||
ssize_t ret = 0;
|
int32_t ret_recv = 0;
|
||||||
|
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
handle_err ("usock_recv", "buf == NULL");
|
handle_err ("usock_recv", "buf == NULL");
|
||||||
@ -57,71 +68,95 @@ enum ipc_errors usock_recv (const int32_t fd, char **buf, ssize_t *len)
|
|||||||
uint32_t msize_read = 0;
|
uint32_t msize_read = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = recv (fd, *buf, *len, 0);
|
ret_recv = recv (fd, *buf, *len, 0);
|
||||||
|
if (ret_recv > 0) {
|
||||||
if (msize == 0) {
|
if (msize == 0) {
|
||||||
if (ret != 0) {
|
|
||||||
memcpy (&msize, *buf + 1, sizeof msize);
|
memcpy (&msize, *buf + 1, sizeof msize);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
printf ("pas la première boucle, msize == %u\n", msize);
|
||||||
|
}
|
||||||
|
msize = ntohl (msize);
|
||||||
|
|
||||||
|
if (msize >= IPC_MAX_MESSAGE_SIZE) {
|
||||||
|
#ifdef IPC_DEBUG
|
||||||
|
printf ("lecture bien passée : %d octets\n", ret_recv);
|
||||||
|
print_hexa ("msg recv", (uint8_t *)*buf, ret_recv);
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
assert (msize < IPC_MAX_MESSAGE_SIZE);
|
assert (msize < IPC_MAX_MESSAGE_SIZE);
|
||||||
msize_read += ret - IPC_HEADER_SIZE;
|
msize_read += ret_recv - IPC_HEADER_SIZE;
|
||||||
|
|
||||||
if (ret < 0) {
|
}
|
||||||
|
else if (ret_recv < 0) {
|
||||||
if (*buf != NULL)
|
if (*buf != NULL)
|
||||||
free (*buf);
|
free (*buf);
|
||||||
|
|
||||||
handle_err ("usock_recv", "recv ret < 0");
|
|
||||||
perror("recv");
|
|
||||||
*len = 0;
|
*len = 0;
|
||||||
|
|
||||||
switch (ret) {
|
switch (errno) {
|
||||||
|
|
||||||
// The receive buffer pointer(s) point outside the process's address space.
|
// The receive buffer pointer(s) point outside the process's address space.
|
||||||
case EFAULT:
|
case EFAULT:
|
||||||
handle_err ("usock_recv", "critical error: use of unallocated memory, quitting...");
|
handle_err ("usock_recv", "critical error: use of unallocated memory, quitting...");
|
||||||
exit (1);
|
fprintf (stderr, "ERROR WHILE RECEIVING: EFAULT\n");
|
||||||
|
break;
|
||||||
|
|
||||||
// Invalid argument passed.
|
// Invalid argument passed.
|
||||||
case EINVAL:
|
case EINVAL:
|
||||||
handle_err ("usock_recv", "critical error: invalid arguments to read(2), quitting...");
|
handle_err ("usock_recv", "critical error: invalid arguments to read(2), quitting...");
|
||||||
exit (1);
|
fprintf (stderr, "ERROR WHILE RECEIVING: EINVAL\n");
|
||||||
|
break;
|
||||||
|
|
||||||
// Could not allocate memory for recvmsg().
|
// Could not allocate memory for recvmsg().
|
||||||
case ENOMEM:
|
case ENOMEM:
|
||||||
handle_err ("usock_recv", "critical error: cannot allocate memory, quitting...");
|
handle_err ("usock_recv", "critical error: cannot allocate memory, quitting...");
|
||||||
exit (1);
|
fprintf (stderr, "ERROR WHILE RECEIVING: ENOMEM\n");
|
||||||
|
break;
|
||||||
|
|
||||||
// The argument sockfd is an invalid descriptor.
|
// The argument sockfd is an invalid descriptor.
|
||||||
case EBADF:
|
case EBADF:
|
||||||
handle_err ("usock_recv", "critical error: invalid descriptor, quitting...");
|
handle_err ("usock_recv", "critical error: invalid descriptor, quitting...");
|
||||||
exit (1);
|
fprintf (stderr, "ERROR WHILE RECEIVING: EBADF\n");
|
||||||
|
break;
|
||||||
|
|
||||||
// The file descriptor sockfd does not refer to a socket.
|
// The file descriptor sockfd does not refer to a socket.
|
||||||
case ENOTSOCK:
|
case ENOTSOCK:
|
||||||
handle_err ("usock_recv", "critical error: fd is not a socket, quitting...");
|
handle_err ("usock_recv", "critical error: fd is not a socket, quitting...");
|
||||||
exit (1);
|
fprintf (stderr, "ERROR WHILE RECEIVING: ENOTSOCK\n");
|
||||||
|
break;
|
||||||
|
|
||||||
// The socket is associated with a connection-oriented protocol and has not
|
// The socket is associated with a connection-oriented protocol and has not
|
||||||
// been connected (see connect(2) and accept(2)).
|
// been connected (see connect(2) and accept(2)).
|
||||||
case ENOTCONN:
|
case ENOTCONN:
|
||||||
handle_err ("usock_recv", "critical error: read(2) on a non connected socket, quitting...");
|
handle_err ("usock_recv", "critical error: read(2) on a non connected socket, quitting...");
|
||||||
exit (1);
|
fprintf (stderr, "ERROR WHILE RECEIVING: ENOTCONN\n");
|
||||||
|
break;
|
||||||
|
|
||||||
// EWOULDBLOCK
|
|
||||||
case EAGAIN:
|
case EAGAIN:
|
||||||
|
fprintf (stderr, "ERROR WHILE RECEIVING: EAGAIN / EWOULDBLOCK\n");
|
||||||
|
break;
|
||||||
|
|
||||||
// A remote host refused to allow the network connection
|
// A remote host refused to allow the network connection
|
||||||
// (typically because it is not running the requested service).
|
// (typically because it is not running the requested service).
|
||||||
case ECONNREFUSED:
|
case ECONNREFUSED:
|
||||||
|
fprintf (stderr, "ERROR WHILE RECEIVING: ECONNREFUSED\n");
|
||||||
|
break;
|
||||||
|
|
||||||
// The receive was interrupted by delivery of a signal before
|
// The receive was interrupted by delivery of a signal before
|
||||||
// any data were available; see signal(7).
|
// any data were available; see signal(7).
|
||||||
case EINTR:
|
case EINTR:
|
||||||
|
handle_err ("usock_recv", "unsupported error");
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
printf ("usock_recv unsupported error : %d\n", errno);
|
||||||
handle_err ("usock_recv", "unsupported error");
|
handle_err ("usock_recv", "unsupported error");
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handle_err ("usock_recv", "recv < 0");
|
||||||
|
perror("recv");
|
||||||
|
|
||||||
return IPC_ERROR_USOCK_RECV;
|
return IPC_ERROR_USOCK_RECV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +168,7 @@ enum ipc_errors usock_recv (const int32_t fd, char **buf, ssize_t *len)
|
|||||||
*len = msize + IPC_HEADER_SIZE;
|
*len = msize + IPC_HEADER_SIZE;
|
||||||
|
|
||||||
// 1 on none byte received, indicates a closed recipient
|
// 1 on none byte received, indicates a closed recipient
|
||||||
if (ret == 0) {
|
if (ret_recv == 0) {
|
||||||
if (*buf != NULL) {
|
if (*buf != NULL) {
|
||||||
free (*buf);
|
free (*buf);
|
||||||
*buf = NULL;
|
*buf = NULL;
|
||||||
@ -181,7 +216,7 @@ enum ipc_errors usock_connect (int32_t *fd, const char *path)
|
|||||||
if(connect(sfd, (struct sockaddr *) &my_addr, peer_addr_size) == -1) {
|
if(connect(sfd, (struct sockaddr *) &my_addr, peer_addr_size) == -1) {
|
||||||
handle_err ("usock_connect", "connect == -1");
|
handle_err ("usock_connect", "connect == -1");
|
||||||
perror("connect");
|
perror("connect");
|
||||||
exit(errno);
|
return IPC_ERROR_USOCK_CONNECT__CONNECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
*fd = sfd;
|
*fd = sfd;
|
||||||
|
@ -9,20 +9,14 @@
|
|||||||
// output: *sent = nb received bytes
|
// output: *sent = nb received bytes
|
||||||
enum ipc_errors 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 unsupported errors from read(2)
|
|
||||||
// exit on most errors from read(2)
|
|
||||||
//
|
|
||||||
// allocation of *len bytes on *buf == NULL
|
// allocation of *len bytes on *buf == NULL
|
||||||
//
|
//
|
||||||
// output: *len = nb sent bytes
|
// output: *len = nb sent bytes
|
||||||
enum ipc_errors 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
|
|
||||||
enum ipc_errors 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
|
|
||||||
enum ipc_errors usock_connect (int32_t *fd, const char *path);
|
enum ipc_errors usock_connect (int32_t *fd, const char *path);
|
||||||
|
|
||||||
enum ipc_errors usock_init (int32_t *fd, const char *path);
|
enum ipc_errors usock_init (int32_t *fd, const char *path);
|
||||||
|
Reference in New Issue
Block a user