-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Example as given in README doesn't work #6
Comments
Sorry, I'm not able to reproduce it. I don't have access to Yocto though, but I tried on Raspbian, by modifying your example with $ cat main.cpp
#include "subprocess.hpp"
#include <chrono>
#include <thread>
int main(int argc, char *argv[])
{
using namespace std::chrono_literals;
while(true)
{
std::string buf;
subprocess::popen cmd("vcgencmd", {"measure_temp"});
std::cout << cmd.stdout().rdbuf();
cmd.wait();
std::this_thread::sleep_for(1s);
}
return 0;
}
$ g++ --version
g++ (Raspbian 8.3.0-6+rpi1) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ -std=c++17 -Iinclude main.cpp -o main
$ sudo ./main
temp=40.0'C
temp=40.0'C
... |
I agree that it is weird, I did try it several times. I could - if you were willing to look a bit deeper - hand you an image to flash, as well as a cross compilation SDK, if that helps. Let me know. |
I must admit I don't have a clue what could be wrong. Since you have the development environment there already existing, maybe you can try couple of random things: Maybe the problem could be related to buffering. You could try calling Secondly, the call to edit: |
Ok, a short update: I was running the following code, and the first of your above suggestions applied:
No output, as before. The following is the session:
So I
To me this indicates that the issue here is somehow todo with meddling with the stdout of the invoking process. Or more general iostreams, because the following example showed the exact same issue:
Adding a std::this_thread::sleep_for(1s); as by your suggestion before trying to capture didn't do anything good, either. I don't think there is a difference between a reference and a pointer, but I will investigate. |
As I feared, changing the reference to a pointer didn't affect the outcome :( |
Thanks for troubleshooting, and sorry that I could not help. One more random idea: Does it make any difference if you change cpp-subprocess/include/subprocess.hpp Line 119 in 2e91c39
|
And one more test: subprocess::popen cmd("ls", {});
cmd.wait();
std::cout << cmd.stdout().rdbuf(); that is, wait for process to terminate before call to |
Neither the wait nor the file mode did change a thing :( It's really weird. It did solve the issue of accumulating processes though. Don't you think it would be a good idea to implicitly invoke wait() in ~popen()? |
Ok, one more bit of information: it works by using printf for printing. I don't get the output printed yet, there is probably something more happening when invoking operator<<, but the before/after are coming! I got this idea after staring at the strace log. I wonder if somehow the C++ stream runtime state is corrupted, and why. |
Could it be somehow distantly related to this https://stackoverflow.com/questions/35261389/stringstream-rdbuf-causing-cout-to-fail, that is: "std::cout is unable to read any characters ... sets failbit on std::cout, and until this state is cleared any further output will fail too". I'm not that familiar with iostreams library to understand this really, and in your case rdbuf() is read only once so it should not be at the end - this still would be unexplained. But it seems consistent with your observation of cout getting in failed state.
Yeah, I think you are right. There is potential problem though, since wait() will block until the executed command exits, but I guess that may be expected by user, at least in most cases. |
Just regarding the last point (will research your first suggestion later): I think the current behavior is the most suprising one. From a RIAA-perspective (and this is how I thought about this as a pattern) it follows for me that the lifetime of the object should govern the lifetime of it's resources. One of the few really bright sides of C++ ;) I agree though that the behavior is not ideal. So from my POV we can do these things:
I'm slightly in favor of killing, because it doesn't make the program hang, and exceptions are a choice that many C++-devs don't want to be forced to use. What do you think? |
Yes, makes sense to me. Maybe the option between wait and kill should be provided anyways even if kill would be default. Killing brings up yet another question: should it be SIGKILL or SIGHUP, where latter would give the child an option for graceful termination. Furthermore, if the process has already terminated earlier |
I think only SIGKILL makes sense, as SIGHUP can be ignored, and then we are in the same space as just doing an implicit wait: the program hangs, and the user has to find out why. Regarding the waitpid I have to admit I'm not deep enough in the details, but it sounds as if you are ;) |
Been over a month since the last reply - ran into the same issue and had to resort to using Python for now ( https://gist.github.com/MLutt/4b50cdd1644564307bda0d276e235ab4 )... Any progress on it? |
I have not had time to work with this, sorry for trouble. |
@MLutt I was not able to reproduce the problem previously, but for future reference, if you can list information on your environment it might be helpful (e.g. linux distribution, gcc/glibc version...) |
Anything else? |
Linux Mint 19.3 seems to be based on Ubuntu 18.04. I'm able to run following $ docker run --rm -it ubuntu:18.04
root@ebba422a9ccd:/# apt-get update
root@ebba422a9ccd:/# apt-get install build-essential wget
root@ebba422a9ccd:/# gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
root@ebba422a9ccd:/# wget https://raw.githubusercontent.com/tsaarni/cpp-subprocess/master/include/subprocess.hpp
root@ebba422a9ccd:/# cat > test.cpp <<EOF
#include "subprocess.hpp"
int
main(int argc, char *argv[])
{
subprocess::popen cmd("ls", {});
std::cout << cmd.stdout().rdbuf();
return 0;
}
EOF
root@ebba422a9ccd:/# g++ -o test test.cpp
root@ebba422a9ccd:/# ./test
bin
boot
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
subprocess.hpp
sys
test
test.cpp
tmp
usr
var but for you |
I had issues as well. I fixed it by renaming stdout(), stderr() and stdin() to out(),err() and in(). It seems that stdout, stderr and stdin were reserved. |
Thanks @oskarirauta, interesting finding! Do you know how to reproduce it? I did not manage myself. Now I made attempt to just have |
Sure thing; here goes..
Intel system with modified lightweight openwrt os and gcc 13.2.0. Modifications to os include development headers and libraries that allow building normally and some extra tools; for example, I can re-build (and I often do) complete openwrt including it's kernel with the same system. Those changes normally are not included in the stock version. Only change was that I renamed stdout() -> out(), stderr() -> err and stdin() -> in and it built without issues. Outside of topic; I kinda forked your work- or at least re-used parts for streams- check it out if curious.. process_cpp - it though builds with c++20 as minimum... There's not much that cpp-subprocess would gain (maybe args vector handling though..) since it's very different. It wasn't a fork in the first place, but I had troubles with streams until I found this and thought that this is nearly perfect for my needs, so I made a combination of sorts. It also does not have this issue, due to it's different approach 😉 EDIT: added cpuinfo and changed console shots to more readable format by separating each command to it's own section. |
Oh ok, there it clearly fails because I guess that others in this github issue had something else going wrong, since I understood it failed at runtime for others, not at compile time.
Cool stuff 👍 Great that this small project helped with your own version! Just curious, if you want to tell, what do you do with openwrt? I used to compile & use it when it ran on Linksys WRT54G 😆 |
Yes.. I am attempting to make my own version of lcd4linux (lcd2linux for now..) since lcd4linux's development has ended ages ago, I made a new widget(a bargraph widget for monitoring network usage) for it and once I thought that I want to take it one more step further, I noticed that it was impossible; growing widget enough made it un-usable (I was able to use it, but nothing showing on display) - so I started my own, it's working nicely already, has widgets for images and truetype text rendering, and now it's time to make plugins for it; one being "exec", so I needed my own for that.. It's not that much a fork of this project but since I used all the "important pieces", I decided that it's best way to give credit for using your code in it. My version of lcd2linux has only support for graphical displays and probably will not support anything else than dpf/ax206 (hacked photo frame) such as this, since that's a display I have and use - as a attempt of it supporting original like expression engine, I have created my own expr_cpp - for the moment as there are no plugins yet available; it is just displaying a simple switching image looking like this:
For the moment, there is no repository for this project since I am writing it alone and it's quite a big, so pushing frequently would just slow me down. I also plan to have plugins for json parsing and optional built-in ubus client (similar to dbus, but minimal version; only in openwrt), that way, to retrieve some information on openwrt, one wouldn't even need to use exec in some cases.. It supports all the original image formats using the same gd library as original used.. Code is there very similar, except this time, scaling actually works.. This also translates coordinates, so if you decide to rotate, original coordinates rotate along. Up to your configuration if they draw on-screen as well though.. So, a small project, eh..? 😉 My server is running openwrt, I am a contributor to project, I develop it (on my own and for myself, some of my modifications are not worth of making a push request, since they serve mostly myself, such as some targeted kernel modifications); and ofcourse, I am running it on quite a few of these a bit more powered routers; my network has 1 router, and 5 other routers mainly acting as a swithes, main router has i7 and 8 1gb ports 32gb ram, living room runs i5 with 6 ports and 16gm ram(one that I develop), and others are running with i3, 3 ports and 16gb ram. All the time I hear how openwrt is limited for this and that, but it isn't true if you are willing to have some effort to it; yet it isn't running graphical ui with office kind of software; but it can perform for all that I think Linux is good for; and who says it doesn't have a graphical ui? lcd4linux has been there for quite some time, and lcd2 is on-going ;) - though I don't know if it will be available as a official package.. I've had some trouble contributing to project for past few years, so I tend to have a 3 month breaks on my package update cycles.. I like openwrt mostly because it is what linux used to be; today, there are not many like it- alpine linux is like it. Others, like ubuntu.. Come with graphical user interface, office suite, have huge amount of depencies who no one is able to track... If you want to put it in a single word; they are huge. My own bake of openwrt base bistro is a bit more than 100mb and has a whole lot of stuff from the beginning, and after installing development environment, it's still way less than 200mb; my server runs podman to run containers for nginx, caddy and php and is accessible only through a vpn (and host provided vnc). Even though I use a lot more console, I think LuCi is a great interface to retrieve status on so many things 😃 I also had wrt54g(s)'s, and I am sure that I still do(in the attic in a box).. I've been member of community and contributor since those.. |
@oskarirauta That is a cool project, thanks for telling about it! I wish you good times with your project 😄 I never used lcd4linux myself but I knew of it, though just from the yellow-green displays. I never before looked at the variety of extensions and other aspects. Distantly related, I wanted to build e-ink display project with inkplate10 to follow weather, energy consumption (and pörssisähkö) etc but the project got stalled and waits for new inspiration. There my idea was just to have purpose-built web app rendered as bitmap and trying to display that with the micro controller / display. |
Yeah, that sounds more like a Arduino related project. There are boards that come with wifi integrated, consider those.. I've tried to stay away from ESP-32, but it might also be a good board for that purpose. |
I tried to get the simple ls-example working, but failed. Starting/Waiting/Closing all works, but not getting a buffer.
I had to resort to
https://github.com/deets/brombeerquark/blob/master/cpp/subprocess/src/cpp-subprocess.cpp
(taken from the tests) to get things to work. The command used btw. is not the culprit, I did in fact start with your ls-example. Just had no reason to commit that.
I have no idea why this is not working. I'm running on a raspberry pi with a YOCTO linux, but glibc and GCC 8.3.0.
The text was updated successfully, but these errors were encountered: