Module: xenomai-gch Branch: for-forge Commit: 1ebdd474129f25167006c31e53d31bdbf3e75df4 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=1ebdd474129f25167006c31e53d31bdbf3e75df4
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/cobalt/stdio.h | 4 + include/rtdk.h | 2 + lib/cobalt/posix.wrappers | 2 + lib/cobalt/printf.c | 134 ++++++++++++++++++++++++++-------------- lib/cobalt/wrappers.c | 12 ++++ testsuite/unit/mutex-torture.c | 4 + 6 files changed, 111 insertions(+), 47 deletions(-) diff --git a/include/cobalt/stdio.h b/include/cobalt/stdio.h index b97ba03..7d161da 100644 --- a/include/cobalt/stdio.h +++ b/include/cobalt/stdio.h @@ -22,6 +22,10 @@ COBALT_DECL(int, printf(const char *fmt, ...)); COBALT_DECL(int, 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 2ddfacc..398b1c9 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/lib/cobalt/posix.wrappers b/lib/cobalt/posix.wrappers index 2aa3d33..a7a6b50 100644 --- a/lib/cobalt/posix.wrappers +++ b/lib/cobalt/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/lib/cobalt/printf.c b/lib/cobalt/printf.c index df527fe..7fc988d 100644 --- a/lib/cobalt/printf.c +++ b/lib/cobalt/printf.c @@ -48,13 +48,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 { @@ -97,7 +98,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; @@ -137,7 +138,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; @@ -157,24 +158,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; @@ -183,6 +195,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); @@ -195,7 +208,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; } @@ -209,13 +222,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; @@ -223,7 +236,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) @@ -255,25 +269,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) @@ -372,10 +398,8 @@ int rt_print_init(size_t buffer_size, const char *buffer_name) return ENOMEM; buffer->ring = malloc(size); - if (!buffer->ring) { - free(buffer); + if (!buffer->ring) return ENOMEM; - } rt_print_init_inner(buffer, size); } @@ -538,16 +562,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; @@ -627,7 +652,6 @@ static __attribute__ ((constructor)) void __rt_print_init(void) first_buffer = NULL; seq_no = 0; - auto_init = 0; default_buffer_size = RT_PRINT_DEFAULT_BUFFER; value_str = getenv(RT_PRINT_BUFFER_ENV); @@ -635,7 +659,7 @@ static __attribute__ ((constructor)) void __rt_print_init(void) errno = 0; default_buffer_size = strtol(value_str, NULL, 10); if (errno || default_buffer_size < RT_PRINT_LINE_BREAK) { - fprintf(stderr, "Invalid %s\n", RT_PRINT_BUFFER_ENV); + __real_fprintf(stderr, "Invalid %s\n", RT_PRINT_BUFFER_ENV); exit(1); } } @@ -646,7 +670,7 @@ static __attribute__ ((constructor)) void __rt_print_init(void) errno = 0; period = strtoll(value_str, NULL, 10); if (errno) { - fprintf(stderr, "Invalid %s\n", RT_PRINT_PERIOD_ENV); + __real_fprintf(stderr, "Invalid %s\n", RT_PRINT_PERIOD_ENV); exit(1); } } @@ -665,8 +689,8 @@ static __attribute__ ((constructor)) void __rt_print_init(void) errno = 0; buffers_count = strtoul(value_str, NULL, 0); if (errno) { - fprintf(stderr, "Invalid %s\n", - RT_PRINT_BUFFERS_COUNT_ENV); + __real_fprintf(stderr, "Invalid %s\n", + RT_PRINT_BUFFERS_COUNT_ENV); exit(1); } } @@ -678,7 +702,7 @@ static __attribute__ ((constructor)) void __rt_print_init(void) pool_bitmap = malloc(pool_bitmap_len * sizeof(*pool_bitmap)); if (!pool_bitmap) { - fprintf(stderr, "Error allocating rt_printf " + __real_fprintf(stderr, "Error allocating rt_printf " "buffers\n"); exit(1); } @@ -687,8 +711,8 @@ static __attribute__ ((constructor)) void __rt_print_init(void) pool_len = buffers_count * pool_buf_size; pool_start = (unsigned long)malloc(pool_len); if (!pool_start) { - fprintf(stderr, "Error allocating rt_printf " - "buffers\n"); + __real_fprintf(stderr, "Error allocating rt_printf " + "buffers\n"); exit(1); } @@ -734,11 +758,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); } } @@ -771,15 +794,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) @@ -789,7 +829,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/lib/cobalt/wrappers.c b/lib/cobalt/wrappers.c index 37a8ab5..cfd3341 100644 --- a/lib/cobalt/wrappers.c +++ b/lib/cobalt/wrappers.c @@ -373,6 +373,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/testsuite/unit/mutex-torture.c b/testsuite/unit/mutex-torture.c index ff76e16..bc32802 100644 --- a/testsuite/unit/mutex-torture.c +++ b/testsuite/unit/mutex-torture.c @@ -377,6 +377,10 @@ void mode_switch(void) { pthread_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