1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
This file describes the coding style and gives some useful informations
for developer who want to add their own module.
--------------------------------------------------------
- please send code submissions to dp-irmp3@dpotter.com -
--------------------------------------------------------
CODING STYLE
------------
The main IRMP3 program can use functions of several modules.
Modules may be included or excluded at build time to have
or haven't support for different hardware. Every modules
is named mod_xxx.c / mod_xxx.h. Modules that are excluded
during build time (Makefile configuration), will not be
compiled.
All functions and global variables within a module should
be called mod_xxx_*, to prevent conflicts with oder modules
or the main program.
Every module must have an init function, which is of type:
char *mod_xxx_init(void);
The init function is called right after starting irmp3,
after reading the configuration and setting up some other
basic things. It should return NULL if it succeeded, and
return an error string on failure.
To get a clue on how a module works, have a look at
mod_debug.c, which is good to learn the basic things.
INCLUDING A NEW MODULE
----------------------
To describe how to write and include a new module, I'll
give an examples on a module called mod_mymod:
1) Set up the Makefile to include the new module. You
should add a section to the configuration part of
the Makefile. Include something like:
MOD_MYMOD = 1
MOD_MYMOD_BLAH = youneedtoconfigurethis
2) Include your changes to the target configuration
section of the Makefile:
ifdef MOD_MYMOD
OBJS += mod_mymod.o
MODS += -DMOD_MYMOD
endif
3) Include your changes to the target section of the
Makefile:
mod_mymod.o: mod_mymod.c
$(CC) $(CFLAGS) -DMOD_MYMOD_BLAH=\"$(MOD_MYMOD_BLAH)\" -c mod_mymod.c -o mod_mymod.o
4) Setup modules.inc to include your module init function.
You need to specify the module init function prototype:
char *mod_mymod_init(void);
and include it in the list of module init functions in
mod_list_init[] like this:
#ifdef MOD_MYMOD
mod_mymod_init,
#endif
5) Now your mod_mymod_init() function is called every time
IRMP3 starts. Your init function should now fill up a
mod_t structure and pass it to mod_register, so that
your module is registered within IRMP3 and the main
program knows what data your module wants to handle.
You should take care that the structure is still valid
if your init function is left, so don't use a local
variable!
The structure contains the following fields:
mod_deinitfunc_t deinit;
Set this to a function (usually
void mod_mymod_deinit (void)) that will
be called before IRMP3 shuts down. This
function typically cleans up all used data
structures, closes connections etc.
mod_reloadfunc_t reload;
This function will be called whenever
IRMP3 needs to reload all configs (usually
when receiving a SIGHUP). You should
do whatever is neccessary here to make
the changes take effect.
fd_set watchfd;
A set of file descriptors that your module
will want to read/write from/to. Your module
may dynamically add or remove fd's from
this set.
mod_pollfunc_t poll(int fd);
This function will be called if incoming
data was detected on any of the file descriptors
in watchfd. The descriptor with input is passed as
fd. This function should read the data, otherwise
it will be called again and again and again,
and probably lock up the whole program.
mod_updatefunc_t update;
This function will be called periodically about
twice a second. If you need to do any periodically
work, this is the right place to do it.
mod_messagefunc_t message;
Every module can send a message through the
message passing system. If you want to react
to messages of other modules, you need to
set a function here and you'll receive all
messages.
mod_sigchldfunc_t chld(pid_t pid, int status);
If your module spawns child processes, you
may want to be notified when they die. If
so, register a function here: Please
*don't* use signal(SIGCHLD,func), or you
will be stealing SIGCHLDs from other
modules.
Again, if you don't understand everything, look at mod_debug.c,
which is a basic custom module and may be also used as a
template for new ones.
CALLING FUNCTIONS
-----------------
Of course your module may use some of the main programs functions:
* Modules
#include "mod.h"
void mod_register (mod_t *newmod);
void mod_sendmsg (int msgtype, char *message);
mod_register is used to register your module (see above).
With mod_sendmsg() you can send a message to other modules.
The msgtype should reflect the type of the message. See
mod.h for different message types.
* Tools
#include "tools.h"
Some useful functions may be found here. Check tools.h.
* Logging
#include "log.h"
log_printf(log-level, "text like printf: %s %d", str, num);
Writes a line to the logfile. See log.h about log-levels.
* Configuration
#include "config.h"
char *value = config_getstr(key, defaultvalue);
int value = config_getnum(key, defaultvalue);
Reads a value of a configuration key which is defined in the
IRMP3 config file. You should name all your keys "mymod_xxx",
so that it's clear where they belong to.
PUBLISHING
----------
If you have developed a new module and it works fine, you probably
want to publish it so that others can use it, too.
First of all you should make sure, that your code meets all the above
requirements. It should be programmed cleanly and easy to read (you
didn't forget comments, did you?). You should also take care that
the whole program also still works without your module. Also don't
forget to make things customizable, a program that does use hardcoded
paths (like /mnt/cdrom) won't be useful for others.
So if your code does meet all these things, you simply have to contact
me via mail or via the mailinglist (see README) and tell me about it.
STANDARD MODULES
----------------
TODO: describe what the standard modules do and how they interact via
the message system.
|