From: Mika Laitio Date: Sat, 2 Oct 2010 10:26:24 +0000 (+0300) Subject: initial version X-Git-Url: http://pilppa.org/gitweb/?p=libplpha.git;a=commitdiff_plain;h=561391b3405e5742124b21cf0af3d68347fd6221 initial version --- 561391b3405e5742124b21cf0af3d68347fd6221 diff --git a/.cproject b/.cproject new file mode 100644 index 0000000..3f7ebe4 --- /dev/null +++ b/.cproject @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..cfa0f55 --- /dev/null +++ b/.project @@ -0,0 +1,78 @@ + + + libplpha + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..0af34e6 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Mika Laitio diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..b2f02dd --- /dev/null +++ b/COPYING @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..7d1c323 --- /dev/null +++ b/INSTALL @@ -0,0 +1,365 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008, 2009 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..7adfd16 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,4 @@ +libplpha is copyrighted software by Mika Laitio . +You can redistribute it and/or modify it under either the terms of the LGPL version 3 +(see COPYING.txt file), or by obtaining the license from the author. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..3fcdfbd --- /dev/null +++ b/Makefile.am @@ -0,0 +1,28 @@ +SUBDIRS = \ + src \ + src_test \ + data/configs +pkgconfigdir = $(libdir)/pkgconfig +EXTRA_DIST = libplpha.pc.in +pkgconfig_DATA = libplpha.pc +DISTCLEANFILES = \ + aclocal.m4 \ + config.h \ + config.h.in \ + config.log \ + config.status \ + config.cache \ + config.guess \ + config.sub \ + configure \ + depcomp \ + install-sh \ + libtool \ + ltmain.sh \ + Makefile.in \ + Makefile \ + missing \ + stamp-h \ + stamp-h1 \ + autom4te.cache \ + $(pkgconfig_DATA) \ No newline at end of file diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/README b/README new file mode 100644 index 0000000..1afd599 --- /dev/null +++ b/README @@ -0,0 +1,29 @@ +Description +----------- +This library provides a mechanism to read service files and launch and monitor them. + +Dependencies to other libraries +------------------------------- +- libuci for reading configuration files + +Build, install and clean +------------------------ +- build with command: ./autobuild.sh (generates required autoconf files) +- install with command: make install +- clean source code from generated build files: make distclean + +Examples +-------- +See the src_test/test_ha +"test_ha" is a example application which launches the processes defined in the +.service files available in the directory "src_test/etc/plp/ha" +(Note that these files needs to be copied to /etc/plp/ha directory and you must fix from them the ExecStart to executables) + +TODO +---- +- inotify integration +- process polling + +License +------- +GNU LESSER GENERAL PUBLIC LICENSE (lgpl) version 3, for details see the COPYING file. diff --git a/autobuild.sh b/autobuild.sh new file mode 100755 index 0000000..c318591 --- /dev/null +++ b/autobuild.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +if ! [ -e Makefile ] ; +then + echo "No Makefile available, generating it." + libtoolize --automake --force --copy + autoreconf --force --install + PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure --prefix=/usr/local +else + echo "Makefile found, no need to generate it." +fi +make diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..44c53b1 --- /dev/null +++ b/configure.ac @@ -0,0 +1,36 @@ +AC_INIT(src/launcher.c) +AM_CONFIG_HEADER(config.h) +AC_CONFIG_MACRO_DIR([m4]) + +PACKAGE=libplpha +VERSION=1.0.0 + +CFLAGS="$CFLAGS -g -Wall -Werror" +LDFLAGS="$LDFLAGS -lpthread" +AC_SUBST(CFLAGS) +AC_SUBST(LDFLAGS) +AC_MSG_NOTICE([libplpha Makefile]) + +AM_INIT_AUTOMAKE($PACKAGE, $VERSION) + +#AC_PROG_CXX +AC_STDC_HEADERS +AC_PROG_LIBTOOL +AC_PROG_INSTALL +#AM_PROG_CC_C_O + +PKG_PROG_PKG_CONFIG() + +PKG_CHECK_MODULES(SRC, libuci) +AC_SUBST(SRC_CFLAGS) +AC_SUBST(SRC_LIBS) + +AC_OUTPUT([ +libplpha.pc +Makefile +src/Makefile +src_test/Makefile +data/configs/Makefile +data/configs/test_client.service +data/configs/test_client2.service +]) diff --git a/data/configs/Makefile.am b/data/configs/Makefile.am new file mode 100644 index 0000000..4623749 --- /dev/null +++ b/data/configs/Makefile.am @@ -0,0 +1,6 @@ +configdir = $(sysconfdir)/plp/ha +config_in_files = test_client.service.in test_client2.service.in +config_DATA = $(config_in_files:.service.in=.service) +EXTRA_DIST = $(config_in_files) +DISTCLEANFILES = $(config_DATA) Makefile.in + diff --git a/data/configs/test_client.service.in b/data/configs/test_client.service.in new file mode 100644 index 0000000..d85d75e --- /dev/null +++ b/data/configs/test_client.service.in @@ -0,0 +1,2 @@ +config 'test_client' 'service' + option 'ExecStart' '@prefix@/bin/test_client' diff --git a/data/configs/test_client2.service.in b/data/configs/test_client2.service.in new file mode 100644 index 0000000..bd4f582 --- /dev/null +++ b/data/configs/test_client2.service.in @@ -0,0 +1,3 @@ +config 'hello' 'service' + option 'ExecStart' '@prefix@/bin/test_client2' + diff --git a/libplpha.pc.in b/libplpha.pc.in new file mode 100644 index 0000000..e71e780 --- /dev/null +++ b/libplpha.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libplpha +Description: pilppa communication bus library +Version: @VERSION@ +Requires: libuci +Cflags: -I${includedir} -I${includedir}/libplpha +Libs: -L${libdir} diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..40b9e27 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,10 @@ +lib_LTLIBRARIES = libplpha.la +libplpha_la_SOURCES = \ + launcher.c launcher.h \ + process_listener.c process_listener.h \ + process_parser.c process_parser.h \ + servicedir_listener.c servicedir_listener.h \ + process_info.h +libplpha_la_LDFLAGS = $(SRC_LIBS) $(all_libraries) -version-info 1:0:0 -no-undefined +AM_CPPFLAGS = $(SRC_CFLAGS) +DISTCLEANFILES = Makefile.in diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..cb99c56 --- /dev/null +++ b/src/common.h @@ -0,0 +1,15 @@ +/* + * common.h + * + * Created on: Sep 19, 2010 + * Author: lamikr + */ + +#ifndef COMMON_H_ +#define COMMON_H_ + +#define CONST_SERVICE_DIRECTORY_LOCATION "/etc/plp/ha" +#define CONST_MAX_INOTIFY_EVENT_COUNT_READ 16 +#define CONST_MAX_EXPECTED_INOTIFY_EVENT_SIZE 1024 + +#endif /* COMMON_H_ */ diff --git a/src/launcher.c b/src/launcher.c new file mode 100644 index 0000000..07f22cc --- /dev/null +++ b/src/launcher.c @@ -0,0 +1,34 @@ +/* + * launcher.c + * + * Created on: Sep 14, 2010 + * Author: lamikr + */ + +#include +#include +#include + +int launch_new_process(char *param_arr[]) { + int ret_val; + int child_pid; + + child_pid = fork(); + if (child_pid == -1) { + // failed to fork a new process + ret_val = -1; + } + else if (child_pid == 0) { + // code for launched child process + //execvp(param_arr[0], param_arr); + // first parameter must contain a full path to executable + execv(param_arr[0], param_arr); + printf("Failed to execute\n"); + exit(-1); + } + else { + // code for parent process which launched the child + ret_val = child_pid; + } + return ret_val; +} diff --git a/src/launcher.h b/src/launcher.h new file mode 100644 index 0000000..138d3b8 --- /dev/null +++ b/src/launcher.h @@ -0,0 +1,13 @@ +/* + * launcher.h + * + * Created on: Sep 14, 2010 + * Author: lamikr + */ + +#ifndef LAUNCHER_H_ +#define LAUNCHER_H_ + +void launch_new_process(char *param_arr[]); + +#endif /* LAUNCHER_H_ */ diff --git a/src/process_info.h b/src/process_info.h new file mode 100644 index 0000000..abe374b --- /dev/null +++ b/src/process_info.h @@ -0,0 +1,28 @@ +/* + * process_info.h + * + * Created on: Sep 17, 2010 + * Author: lamikr + */ + +#ifndef PROCESS_INFO_H_ +#define PROCESS_INFO_H_ + +typedef struct t_process_arg_list { + int count; + char **arg_arr; +} t_process_arg_list; + +typedef struct t_process_info { + int p_id; + t_process_arg_list *arg_list; + struct t_process_info *next; +} t_process_info; + +typedef struct t_process_info_list { + int count; + t_process_info *first_item; + t_process_info *last_item; +} t_process_info_list; + +#endif /* PROCESS_INFO_H_ */ diff --git a/src/process_listener.c b/src/process_listener.c new file mode 100644 index 0000000..81ef446 --- /dev/null +++ b/src/process_listener.c @@ -0,0 +1,50 @@ +/* + * process_listener.c + * + * Created on: Sep 18, 2010 + * Author: lamikr + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "process_listener.h" + +static pthread_t _listener_thread; +static bool _continue; + +static void *process_listener_thread(void *thread_args_pointer) +{ + int status; + int closed_pid; + + while(_continue) { + closed_pid = wait(&status); + if (closed_pid >= 0) { + printf("process closed: %d, status: %d\n", closed_pid, status); + } + } + pthread_exit(NULL); +} + +void start_process_listener() { + printf("listen_closed_processes()\n"); + + _listener_thread = 0; + _continue = true; + pthread_create(&_listener_thread, + NULL, + process_listener_thread, + (void *)NULL); +} + +void stop_process_listener() { + _continue = false; +// pthread_cancel(_listener_thread); +// pthread_join(_listener_thread, NULL); +} diff --git a/src/process_listener.h b/src/process_listener.h new file mode 100644 index 0000000..a82a129 --- /dev/null +++ b/src/process_listener.h @@ -0,0 +1,17 @@ +/* + * process_listener.h + * + * Created on: Sep 18, 2010 + * Author: lamikr + */ + +#ifndef PROCESS_LISTENER_H_ +#define PROCESS_LISTENER_H_ + +/** + * Listens when the launched processes will close. + */ +void start_process_listener(); +void stop_process_listener(); + +#endif /* PROCESS_LISTENER_H_ */ diff --git a/src/process_parser.c b/src/process_parser.c new file mode 100644 index 0000000..2dffdda --- /dev/null +++ b/src/process_parser.c @@ -0,0 +1,186 @@ +/* + * process_parser.c + * + * Created on: Sep 16, 2010 + * Author: lamikr + */ +#include +#include +#include +#include +#include + +#include "common.h" +#include "process_parser.h" + +t_process_arg_list *parse_command_line_args(char *cmd_line_param) { + char *line_pointer; + char *start; + int len; + t_process_arg_list *ret_val; + + ret_val = NULL; + if (cmd_line_param != NULL) { + ret_val = calloc(1, sizeof(t_process_arg_list)); + line_pointer = cmd_line_param; + while(*line_pointer != '\0') { + while((*line_pointer == ' ') || + (*line_pointer == '\t')) { + line_pointer++; + } + if (*line_pointer != '\0') { + if (ret_val->arg_arr == NULL) { + ret_val->arg_arr = calloc(1, sizeof(char *)); + } + else { + char **arg_arr; + + arg_arr = ret_val->arg_arr; + arg_arr = realloc(arg_arr, (ret_val->count + 1) * sizeof(char *)); + ret_val->arg_arr = arg_arr; + } + start = line_pointer; + len = 1; + while((*++line_pointer != '\0') && + (*line_pointer != ' ') && + (*line_pointer != '\t')) { + len++; + } + ret_val->arg_arr[ret_val->count] = strndup(start, len); + printf("ret_val[%d] = %s\n", ret_val->count, ret_val->arg_arr[ret_val->count]); + ret_val->count = ret_val->count + 1; + } + else { + break; + } + } + // terminate list with null + ret_val->arg_arr = realloc(ret_val->arg_arr, (ret_val->count + 1) * sizeof(char *)); + ret_val->arg_arr[ret_val->count] = NULL; + ret_val->count = ret_val->count + 1; + } + return ret_val; +} + +t_process_info *parse_process_info(struct uci_option *option_param) { + t_process_info *ret_val; + + ret_val = NULL; + if (option_param->type == UCI_TYPE_STRING) { + ret_val = calloc(1, sizeof(t_process_info)); + ret_val->arg_list = parse_command_line_args(option_param->v.string); + } + return ret_val; +} + +int add_process_config(t_process_info_list *list_param, struct uci_option *option_param) { + int ret_val; + t_process_info *new_item; + + ret_val = -1; + new_item = parse_process_info(option_param); + if (new_item != NULL) { + if (list_param->last_item != NULL) { + list_param->last_item->next = new_item; + list_param->last_item = new_item; + } + else { + list_param->first_item = new_item; + list_param->last_item = new_item; + } + list_param->count = list_param->count + 1; + ret_val = 0; + } + return ret_val; +} + +t_process_info_list *get_process_config_list() { + char **config_list; + char **config_file; + int err_flg; + struct uci_context *ctx; + struct uci_package *pkg; + struct uci_section *section; + struct uci_option *option; + t_process_info_list *ret_val; + + ret_val = calloc(1, sizeof(t_process_info_list)); + ctx = uci_alloc_context(); + if (ctx != NULL) { + uci_set_confdir(ctx, CONST_SERVICE_DIRECTORY_LOCATION); + config_list = NULL; + err_flg = uci_list_configs(ctx, &config_list); + if ((err_flg == UCI_OK) && + (config_list != NULL)) { + for (config_file = config_list; *config_file != NULL; config_file++) { + err_flg = uci_load(ctx, *config_file, &pkg); + if (err_flg == UCI_OK) { + section = uci_lookup_section(ctx, pkg, "service"); + if (section != NULL) { + option = uci_lookup_option(ctx, section, "ExecStart"); + switch (option->type) { + case UCI_TYPE_STRING: + printf("config file: %s name: %s, value: %s\n", *config_file, option->e.name, option->v.string); + add_process_config(ret_val, option); + break; + default: + break; + } + } + //int num_sections = _uci_show_package(*config_file, result); + //printf("Queried package: %s -> %d\n", *config_file, num_sections); + } + uci_unload(ctx, pkg); + } + // free config_files +/* + for (config_file = config_list; *config_file != NULL; config_file++) { + free(config_file); + } +*/ + free(config_list); + } + else { + printf("Failed to read service configurations from directory: %s\n", CONST_SERVICE_DIRECTORY_LOCATION); + } + uci_free_context(ctx); + } + else { + printf("Failed to read service configurations from directory: %s\n Memory allocation error.", CONST_SERVICE_DIRECTORY_LOCATION); + } + return ret_val; +} + +void release_process_config_arg_list(t_process_arg_list *arg_list_param) { + int ii; + + for (ii = 0; ii < arg_list_param->count; ii++) { + if (arg_list_param->arg_arr[ii] != NULL) { + free(arg_list_param->arg_arr[ii]); + arg_list_param->arg_arr[ii] = NULL; + } + } + free(arg_list_param->arg_arr); + arg_list_param->count = 0; + free(arg_list_param); +} + +void release_process_config_list(t_process_info_list *list_param) { + t_process_info *item; + t_process_info *next; + + if (list_param != NULL) { + item = list_param->first_item; + while (item != NULL) { + next = item->next; + item->next = NULL; + release_process_config_arg_list(item->arg_list); + item->arg_list = NULL; + free(item); + item = next; + } + list_param->first_item = NULL; + list_param->last_item = NULL; + free(list_param); + } +} diff --git a/src/process_parser.h b/src/process_parser.h new file mode 100644 index 0000000..7f2d0db --- /dev/null +++ b/src/process_parser.h @@ -0,0 +1,17 @@ +/* + * process_parser.h + * + * Created on: Sep 16, 2010 + * Author: lamikr + */ + +#ifndef INIT_PARSER_H_ +#define INIT_PARSER_H_ + +#include "process_info.h" + +t_process_info_list *get_process_config_list(); +void release_process_config_list(t_process_info_list *list_param); +void release_process_config_arg_list(t_process_arg_list *arg_list_param); + +#endif /* INIT_PARSER_H_ */ diff --git a/src/servicedir_listener.c b/src/servicedir_listener.c new file mode 100644 index 0000000..d3d42b2 --- /dev/null +++ b/src/servicedir_listener.c @@ -0,0 +1,170 @@ +/* + * servicedir_listener.c + * + * Created on: Sep 25, 2010 + * Author: lamikr + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "servicedir_listener.h" + +static pthread_t _listener_thread; +static bool _listener_stop_requested; +static bool _listener_running = false; +static int _dir_handle = -1; +static int _inotify_handle = -1; +static pthread_mutex_t _listener_mutex; + +static void init_servicedir_listener() { + //_listener_mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_init(&_listener_mutex, NULL); +} + +static void deinit_servicedir_listener() { + pthread_mutex_destroy(&_listener_mutex); +} + +static void *servicedir_listener_thread(void *thread_args_pointer) +{ + int b_count; + int ii; + char *buffer; + struct inotify_event *event; + int buffer_max_size; + + /* + * Size of each i-notify event read: size of event structure + filename length that caused the event. (name follows the struct). + * We create a buffer that could in theory handle 16 events for files which name would be in maximum 1024 chars. (=CONST_MAX_EXPECTED_INOTIFY_EVENT_SIZE) + */ + buffer_max_size = CONST_MAX_INOTIFY_EVENT_COUNT_READ * (sizeof(struct inotify_event) + CONST_MAX_EXPECTED_INOTIFY_EVENT_SIZE); + buffer = calloc(1, buffer_max_size); + if (buffer != NULL) { + _inotify_handle = inotify_init(); + if (_inotify_handle >= 0) { + _dir_handle = inotify_add_watch(_inotify_handle, + CONST_SERVICE_DIRECTORY_LOCATION, + IN_CREATE | IN_ATTRIB | IN_MODIFY | IN_DELETE); + if (_dir_handle >= 0) { + printf("Waiting service directory file events\n"); + while (_listener_stop_requested == false) { + ii = 0; + printf("Waiting service directory file event\n"); + b_count = read(_inotify_handle, + buffer, + buffer_max_size); + printf("Service directory file event received\n"); + if (b_count >= 0) { + while (ii < b_count) { + event = (struct inotify_event *)&buffer[ii]; + printf("event length = %d\n", event->len); + if (event->len) { + if (event->mask & IN_CREATE) { + if ((event->mask & IN_ISDIR) == 0) { + printf("file create event: %s\n", event->name); + } + else { + printf("sub-directory create event: %s, no need to process\n", event->name); + } + } + else if (event->mask & IN_ATTRIB) { + if ((event->mask & IN_ISDIR) == 0) { + printf("file attribute change event: %s\n", event->name); + } + else { + printf("sub-directory attribute change event: %s, no need to process\n", event->name); + } + } + else if (event->mask & IN_MODIFY) { + if ((event->mask & IN_ISDIR) == 0) { + printf("file modify event: %s\n", event->name); + } + else { + printf("sub-directory modify event: %s, no need to process\n", event->name); + } + } + else if (event->mask & IN_DELETE) { + if ((event->mask & IN_ISDIR) == 0) { + printf("file delete event: %s\n", event->name); + } + else { + printf("sub-directory delete event: %s, no need to process\n", event->name); + } + } + } + ii = ii + sizeof(struct inotify_event) + event->len; + } + } + else { + printf("Failed to initialize service directory listener: %s, event read failed.\n", CONST_SERVICE_DIRECTORY_LOCATION); + } + } + printf("Closing service directory listener: %s, close request received.\n", CONST_SERVICE_DIRECTORY_LOCATION); + pthread_mutex_lock(&_listener_mutex); + if ((_inotify_handle > 0) && (_dir_handle)) { + inotify_rm_watch(_inotify_handle, _dir_handle); + _dir_handle = -1; + } + pthread_mutex_unlock(&_listener_mutex); + } + else { + printf("Failed to initialize service directory listener: %s, event listener start-up error.\n", CONST_SERVICE_DIRECTORY_LOCATION); + } + pthread_mutex_lock(&_listener_mutex); + if (_inotify_handle > 0) { + close(_inotify_handle); + _inotify_handle = -1; + } + pthread_mutex_unlock(&_listener_mutex); + } + else { + printf("Failed to initialize service directory listener: %s\n", CONST_SERVICE_DIRECTORY_LOCATION); + } + if (buffer != NULL) { + free(buffer); + buffer = NULL; + } + } + else { + printf("Failed to initialize service directory listener: %s, buffer allocation error.\n", CONST_SERVICE_DIRECTORY_LOCATION); + } + _listener_running = false; + pthread_exit(NULL); +} + +void start_servicedir_listener() { + printf("listen_closed_processes()\n"); + init_servicedir_listener(); + if (_listener_running == false) { + _listener_thread = 0; + _listener_stop_requested = false; + _listener_running = true; + pthread_create(&_listener_thread, + NULL, + servicedir_listener_thread, + (void *)NULL); + } +} + +void stop_servicedir_listener() { + _listener_stop_requested = true; + pthread_mutex_lock(&_listener_mutex); + if ((_inotify_handle > 0) && (_dir_handle)) { + inotify_rm_watch(_inotify_handle, _dir_handle); + close(_inotify_handle); + _dir_handle = -1; + _inotify_handle = -1; + } + pthread_mutex_unlock(&_listener_mutex); + pthread_join(_listener_thread, NULL); + deinit_servicedir_listener(); +} diff --git a/src/servicedir_listener.h b/src/servicedir_listener.h new file mode 100644 index 0000000..377fee4 --- /dev/null +++ b/src/servicedir_listener.h @@ -0,0 +1,17 @@ +/* + * servicedir_listener.h + * + * Created on: Sep 25, 2010 + * Author: lamikr + */ + +#ifndef SERVICEDIR_LISTENER_H_ +#define SERVICEDIR_LISTENER_H_ + +/** + * Listens changes in the service configuration directory. + */ +void start_servicedir_listener(); +void stop_servicedir_listener(); + +#endif /* SERVICEDIR_LISTENER_H_ */ diff --git a/src_test/Makefile.am b/src_test/Makefile.am new file mode 100644 index 0000000..5310373 --- /dev/null +++ b/src_test/Makefile.am @@ -0,0 +1,14 @@ +bin_PROGRAMS = test_ha test_client test_client2 + +test_ha_SOURCES = test_ha.c +test_ha_LDADD = $(SRC_LIBS) ../src/.libs/libplpha.a + +test_client_SOURCES = test_client.c +test_client_LDADD = $(SRC_LIBS) ../src/.libs/libplpha.a + +test_client2_SOURCES = test_client.c +test_client2_LDADD = $(SRC_LIBS) ../src/.libs/libplpha.a + +AM_CPPFLAGS = $(SRC_CFLAGS) -I../src + +DISTCLEANFILES = Makefile.in \ No newline at end of file diff --git a/src_test/test_client.c b/src_test/test_client.c new file mode 100644 index 0000000..cd2bafe --- /dev/null +++ b/src_test/test_client.c @@ -0,0 +1,46 @@ +/* + * test_client.c + * + * Created on: Jun 9, 2010 + * Author: lamikr + */ + +#include +#include +#include + +#include "common.h" +#include "process_parser.h" +#include + +int main(int argc, char** argv) +{ + int sleep_time = 2; + + t_process_arg_list *ret_val; + int ii; + + ret_val = calloc(1, sizeof(t_process_arg_list)); + for (ii = 0; ii < 1; ii++) { + if (ret_val->arg_arr == NULL) { + ret_val->arg_arr = calloc(1, sizeof(char *)); + } + else { + char **arg_arr; + + arg_arr = ret_val->arg_arr; + arg_arr = realloc(arg_arr, (ret_val->count + 1) * sizeof(char *)); + ret_val->arg_arr = arg_arr; + } + ret_val->arg_arr[ii] = strdup("hello\n"); + ret_val->count = ret_val->count + 1; + } + if (argc > 1) { + sleep_time = atoi(argv[1]); + } + release_process_config_arg_list(ret_val); + ret_val = NULL; + printf("sleep-time: %d seconds\n", sleep_time); + sleep(sleep_time); + return 0; +} diff --git a/src_test/test_ha.c b/src_test/test_ha.c new file mode 100644 index 0000000..e7fe1e7 --- /dev/null +++ b/src_test/test_ha.c @@ -0,0 +1,44 @@ +/* + * test_ha.c + * + * Created on: Sep 16, 2010 + * Author: lamikr + */ + +#include +#include +#include +#include +#include + +#include "launcher.h" +#include "process_parser.h" +#include "process_listener.h" +#include "servicedir_listener.h" + +int main(int argc, char** argv) +{ + t_process_info_list *process_list; + t_process_info *process_item; + + start_process_listener(); + start_servicedir_listener(); + process_list = get_process_config_list(); + if (process_list != NULL) { + printf("process_list->count: %d\n", process_list->count); + process_item = process_list->first_item; + if (process_item != NULL) { + if ((process_item->arg_list != NULL) && + (process_item->arg_list->arg_arr != NULL)) { + launch_new_process(process_item->arg_list->arg_arr); + process_item = process_item->next; + } + } + sleep(8); + stop_servicedir_listener(); + release_process_config_list(process_list); + } + //closed_pid = wait(&status); + //printf("closed process: %d, status: %d\n", closed_pid, status); + return 0; +}