|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| |||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
Creating a frontend for bc
I am trying to create a simple Gtk2 frontend for the bc program, so I started playing around with pipes.
Bc is a program that can solve expression (e.g. 2+2), and when you run the "bc " command you can type an expression folowed by <enter> and it will output the solution plus a \n . Well, my question is, how can I run bc and then pass the expression that the user types into my GUI frontend to bc, and then get the solution and show it in on my GUI? I have tried popen(), and I can read the output if I pass a file containing the expression as an argument, but I cant seem pass the expression that the user typed in and then read the output. The code below is what I have so far. Code:
FILE *bc_read;
int bytes_read;
size_t nbytes = 100;
char *my_string;
bc_read = popen ("bc -q /tmp/expression", "r");
if ((!bc_read) )
{
cout << "Pipe failed.\n" << endl;
return EXIT_FAILURE;
}
my_string = (char *) malloc (nbytes );
bytes_read = getline (&my_string, &nbytes,bc_read);
if (pclose (bc_read) != 0)
{
cout << "Error.\n" << endl;
}
cout << my_string;
Could someone help me out? Thank you in advance. |
|
#2
|
||||
|
||||
|
Just to offer a little brain-storming.
Is it possible to do a popen for both read and write? Or, lay the pipe by hand, so to speak. 1. call pipe. 2. fork 3. have the child dup its end of the pipe to stdin and stdout, then close its end of the pipe. This will make reads from stdin and writes to stdout come from and go to the pipe. 4. do your favorite flavor of exec* to run bc. 5. The parent process communicates with bc through the pipe. I've seen it described, but I haven't tried it yet. |
|
#3
|
|||
|
|||
|
I don't think so, because you cant do popen ("bc", "rw") .
I'll try what you have described, although I don't understand what you are talking about ![]() Last edited by Tuxie : June 16th, 2003 at 02:05 PM. |
|
#4
|
||||
|
||||
|
For fun, I put a rudimentary example together of fork-exec'ing bc with its stdin and stdout redirected to pipes. Sorry for the delay, but I kept getting a "broken pipe" error which I finally tracked down to having not called exec* properly:
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <wait.h>
/* bcfe -- bc front end
Create a process running bc and send commands and read responses
via pipes.
*/
int main(void)
{
char buf[64];
int wrpipe[2]; // two file descriptors:
int rdpipe[2]; // [0] read, [1] write
int pid;
// open the two pipes
// note that a single pipe should not be used for bidirectional
// communication, so we open one to write to and one to read from.
if (pipe(wrpipe) == -1)
{
perror("wrpipe error");
exit(-1);
}
if (pipe(rdpipe) == -1)
{
perror("rdpipe error");
exit(-1);
}
// fork a child process
pid = fork( );
if (pid == -1)
{
perror("fork error");
exit(-1);
}
// initialize the buffer
memset(buf,0,64);
// different actions for child and parent
if (pid == 0)
{ // child
// perform redirection
// close stdin & stdout then dup pipes to them
close(0); // close stdin
dup2(wrpipe[0],0);
close(1); // close stdout
dup2(rdpipe[1],1);
// close our end of the pipes
close(wrpipe[0]); // write pipe
close(wrpipe[1]); // write pipe
close(rdpipe[0]); // read pipe
close(rdpipe[1]); // read pipe
// run bc
// this replaces the child process, but keeps its file descriptors
execlp("bc","bc",0);
// will never reach here
}
else
{ // parent
// close the read-end of the write pipe and
// the write-end of the read pipe
close(wrpipe[0]); // write pipe
close(rdpipe[1]); // read pipe
// send a problem to bc
write(wrpipe[1],"1+1\n",4);
// read bc's answer and echo it to stdout
read(rdpipe[0],buf,64);
printf("%s\n",buf);
// command bc to quit
write(wrpipe[1],"quit\n",5);
// wait for bc to terminate
waitpid(pid,NULL,0);
// close the pipes
close(wrpipe[1]); // write pipe
close(rdpipe[0]); // read pipe
}
return 0;
}
Of course, in your case the parent's communication with bc and with the user will be more complex and interactive, but this should give you the basics of tying stdin and stdout to pipes and using them with a child process. Hope it helps. Last edited by dwise1_aol : June 17th, 2003 at 11:43 AM. |
![]() |
| Viewing: Dev Shed Forums > Programming Languages > C Programming > Creating a frontend for bc |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
|
|