Forgetful Interpreter

B

Bill Orcutt

Having seen the number of lost souls asking questions about embedding
Python in the archives of this group, I hesitate to add myself to
their number, but I've hit a problem I can't quite get my head around.

I have a simple C program that embeds a python interpreter to execute
python commands and return stdout, and to a point everything works as
intended. The problem that each command seems to be executed in its
own context and knows nothing of what's come before. So if enter
"print 2+2", I get back "4", but if I enter "a=2+2" then enter "print
a", I get back the error, "a is undefined." My guess is that this has
something to calling PyRun_SimpleString inside of a child process, but
I can't get much further than this.

Any assistance is appreciated.

thanks

-Bill

//call this once at the beginning to initialize
void * nyptho_doinit(t_gogo* x, short flag)
{
Py_Initialize();
char capture_stdout[] ="import sys,
StringIO\n\sys.stderr=sys._capture=StringIO.StringIO()\n";
int rc = PyRun_SimpleString(capture_stdout);
return x;
}

//this executes the command
FILE * nyptho_exec(t_gogo* x, char * cmd, short bflag, short fflag)
{
int pfd[2],i,z=0;
pid_t pid;
FILE *fp;
extern int errno;

if (pipe(pfd) < 0)
return(NULL); // errno set by pipe()

if ( (pid = fork()) < 0)
return(NULL); // errno set by fork()

else if (pid == 0) // child
{
close(pfd[0]);

// close all descriptors in childpid[]
if (x->childpid[0] > 0)
close(0);

PyRun_SimpleString(cmd);

//PyRun_SimpleString("import sys");
PyObject* sysmod = PyImport_ImportModule("sys");
PyObject* capobj =
PyObject_GetAttrString(sysmod,"_capture");
PyObject* strres =
PyObject_CallMethod(capobj,"getvalue",0);
char * dodo = PyString_AsString(strres);
strcpy(globalBuf,dodo);

write(pfd[1], globalBuf, (long)strlen(globalBuf));
globalBuf[0]='\0';

_exit(127); //child exits
}
// parent
close(pfd[1]);

if ( (fp = fdopen(pfd[0], "r")) == NULL)
return(NULL);

x->childpid[fileno(fp)] = pid; // remember child pid for this
fd
return(fp);

}
 
D

Dave Kuhlman

Bill said:
Having seen the number of lost souls asking questions about
embedding Python in the archives of this group, I hesitate to add
myself to their number, but I've hit a problem I can't quite get
my head around.

I have a simple C program that embeds a python interpreter to
execute python commands and return stdout, and to a point
everything works as intended. The problem that each command seems
to be executed in its own context and knows nothing of what's come
before. So if enter "print 2+2", I get back "4", but if I enter
"a=2+2" then enter "print a", I get back the error, "a is
undefined." My guess is that this has something to calling
PyRun_SimpleString inside of a child process, but I can't get much
further than this.

Take a look at Python-2.3.2/Demo/embed/demo.c in the Python source
code distribution for clues. That program calls
PyRun_SimpleString() several times with the same context. If you
do not switch interpreters (thread state, whatever) or
re-initialize etc, then each call to PyRun_SimpleString() should
have the same global variables etc.

Why are you calling fork()? Someone else will have to tell you
the consequences of doing that.

Dave

[snip]
 
B

Bill Orcutt

Thanks for your reply. I agree that PyRun_SimpleString should be
running in the same context-- its worked that way for me in the past--
The only thing that's different this time is fork() and that's what
I'm hoping someone will tell me how to deal with, since I'm stuck with
it this time.

I'm updating the subject line to something more descriptive.

thanks

-Bill

Dave Kuhlman said:
Bill said:
Having seen the number of lost souls asking questions about
embedding Python in the archives of this group, I hesitate to add
myself to their number, but I've hit a problem I can't quite get
my head around.

I have a simple C program that embeds a python interpreter to
execute python commands and return stdout, and to a point
everything works as intended. The problem that each command seems
to be executed in its own context and knows nothing of what's come
before. So if enter "print 2+2", I get back "4", but if I enter
"a=2+2" then enter "print a", I get back the error, "a is
undefined." My guess is that this has something to calling
PyRun_SimpleString inside of a child process, but I can't get much
further than this.

Take a look at Python-2.3.2/Demo/embed/demo.c in the Python source
code distribution for clues. That program calls
PyRun_SimpleString() several times with the same context. If you
do not switch interpreters (thread state, whatever) or
re-initialize etc, then each call to PyRun_SimpleString() should
have the same global variables etc.

Why are you calling fork()? Someone else will have to tell you
the consequences of doing that.

Dave

[snip]
 
J

Jeff Epler

What you are doing won't work -- fork() behaves as though it makes a
copy of all the data in the current process's address spaces, so changes
in the child aren't mirrored in the parent.

Example C program:

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>

int i = 0;

void increment_i_in_forked_subprocess() {
pid_t pid = fork();
if (pid == -1) {
perror("fork"); exit(1);
}
if (pid == 0) {
i++;
printf("In subprocess %d, i=%d\n", getpid(), i);
exit(0);
}
wait(NULL);
printf("Subprocess exited\n");
}

int main(void) {
int j;
for(j=0; j<10; j++) {
increment_i_in_forked_subprocess();
}
return 0;
}

$ gcc orcutt.c && ./a.out
In subprocess 16632, i=1
Subprocess exited
In subprocess 16633, i=1
Subprocess exited
In subprocess 16634, i=1
Subprocess exited
In subprocess 16635, i=1
Subprocess exited
In subprocess 16636, i=1
Subprocess exited
In subprocess 16637, i=1
Subprocess exited
In subprocess 16638, i=1
Subprocess exited
In subprocess 16639, i=1
Subprocess exited
In subprocess 16640, i=1
Subprocess exited
In subprocess 16641, i=1
Subprocess exited
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top