libslack(msg) - message module
#include <slack/std.h> #include <slack/msg.h> typedef struct Msg Msg; typedef void msg_out_t(void *data, const void *mesg, size_t mesglen); typedef void msg_release_t(void *data); Msg *msg_create(int type, msg_out_t *out, void *data, msg_release_t *destroy); Msg *msg_create_with_locker(Locker *locker, int type, msg_out_t *out, void *data, msg_release_t *destroy); int msg_rdlock(Msg *mesg); int msg_wrlock(Msg *mesg); int msg_unlock(Msg *mesg); void msg_release(Msg *mesg); void *msg_destroy(Msg **mesg); void msg_out(Msg *dst, const char *format, ...); void msg_out_unlocked(Msg *dst, const char *format, ...); void vmsg_out(Msg *dst, const char *format, va_list args); void vmsg_out_unlocked(Msg *dst, const char *format, va_list args); Msg *msg_create_fd(int fd); Msg *msg_create_fd_with_locker(Locker *locker, int fd); Msg *msg_create_stderr(void); Msg *msg_create_stderr_with_locker(Locker *locker); Msg *msg_create_stdout(void); Msg *msg_create_stdout_with_locker(Locker *locker); Msg *msg_create_file(const char *path); Msg *msg_create_file_with_locker(Locker *locker, const char *path); Msg *msg_create_syslog(const char *ident, int option, int facility, int priority); Msg *msg_create_syslog_with_locker(Locker *locker, const char *ident, int option, int facility, int priority); Msg *msg_syslog_set_facility(Msg *mesg, int facility); Msg *msg_syslog_set_facility_unlocked(Msg *mesg, int facility); Msg *msg_syslog_set_priority(Msg *mesg, int priority); Msg *msg_syslog_set_priority_unlocked(Msg *mesg, int priority); Msg *msg_create_plex(Msg *msg1, Msg *msg2); Msg *msg_create_plex_with_locker(Locker *locker, Msg *msg1, Msg *msg2); int msg_add_plex(Msg *mesg, Msg *item); int msg_add_plex_unlocked(Msg *mesg, Msg *item); const char *msg_set_timestamp_format(const char *format); int msg_set_timestamp_format_locker(Locker *locker); int syslog_lookup_facility(const char *facility); int syslog_lookup_priority(const char *priority); const char *syslog_facility_str(int spec); const char *syslog_priority_str(int spec); int syslog_parse(const char *spec, int *facility, int *priority);
This module provides general messaging functions. Message channels can be
created that send messages to a file descriptor, a file, syslog or a
client defined message handler or that multiplexes messages to any
combination of the above. Messages sent to files are timestamped using (by
default) the strftime(3) format: "%Y%m%d %H:%M:%S"
.
It also provides functions for parsing syslog targets, converting between syslog facility names and codes, and converting between syslog priority names and codes.
Msg *msg_create(int type, msg_out_t *out, void *data, msg_release_t *destroy)
Creates a Msg object initialised with type
, out
, data
and
destroy
. Client defined message handlers must specify a type
greater
than 4
. It is the caller's responsibility to deallocate the new Msg
with msg_release(3) or msg_destroy. On success, returns the new Msg
object. On error, returns null
.
Msg *msg_create_with_locker(Locker *locker, int type, msg_out_t *out, void *data, msg_release_t *destroy)
Equivalent to msg_create(3) except that multiple threads accessing the
new Msg will be synchronised by locker
.
int msg_rdlock(Msg *mesg)
Claims a read lock on mesg
(if mesg
was created with a Locker).
This is needed when multiple read only msg(3) module functions
need to be called atomically. It is the caller's responsibility to call
msg_unlock(3) after the atomic operation. The only functions that may be
called on mesg
between calls to msg_rdlock(3) and msg_unlock(3) are
any read only msg(3) module functions whose name ends with
_unlocked
. On success, returns 0
. On error, returns an error code.
int msg_wrlock(Msg *mesg)
Claims a write lock on mesg
.
Claims a write lock on mesg
(if mesg
was created with a Locker).
This is needed when multiple read/write msg(3) module functions
need to be called atomically. It is the caller's responsibility to call
msg_unlock(3) after the atomic operation. The only functions that may be
called on mesg
between calls to msg_rdlock(3) and msg_unlock(3) are
any msg(3) module functions whose name ends with _unlocked
. On
success, returns 0
. On error, returns an error code.
int msg_unlock(Msg *mesg)
Unlocks a read or write lock on mesg
obtained with msg_rdlock(3) or
msg_wrlock(3) (if mesg
was created with a Locker). On success,
returns 0
. On error, returns an error code.
void msg_release(Msg *mesg)
Releases (deallocates) mesg
and its internal data.
void *msg_destroy(Msg **mesg)
Destroys (deallocates and sets to null
) *mesg
. Returns null
.
void msg_out(Msg *dst, const char *format, ...)
Sends a message to dst
. format
is a printf(3)-like format string.
Any remaining arguments are processed as in printf(3).
Warning: Do not under any circumstances ever pass a non-literal string as the format argument unless you know exactly how many conversions will take place. Being careless with this is a very good way to build potential security holes into your programs. The same is true for all functions that take a printf()-like format string as an argument.
msg_out(dst, buf); // EVIL msg_out(dst, "%s", buf); // GOOD
void msg_out_unlocked(Msg *dst, const char *format, ...)
Equivalent to msg_out(3) except that dst
is not read locked.
void vmsg_out(Msg *dst, const char *format, va_list args)
Sends a message to dst
. format
is a printf(3)-like format string.
args
is processed as in vprintf(3).
void vmsg_out_unlocked(Msg *dst, const char *format, va_list args)
Equivalent to vmsg_out(3) except that dst
is not read locked.
Msg *msg_create_fd(int fd)
Creates a Msg object that sends messages to file descriptor fd
. It is
the caller's responsibility to deallocate the new Msg with
msg_release(3) or msg_destroy(3). On success, returns the new Msg
object. On error, returns null
.
Msg *msg_create_fd_with_locker(Locker *locker, int fd)
Equivalent to msg_create_fd(3) except that multiple threads accessing the
new Msg will be synchronised by locker
.
Msg *msg_create_stderr(void)
Creates a Msg object that sends messages to standard error. It is the
caller's responsibility to deallocate the new Msg with msg_release(3)
or msg_destroy(3). On success, returns the new Msg object. On error,
returns null
.
Msg *msg_create_stderr_with_locker(Locker *locker)
Equivalent to msg_create_stderr(3) except that multiple threads accessing
the new Msg will be synchronised by locker
.
Msg *msg_create_stdout(void)
Creates a Msg object that sends messages to standard output. It is the
caller's responsibility to deallocate the new Msg with msg_release(3)
or msg_destroy(3). On success, returns the new Msg object. On error,
returns null
.
Msg *msg_create_stdout_with_locker(Locker *locker)
Equivalent to msg_create_stdout(3) except that multiple threads accessing
the new Msg will be synchronised by locker
.
Msg *msg_create_file(const char *path)
Creates a Msg object that sends messages to the file specified by
path
. It is the caller's responsibility to deallocate the new Msg with
msg_release(3) or msg_destroy(3). On success, returns the new Msg
object. On error, returns null
with errno
set appropriately.
Msg *msg_create_file_with_locker(Locker *locker, const char *path)
Equivalent to msg_create_file(3) except that multiple threads accessing
the new Msg will be synchronised by locker
.
Msg *msg_create_syslog(const char *ident, int option, int facility, int priority)
Creates a Msg object that sends messages to syslog initialised with
ident
, option
, facility
and priority
. It is the caller's
responsibility to deallocate the new Msg with msg_release(3) or
msg_destroy(3). On success, returns the new Msg object. On error,
returns null
with errno
set appropriately.
Msg *msg_create_syslog_with_locker(Locker *locker, const char *ident, int option, int facility, int priority)
Equivalent to msg_create_syslog(3) except that multiple threads accessing
the new Msg will be synchronised by locker
.
Msg *msg_syslog_set_facility(Msg *mesg, int facility)
Sets the facility field in mesg
's data to facility
. On success,
returns mesg
. On error, returns null
with errno
set appropriately.
Msg *msg_syslog_set_facility_unlocked(Msg *mesg, int facility)
Equivalent to msg_syslog_set_facility(3) except that mesg
is not write
locked.
Msg *msg_syslog_set_priority(Msg *mesg, int priority)
Sets the priority field in mesg
's data to priority
. On success,
returns mesg
. On error, returns null
with errno
set appropriately.
Msg *msg_syslog_set_priority_unlocked(Msg *mesg, int priority)
Equivalent to msg_syslog_set_priority(3) except that mesg
is not write
locked.
Msg *msg_create_plex(Msg *msg1, Msg *msg2)
Creates a Msg object that multiplexes messages to msg1
and msg2
.
Further Msg objects may be added to its list using msg_add_plex(3). It
is the caller's responsibility to deallocate the new Msg with
msg_release(3) or msg_destroy(3). On success, returns the new Msg
object. On error, returns null
with errno
set appropriately.
Msg *msg_create_plex_with_locker(Locker *locker, Msg *msg1, Msg *msg2)
Equivalent to msg_create_plex(3) except that multiple threads accessing
the new Msg will be synchronised by locker
.
int msg_add_plex(Msg *mesg, Msg *item)
Adds item
to the list of Msg objects multiplexed by mesg
. On
success, returns 0
. On error, returns -1
with errno
set
appropriately.
int msg_add_plex_unlocked(Msg *mesg, Msg *item)
Equivalent to msg_add_plex(3) except that mesg
is not write locked.
const char *msg_set_timestamp_format(const char *format)
Sets the strftime(3) format string used when sending messages to a file.
By default, it is "%Y%m%d %H:%M:%S "
. On success, returns the previous
format string. On error, returns null
with errno
set appropriately.
int msg_set_timestamp_format_locker(Locker *locker)
Sets the locking strategy for changing the timestamp format used when
sending messages to a file. This is only needed if the timestamp format will
be modified in multiple threads. On success, returns 0
. On error, returns
-1
with errno
set appropriately.
int syslog_lookup_facility(const char *facility)
Returns the code corresponding to facility
. If not found, returns -1
.
int syslog_lookup_priority(const char *priority)
Returns the code corresponding to priority
. If not found, returns -1
.
const char *syslog_facility_str(int spec)
Returns the name corresponding to the facility part of spec
. If not
found, returns null
.
const char *syslog_priority_str(int spec)
Returns the name corresponding to the priority part of spec
. If not
found, returns null
.
int syslog_parse(const char *spec, int *facility, int *priority)
Parses spec
as a facility.priority string. If facility
is
non-null
, the parsed facility is stored in the location pointed to by
facility
. If priority
is non-null
the parsed priority is stored in
the location pointed to by priority
. On success, returns 0
. On error,
returns -1
with errno
set appropriately.
syslog facilities syslog priorities ---------------------- ----------------------- "kern" LOG_KERN "emerg" LOG_EMERG "user" LOG_USER "alert" LOG_ALERT "mail" LOG_MAIL "crit" LOG_CRIT "daemon" LOG_DAEMON "err" LOG_ERR "auth" LOG_AUTH "warning" LOG_WARNING "syslog" LOG_SYSLOG "info" LOG_INFO "lpr" LOG_LPR "debug" LOG_DEBUG "news" LOG_NEWS "uucp" LOG_UUCP "cron" LOG_CRON "local0" LOG_LOCAL0 "local1" LOG_LOCAL1 "local2" LOG_LOCAL2 "local3" LOG_LOCAL3 "local4" LOG_LOCAL4 "local5" LOG_LOCAL5 "local6" LOG_LOCAL6 "local7" LOG_LOCAL7
On error, errno
is set by underlying functions or as follows:
EINVAL
An argument was null
or could not be parsed.
MT-Disciplined - msg functions - See locker(3) for details.
MT-Safe - syslog functions
Parse syslog facility priority pair:
#include <slack/std.h> #include <slack/msg.h> int main(int ac, char **av) { int facility, priority; if (syslog_parse(av[1], &facility, &priority) != -1) syslog(facility | priority, "syslog(%s)", av[1]); return EXIT_SUCCESS; }
Multiplex a message to several locations:
#include <slack/std.h> #include <slack/msg.h> int main(int ac, char **av) { Msg *stdout_msg = msg_create_stdout(); Msg *stderr_msg = msg_create_stderr(); Msg *file_msg = msg_create_file("/tmp/junk"); Msg *syslog_msg = msg_create_syslog("ident", 0, LOG_DAEMON, LOG_ERR); Msg *plex_msg = msg_create_plex(stdout_msg, stderr_msg); msg_add_plex(plex_msg, file_msg); msg_add_plex(plex_msg, syslog_msg); msg_out(plex_msg, "Multiplex message\n"); unlink("/tmp/junk"); return EXIT_SUCCESS; }
libslack(3), err(3), prog(3), openlog(3), syslog(3), locker(3)
20100612 raf <raf@raf.org>