[comp.databases] ORACLE 6.0 and signal handling under UNIX

jon@fdmetd.uucp (Jon Ivar Tr|stheim) (08/27/90)

I am running ORACLE 6.0 with UNIX 3.2 on a TOWER 32/600. I run into
problems with oracle's way to handle system-call in Pro*c.

In the Oracle Installation & Users's Guide ORACLE says that under TOWER
UNIX, certian operating system call may interfere with the functioning
of the ORACLE precompilers.

This text is copied from the Installation & Uses's Guide manual.

The ORACLE 6.0 uses the following signals:

SIGINT		Used by all two-task drivers to detect user interuupt
			requests and ORACLE errors.

SIGPIPE     Used by the Pipe driver to detect end-of-file on the 
			communication channel.

SIGTERM 	Used by the Pipe driver to re-synchronize communication 
			between the user and ORACLE after an error or interrupt.

The manaual also say's that these signals will, in general be caught by
the users process. They can also be caught by the hli(oci) or pcc(pro)
program, but in a way that preserves the orginal signal handler.

My questions is ......    can anybody tell me how i shall set up the
signal-handling routine within a user-exit in Sqlforms ?


I have a Sqlforms-program which contain a user-exit routine i C. The
user-exit routine is very simple. It is just my own implementation of
the ORACLE "host" command in Sqlforms. The source code for the user-exit
follows (skip down to line containing PROBLEM STARTS HERE):



#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <termio.h>
#include <string.h>
#include <signal.h>
#include <uabincl/uab.h>
#include <uabincl/uab_client.h>



#define	SINGLE_QUOTE	'\''
#define trace(fp, msg)  fprintf(fp, msg)

struct termio term, term_in_func;

#ifdef unix
extern void saveterm();
extern void resetterm();
#endif

EXEC SQL INCLUDE SQLCA.H;

EXEC SQL BEGIN DECLARE SECTION;
VARCHAR     get_file_dummy[10];
EXEC SQL END DECLARE SECTION;


extern  void    uab_errmsg();
extern 	int 	errno, sys_nerr;
extern 	char 	*sys_errlist[];

#ifdef unix
extern	struct	uab_curses	Uab_curses;
extern	void	tputs();
extern	void	outc();
#endif

FILE *fp, *fopen();

/* ------------------------------------------------------------ */
/* uab_host() - IAP user exit function                  */
/* ------------------------------------------------------------ */
int uab_host(cmd, cmdl, err, errl, inqury)
char    *cmd;   /* Command line string      */
int     *cmdl;  /* Length of command line   */
char    *err;   /* Error message string     */
int     *errl;  /* length of error message  */
int     *inqury;/* 1 if IAP Enter Query     */
{
    char    exit_msg[80];
    int     exit_msg_len;
	int		i, j, inword, len;
	int		pid, cpid, status;
	int		get_word();
	int		command;
    char    cmd_line[1000]; /* Our copy of the command line     */
	char    *strp, *malloc();
	char    buff[256];
	char	*word[20];      /* table to contain each word */
	char	*word_contain[20];
	char	host_cmd[1000];
	void	remove_first_word();
	void	move_left();



    cmd[*cmdl] = '\0';      /* NULL terminate argument string   */


	strcpy(cmd_line, cmd);
	len = strlen(cmd_line);

	get_word(cmd_line, NULL, buff);
	if (strcmp(cmd_line, buff) == NULL) {
		len = NULL;
	    command = FALSE;
    }

	if (len > 0)
		remove_first_word(cmd_line);

	if (cmd_line[0] == SINGLE_QUOTE &&
		cmd_line[strlen(cmd_line) -1] == SINGLE_QUOTE) {

		strp = &cmd_line[1];    /* skipper f|rste tegn (') */
		strcpy(cmd_line, strp);
		cmd_line[strlen(cmd_line) -1] = '\0'; /* skipp siste (') */

		/* Bygger opp host kommandoen */

		strcpy(host_cmd, cmd_line);
		command = TRUE;
	}
	else
	if (len > 0) { 

		for (i = 0, j = 0, inword = FALSE; i < len; i++) {
			if (cmd_line[i] == ' ' || cmd_line[i] == '\n' ||
				cmd_line[i] == '\t') {
				
				cmd_line[i] = '\0';
				inword = FALSE;
			}
			else {
				if (inword == FALSE) {
					inword = TRUE;
					word[j] = cmd_line + i;
					j++;
				}
			}
		}

		/* N} er linjen brutt ned i endkelt ord
				word[0] = variable1
				word[1] = variable2 osv.
		*/

		for (i = 0; i < j; i++) {
			strp = (char *)malloc(sizeof(buff));
    		if (!sql_iaf_get(strp, word[i])) {
				sprintf(buff,"IAF GET feilet for felt %s", word[i]);
        		uab_errmsg(buff);
        		return (IAPFAIL);
    		}
			word_contain[i] = strp;
		}

		/* N} er innholdet av hver variabel hentet ut og lagt i tabell
		   word_contain. (eks p} inh. av tabell)
		   word_contain[0] = "struct.sh"
		   Bygger deretter opp host kommando strengen.
		*/

		host_cmd[0] = '\0';

		for (i = 0; i < j; i++) {
			strcat(host_cmd, word_contain[i]);
			if (j > 1)
				strcat(host_cmd, " ");
		}
		command = TRUE;
	}

	saveterm(&term);


   	if (ioctl(0, TCGETA, &term_in_func) == -1) {
   		uab_errmsg
		("uab_host(): ioctl TCGETA failed!!, standard input not a tty");
   		return (IAPFAIL);
	}

	term_in_func.c_iflag |= (BRKINT | ICRNL | ISTRIP | IXON);
	term_in_func.c_oflag |= OPOST;
	term_in_func.c_lflag |= (ICANON | ISIG | ECHO);
	term_in_func.c_cflag |= CLOCAL;

	if (ioctl(0, TCSETAF, &term_in_func) == -1) {
		uab_errmsg
		("uab_host(): ioctl TCSETAF failed!!, standard input not a tty");
   		return (IAPFAIL);
	}

	pid = fork();


	if (pid == -1) {

		if (errno < sys_nerr)
			sprintf(buff,"uab_host(): (1) fork failed - %s",
						 sys_errlist[errno]);
        uab_errmsg(buff);
        return (IAPFAIL);
    }

	if (pid == 0) {     	 /* child */


		setuid(getuid());    /* set effektiv UID til virkelig UID */			


		tputs(Uab_curses.clear_screen, 1, outc);
		tputs(Uab_curses.end_inverse, 1, outc);

		if (command == TRUE)
			if ((execlp(host_cmd, host_cmd, (char *) 0)) == -1)
				execlp("/bin/sh", "sh", "-c", host_cmd, (char *) 0);
		else
			execlp("/bin/sh", "sh", (char *) 0);

		uab_errmsg("uab_host(): execl failed !!!");
	}
	else { 					/* parent wait for child */
  
*********************

PROBLEM STARTS HERE !

*********************

This do-while loop worked just fine under ORACLE 5.1. But when i ported
this code to ORACLE 6.0 i get interupted by ORACLE, and the wait system
call return -1.

		do {		
			cpid = wait(&status);
		} while(pid != cpid);
	}		

If i trace the status of cpid after the first loop-through then cpid is
equal -1 and errno is equal 4 Interrupted system call !.

    
	term.c_cc[4] = 4;		/* ^d */
	resetterm(&term);

	return(IAPSUCC);
}
I would be very pleased if anybody could tell me the correct way to set
up signal-handling routines within Pro*c programs in ORACLE 6.0.
-- 
Jon Tr|stheim, Fellesdata a.s, P.O. Box 248, 0212 OSLO 2, NORWAY
Phone : +47 2 52 82 91                            Fax   : +47 2 52 85 10
E-mail : ...!mcsun!nuug!fdmetd!jon  or            jon@fdmetd.uucp
<The opinions expressed, if any, do not represent Fellesdata a.s>