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>