Comments (8)
Thanks, I will try to fix #316 for all cases. It's necessary for the buffer changes. I hope I will be able to have a better buffer class soon
from cpp-terminal.
@wmarini Thx for the report, In fact it is a bug I think. You are correct saying that Term::cout Term::clog Term::cin are always connected to the terminal by design.
I would like to let the Term::cin always be bind to the terminal /dev/tty. I think what could be done is to redesign the buffer class to be able to change to whom is talking to and do :
if(m_counter++ == 0)
{
std::ios_base::Init();
new(&Term::cout) TOstream(Term::Buffer::Type::FullBuffered, BUFSIZ);
new(&Term::clog) TOstream(Term::Buffer::Type::LineBuffered, BUFSIZ);
new(&Term::cerr) TOstream(Term::Buffer::Type::Unbuffered, 0);
new(&Term::cin) TIstream(Term::Buffer::Type::FullBuffered, BUFSIZ);
std::cin.rdbuf(Term::rdbuf(stdin));
}
The use of the buffer class in this case std::cin.rdbuf(Term::cin.rdbuf());
is to be able to read form std::cin even when the terminal is in raw mode. The fact that is always reading to /dev/tty is not intentionnal but just a lack of modularity of the class buffer.
I think we could redesigne the buffer class to add the possibility to change to whom is talking and this would solve your problem right ?
Could you provide a very basic code you wanted it to work? We could add it as example or test to avoid such problem in the future
In my humble opinion, to assure that Term::cin clog cerr etc are always binded to /dev/tty is something important. User can then choose std::cout if he want the consumer to be able to redirect some messages
from cpp-terminal.
The buffer
class.. is not optimal; it is my first time dealing with IOStreams internals and the design is a bit hard to follow for me, at least for now. I need time to study and digest the Standard C++ Iostreams and Locales: Advanced Programmer's Guide and Reference
.
from cpp-terminal.
Some toy code : master...flagarde:cpp-terminal:master
It seems to do what you want on linux, need to check windows and there is many bugs too, we need to deal with raw and cooked by ourself, but using the example ./cin_raw or ./cin_cooked it seems to do what you want :
echo "1234 toto" | ./cin_cooked
but then we trigger the last issue you mentionned before (#316). It the path I would like to follow but it need more cleaning
And #316 need a better fix, I just did a naive one, I knew it would be triggered in some corner cases.
from cpp-terminal.
Hi, sure, I can provide an example program that handles that scenario. Let me review the example directory first and prepare something that is not covered in other example program.
from cpp-terminal.
@wmarini I have made some change on the code. It seems it is closer to what you want to do. Doing :
echo "42 Hello" | ./cin_raw
or :
echo "42 Hello" | ./cin_cooked
you can catch the value using std::cin. Don't use Term::cin as it is always binded to the terminal. Maybe need more polishing but the behaviour you want seems possible now.
from cpp-terminal.
Excellent! It's working now!
My preliminary test works as expected:
$ echo -e "test std::cin\ntest stdin" | ./pipe_cin
Checking if std::cin is empty
std::cin => "test std::cin"
Checking if stdin is empty
stdin => "test stdin"
I did that simple test just to make sure stdin
and std::cin
are using the pipe to read input:
#include "cpp-terminal/color.hpp"
#include "cpp-terminal/terminal.hpp"
#include <iostream>
#include <string>
#include <sys/select.h>
#include <unistd.h>
namespace {
bool isStdinEmpty()
{
struct timeval tv{0,0};
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
return select(STDIN_FILENO + 1, &rfds, nullptr, nullptr, &tv) == 0;
}
std::string ReadStdin()
{
if (isStdinEmpty()) {
return "stdin is empty";
}
std::string stdin_result;
char c;
while((c = static_cast<char>(std::fgetc(stdin))) != EOF) {
if (c == '\n')
break;
stdin_result += c;
}
return stdin_result;
}
bool isCinPipe()
{
return isatty(fileno(stdin)) == 0;
}
std::string ReadCin()
{
if (!isCinPipe()) {
return "std::cin isn't an unamed pipe";
}
std::string cin_result;
char c;
while((c = static_cast<char>(std::cin.get())) != '\n') {
cin_result += c;
}
return cin_result;
}
std::ostream& PrintOutColor(std::ostream& ostr, std::string const& str, Term::Color::Name color)
{
ostr << "\"" <<
Term::color_fg(color) << str << Term::color_fg(Term::Color::Name::Default)
<< "\"" << std::endl;
return ostr;
}
} // namespace
int main()
{
std::string cinBuff{};
std::cout << "Checking if std::cin is empty" << std::endl;
cinBuff = ReadCin();
std::cout << "std::cin => ";
PrintOutColor(std::cout, cinBuff, Term::Color::Name::Red);
std::cout << "Checking if stdin is empty" << std::endl;
cinBuff = ReadStdin();
std::cout << "stdin => ";
PrintOutColor(std::cout, cinBuff, Term::Color::Name::Red);
return 0;
}
I'm going to continue working to finish my original program that tries to highlight some selected words on my terminal from an unamed pipe.
Thank you!!!
from cpp-terminal.
Great, I'm not yet sure if the fix is working on all cases but it's a first move in the right direction.
Thx for the code, would you allow us to take it and use it as basis for some example or test in cpp-terminal ?
from cpp-terminal.
Related Issues (20)
- Windows terminal can be turned into `legacy mode` and so crash our ANSII support detection
- example 'kilo' does not support special characters HOT 7
- exception leaking destructor is dangerous HOT 10
- build as shared library, error adding symbols: DSO missing from command line HOT 12
- Compiling the examples with GCC results in errors HOT 7
- Create a list of projects that are using this library HOT 3
- Bug: cpp-terminal crashes if two utf8 are inserted simultaneously HOT 42
- Multiline prompt stopped working on macOS
- Ctrl + I and Tab HOT 6
- Bug: Text Wrap Incompatibility HOT 6
- Bring back the list of other similar libraries HOT 4
- Pressing Ctrl, Alt, Shift creates a copy paste event on windows? HOT 3
- Addition of Metakey and Key results in warning of deprecation HOT 1
- Bug in key + metakey arithmetic HOT 7
- Exception thrown at this line when typeing to fast HOT 7
- mouse sending random characters to the terminal after examples/minimal ends HOT 8
- Issue with file headers HOT 3
- Doctest.h needs to be updated to the latest version - compile error on Ubuntu 22.04 HOT 2
- Error linking with CMake HOT 8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cpp-terminal.