1 | /* |
---|
2 | * Copyright (C) 2014 Chris Johns (chrisj@rtems.org) |
---|
3 | * |
---|
4 | * The license and distribution terms for this file may be |
---|
5 | * found in the file LICENSE in this distribution. |
---|
6 | * |
---|
7 | * This software with is provided ``as is'' and with NO WARRANTY. |
---|
8 | */ |
---|
9 | |
---|
10 | /* |
---|
11 | * @brief Redirect an stdio file decriptor. |
---|
12 | * |
---|
13 | * The is a helper module of code design to redirect an stdio file |
---|
14 | * descriptor. You can optionally have the data buffered and/or you can provide |
---|
15 | * a handler function that is called when data arrives. |
---|
16 | * |
---|
17 | * The module uses standard POSIX calls to implement the redirection and if the |
---|
18 | * threading was POSIX based the code would be portable. Currently the code |
---|
19 | * uses RTEMS threads. |
---|
20 | * |
---|
21 | * Redirecting stderr and stdout is useful in embedded system because you can |
---|
22 | * transport the output off your device or create a web interface that can |
---|
23 | * display the output. This can be a very powerful diagnostic and support tool. |
---|
24 | * |
---|
25 | * The implementation does: |
---|
26 | * |
---|
27 | * 1. Duplicate the file descriptor (fd) to redirect using the dup call. The |
---|
28 | * duplicated desciptor is used to echo the output out the existing path. |
---|
29 | * |
---|
30 | * 2. Create a pipe using the pipe call. |
---|
31 | * |
---|
32 | * 3. Duplicate the pipe's writer file descriptor to user's file |
---|
33 | * descriptor. This results in any writes to the user's fd being written to |
---|
34 | * the pipe. |
---|
35 | * |
---|
36 | * 4. Create a reader task that blocks on the pipe. It optionally calls a |
---|
37 | * handler and if configured buffers the data. |
---|
38 | */ |
---|
39 | |
---|
40 | #if !defined(RTEMS_STDIO_REDIRECT_H) |
---|
41 | #define RTEMS_STDIO_REDIRECT_H |
---|
42 | |
---|
43 | #include <stdbool.h> |
---|
44 | #include <rtems.h> |
---|
45 | #include <rtems/thread.h> |
---|
46 | |
---|
47 | #ifdef __cplusplus |
---|
48 | extern "C" { |
---|
49 | #endif /* __cplusplus */ |
---|
50 | |
---|
51 | /* |
---|
52 | * Handler called whenever redirected data arrives. |
---|
53 | * |
---|
54 | * @param buffer The data. |
---|
55 | * @param length The amount of data in the buffer. |
---|
56 | */ |
---|
57 | typedef void (*rtems_stdio_redirect_handler)(const char* buffer, |
---|
58 | ssize_t length); |
---|
59 | |
---|
60 | /* |
---|
61 | * Redirector data. |
---|
62 | */ |
---|
63 | typedef struct |
---|
64 | { |
---|
65 | volatile uint32_t state; /**< The state. */ |
---|
66 | rtems_id reader; /**< The reader thread. */ |
---|
67 | rtems_mutex lock; /**< Lock for this struct. */ |
---|
68 | int fd; /**< The file descriptor to redirect. */ |
---|
69 | int fd_dup; /**< Duplicated fd to write to. */ |
---|
70 | int pipe[2]; /**< The pipe to the reader thread. */ |
---|
71 | char* input; /**< The input buffer the reader uses. */ |
---|
72 | ssize_t input_size; /**< The input buffer size. */ |
---|
73 | char* buffer; /**< Captured redirected data. */ |
---|
74 | ssize_t buffer_size; /**< Capture buffer size. */ |
---|
75 | ssize_t in; /**< Buffer in index. */ |
---|
76 | bool full; /**< The buffer is full. */ |
---|
77 | bool echo; /**< Echo the data out the existing path. */ |
---|
78 | rtems_stdio_redirect_handler handler; /**< Redirected data handler. */ |
---|
79 | } rtems_stdio_redirect; |
---|
80 | |
---|
81 | /* |
---|
82 | * Open a redirector returning the handle to it. |
---|
83 | * |
---|
84 | * @param fd The file descriptor to redirect. |
---|
85 | * @param priority The priority of the reader thread. |
---|
86 | */ |
---|
87 | rtems_stdio_redirect* rtems_stdio_redirect_open(int fd, |
---|
88 | rtems_task_priority priority, |
---|
89 | size_t stack_size, |
---|
90 | ssize_t input_size, |
---|
91 | ssize_t buffer_size, |
---|
92 | bool echo, |
---|
93 | rtems_stdio_redirect_handler handler); |
---|
94 | |
---|
95 | /* |
---|
96 | * Close the redirector. |
---|
97 | */ |
---|
98 | void rtems_stdio_redirect_close(rtems_stdio_redirect* sr); |
---|
99 | |
---|
100 | /* |
---|
101 | * Get data from the capture buffer. Data read is removed from the buffer. |
---|
102 | * |
---|
103 | * @param sr The stdio redirection handle. |
---|
104 | * @param buffer The buffer data is written into. |
---|
105 | * @param length The size of the buffer. |
---|
106 | * @return ssize_t The amount of data written and -1 or an error. |
---|
107 | */ |
---|
108 | ssize_t rtems_stdio_redirect_read(rtems_stdio_redirect* sr, |
---|
109 | char* buffer, |
---|
110 | ssize_t length); |
---|
111 | |
---|
112 | #ifdef __cplusplus |
---|
113 | } |
---|
114 | #endif /* __cplusplus */ |
---|
115 | |
---|
116 | #endif |
---|