Thread: C function - other process

C function - other process

From
Jakub Woźny
Date:
Hello,

I wrote a simple function:

PG_FUNCTION_INFO_V1(my_fcn);

Datum
my_fcn()
{   int i,ret;   i=0;   signal(SIGCHLD,SIG_IGN);   switch(fork())   {       case 0:       {            SPI_connect();
       for(i=0;i<10;i++)           {               SPI_exec("insert into my_tmp values ('asdasd');",1);
sleep(1);           }           ret = SPI_finish();           exit(ret);       }       default:       {           ;
 }   }
 
}

Next I create a function in my database:

CREATE FUNCTION my_fcn() RETURNS void   AS '$libdir/my_fcn', 'my_fcn'   LANGUAGE c;

Now I execute "select my_fcn();" and I don't see records in table
'my_tmp', but function works.
I checked returns values from SPI function, tehere are correct.
What is wrong?

Best regards,
jakub

-- 
kubaw@o2.pl


Re: C function - other process

From
Tom Lane
Date:
Jakub Woźny <kubaw@o2.pl> writes:
> I wrote a simple function:

>     signal(SIGCHLD,SIG_IGN);
>     switch(fork())

This will NOT work.  It WILL corrupt your database.  You do not get to
randomly introduce new processes into the backend set.
        regards, tom lane


Re: C function - other process

From
Michael Fuhr
Date:
On Fri, Apr 22, 2005 at 03:39:55PM -0400, Tom Lane wrote:
> Jakub Woźny <kubaw@o2.pl> writes:
> > I wrote a simple function:
> 
> >     signal(SIGCHLD,SIG_IGN);
> >     switch(fork())
> 
> This will NOT work.  It WILL corrupt your database.  You do not get to
> randomly introduce new processes into the backend set.

What about fork() followed by exec*(), either explicitly or via
popen(), system(), etc.?  Should these be avoided as well, or is
there a safe way to do them?  I'm thinking of the case where a
user-defined function wants to invoke some external command -- I've
done that in experiments but I've never been sure how safe it was.

-- 
Michael Fuhr
http://www.fuhr.org/~mfuhr/


Re: C function - other process

From
Tom Lane
Date:
Michael Fuhr <mike@fuhr.org> writes:
> What about fork() followed by exec*(), either explicitly or via
> popen(), system(), etc.?  Should these be avoided as well, or is
> there a safe way to do them?  I'm thinking of the case where a
> user-defined function wants to invoke some external command -- I've
> done that in experiments but I've never been sure how safe it was.

Execing some new program is safe enough, although you might wish to
explicitly close the various sockets the backend holds to make sure
the new program doesn't maliciously scribble on them.  (It may be worth
marking them close-on-exec, although doing this without breaking the
Windows port might be hard.)

The problem with the hack at hand is that you can't have two processes
sharing the same backend slot (not to mention the same transaction ID).
But launching something that isn't a backend is no problem.
        regards, tom lane


Re: C function - other process

From
Michael Fuhr
Date:
On Fri, Apr 22, 2005 at 04:07:48PM -0400, Tom Lane wrote:
> 
> Execing some new program is safe enough, although you might wish to
> explicitly close the various sockets the backend holds to make sure
> the new program doesn't maliciously scribble on them.

Is there a way to find out which fds to close, or should a function
just close everything from, say, 3 to <some value> (assuming that
0, 1, and 2 are stdin, stdout, and stderr)?  I could think of
non-portable ways like looking under /proc/<pid>/fd, but I was
wondering if the backend keeps track of its fds somewhere.

Thanks.

-- 
Michael Fuhr
http://www.fuhr.org/~mfuhr/