Module: xenomai-2.6
Branch: master
Commit: 9abc5faaf2bf190879ce93b247031bf05f0a8e3f
URL:    
http://git.xenomai.org/?p=xenomai-2.6.git;a=commit;h=9abc5faaf2bf190879ce93b247031bf05f0a8e3f

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

Reply via email to