hello, been googling this for a while and can't come up with anything good, so hopefully this won't be so easy to answer that it makes me look lazy.

I'm writing an application for linux (gcc compiler) that calls various system and custom commands from inside my own program, nothing special. I'm using NCurses to make it look a little nicer but the output of the system commands (even with noecho(), odd) becomes unruly and ugly. So I put the commands into pipes, and, using fgets, capture the input line by line and put it where I want, makes it neater. The issue I'm facing is that user-input is required for some of the commands I'm calling, the actual user input is not a problem as the person can just enter their data (passwords usually) and somehow it automatically goes to the pipe's stdin and works, I want to automate the data input. As in, store their information, and, when necessary, put it in automatically, mainly so that it can be run overnight or unsupervised.

Here's the sample scripts I'm using so I can debug my idea before I implement it in my real program:

file 1:

int main()
{
	cout << "Press enter to test drive the automated script ";
	cin.get();

    FILE *file;
    char text[255];
    std::string temp;

    file = popen("[path]/test2", "r");
    while(fgets(text, sizeof(text), file)) //gets each line
    {
        cout << text << endl; //writes each line gotten from the pipe

        temp = text; //converts to string to I can use my trim function
        trim(temp); //trims the text of any newlines or blanks

        if(temp == "7")
        {
            cout << "hit 7, press 'c' to continue";
            cout << endl;
            //somehow automatically write 'c' into the stream
        }
    }
    pclose(file);

	cout << "Closed pipe";

	cout << endl;
	return 0;
}

file 2 (being called by file 1):

int main()
{
    std::string temp; //this file is pretty self explanatory I think
    char input;
	for(int x=0;x<10;++x)
	{
	    cout << x << endl;
	    if(x == 7)
	    {
	        do
	        {
	            cin >> input;
	        }
	        while(input != 'c');
	    }
	}
	cout << "Loop finished" << endl;

	return 0;
}

I know that if I use "r+" in my popen, I should be able to read and write, but it segmentation faults whenever I add the "+", so I assume somehow it doesn't work for me.

Also note, I would like to keep using pipes as it opens more functionality options for my program, I would be willing to switch to threads, but honestly I don't know much about them. Thanks!

~J

anybody got an idea?

to boil it down, like I suppose I should have done in my original post, is how can I, using pipes (or threads) get output and also be able to provide input?

thanks for the reply.

While I was unaware that an fflush() or fseek() is required, it still doesn't solve the segmentation fault. It faults upon opening the pipe, all else held constant, adding a "+" causes a fault.

I'm going away for the weekend so I won't be able to respond til late sunday.

~J

hello again,

I found this: http://www.unix.com/high-level-programming/12028-popening-read-write.html

according to that site, pipes cannot be used for reading and writing, at least in the linux environment maybe others as well.

That being said, if I want to automate this task, I will have to resort to threads I believe. I've also heard of fork() but isn't that just a second instance of the same program? ie. prog.exe calling fork and it starts and runs another instance of prog.exe and runs them simultaneously? that would not be useful for my application unless I am mistaken in it's definition. So, looks like I'll have to go to threads. I have done some research on them, but I'm still trying to fill in the blanks, so if anyone has any good sites on threads I'd be grateful, or if you know a better way of doing this.

thanks

~J

This article has been dead for over six months. Start a new discussion instead.