Skip to content

Commit

Permalink
StdioSerial.h: add SERIAL_OUTPUT_FILENO macro to allow clobbering on …
Browse files Browse the repository at this point in the history
…the command line (see #92)
  • Loading branch information
bxparks committed Jan 2, 2025
1 parent 37e8bd6 commit abfe161
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
* Unreleased
* Support sending output of `Serial` port to `STDERR`
(replaces [PR#92](https://github.com/bxparks/EpoxyDuino/pull/92).
* Add `SERIAL_OUTPUT_FILENO` macro which can be overridden on the command
line (e.g. `make EXTRA_CPPFLAGS='SERIAL_OUTPUT_FILENO=2'` to override the
default output file descriptor of `Serial` at compile time.
* 1.6.0 (2024-07-25)
* Add `strncat_P()` to `pgmspace.h`.
* Add `ESP.restart()` and `ESP.getChipId()`. See
Expand Down
52 changes: 50 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ The disadvantages are:
* [Enable Terminal Echo](#EnableTerminalEcho)
* [Output to STDERR](#OutputToStderr)
* [Multiple Serial Ports](#MultipleSerialPorts)
* [Shell Redirection](#ShellRedirection)
* [Libraries and Mocks](#LibrariesAndMocks)
* [Inherently Compatible Libraries](#InherentlyCompatibleLibraries)
* [Emulation Libraries](#EmulationLibraries)
Expand Down Expand Up @@ -1110,8 +1111,8 @@ void setup() {
#### Output to STDERR

By default, the `Serial` instance sends its output to the STDOUT (file
descriptor `STDOUT_FILENO`, i.e. 1). We can override that to send the output to
STDERR (file descriptor `STDERR_FILENO`) using the
descriptor `STDOUT_FILENO` which is always 1). We can override that to send the
output to STDERR (file descriptor `STDERR_FILENO`) using the
`StdioSerial::setOutputFileDescriptor(int fd)` method:

```C++
Expand All @@ -1120,6 +1121,20 @@ Serial.setOutputFileDescriptor(STDERR_FILENO);
Serial.println("This goes to STDERR");
```

Another way to override the output file descriptor of the `Serial` instance is
to override the `SERIAL_OUTPUT_FILENO` macro on the command line during
compiling. The compiler `c++` or `g++` allows the `-D` flag like this:

```
$ c++ -D SERIAL_OUTPUT_FILENO=2 file.cpp ...
```

When using `make`, the flag can be passed into the compiler like this:

```
$ make EXTRA_CPPFLAGS='-D SERIAL_OUTPUT_FILENO=2'
```

<a name="MultipleSerialPorts"></a>
#### Multiple Serial Ports

Expand All @@ -1145,6 +1160,39 @@ void someFunction() {
}
```

See [examples/StdioSerialMultiple](examples/StdioSerialMultiple) for details.

<a name="ShellRedirection"></a>
#### Shell Redirection

This probably a good place to remind Unix users that shell redirection is
available on specific file descriptors using the `N>` syntax. Suppose we change
the above example to use 3 and 4 instead, like this:

```C++
#ifdef EPOXY_DUINO
StdioSerial Serial1(3);
StdioSerial Serial2(4);
#endif
...
void someFunction() {
Serial1.println("Print to 3");
Serial2.println("Print to 4");
...
}
```

We can run the executable in the `bash(1)` shell like this:

```
$ ./StdioSerialMultiple.out 3> stream3.txt 4> stream4.txt
```

We then get 2 files:

- `stream3.txt` contains the string "Print to 3", and
- `stream4.txt` contains the string "Print to 4".

<a name="LibrariesAndMocks"></a>
## Libraries and Mocks

Expand Down
16 changes: 14 additions & 2 deletions cores/epoxy/StdioSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@
#include "Print.h"
#include "Stream.h"

#ifndef SERIAL_OUTPUT_FILENO
// Default output file number used by `StdioSerial` class, and therefore, the
// `Serial` instance. Normally this is `STDOUT_FILENO` but can be overridden on
// the command line. For example, recompiling with `-D SERIAL_OUTPUT_FILENO=2`
// will configure `Serial` to print to `STDERR` instead.
#define SERIAL_OUTPUT_FILENO STDOUT_FILENO
#endif

/**
* A version of Serial that reads from STDIN and sends output to STDOUT on
* Linux or MacOS.
Expand All @@ -20,9 +28,13 @@ class StdioSerial: public Stream {
* Construct an instance. The default output file descriptor is
* STDOUT_FILENO, but STDERR_FILENO is another option. POSIX.1-2017 defines
* these values in <unistd.h> (see
* https://unix.stackexchange.com/questions/437602).
* https://unix.stackexchange.com/questions/437602), so works under Linux
* and MacOS (and assumed to work under FreeBSD, but not explicitly tested).
*
* The default file descriptor can be overridden by defining the
* `SERIAL_OUTPUT_FILENO={n}` macro on the command line when compiling.
*/
StdioSerial(int fd = STDOUT_FILENO) : outputFd(fd) { }
StdioSerial(int fd = SERIAL_OUTPUT_FILENO) : outputFd(fd) { }

/**
* Override the output file descriptor. Two common values are expected to be
Expand Down

0 comments on commit abfe161

Please sign in to comment.