|
15 | 15 | #include <fcntl.h>
|
16 | 16 | #include <sys/select.h>
|
17 | 17 | #include <unistd.h>
|
| 18 | +#include <poll.h> |
18 | 19 |
|
19 | 20 | #include <drivers/uart.h>
|
20 | 21 | #include "cmdline.h" /* native_posix command line options header */
|
@@ -46,6 +47,7 @@ static void np_uart_poll_out(const struct device *dev,
|
46 | 47 | unsigned char out_char);
|
47 | 48 |
|
48 | 49 | static bool auto_attach;
|
| 50 | +static bool wait_pts; |
49 | 51 | static const char default_cmd[] = CONFIG_NATIVE_UART_AUTOATTACH_DEFAULT_CMD;
|
50 | 52 | static char *auto_attach_cmd;
|
51 | 53 |
|
@@ -184,6 +186,15 @@ static int open_tty(struct native_uart_status *driver_data,
|
184 | 186 | posix_print_trace("%s connected to pseudotty: %s\n",
|
185 | 187 | uart_name, slave_pty_name);
|
186 | 188 |
|
| 189 | + if (wait_pts) { |
| 190 | + /* |
| 191 | + * This trick sets the HUP flag on the tty master, making it |
| 192 | + * possible to detect a client connection using poll. |
| 193 | + * The connection of the client would cause the HUP flag to be |
| 194 | + * cleared, and in turn set again at disconnect. |
| 195 | + */ |
| 196 | + close(open(slave_pty_name, O_RDWR | O_NOCTTY)); |
| 197 | + } |
187 | 198 | if (do_auto_attach) {
|
188 | 199 | attach_to_tty(slave_pty_name);
|
189 | 200 | }
|
@@ -261,9 +272,21 @@ static void np_uart_poll_out(const struct device *dev,
|
261 | 272 | unsigned char out_char)
|
262 | 273 | {
|
263 | 274 | int ret;
|
264 |
| - struct native_uart_status *d; |
| 275 | + struct native_uart_status *d = (struct native_uart_status *)dev->data; |
| 276 | + |
| 277 | + if (wait_pts) { |
| 278 | + struct pollfd pfd = { .fd = d->out_fd, .events = POLLHUP }; |
| 279 | + |
| 280 | + while (1) { |
| 281 | + poll(&pfd, 1, 0); |
| 282 | + if (!(pfd.revents & POLLHUP)) { |
| 283 | + /* There is now a reader on the slave side */ |
| 284 | + break; |
| 285 | + } |
| 286 | + k_sleep(K_MSEC(100)); |
| 287 | + } |
| 288 | + } |
265 | 289 |
|
266 |
| - d = (struct native_uart_status *)dev->data; |
267 | 290 | ret = write(d->out_fd, &out_char, 1);
|
268 | 291 |
|
269 | 292 | if (ret != 1) {
|
@@ -379,7 +402,13 @@ static void np_add_uart_options(void)
|
379 | 402 | (void *)&auto_attach_cmd, NULL,
|
380 | 403 | "Command used to automatically attach to the terminal, by "
|
381 | 404 | "default: '" CONFIG_NATIVE_UART_AUTOATTACH_DEFAULT_CMD "'"},
|
382 |
| - |
| 405 | + IF_ENABLED(CONFIG_UART_NATIVE_WAIT_PTS_READY_ENABLE, ( |
| 406 | + {false, false, true, |
| 407 | + "wait_uart", "", 'b', |
| 408 | + (void *)&wait_pts, NULL, |
| 409 | + "Hold writes to the uart/pts until a client is " |
| 410 | + "connected/ready"},) |
| 411 | + ) |
383 | 412 | ARG_TABLE_ENDMARKER
|
384 | 413 | };
|
385 | 414 |
|
|
0 commit comments