Forgetful Interpreter

Discussion in 'Python' started by Bill Orcutt, Oct 17, 2003.

  1. Bill Orcutt

    Bill Orcutt Guest

    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);

    }
    Bill Orcutt, Oct 17, 2003
    #1
    1. Advertising

  2. Bill Orcutt

    Dave Kuhlman Guest

    Bill Orcutt wrote:

    > 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]

    --
    Dave Kuhlman
    http://www.rexx.com/~dkuhlman
    Dave Kuhlman, Oct 17, 2003
    #2
    1. Advertising

  3. Bill Orcutt

    Bill Orcutt Guest

    Calling PyRun_SimpleString in a Child Process. [Was Forgetful Interpreter]

    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 <> wrote in message news:<bmprfj$pem2q$-berlin.de>...
    > Bill Orcutt wrote:
    >
    > > 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]
    Bill Orcutt, Oct 18, 2003
    #3
  4. Bill Orcutt

    Jeff Epler Guest

    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
    Jeff Epler, Oct 18, 2003
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Goblin
    Replies:
    1
    Views:
    8,428
  2. adam
    Replies:
    0
    Views:
    952
  3. MackS
    Replies:
    0
    Views:
    457
    MackS
    Mar 11, 2005
  4. Michael Pitoniak
    Replies:
    1
    Views:
    544
    Michael Pitoniak
    Dec 20, 2003
  5. Replies:
    3
    Views:
    748
    Ziga Seilnacht
    Jan 3, 2007
Loading...

Share This Page