diff --git a/include/sxmp/sxmp.h b/include/sxmp/sxmp.h index edac276..6c68cf5 100644 --- a/include/sxmp/sxmp.h +++ b/include/sxmp/sxmp.h @@ -227,6 +227,14 @@ struct sxstream_ops { }; }; +typedef enum { + SXCRITICAL_LOG = 0, + SXERROR_LOG, + SXWARNING_LOG, + SXINFO_LOG, + SXDEBUG_LOG, +} sxlogtype_t; + /** * \brief Hub subsystem structure. * @@ -251,6 +259,7 @@ typedef struct __sxhub_type { * during setting up a typed channel */ void (*on_destroy)(sxlink_t *); /** < callback on connection destroy */ void (*on_pulse)(sxlink_t *, sexp_t *); /** < callback on pulse emit */ + int (*log)(const sxlogtype_t, const char *, ...); /** < this function is used to output logs with user way */ SSL_CTX *ctx; /** < SSL context */ void *priv; } sxhub_t; @@ -263,6 +272,12 @@ typedef struct __sxhub_type { #define sxhub_set_onpulse(c, f) (c)->on_pulse = (f) #define sxhub_set_priv(c, p) (c)->priv = (p) #define sxhub_get_priv(c) (c)->priv +#define sxhub_set_logops(c, f) (c)->log = (f) + +/* this macro is used to make calling sxhub log function easier */ +#define sxlink_log(c, type, fmt, ...) \ + (c)->hub ? (c)->hub->log((type), (fmt), ## __VA_ARGS__) : \ + fprintf(stderr, (fmt), ## __VA_ARGS__); typedef struct __rpc_typed_list_type { int type_id; diff --git a/sxmp/hub.c b/sxmp/hub.c index a74ba4b..362aafe 100644 --- a/sxmp/hub.c +++ b/sxmp/hub.c @@ -524,6 +524,16 @@ static long __cmp_cstr(const void *a, const void *b) return (long)strcmp((const char *)a, (const char *)b); } +static int __sxhub_log_dummy(const sxlogtype_t type, const char *fmt, ...) +{ + int r; + va_list arglist; + va_start(arglist, fmt); + r = vfprintf(stderr, fmt, arglist); + va_end(arglist); + return r; +} + int sxhub_init(sxhub_t *ssys) { int r = 0; @@ -573,6 +583,9 @@ int sxhub_init(sxhub_t *ssys) } } + /* set function pointers to default implementation */ + sxhub_set_logops(ssys, __sxhub_log_dummy); + return 0; __lfini: diff --git a/sxmp/sxmplv2.c b/sxmp/sxmplv2.c index 722c6f5..5d216af 100644 --- a/sxmp/sxmplv2.c +++ b/sxmp/sxmplv2.c @@ -95,7 +95,7 @@ static int __conn_read(sxlink_t *co, void *buf, size_t buf_len) ofcmode = fcntl(rfd, F_GETFL,0); ofcmode |= O_NDELAY; if(fcntl(rfd, F_SETFL, ofcmode)) - fprintf(stderr, "[sxmplv2] (RD)Couldn't make socket nonblocking"); + sxlink_log(co, SXERROR_LOG, "[sxmplv2] (RD)Couldn't make socket nonblocking"); #endif __retry: @@ -120,26 +120,26 @@ static int __conn_read(sxlink_t *co, void *buf, size_t buf_len) case SSL_ERROR_SYSCALL: if(errno == EAGAIN || errno == EINTR) goto __try_again; else { - fprintf(stderr, "[sxmplv2] (RD)SSL syscall error.\n"); + sxlink_log(co, SXERROR_LOG, "[sxmplv2] (RD)SSL syscall error.\n"); goto __close_conn; } break; case SSL_ERROR_WANT_CONNECT: case SSL_ERROR_WANT_ACCEPT: - fprintf(stderr, "[sxmplv2] (RD)SSL negotiation required. Trying again.\n"); + sxlink_log(co, SXERROR_LOG, "[sxmplv2] (RD)SSL negotiation required. Trying again.\n"); goto __try_again; break; case SSL_ERROR_SSL: - fprintf(stderr, "[sxmplv2] (RD)SSL error occured. Connection will be closed.\n"); + sxlink_log(co, SXERROR_LOG, "[sxmplv2] (RD)SSL error occured. Connection will be closed.\n"); goto __close_conn; break; case SSL_ERROR_ZERO_RETURN: - fprintf(stderr, "[sxmplv2] (RD)SSL connection is cleary closed.\n"); + sxlink_log(co, SXERROR_LOG, "[sxmplv2] (RD)SSL connection is cleary closed.\n"); default: __close_conn: ERR_free_strings(); co->flags |= SXMP_CLOSED; - fprintf(stderr, "[sxmplv2] (RD)Unknown error on %s (errno = %d)\n", co->uuid, errno); + sxlink_log(co, SXERROR_LOG, "[sxmplv2] (RD)Unknown error on %s (errno = %d)\n", co->uuid, errno); ERR_remove_state(0); return -1; } @@ -154,12 +154,12 @@ static int __conn_read(sxlink_t *co, void *buf, size_t buf_len) r = select(rfd + 1, &readset, NULL, NULL, NULL); if(r < 0) { if(errno == EINTR || errno == EAGAIN) goto __select_retry; - fprintf(stderr, "[sxmplv2] (RD)Select (%d) on %s\n", errno, co->uuid); + sxlink_log(co, SXERROR_LOG, "[sxmplv2] (RD)Select (%d) on %s\n", errno, co->uuid); ERR_remove_state(0); return -1; } if(!r) { - fprintf(stderr, "[sxmplv2] (RD)Nothing to wait for\n"); + sxlink_log(co, SXERROR_LOG, "[sxmplv2] (RD)Nothing to wait for\n"); ERR_remove_state(0); return 0; } @@ -209,7 +209,7 @@ static int __conn_write(sxlink_t *co, void *buf, size_t buf_len) /* set closed flag */ ERR_free_strings(); co->flags |= SXMP_CLOSED; - fprintf(stderr, "[sxmplv2] (WR)Unknown error on %s (%d)\n", co->uuid, r); + sxlink_log(co, SXERROR_LOG, "[sxmplv2] (WR)Unknown error on %s (%d)\n", co->uuid, r); ERR_remove_state(0); return -1; } else return r; @@ -811,7 +811,7 @@ static void *__sxmpl_thread(void *b) /* reply came ... */ if(mid > (MAX_MSGINPROCESS - 1)) { __inval_idx_nor: - fprintf(stderr, "[sxmplv2] Invalid index of the message (%lu).\n", mid); + sxlink_log(co, SXERROR_LOG, "[sxmplv2] Invalid index of the message (%lu).\n", mid); goto __again; }