Thread: C function - other process
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
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
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/
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
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/