Module: xenomai-2.6 Branch: master Commit: 7573831dd9a65a36ee272294c1aefc1001a58307 URL: http://git.xenomai.org/?p=xenomai-2.6.git;a=commit;h=7573831dd9a65a36ee272294c1aefc1001a58307
Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org> Date: Fri Nov 11 18:07:56 2011 +0100 rtdk/posix: implement fwrite gcc substitutes fprintf calls with fwrite calls, so we need fwrite. At this chance get rt_fwrite working for non null terminated data blocks. --- include/posix/stdio.h | 4 ++ include/rtdk.h | 2 + src/skins/common/rt_print.c | 89 +++++++++++++++++++++++------------ src/skins/posix/posix.wrappers | 2 + src/skins/posix/printf.c | 26 ++++++++-- src/skins/posix/wrappers.c | 12 +++++ src/testsuite/unit/mutex-torture.c | 4 ++ 7 files changed, 103 insertions(+), 36 deletions(-) diff --git a/include/posix/stdio.h b/include/posix/stdio.h index e4ad01c..6af0129 100644 --- a/include/posix/stdio.h +++ b/include/posix/stdio.h @@ -21,6 +21,10 @@ int __real_printf(const char *fmt, ...); int __real_puts(const char *s); +int __real_fputs(const char *s, FILE *stream); + +size_t __real_fwrite(const void *ptr, size_t sz, size_t nmemb, FILE *stream); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/include/rtdk.h b/include/rtdk.h index a0d63c8..e1fc3b4 100644 --- a/include/rtdk.h +++ b/include/rtdk.h @@ -53,6 +53,8 @@ int rt_vprintf(const char *format, va_list args); int rt_fprintf(FILE *stream, const char *format, ...); int rt_printf(const char *format, ...); int rt_puts(const char *s); +int rt_fputs(const char *s, FILE *stream); +size_t rt_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); void rt_syslog(int priority, const char *format, ...); void rt_vsyslog(int priority, const char *format, va_list args); diff --git a/src/skins/common/rt_print.c b/src/skins/common/rt_print.c index cdd4ed3..c1849a5 100644 --- a/src/skins/common/rt_print.c +++ b/src/skins/common/rt_print.c @@ -47,13 +47,14 @@ #define RT_PRINT_SYSLOG_STREAM NULL #define RT_PRINT_MODE_FORMAT 0 -#define RT_PRINT_MODE_PUTS 1 +#define RT_PRINT_MODE_FWRITE 1 struct entry_head { FILE *dest; uint32_t seq_no; int priority; - char text[1]; + size_t len; + char data[0]; } __attribute__((packed)); struct print_buffer { @@ -96,7 +97,7 @@ static void print_buffers(void); /* *** rt_print API *** */ static int vprint_to_buffer(FILE *stream, int priority, unsigned int mode, - const char *format, va_list args) + size_t sz, const char *format, va_list args) { struct print_buffer *buffer = pthread_getspecific(buffer_key); off_t write_pos, read_pos; @@ -136,7 +137,7 @@ static int vprint_to_buffer(FILE *stream, int priority, unsigned int mode, head = buffer->ring + write_pos; head->seq_no = seq_no; head->priority = 0; - head->text[0] = 0; + head->len = 0; /* Forward to the ring buffer start */ write_pos = 0; @@ -156,24 +157,35 @@ static int vprint_to_buffer(FILE *stream, int priority, unsigned int mode, head = buffer->ring + write_pos; if (mode == RT_PRINT_MODE_FORMAT) { - res = vsnprintf(head->text, len, format, args); - - if (res < len) { - /* Text was written completely, res contains its - length */ - len = res; + if (stream != RT_PRINT_SYSLOG_STREAM) { + /* We do not need the terminating \0 */ + res = vsnprintf(head->data, len + 1, format, args); + + if (res < len + 1) { + /* Text was written completely, res contains its + length */ + len = res; + } else { + /* Text was truncated */ + res = len; + } } else { - /* Text was truncated, remove closing \0 that - entry_head already includes */ - len--; - res = len; + /* We DO need the terminating \0 */ + res = vsnprintf(head->data, len, format, args); + + if (res < len) { + /* Text was written completely, res contains its + length */ + len = res + 1; + } else { + /* Text was truncated */ + res = len; + } } - } else if (len >= 2) { - str_len = strlen(format); - len = (str_len < len - 2) ? str_len : len - 2; - strncpy(head->text, format, len); - head->text[len++] = '\n'; - head->text[len] = 0; + } else if (len >= 1) { + str_len = sz; + len = (str_len < len) ? str_len : len; + memcpy(head->data, format, len); } else len = 0; @@ -182,6 +194,7 @@ static int vprint_to_buffer(FILE *stream, int priority, unsigned int mode, head->seq_no = ++seq_no; head->priority = priority; head->dest = stream; + head->len = len; /* Move forward by text and head length */ write_pos += len + sizeof(struct entry_head); @@ -194,7 +207,7 @@ static int vprint_to_buffer(FILE *stream, int priority, unsigned int mode, head = buffer->ring + write_pos; head->seq_no = seq_no; head->priority = priority; - head->text[0] = 0; + head->len = 0; write_pos = 0; } @@ -208,13 +221,13 @@ static int vprint_to_buffer(FILE *stream, int priority, unsigned int mode, } static int print_to_buffer(FILE *stream, int priority, unsigned int mode, - const char *format, ...) + size_t sz, const char *format, ...) { va_list args; int ret; va_start(args, format); - ret = vprint_to_buffer(stream, priority, mode, format, args); + ret = vprint_to_buffer(stream, priority, mode, sz, format, args); va_end(args); return ret; @@ -222,7 +235,8 @@ static int print_to_buffer(FILE *stream, int priority, unsigned int mode, int rt_vfprintf(FILE *stream, const char *format, va_list args) { - return vprint_to_buffer(stream, 0, RT_PRINT_MODE_FORMAT, format, args); + return vprint_to_buffer(stream, 0, + RT_PRINT_MODE_FORMAT, 0, format, args); } int rt_vprintf(const char *format, va_list args) @@ -254,25 +268,37 @@ int rt_printf(const char *format, ...) return n; } +int rt_fputs(const char *s, FILE *stream) +{ + return print_to_buffer(stream, 0, RT_PRINT_MODE_FWRITE, strlen(s), s); +} + int rt_puts(const char *s) { - return print_to_buffer(stdout, 0, RT_PRINT_MODE_PUTS, s); + return rt_fputs(s, stdout); +} + +size_t rt_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + print_to_buffer(stream, 0, RT_PRINT_MODE_FWRITE, size * nmemb, ptr); + return nmemb; } + void rt_syslog(int priority, const char *format, ...) { va_list args; va_start(args, format); vprint_to_buffer(RT_PRINT_SYSLOG_STREAM, priority, - RT_PRINT_MODE_FORMAT, format, args); + RT_PRINT_MODE_FORMAT, 0, format, args); va_end(args); } void rt_vsyslog(int priority, const char *format, va_list args) { vprint_to_buffer(RT_PRINT_SYSLOG_STREAM, priority, - RT_PRINT_MODE_FORMAT, format, args); + RT_PRINT_MODE_FORMAT, 0, format, args); } static void set_buffer_name(struct print_buffer *buffer, const char *name) @@ -541,16 +567,17 @@ static void print_buffers(void) read_pos = buffer->read_pos; head = buffer->ring + read_pos; - len = strlen(head->text); + len = head->len; if (len) { /* Print out non-empty entry and proceed */ /* Check if output goes to syslog */ if (head->dest == RT_PRINT_SYSLOG_STREAM) { - syslog(head->priority, "%s", head->text); + syslog(head->priority, + "%s", head->data); } else { - /* Output goes to specified stream */ - fprintf(head->dest, "%s", head->text); + fwrite(head->data, + head->len, 1, head->dest); } read_pos += sizeof(*head) + len; diff --git a/src/skins/posix/posix.wrappers b/src/skins/posix/posix.wrappers index 2aa3d33..a7a6b50 100644 --- a/src/skins/posix/posix.wrappers +++ b/src/skins/posix/posix.wrappers @@ -94,6 +94,8 @@ --wrap fprintf --wrap printf --wrap puts +--wrap fputs +--wrap fwrite --wrap syslog --wrap vsyslog --wrap malloc diff --git a/src/skins/posix/printf.c b/src/skins/posix/printf.c index d838b8a..99587d7 100644 --- a/src/skins/posix/printf.c +++ b/src/skins/posix/printf.c @@ -7,11 +7,10 @@ int __wrap_vfprintf(FILE *stream, const char *fmt, va_list args) { if (unlikely(xeno_get_current() != XN_NO_HANDLE && !(xeno_get_current_mode() & XNRELAX))) - return rt_vfprintf(stream, fmt, args); else { rt_print_flush_buffers(); - return vfprintf(stream, fmt, args); + return __real_vfprintf(stream, fmt, args); } } @@ -44,15 +43,32 @@ int __wrap_printf(const char *fmt, ...) return rc; } +int __wrap_fputs(const char *s, FILE *stream) +{ + if (unlikely(xeno_get_current() != XN_NO_HANDLE && + !(xeno_get_current_mode() & XNRELAX))) + return rt_fputs(s, stream); + else { + rt_print_flush_buffers(); + return __real_fputs(s, stream); + } +} + int __wrap_puts(const char *s) { + return __wrap_fputs(s, stdout); +} + +size_t __wrap_fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ if (unlikely(xeno_get_current() != XN_NO_HANDLE && !(xeno_get_current_mode() & XNRELAX))) - return rt_puts(s); + return rt_fwrite(ptr, size, nmemb, stream); else { rt_print_flush_buffers(); - return puts(s); + return __real_fwrite(ptr, size, nmemb, stream); } + } void __wrap_vsyslog(int priority, const char *fmt, va_list ap) @@ -62,7 +78,7 @@ void __wrap_vsyslog(int priority, const char *fmt, va_list ap) return rt_vsyslog(priority, fmt, ap); else { rt_print_flush_buffers(); - vsyslog(priority, fmt, ap); + __real_vsyslog(priority, fmt, ap); } } diff --git a/src/skins/posix/wrappers.c b/src/skins/posix/wrappers.c index 3dbce0f..bdedcb7 100644 --- a/src/skins/posix/wrappers.c +++ b/src/skins/posix/wrappers.c @@ -359,6 +359,18 @@ int __real_puts(const char *s) } __attribute__ ((weak)) +int __real_fputs(const char *s, FILE *stream) +{ + return fputs(s, stream); +} + +__attribute__ ((weak)) +size_t __real_fwrite(const void *ptr, size_t sz, size_t nmemb, FILE *stream) +{ + return fwrite(ptr, sz, nmemb, stream); +} + +__attribute__ ((weak)) void __real_syslog(int priority, const char *fmt, ...) { va_list args; diff --git a/src/testsuite/unit/mutex-torture.c b/src/testsuite/unit/mutex-torture.c index d29438a..182dfc1 100644 --- a/src/testsuite/unit/mutex-torture.c +++ b/src/testsuite/unit/mutex-torture.c @@ -484,6 +484,10 @@ void mode_switch(void) { mutex_t mutex; + /* Cause a switch to secondary mode */ +#ifdef XENO_POSIX + __real_sched_yield(); +#endif fprintf(stderr, "mode_switch\n"); dispatch("switch mutex_init", MUTEX_CREATE, 1, 0, &mutex, 1, 0); _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git