[daip] problems with AIPS installation
Eric Greisen
egreisen at aoc.nrao.edu
Mon Jun 23 19:17:15 EDT 2003
RedHat 9 involves several new things that make AIPS not compile
properly. I would recommend using the gnu 3.2+ or 3.3 compiler
provided with RedHat 9 rather than 2.95.3 which is responsible for
several of the error messages in the link edits. Unfortunately,
software "errors" (they were once legitimate...) are responsible for
the failures. I have fixed 31DEC03 which you could install instead of
the frozen version. Alternatively, you could fix the errors:
The changes are:
11284. April 13, 2003 errno.h Eric
The standard unix error code should be obtained by
#include <errno.h>
not with the obsolete
extern int errno
RedHat 9 can detect that the latter was used!
Changed numerous versions of ZPRMPT.C and a variety of other
routines.
Moved nowhere.
11285. April 14, 2003 ZERRO2, ZACTV9 Eric
Another change is to complain about direct references to
sys_errlist and sys_nerr. Changed ZERRO2 and ZACTV9 to call
strerror - the thread safe version strerror_r is not available
on Solaris.
Moved nowhere.
13-APR-2003 20:22:07 20030413 TST APLLINUX ZPRMPT.C direct access to errno
13-APR-2003 20:48:22 20030413 TST APLUNIX ZTPMI2.C errno
14-APR-2003 17:20:33 20030414 TST APLUNIX ZERRO2.C sys_errlist
14-APR-2003 17:20:34 20030414 TST APLUNIX ZACTV9.C sys_errlist
These routines follow:
#define Z_prmpt__
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <NOTST/GNU/history.h>
#define HAVE_STRING_H /* Needed inside readline.h */
#include <NOTST/GNU/readline.h>
#include <AIPSPROTO.H>
/* Local signal-handler. */
#if __STDC__
static void zprmpt_sigs(int sig)
#else
static void zprmpt_sigs(sig)
int sig;
#endif
{
extern int _rl_meta_flag;
extern int kill (); /* Arg...some OS's...really! */
extern void rl_prep_terminal ();
kill (getpid (), SIGTSTP);
rl_prep_terminal (_rl_meta_flag);
}
#if __STDC__
void zprmpt_(char ipc[1], char buff[80], int *ierr)
#else
void zprmpt_(ipc, buff, ierr)
char ipc[1], buff[80];
int *ierr;
#endif
/*--------------------------------------------------------------------*/
/*! prompt user and read 80 characters from CRT screen */
/*# Terminal */
/*--------------------------------------------------------------------*/
/*; Copyright (C) 1995-1997, 2003 */
/*; Associated Universities, Inc. Washington DC, USA. */
/*; */
/*; This program is free software; you can redistribute it and/or */
/*; modify it under the terms of the GNU General Public License as */
/*; published by the Free Software Foundation; either version 2 of */
/*; the License, or (at your option) any later version. */
/*; */
/*; This program is distributed in the hope that it will be useful, */
/*; but WITHOUT ANY WARRANTY; without even the implied warranty of */
/*; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/*; GNU General Public License for more details. */
/*; */
/*; You should have received a copy of the GNU General Public */
/*; License along with this program; if not, write to the Free */
/*; Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, */
/*; MA 02139, USA. */
/*; */
/*; Correspondence concerning AIPS should be addressed as follows: */
/*; Internet email: aipsmail at nrao.edu. */
/*; Postal address: AIPS Project Office */
/*; National Radio Astronomy Observatory */
/*; 520 Edgemont Road */
/*; Charlottesville, VA 22903-2475 USA */
/*--------------------------------------------------------------------*/
/* ZPRMPT prompts user on CRT screen and reads a line of user input */
/* via the GNU readline (+history) library. The input line is placed */
/* in a buffer and either truncated to 80 characters or space-padded */
/* to 80 characters prior to return. Non-empty lines are added to a */
/* history list for possible later access/reuse via the */
/* history-manipulation key-bindings (a la Bash/Ksh/Emacs--or even */
/* vi). If the user is not on an interactive tty, say by giving AIPS */
/* input via a shell-script "here document," then the old */
/* (non-readline) behavior is used and the input line is not added to */
/* the history. Use of the readline library can be disabled by */
/* starting AIPS with the "norl" option. */
/* */
/* Input: */
/* IPC C*1 prompt character */
/* Output: */
/* BUFF C*80 line of user input. */
/* IERR I Error return code: 0 => ok */
/* 1 => read/write error (not implemented/set) */
/* */
/* UNIX GNU-readline version (with terminal-reset signal-handler). */
/* */
/* JAU 26 Jul 95: Jeff Uphoff, NRAO. Added GNU readline support. */
/* JAU 29 Aug 95: Jeff Uphoff, NRAO. Overhaul of several portions. */
/* JAU 22 Sep 95: Jeff Uphoff, NRAO. Added check for userno prompt. */
/* JAU 25 Jun 97: Jeff Uphoff, NRAO. Fix prompt bug. */
/*--------------------------------------------------------------------*/
{
char *rlenv = NULL;
char *temp = NULL;
register int i, ttyp;
/*--------------------------------------------------------------------*/
*ierr = 0;
buff[0] = '\0'; /* Initialize buffer. */
/* Check if readline disabled */
if (!(ttyp = isatty (0)) || /* or if not interactive tty. */
(((rlenv = getenv ("READLINE")) != NULL) &&
!strcmp (rlenv, "NO"))) {
char pc = ipc[0]; /* OK, fall back to old */
/* prompting and input- */
/* handling behavior. */
if(!(temp = (char *)malloc (81))) {
perror ("ZPRMPT: malloc failed");
exit (errno); /* This is *very* bad! */
}
putchar (pc); /* Display prompt. */
/* Use old input method. */
if (fgets (temp, 81, stdin) == NULL) {
free (temp);
temp = NULL;
}
ttyp = 0; /* We'll fake this for later. */
} else { /* Use GNU readline for input */
char prompt[2];
if (ipc[0] == '?') /* Check if userno. prompt. */
rl_bind_key ('\t', NULL); /* If so, disable TAB's. */
zignal_ (SIGTTIN, zprmpt_sigs); /* All of these signal- */
zignal_ (SIGTTOU, zprmpt_sigs); /* handling shenanigans are */
/* due to general insanity. */
prompt[0] = ipc[0]; /* Ensure prompt sanity. */
prompt[1] = '\0';
temp = readline (prompt); /* Use readline to prompt */
/* user and return pointer */
/* to line of user input. */
/* readline() does the */
/* malloc() for us, but we */
/* must free() the pointer. */
zignal_ (SIGTTIN, SIG_DFL); /* More fun with signals. */
zignal_ (SIGTTOU, SIG_DFL);
}
if (temp == NULL) /* NULL pointer means EOF at */
sprintf (buff, "EXIT"); /* *beginning* of user input. */
else { /* Non-NULL means good input. */
if (*temp && ttyp) /* If not blank (and */
add_history (temp); /* interactive), put in hist. */
/* unless readline disabled */
/* (the reason for "faking" */
/* ttyp = 0 earlier). */
/* readline() strips the new- */
/* line for us. We need to */
/* find the first null and */
/* then pad the output buffer */
/* with trailing spaces. */
/* The 80-column limit is */
/* historical... */
for (i = 0; i < 80 && temp[i] != '\0'; i++)
buff[i] = temp[i]; /* Copy up to first null. */
for (i = i; i < 80; i++)
buff[i] = ' '; /* Pad remainder with spaces. */
if (temp)
free (temp); /* Free the readline pointer. */
}
return;
}
/*
* Local Variables:
* c-basic-offset: 3
* comment-column: 40
* indent-tabs-mode: nil
* End:
*/
#define Z_tpmi2__
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <AIPSPROTO.H>
#if __STDC__
void ztpmi2_(char *oper, int *fcb, char *buff, int *nbytes, int *ierr)
#else
void ztpmi2_(oper, fcb, buff, nbytes, ierr)
char oper[], buff[];
int *fcb, *nbytes, *ierr;
#endif
/*--------------------------------------------------------------------*/
/*! read/write from/to a tape device */
/*# IO-basic Tape */
/*--------------------------------------------------------------------*/
/*; Copyright (C) 1995, 1997, 2003 */
/*; Associated Universities, Inc. Washington DC, USA. */
/*; */
/*; This program is free software; you can redistribute it and/or */
/*; modify it under the terms of the GNU General Public License as */
/*; published by the Free Software Foundation; either version 2 of */
/*; the License, or (at your option) any later version. */
/*; */
/*; This program is distributed in the hope that it will be useful, */
/*; but WITHOUT ANY WARRANTY; without even the implied warranty of */
/*; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/*; GNU General Public License for more details. */
/*; */
/*; You should have received a copy of the GNU General Public */
/*; License along with this program; if not, write to the Free */
/*; Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, */
/*; MA 02139, USA. */
/*; */
/*; Correspondence concerning AIPS should be addressed as follows: */
/*; Internet email: aipsmail at nrao.edu. */
/*; Postal address: AIPS Project Office */
/*; National Radio Astronomy Observatory */
/*; 520 Edgemont Road */
/*; Charlottesville, VA 22903-2475 USA */
/*--------------------------------------------------------------------*/
/* Read/write "nbytes" 8-bit bytes of data from/to a tape device */
/* using "map" I/O (i.e., double buffered, asynchronous I/O). */
/* Inputs: */
/* oper C*4 Operation code "READ" or "WRIT" */
/* fcb I(*) File control block for opened tape drive */
/* buff I(*) I/O buffer */
/* nbytes I Number of 8-bit bytes to be transferred */
/* Output: */
/* ierr I Error return code: 0 => no error */
/* 2 => bad opcode */
/* 3 => I/O error (left for ZTPWA2 now) */
/* Generic UNIX version - sysnchronous I/O actually, reports IO error*/
/* but not End Of File */
/* Modified for real-time VLA calling olread when fd < 0 */
/*--------------------------------------------------------------------*/
{
/* Offsets to entries in the */
/* file control blocks */
extern int Z_fcbfd, Z_fcbreq, Z_fcberr, Z_fcbxfr, Z_fcbsiz,
Z_fcbsp1, Z_fcbsp2, Z_fcbsp3, Z_fcbsp4;
int fd, n8 = 8, ifd, ntry, otry, jerr;
register int i;
float secs = 100.0;
char op[5], msgbuf[80], pathname[MAXAPATH] = "ON-LINE";
/*--------------------------------------------------------------------*/
*ierr = 0;
pathname[7] = '\0';
/* Form null terminated */
/* opcode. */
for (i = 0; i < 4; i++)
op[i] = oper[i];
op[4] = '\0';
/* Get file descriptor from */
/* the file control block as */
/* stored there by ZTPOP2. */
fd = *(fcb + Z_fcbfd);
/* Record byte request in the */
/* file control block. */
*(fcb + Z_fcbreq) = *nbytes;
/* Also, zero error status & */
/* transfer count entries. */
*(fcb + Z_fcberr) = 0;
*(fcb + Z_fcbxfr) = 0;
/* Zero byte request just */
/* initiates double buffered */
/* I/O. */
if (*(fcb + Z_fcbreq) != 0) {
/* Perform the I/O and record */
/* the # of bytes transferred */
/* in *(fcb + Z_fcbxfr). */
/* Record the system error */
/* code (if any) in */
/* *(fcb + Z_fcberr). */
if (strcmp (op, "READ") == 0) {
/* fake fd<0 ==> use Wes' */
/* on-line device. */
if (fd < 0) {
for (ntry=0; ntry<100; ntry++) {
*(fcb + Z_fcbxfr) = olread_(&fd, buff, *(fcb + Z_fcbreq));
/* error - close and re-open */
if (*(fcb + Z_fcbxfr) == 0) {
sprintf (msgbuf, "ZTPMI2: End-of-data: try to reopen");
zmsgwr_ (msgbuf, &n8);
olclose_(&fd);
for (otry=0; otry<100; otry++) {
ifd = -99;
zdela2_ (&secs, &jerr) ;
fd = olopen_(&ifd, pathname, strlen(pathname));
sprintf (msgbuf, "ZTPMI2: olopen %d", fd);
zmsgwr_ (msgbuf, &n8);
/* open fails */
if (fd == -99 || fd >= 0) {
sprintf (msgbuf,
"ZTPOP2: FAILS TO OPEN ON-LINE - RETRY");
if (otry == 99) {
sprintf (msgbuf,
"ZTPOP2: FAILS TO OPEN ON-LINE - QUIT");
ntry = 101;
}
zmsgwr_ (msgbuf, &n8);
}
else {
*(fcb + Z_fcbfd) = fd;
otry = 1000;
}
}
}
else {
ntry=1000;
}
}
}
else {
*(fcb + Z_fcbxfr) = read(fd, buff, *(fcb + Z_fcbreq));
}
if (*(fcb + Z_fcbxfr) == -1) {
*(fcb + Z_fcberr) = errno;
}
}
else if (strcmp (op, "WRIT") == 0) {
if ((*(fcb + Z_fcbxfr) =
write (fd, buff, *(fcb + Z_fcbreq))) == -1) {
*(fcb + Z_fcberr) = errno;
}
}
/* Bad opcode. */
else {
*ierr = 2;
}
}
/* Exit. */
return;
}
#define Z_erro2__
#include <stdio.h>
#include <string.h>
#if __STDC__
void zerro2_(int *syserr, int *elen, char *errmsg)
#else
void zerro2_(syserr, elen, errmsg)
int *syserr, *elen;
char errmsg[];
#endif
/*--------------------------------------------------------------------*/
/*! return system error message for given system error code */
/*# Service */
/*--------------------------------------------------------------------*/
/*; Copyright (C) 1995, 1997-1998, 2003 */
/*; Associated Universities, Inc. Washington DC, USA. */
/*; */
/*; This program is free software; you can redistribute it and/or */
/*; modify it under the terms of the GNU General Public License as */
/*; published by the Free Software Foundation; either version 2 of */
/*; the License, or (at your option) any later version. */
/*; */
/*; This program is distributed in the hope that it will be useful, */
/*; but WITHOUT ANY WARRANTY; without even the implied warranty of */
/*; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/*; GNU General Public License for more details. */
/*; */
/*; You should have received a copy of the GNU General Public */
/*; License along with this program; if not, write to the Free */
/*; Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, */
/*; MA 02139, USA. */
/*; */
/*; Correspondence concerning AIPS should be addressed as follows: */
/*; Internet email: aipsmail at nrao.edu. */
/*; Postal address: AIPS Project Office */
/*; National Radio Astronomy Observatory */
/*; 520 Edgemont Road */
/*; Charlottesville, VA 22903-2475 USA */
/*--------------------------------------------------------------------*/
/* This routine gets the text of the system error message */
/* corresponding to a system error code. Called by ZERROR. */
/* Inputs: */
/* syserr I System error code */
/* In/Out: */
/* elen I In: length of errmsg variable in bytes */
/* Out: 1-relative position of last non-blank */
/* character in error message text */
/* corresponding to syserr (if any, */
/* otherwise, zero) */
/* errmsg C*(elen) Text of system error message */
/* Generic UNIX version. */
/*--------------------------------------------------------------------*/
{
register int i;
int elnb;
/*--------------------------------------------------------------------*/
/* Get system error message */
if (*syserr >= 0) {
sprintf (errmsg, "ERRNO = %d (%s)", *syserr, strerror(*syserr));
for (i = 0; i < *elen && errmsg[i] != '\0'; i++);
/* Blank fill remainder */
elnb = i;
for (i = elnb; i < *elen; i++)
errmsg[i] = ' ';
*elen = elnb;
}
/* no message in list */
else
*elen = 0;
return;
}
#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE
#endif
#include <unistd.h>
/* If <unistd.h> can not be */
/* found you do not have a */
/* POSIX.1 compliant system */
/* and ZACTV9 requires local */
/* development. */
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <signal.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
/* We use our own prototypes */
/* for string functions if we */
/* are not using an ANSI C */
/* compiler so that we don't */
/* have to worry about the use */
/* of <strings.h> on older BSD */
/* systems. */
#ifdef __STDC__
#include <string.h>
#else
extern int strcmp();
extern char *strcpy();
extern int strlen();
#endif
/* The malloc prototype may */
/* also be stored in */
/* unpredictable headers if */
/* not using ANSI C. */
#ifdef __STDC__
#include <stdlib.h>
#else
extern char *malloc();
#endif
#include <AIPSPROTO.H>
#define PMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
#define CMODE (O_WRONLY | O_CREAT | O_TRUNC | O_EXCL)
extern int msg_fd; /* Message terminal file */
/* descriptor (shared by all */
/* AIPS processes in this */
/* session) if messages are not */
/* directed to the controlling */
/* terminal (-1 if they are) */
#if __STDC__
void zactv9_(int *flen, char fulnam[], int *plen, char cpname[],
int *idbg, pid_t *pid, int *syserr, int *ierr)
#else
void zactv9_(flen, fulnam, plen, cpname, idbg, pid, syserr, ierr)
int *flen, *plen, *idbg, *pid, *syserr, *ierr;
char fulnam[], cpname[];
#endif
/*--------------------------------------------------------------------*/
/*! starts requested load module under requested process name */
/*# Z2 System */
/*--------------------------------------------------------------------*/
/*; Copyright (C) 1995, 1997, 2003 */
/*; Associated Universities, Inc. Washington DC, USA. */
/*; */
/*; This program is free software; you can redistribute it and/or */
/*; modify it under the terms of the GNU General Public License as */
/*; published by the Free Software Foundation; either version 2 of */
/*; the License, or (at your option) any later version. */
/*; */
/*; This program is distributed in the hope that it will be useful, */
/*; but WITHOUT ANY WARRANTY; without even the implied warranty of */
/*; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/*; GNU General Public License for more details. */
/*; */
/*; You should have received a copy of the GNU General Public */
/*; License along with this program; if not, write to the Free */
/*; Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, */
/*; MA 02139, USA. */
/*; */
/*; Correspondence concerning AIPS should be addressed as follows: */
/*; Internet email: aipsmail at nrao.edu. */
/*; Postal address: AIPS Project Office */
/*; National Radio Astronomy Observatory */
/*; 520 Edgemont Road */
/*; Charlottesville, VA 22903-2475 USA */
/*--------------------------------------------------------------------*/
/* ZACTV9 will execute the load module "fulnam" as a process/sub- */
/* process called "cpname" which consists of the program name with a */
/* POPS number suffix x (e.g., AIPSx, BATERx, AIPSCx, AIPSBx, QMNGRx */
/* or <taskname>x). AIPSx an BATERx are initiated as processes that */
/* replace the process that invokes ZACTV9 (i.e., without first */
/* forking a subprocess). This means that in the case of AIPSx and */
/* BATERx, there is no return from ZACTV9. The startup programs */
/* ZSTRTA and ZSTRTB invoke ZACTV9 (via ZACTV8) as part of the */
/* process of initiating an interative AIPS or BATER session. */
/* ZACTV9 is only called by ZACTV8. Note that the AIPS daemon */
/* DAIPx is treated exactly as AIPSx. */
/* */
/* Inputs: */
/* FLEN I Length in characters of "fulnam" */
/* FULNAM C*(flen) Full path name of the required executable */
/* module */
/* PLEN I Length in characters of "cpname" */
/* CPNAME C*(plen) Desired process name (6 characters or */
/* less = program name + POPS number) */
/* IDBG I 1 => start in DEBUGger if possible */
/* 0 => use no DEBUGger if possible */
/* Ignore on CPNAME='AIPSn','BATERn' */
/* In/Out: */
/* PID I(4) Process identification information: */
/* In: *(pid + 0) user number for systems */
/* use it (= 0 otherwise and */
/* on all AIPSB invocations) */
/* Out: *(pid + 1) process ID number from */
/* "fork" or "vfork" */
/* *(pid + 2) not used */
/* *(pid + 3) not used */
/* Output: */
/* SYSERR I System error code (i.e., errno) if error */
/* IERR I Error return code: 0 => no error */
/* 1 => error */
/* Generic UNIX version. */
/* If the OS is does not comply with POSIX.1 then ZACTV9 will issue */
/* a message and return an error code. */
/*--------------------------------------------------------------------*/
/* If _POSIX_VERSION is not */
/* defined then we do not have */
/* a POSIX.1 system. */
#ifndef _POSIX_VERSION
{
printf("ZACTV9 REQUIRES LOCAL DEVELOPMENT\n");
*ierr = 1;
return;
}
/*--------------------------------------------------------------------*/
#else
{
char *pathname; /* pathname of executable. */
char *dirname; /* directory name of */
char procname[7]; /* desired process name. */
char rootname[6]; /* root name of desired */
/* process (ie. process name */
/* without the POPS number. */
char *debugger; /* pathname of debugger. */
struct sigaction newaction; /* Signal action for INT */
struct sigaction saved; /* Previous signal action for */
/* INT */
char lockname[_POSIX_PATH_MAX]; /* Name of lock file */
int lockfile; /* lock file file descriptor */
pid_t child; /* PID of child process */
pid_t grandchild; /* PID of grandchild process */
int p[2]; /* File descriptors for pipe */
int i, j, n8 = 8;
char msg[80];
/*--------------------------------------------------------------------*/
*syserr = 0;
if (*plen > 6) {
*ierr = 2;
return;
}
/* Convert pathname of */
/* executable to null- */
/* terminated form: */
pathname = malloc (*flen+1);
dirname = malloc (*flen+1);
for (i = 0; i != *flen && fulnam[i] != ' '; i++) {
/* Invariant: for all k, */
/* 0 <= k < i, */
/* pathname[k] = fulnam[k] and */
/* dirname[k] = fulnam[k] */
pathname[i] = fulnam[i];
dirname[i] = fulnam[i];
if (fulnam[i] == '/') j = i;
}
pathname[i] = '\0';
dirname[j] = '\0';
/* Convert desired process */
/* name to null-terminated */
/* form and save rootname: */
for (i = 0; i != *plen && cpname[i] != ' '; i++) {
/* Invariant: for all j, */
/* 0 <= j < i, */
/* procname[j] = cpname[j] and */
/* rootname[j] = cpname[j]. */
procname[i] = cpname[i];
rootname[i] = cpname[i];
}
procname[i] = '\0';
rootname[i-1] = '\0';
/* Extract the pathname of the */
/* debugger: */
debugger = NULL;
if (strcmp (rootname, "AIPS") == 0 ||
strcmp (rootname, "DAIP") == 0) {
if (getenv ("AIPSDBUGR") != NULL) {
debugger = malloc (strlen (getenv ("AIPSDBUGR")) + 1);
strcpy (debugger, getenv ("AIPSDBUGR"));
}
}
else if (strcmp (rootname, "BATER") == 0) {
if (getenv ("BATERDBUGR") != NULL) {
debugger = malloc (strlen (getenv ("BATERDBUGR")) + 1);
strcpy (debugger, getenv ("BATERDBUGR"));
}
}
else if (*idbg == 1) {
if (getenv ("DBUGR") != NULL) {
debugger = malloc (strlen (getenv ("DBUGR")) + 1);
strcpy (debugger, getenv ("DBUGR"));
}
}
/* Check that the executable */
/* exists and that this */
/* process can execute it. */
if (access (pathname, F_OK) != 0) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: CANNOT FIND %s", pathname);
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno, strerror(errno));
zmsgwr_ (msg, &n8);
}
return;
}
if (access (pathname, X_OK) != 0) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: NO EXECUTE PERMISSION FOR %s", pathname);
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno, strerror(errno));
zmsgwr_ (msg, &n8);
}
return;
}
if (debugger != NULL) {
/* Debug mode startup. */
/* Ignore interrupt signals */
newaction.sa_handler = SIG_IGN;
sigemptyset(&newaction.sa_mask);
newaction.sa_flags =0;
if (sigaction (SIGINT, &newaction, &saved) == -1) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: CANNOT INSTALL SIGINT HANDLER");
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno, strerror(errno));
zmsgwr_ (msg, &n8);
}
return;
}
/* Check that debugger exists */
/* and is executable: */
if (access (debugger, F_OK) == -1) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: CANNOT FIND %s", debugger);
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno, strerror(errno));
zmsgwr_ (msg, &n8);
}
goto restore;
}
if (access (debugger, X_OK) == -1) {
*syserr = errno;
*ierr = 1;
sprintf("ZACTV9: NO EXECUTE PERMISSION FOR %s", debugger);
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno, strerror(errno));
zmsgwr_ (msg, &n8);
}
goto restore;
}
/* We need to start the */
/* program through a link */
/* otherwise the POPS number */
/* doesn't propagate through */
/* the debugger and ZWHOMI */
/* will fail */
if (chdir (dirname) == -1) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: CAN NOT CHANGE DIRECTORY TO %s",
dirname);
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno, strerror(errno));
zmsgwr_ (msg, &n8);
}
goto restore;
}
unlink(procname);
if (link (pathname, procname) == -1) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: CAN NOT CREATE LINK TO %s", procname);
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno, strerror(errno));
zmsgwr_ (msg, &n8);
}
goto restore;
}
if (strcmp (rootname, "AIPS") == 0 ||
strcmp (rootname, "BATER") == 0 ||
strcmp (rootname, "DAIP") == 0) {
/* Execute new program in this */
/* process: */
pid[1] = (int)getpid ();
sprintf (lockname, "/tmp/%s.%d", procname, pid[1]);
/* Create lock file: */
if ((lockfile = open (lockname, CMODE, PMODE)) == -1) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: CANNOT CREATE LOCK FILE %s",
lockname);
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
goto restore;
}
close (lockfile);
if (execl (debugger, debugger, procname, NULL) == -1) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: CANNOT START DEBUGGER");
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
goto restore;
}
}
else { /* Not AIPS or BATER */
if ((pid[1] = fork()) == 0) { /* Child process */
/* Close all open file */
/* descriptors except for */
/* anything that might be the */
/* message terminal: */
for (i = 0; i != sysconf(_SC_OPEN_MAX); i++) {
if ((i != msg_fd) && (i > 2)) {
close (i);
}
}
if (execl (debugger, debugger, procname, NULL) == -1) {
sprintf(msg, "ZACTV9: CANNOT START %s", procname);
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
exit (1);
}
exit (0);
}
else if (pid[1] == -1) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: CANNOT SPAWN CHILD PROCESS");
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
goto restore;
}
else { /* Still parent */
/* Create lock file: */
sprintf(lockname, "/tmp/%s.%d", procname, pid[1]);
zmsgwr_ (msg, &n8);
if ((lockfile = open (lockname, CMODE, PMODE)) == -1) {
sprintf(msg, "ZACTV9: CANNOT CREATE LOCK FILE");
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
exit (1);
}
close (lockfile);
/* Wait for child: */
waitpid (pid[1], &i, 0);
}
restore:
free (debugger);
unlink (procname);
/* Restore signal handling: */
if (sigaction (SIGINT, &saved, &newaction) == -1) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: CANNOT RESTORE SIGNAL HANDLERS");
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
return;
}
}
}
else { /* Non-debug mode */
if (strcmp (rootname, "AIPS") == 0 ||
strcmp (rootname, "BATER") == 0 ||
strcmp (rootname, "DAIP") == 0) {
/* Execute new program in this */
/* process: */
pid[1] = (int)getpid ();
sprintf(lockname, "/tmp/%s.%d", procname, pid[1]);
/* Create lock file: */
if ((lockfile = open (lockname, CMODE, PMODE)) == -1) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: CANNOT CREATE LOCK FILE %s",
lockname);
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
return;
}
close (lockfile);
if (execl (pathname, procname, NULL) == -1) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: CANNOT START %s", procname);
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
return;
}
}
else { /* Not AIPS or BATER */
/* Spawn new process as a */
/* grandchild to prevent an */
/* accumulation of zombies; */
/* the pid of the grandchild */
/* will be returned through a */
/* pipe: */
if (pipe(p) == -1) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: CANNOT CREATE PIPE TO CHILD");
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
return;
}
if ((child = fork()) == 0) { /* Child process */
close(p[0]);
/* Close all open file */
/* descriptors (apart from the */
/* pipe and anything that */
/* might be the message */
/* terminal): */
for (i = 0; i != sysconf(_SC_OPEN_MAX); i++) {
if ((i != p[1]) && (i != msg_fd) && (i > 2)) {
close (i);
}
}
if ((grandchild = fork()) == 0) {
/* Grandchild process */
/* No need to close file */
/* descriptors since they were */
/* already closed in the */
/* immediate parent. */
if (execl (pathname, procname, NULL) == -1) {
sprintf(msg, "ZACTV9: CANNOT START %s", procname);
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
exit (1);
}
}
else if (grandchild == -1) {
sprintf(msg, "ZACTV9: CANNOT SPAWN GRANDCHILD");
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
exit (1);
}
else { /* Still child */
/* Create lock file: */
sprintf(lockname, "/tmp/%s.%d", procname, grandchild);
if ((lockfile = open (lockname, CMODE, PMODE)) == -1) {
sprintf(msg, "ZACTV9: CANNOT CREATE LOCK FILE");
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
exit (1);
}
close (lockfile);
/* Return grandchild pid to */
/* parent process: */
if (write (p[1], &grandchild, sizeof(pid_t)) == -1) {
sprintf(msg, "ZACTV9: CANNOT SEND PID TO PARENT");
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
exit (1);
}
close (p[1]);
exit (0);
}
}
else if (child == -1) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: CANNOT SPAWN CHILD PROCESS");
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
return;
}
else { /* Still parent */
close(p[1]);
/* Read grandchild pid */
if (read (p[0], &grandchild, sizeof(pid_t)) == -1) {
*syserr = errno;
*ierr = 1;
sprintf(msg, "ZACTV9: CANNOT READ PID");
zmsgwr_ (msg, &n8);
if (errno >= 0) {
sprintf (msg, "ERRNO = %d (%s)", errno,
strerror(errno));
zmsgwr_ (msg, &n8);
}
return;
}
close(p[0]);
pid[1] = (int)grandchild;
/* Wait for child: */
waitpid (child, &i, 0);
}
}
}
free (pathname);
free (dirname);
}
#endif
More information about the Daip
mailing list