Example #1
0
static pid_t
FakeFork (void)
{
    static Boolean debugInit = True;
    static int debugForkFailures = 0;
    char *c;

    if (isDebugFSet('f', 10)) {
#ifdef	BBA
#pragma BBA_IGNORE
#endif	/*BBA*/
        _DtTermProcessLock();
	if (debugInit) {
	    if (c = getenv("dttermDebugForkFailures")) {
		debugForkFailures = strtol(c, (char **) 0, 0);
		debugInit = 0;
	    }
	}
	if (debugForkFailures > 0) {
	    /* decrement the number of failures... */
	    (void) debugForkFailures--;

	    /* set our error return... */
	    errno = EAGAIN;

	    /* and error out... */
	    _DtTermProcessUnlock();
	    return(-1);
	}
        _DtTermProcessUnlock();
    }

    /* just do a fork()... */
    return(fork());
}
Example #2
0
void _DtTermPrimInitRepTypes(void)
{
    static Boolean first = True;

    _DtTermProcessLock();
    if (first) {
	/* register our resource converters... */
#ifdef NotDefined
	(void) XtSetTypeConverter(XmRString, DtRDtTermTerminalSize,
		CvtStringToTerminalSize, NULL, 0, XtCacheNone,
		CvtStringToTerminalSizeDestroy);
#endif /* NotDefined */
	(void) XtSetTypeConverter(XmRString, DtRDtTermTerminalSizeList,
		CvtStringToTerminalSizeList, NULL, 0, XtCacheNone,
		CvtStringToTerminalSizeListDestroy);
	(void) XmRepTypeRegister(DtRDtTermEmulationMode,
		TermEmulationModeStrings,
		NULL, (unsigned char ) XtNumber(TermEmulationModeStrings));
	(void) XmRepTypeRegister(DtRDtTermCharCursorStyle,
		CharCursorStyleStrings,
		NULL, (unsigned char ) XtNumber(CharCursorStyleStrings));

	_DtTermPrimEmulationMode = XmRepTypeGetId(DtRDtTermEmulationMode);
	_DtTermPrimCharCursorStyle = XmRepTypeGetId(DtRDtTermCharCursorStyle);

	first = False;
    }
    _DtTermProcessUnlock();

    return;
}
Example #3
0
_termSubprocId
_DtTermPrimAddSubproc(Widget		w, 
		      pid_t		pid, 
		      _termSubprocProc	proc,
		      XtPointer		client_data)
{
    subprocInfo *subprocTmp;

    /* malloc a new entry... */
    subprocTmp = (subprocInfo *) XtCalloc(1, sizeof(subprocInfo));

    /* fill in the structures... */
    subprocTmp->pid = pid;
    subprocTmp->w = w;
    subprocTmp->proc = proc;
    subprocTmp->client_data = client_data;
    subprocTmp->signal_id = XtAppAddSignal(XtWidgetToApplicationContext(w), 
					   InvokeCallbacks, subprocTmp);

    /* insert it after the head of the list... */
    _DtTermProcessLock();
    subprocTmp->prev = subprocHead;
    subprocTmp->next = subprocHead->next;
    subprocHead->next = subprocTmp;
    if (subprocTmp->next) {
	subprocTmp->next->prev = subprocTmp;
    }
    _DtTermProcessUnlock();

    /* return the pointer... */
    return((_termSubprocId) subprocTmp);
}
Example #4
0
void
_DtTermPrimPtyGetDefaultModes()
{
    int tty = -1;
    int refTty = -1;

#if defined (USE_CSWIDTH)
    struct strioctl i_str;
#endif   /* (USE_CSWIDTH) */

    _DtTermProcessLock();
    if (!refValid) {
	/* see if we can get a reference tty to get our base reference from...
	 */
	if ((tty = open("/dev/tty", O_RDONLY, 0)) >= 0) {
	    if (!tcgetattr(tty, &refTio)) {
		/* we got a valid reference tty... */
		DebugF('p', 3, fprintf(stderr,
			">>_DtTermPrimPtyGetDefaultModes() valid reference \"/dev/tty\"\n"));
		refTty = tty;
		refValid = 1;
	    }
	}

	if (!refValid) {
	    for (refTty = 0; refTty < 3; refTty++) {
		if (!tcgetattr(refTty, &refTio)) {
		    DebugF('p', 3, fprintf(stderr,
			    ">>_DtTermPrimPtyGetDefaultModes() valid reference \fd %d\n", refTty));
		    refValid = 1;
		    break;
		}
	    }
	}

#if defined (USE_CSWIDTH)
	if (refValid && (MB_CUR_MAX > 1))
	{
	    /*
	    ** we are in a wide character locale, get the current
	    ** width settings...
	    */
	    i_str.ic_cmd    = EUC_WGET;
	    i_str.ic_timout = 0;
	    i_str.ic_len    = sizeof(struct eucioc);
	    i_str.ic_dp     = (char *)&refWp;
	    (void)ioctl(refTty, I_STR, &i_str);
	}
#endif   /* (USE_CSWIDTH) */

	/* all done...
	 */
	/* close off the "/dev/tty" fd... */
	if (tty >= 0) {
	    (void) close(tty);
	}
    }
    _DtTermProcessUnlock();
}
Example #5
0
static void
DeleteLogFileEntry
(
    FILE		 *logFile
)
{
    logInfo		 *logInfoTmp;
    sigset_t		  newSigs;
    sigset_t		  oldSigs;

    /* find the entry... */
    _DtTermProcessLock();
    for (logInfoTmp = logInfoHead->next; logInfoTmp;
	    logInfoTmp = logInfoTmp->next) {
	if (logInfoTmp->logFile == logFile) {
	    break;
	}
    }

    /* did we find anything... */
    if (!logInfoTmp) {
	/* not found... */
        _DtTermProcessUnlock();
	return;
    }

    /* delete entry from the list...
     */
    /* block all signals... */
    (void) sigfillset(&newSigs);
    (void) sigemptyset(&oldSigs);
    (void) sigprocmask(SIG_BLOCK, &newSigs, &oldSigs);

    /* remove it... */
    logInfoTmp->prev->next = logInfoTmp->next;
    if (logInfoTmp->next) {
	logInfoTmp->next->prev = logInfoTmp->prev;
    }

    /* restore signals... */
    (void) sigprocmask(SIG_SETMASK, &oldSigs, (sigset_t *) 0);

    /* free up the data... */
    (void) XtFree((char *) logInfoTmp);
    _DtTermProcessUnlock();
}
Example #6
0
static void
suidInit()
{
    _DtTermProcessLock();
    if (first) {
	uid_user = getuid();
	uid_root = geteuid();

	gid_user = getgid();
	gid_root = getegid();

	first = False;
    }
    _DtTermProcessUnlock();
}
Example #7
0
void
_DtTermPrimWriteLog(DtTermPrimitiveWidget tw, char *buffer, int cnt)
{
    DtTermPrimData tpd = tw->term.tpd;

    if (cnt > 0)
    {
	_DtTermProcessLock();

	(void) fwrite(buffer, cnt, 1, tpd->logStream);

	if ((errno == EPIPE) && ferror(tpd->logStream))
	{
	    ForceCloseLog(tw);
	}

	_DtTermProcessUnlock();
    }
}
Example #8
0
void
_DtTermPrimSubprocRemoveSubproc(Widget w, _termSubprocId id)
{
    subprocInfo *subprocTmp = (subprocInfo *) id;

    /* remove the entry from the linked list...
     */
    /* there will always be a head, so we can always update it... */
    _DtTermProcessLock();
    subprocTmp->w = NULL;
    subprocTmp->prev->next = subprocTmp->next;
    if (subprocTmp->next) {
	subprocTmp->next->prev = subprocTmp->prev;
    }
    _DtTermProcessUnlock();

    XtRemoveSignal(subprocTmp->signal_id);

    /* free our storage... */
    (void) XtFree((char *) subprocTmp);
}
Example #9
0
void
_DtTermPrimLogFileCleanup
(
    void
)
{
    logInfo		 *logInfoTmp;

    DebugF('s', 10, fprintf(stderr,
	    ">>_DtTermPrimLogFileCleanup() starting\n"));

    /* flush all the log files... */
    _DtTermProcessLock();
    for (logInfoTmp = logInfoHead->next; logInfoTmp;
	    logInfoTmp = logInfoTmp->next) {
	DebugF('s', 10, fprintf(stderr,
		">>flushing logfile 0x%lx\n", logInfoTmp->logFile));
	(void) fflush(logInfoTmp->logFile);
    }
    _DtTermProcessUnlock();
    DebugF('s', 10, fprintf(stderr,
	    ">>_DtTermPrimLogFileCleanup() finished\n"));
}
Example #10
0
static void
AddLogFileEntry
(
    FILE		 *logFile
)
{
    logInfo		 *logInfoTmp;
    sigset_t		  newSigs;
    sigset_t		  oldSigs;

    /* malloc a new entry... */
    logInfoTmp = (logInfo *) XtMalloc(sizeof(logInfo));
    (void) memset(logInfoTmp, '\0', sizeof(logInfo));

    /* fill in the structure... */
    logInfoTmp->logFile = logFile;

    /* insert it after the head of the list...
     */
    /* block all signals... */
    (void) sigfillset(&newSigs);
    (void) sigemptyset(&oldSigs);
    (void) sigprocmask(SIG_BLOCK, &newSigs, &oldSigs);

    /* insert the entry into the list... */
    _DtTermProcessLock();
    logInfoTmp->prev = logInfoHead;
    logInfoTmp->next = logInfoHead->next;
    logInfoHead->next = logInfoTmp;
    if (logInfoTmp->next) {
	logInfoTmp->next->prev = logInfoTmp;
    }
    _DtTermProcessUnlock();

    /* restore signals... */
    (void) sigprocmask(SIG_SETMASK, &oldSigs, (sigset_t *) 0);
}
Example #11
0
/*
** Parse the character, tell the calling routine if we are not
** in the start state.
*/
Boolean
_DtTermPrimParse
(
    Widget          w,
    unsigned char  *parseChar,
    int		    parseCharLen
)
{
    ParserContext   context = GetParserContext(w);
    StateEntry      thisEntry;
    StateEntry      thisPreParseEntry;

#ifdef    NOCODE
    /*
    ** This decision should be made somewhere else.
    */
    if (tp->t_modes.disp_func == 1)
    {
        in_disp_func();
        return(False);
    }
#endif /* NOCODE */

    if (parseCharLen == 1) {
	*context->inputChar = *parseChar;
    } else {
	(void) memmove(context->inputChar, parseChar, parseCharLen);
    }
    context->inputCharLen = parseCharLen;

    if (isDebugFSet('p', 1)) {
#ifdef	BBA
#pragma	BBA_IGNORE
#endif	/*BBA*/
	static unsigned char debugChar;
	static Boolean first = True;
	char *c;

	if (parseCharLen == 1) {
	    _DtTermProcessLock();
	    if (first) {
		if (!(c = getenv("dttermDebugParseChar"))) {
		    c = "0x03";
		}
		debugChar = strtol(c, (char **) 0, 0);
		first = False;
	    }
	    _DtTermProcessUnlock();

	    if (*parseChar == debugChar) {
		ParseTrap();
		return 0;
	    }
	}
    }
	
    /*
    ** Determine which state entry to use.
    */
    thisPreParseEntry = context->stateTable->statePreParseEntry;
    thisEntry = context->stateTable->stateEntry;

    /* first run through the preParse entry... */
    if (thisPreParseEntry && (parseCharLen == 1)) {
	while ((*parseChar < thisPreParseEntry->lower) ||
		(*parseChar > thisPreParseEntry->upper)) {
	    thisPreParseEntry++;
	}
	/* if we hit the end, ignore it... */
	if ((0x00 == thisPreParseEntry->lower) &&
		(0xff == thisPreParseEntry->upper)) {
	    thisPreParseEntry = (StateEntry) 0;
	}
    }

    /* if we hit a valid preParseEntry, then let's execute it and
     * return...
     */
    if (thisPreParseEntry) {
	/*
	** Now change states.  If the next state is NULL, stay in the
	** current state.  This is for parse entries that do not break us
	** out of the current parse thread.  If we need to bail out of the
	** current parse thread, then we have a new state specified and
	** will switch to it.  We do this before we execute the function
	** incase the function needs to change the state as well...
	*/
	if (thisPreParseEntry->nextState) {
	    context->stateTable = thisPreParseEntry->nextState;
	}

	/*
	** Execute the action associated with the entry.
	*/
	if (thisPreParseEntry->action) {
	    (*thisPreParseEntry->action)(w);
	}

	return(!context->stateTable->startState);
    }

    /* HACK ALERT!!!!
     *
     * We need two different search algorithms - the first to deal
     * with single byte characters, the second to deal with multi-byte
     * characters.  For now, we will match multi-byte character with
     * the parse entry that covers 0..255.  If we find that this will
     * not work for everything, we may need to rethink this.
     */
    if (parseCharLen == 1) {
	while ((*parseChar < thisEntry->lower) ||
		(*parseChar > thisEntry->upper))
	{
	    thisEntry++;
	}
    } else {
	while ((0x00 != thisEntry->lower) ||
		(0xff != thisEntry->upper))
	{
	    thisEntry++;
	}
    }
	
    /*
    ** Now change states.  We do this before we execute the function incase
    ** the function needs to change the state as well...
    */
    context->stateTable = thisEntry->nextState;

    /*
    ** Execute the action associated with the entry.
    */
    if (thisEntry->action) {
	(*thisEntry->action)(w);
    }

    return(!context->stateTable->startState);
}
Example #12
0
void
_DtTermPrimPtyInit
(
    int   pty,
    char *modeString,
    char *csWidthString
)
{
    struct termios tio;

#if defined (USE_CSWIDTH)
    struct strioctl i_str;
    eucioc_t        wp;
#endif   /* (USE_CSWIDTH) */

#if defined (USE_SETCSMAP)
    /*
    ** set thing up so we can use setcsmap()
    ** for the time being, this is IBM specific
    */
    char path[MAXPATHLEN];
    int  oldStdin = -1;
#endif   /* (USE_SETCSMAP) */

#ifdef	NOTDEF
#ifdef	USE_STREAMS
    if (ioctl(pty, I_PUSH, "ptem") < 0) {
	(void) perror("I_PUSH ptem");
    }

    if (ioctl(pty, I_PUSH, "ldterm") < 0) {
	(void) perror("I_PUSH ldterm");
    }

    if (ioctl(pty, I_PUSH, "ttcompat") < 0) {
	(void) perror("I_PUSH ttcompat");
    }
#endif	/* USE_STREAMS */
#endif	/* NOTDEF */

    if (refValid) {
	/* we will start from the reference tty...
	 */
	/* we already got the termios structure.  No need to get again... */
	DebugF('p', 3, fprintf(stderr,
		">>_DtTermPrimPtyInit() using refTio\n"));
	tio = refTio;

#if defined (USE_CSWIDTH)
	/*
	** use the cs width information from the reference...
	*/
	wp  = refWp;
#endif   /* (USE_CSWIDTH) */
	
	/* DKS: are there any other terminal states we need to get?... */
    } else {
	/* let's set a reasonable default... */
	DebugF('p', 3, fprintf(stderr,
		">>_DtTermPrimPtyInit() generating default termio\n"));
	(void) memset(&tio, '\0', sizeof(tio));

	tio.c_iflag       = ICRNL | IXON   | IXOFF;
	tio.c_oflag       = OPOST | ONLCR  | TAB3;
	tio.c_cflag       = B9600 | CS8    | CREAD | PARENB | HUPCL;
	tio.c_lflag       = ISIG|ICANON|ECHO|ECHOE|ECHOK|IEXTEN|ECHOCTL|ECHOKE;
	/* DKS: this is termio specific.  Do we need it?...
	tio.c_line        = 0;
	*/
	tio.c_cc[VINTR]   = 0x7f;         /* DEL          */
	tio.c_cc[VQUIT]   = '\\' & 0x3f;  /* '^\'         */
	tio.c_cc[VERASE]  = '#';          /* '#'          */
	tio.c_cc[VKILL]   = '@';          /* '@'          */
	tio.c_cc[VEOF]    = 'D' & 0x3f;   /* '^D'         */
	tio.c_cc[VEOL]    = '@' & 0x3f;   /* '^@'         */
#ifdef VSWITCH
	tio.c_cc[VSWITCH] = '@' & 0x3f;   /* '^@'         */
#endif  /* VSWITCH */

#if defined (USE_CSWIDTH)
	/*
	** get the cs width information from the resource
	*/
	parseCSWidth(csWidthString, &wp);
#endif   /* (USE_CSWIDTH) */

    }

    /* now, let's clean up certain flags... */
    /* input: nl->nl, don't ignore cr, cr->nl
     *        turn on IXOFF pacing so that we can do paste without
     *        overflowing the buffer...
     */
    tio.c_iflag &= ~(INLCR | IGNCR);
    tio.c_iflag |=   ICRNL | IXOFF;

    /* output: cr->cr, nl is not return, no delays, nl->cr/nl
     */
    tio.c_oflag &= ~(OCRNL | ONLRET | NLDLY | CRDLY | TABDLY |
		     BSDLY | VTDLY  | FFDLY);
    tio.c_oflag |=   ONLCR;

    /* baud rate is 9600 (nice default), turn off clocal and turn on
     * hupcl so that the last close will SIGHUP processes running on
     * the tty...
     */
    tio.c_cflag &= ~(CBAUD | CLOCAL);
    tio.c_cflag |= B9600 | HUPCL;

    /* enable signals, canonical processing (erase, kill, etc), echo...
     */
    tio.c_lflag |= ISIG | ICANON | ECHO | IEXTEN | ECHOCTL | ECHOKE;

    /* reset EOL to the default value (ksh mucks this up sometimes)...
     */
    tio.c_cc[VEOL] = '@' & 0x3f;			/* '^@' */

    /* reset EOF to the default value (ksh and csh muck with this)... */
    tio.c_cc[VEOF] = 'D' & 0x3f;			/* '^D' */

    /* 
    ** Now its time to handle the ttyModes
    ** Decide if the user supplied a ttyModes resource, if so then
    ** parse it and if it was a legal mode string, pass the parse result
    */
#define TMODE(ind,var) if (_DtTermPrimTtyModeList[ind].set) var = _DtTermPrimTtyModeList[ind].value;

    _DtTermProcessLock();
    if (modeString)
    {
        if (parseTtyModes(modeString, _DtTermPrimTtyModeList) < 0)
        {
            /*
            ** NOTE: should we prepend the program name to this string?
            */
            fprintf(stderr, "Bad tty modes \"%s\"\n", modeString);
        }
        else
        {
            TMODE (XTTYMODE_intr,  tio.c_cc[VINTR]);
            TMODE (XTTYMODE_quit,  tio.c_cc[VQUIT]);
            TMODE (XTTYMODE_erase, tio.c_cc[VERASE]);
            TMODE (XTTYMODE_kill,  tio.c_cc[VKILL]);
            TMODE (XTTYMODE_eof,   tio.c_cc[VEOF]);
            TMODE (XTTYMODE_eol,   tio.c_cc[VEOL]);

#if	defined(HP_ARCHITECTURE)
            TMODE (XTTYMODE_swtch, tio.c_cc[VSWTCH]);
            TMODE (XTTYMODE_susp,  tio.c_cc[VSUSP]);
#if	OSMAJORVERSION > 9
	    /* HP-UX 10.0 supports the new, extended c_cc[] array...
	     */
            TMODE (XTTYMODE_start, tio.c_cc[VSTART]);
            TMODE (XTTYMODE_stop,  tio.c_cc[VSTOP]);
            TMODE (XTTYMODE_dsusp, tio.c_cc[VDSUSP]);
#ifdef	NOTDEF
	    /* the following two parameters are not supported by
	     * HP-UX 10.0.
	     */
            TMODE (XTTYMODE_rprnt, tio.c_cc[VREPRINT]);
            TMODE (XTTYMODE_flush, tio.c_cc[VDISCARD]);
#endif	/* NOTDEF */
            TMODE (XTTYMODE_weras, tio.c_cc[VWERASE]);
            TMODE (XTTYMODE_lnext, tio.c_cc[VLNEXT]);
#else	/* OSMAJORVERSION > 9 */
	    {
		/* With HP-UX 9.0 (and earlier) we need to set dsuspc
		 * via the ltchars array.  In addition, we have no support
		 * for rprnt, flush, weras, and lnext...
		 */
		struct ltchars ltc;

		if (!ioctl(pty, TIOCGLTC, &ltc)) {
		    TMODE (XTTYMODE_dsusp, ltc.t_dsuspc);
		    (void) ioctl(pty, TIOCSLTC, &ltc);
		}
	    }
#endif	/* OSMAJORVERSION > 9 */

#elif	defined(IBM_ARCHITECTURE)
            TMODE (XTTYMODE_start, tio.c_cc[VSTRT]);
            TMODE (XTTYMODE_stop,  tio.c_cc[VSTOP]);
            TMODE (XTTYMODE_susp,  tio.c_cc[VSUSP]);
            TMODE (XTTYMODE_dsusp, tio.c_cc[VDSUSP]);
            TMODE (XTTYMODE_rprnt, tio.c_cc[VREPRINT]);
            TMODE (XTTYMODE_flush, tio.c_cc[VDISCRD]);
            TMODE (XTTYMODE_weras, tio.c_cc[VWERSE]);
            TMODE (XTTYMODE_lnext, tio.c_cc[VLNEXT]);

#elif	defined(SUN_ARCHITECTURE)
            TMODE (XTTYMODE_swtch, tio.c_cc[VSWTCH]);
            TMODE (XTTYMODE_start, tio.c_cc[VSTART]);
            TMODE (XTTYMODE_stop,  tio.c_cc[VSTOP]);
            TMODE (XTTYMODE_susp,  tio.c_cc[VSUSP]);
            TMODE (XTTYMODE_dsusp, tio.c_cc[VDSUSP]);
            TMODE (XTTYMODE_rprnt, tio.c_cc[VREPRINT]);
            TMODE (XTTYMODE_flush, tio.c_cc[VDISCARD]);
            TMODE (XTTYMODE_weras, tio.c_cc[VWERASE]);
            TMODE (XTTYMODE_lnext, tio.c_cc[VLNEXT]);

#elif   defined(ALPHA_ARCHITECTURE)
	    TMODE (XTTYMODE_start, tio.c_cc[VSTART]);
	    TMODE (XTTYMODE_stop,  tio.c_cc[VSTOP]);
	    TMODE (XTTYMODE_susp,  tio.c_cc[VSUSP]);
	    TMODE (XTTYMODE_dsusp, tio.c_cc[VDSUSP]);
	    TMODE (XTTYMODE_rprnt, tio.c_cc[VREPRINT]);
	    TMODE (XTTYMODE_flush, tio.c_cc[VDISCARD]);
	    TMODE (XTTYMODE_weras, tio.c_cc[VWERASE]);
	    TMODE (XTTYMODE_lnext, tio.c_cc[VLNEXT]);
#endif
        }
#undef TMODE
    }
    _DtTermProcessUnlock();
    
    (void) tcsetattr(pty, TCSADRAIN, &tio);

#if defined (USE_CSWIDTH)
    if (MB_CUR_MAX > 1)
    {
	/*
	** we are in a wide character locale, set the cs
	** width settings...
	*/
	i_str.ic_cmd    = EUC_WSET;
	i_str.ic_timout = 0;
	i_str.ic_len    = sizeof(struct eucioc);
	i_str.ic_dp     = (char *)&wp;
	(void)ioctl(pty, I_STR, &i_str);
    }
#endif   /* (USE_CSWIDTH) */

#if defined (USE_SETCSMAP)
    /*
    ** NOTE:
    **     Setcsmap() only operates on STDIN, so we have to do some
    **     munging around to map the pty to STDIN in order to get
    **     the desired result.  This may seem wasteful, but it 
    **     makes it easier to encapsulate the OS dependencies in
    **     this function.
    */
    if (pty != 0)
    {
	oldStdin = fcntl(0, F_DUPFD, 1);
	(void) close(0);
	(void) dup(pty);
    }

    sprintf(path, "%s%s", CSMAP_DIR, nl_langinfo(CODESET));
    if(access(path, E_ACC|R_ACC) == 0)
    {
	setcsmap(path);
    }
	
    if (pty != 0)
    {
	(void) close(0);
	if (oldStdin >= 0)
	{
	    (void) dup(oldStdin);
	    (void) close(oldStdin);
	}
    }
#endif   /* (USE_SETCSMAP) */
}
Example #13
0
void
_DtTermPrimStartLog(Widget w)
{
    DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
    DtTermPrimData tpd = tw->term.tpd;

    char            *cp;
    int              i;

    if ( tw->term.log_on || tw->term.logInhibit ) { return; }

    if (!tw->term.logFile || !*tw->term.logFile) {
	tw->term.logFile = "DttermLogXXXXX";
    }

    if (!strcmp(tw->term.logFile + strlen(tw->term.logFile) - 5, "XXXXX")) {
	/* make a local copy in case we are going to change it... */
	cp = XtMalloc(strlen(tw->term.logFile) + 1);
	(void) strcpy(cp, tw->term.logFile);

        (void) mktemp(cp);
	if (cp && *cp) {
	    tw->term.logFile = cp;
	} else {
	    (void) XtFree(cp);
	    return;
	}
    }

    if ('|' == *tw->term.logFile ) {
        /*
        ** pipe logfile into command
        */
        int p[2];

	_DtTermProcessLock();
        if (pipe(p) < 0 || (i = fork()) < 0) {
	    _DtTermProcessUnlock();
	    return;
	}

        if (i == 0) {
            /*
            ** child
            */
	    _DtTermProcessUnlock();

	    /* Remove suid root capability...
	     */
	    (void) _DtTermPrimRemoveSuidRoot();

            (void) close(p[1]);
            (void) close(0);
            (void) dup(p[0]);
            (void) close(p[0]);
            /*
            ** set close on exec flag on all other fd's
            */            for (i = 3; i < _NFILE; i++) {
                (void) fcntl(i, F_SETFD, 1);
            }
            /*
            ** reset signals
            */
            (void) signal(SIGHUP, SIG_DFL);
            (void) signal(SIGCHLD, SIG_DFL);
#ifdef	BBA
	    _bA_dump();
#endif	/* BBA */
            (void) execl(DEFAULT_SHELL, DEFAULT_SHELL_ARGV0, 
                         "-c", &tw->term.logFile[1], 0);
            (void) fprintf(stderr, " Can't exec \"%s\"\n",
                                       &tw->term.logFile[1]);
            (void) exit(1);
        }

        _DtTermProcessUnlock();
        (void) close(p[0]);
        tpd->logStream = fdopen(p[1], "w");
	(void) AddLogFileEntry(tpd->logStream);
        (void) signal(SIGPIPE, SIG_IGN);
    }
    else {
        if (access(tw->term.logFile, F_OK) == 0) {
            if (access(tw->term.logFile, W_OK) < 0) {
		return;
	    }
        } else if (cp = strrchr(tw->term.logFile, '/')) {
            *cp = 0;
            i   = access(tw->term.logFile, W_OK);
            *cp = '/';
            if (i < 0) {
		return;
	    }
        } else if (access(".", W_OK) < 0) {
	    return;
	}
        if ((tpd->logStream = fopen(tw->term.logFile, "a")) == NULL) {
            return;
        }
	(void) AddLogFileEntry(tpd->logStream);
        (void) chown(tw->term.logFile, getuid(), getgid());
    }
    tw->term.log_on = True ;
}
Example #14
0
void
_DtTermPrimCursorOn(Widget w)
{
    DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
    struct termData *tpd = tw->term.tpd;
    XPoint point;
    static Boolean alreadyActive = False;
    short chunkWidth;
    enhValues enhancements;
    unsigned long valueMask = 0L;
    XGCValues values;
    TermEnhInfoRec enhInfo;
    int cursorRow;

    /* if we are being called cyclically (by _DtTermPrimScrollWait ->
     * _DtTermPrimExposeText -> _DtTermPrimCursorOn), just return...
     */
    _DtTermProcessLock();
    if (alreadyActive) {
	/*DKS!!! vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */
	fprintf(stderr, "tell Dave _DtTermPrimCursorOn has alreadyActive == True\n");
	/*DKS!!! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
	_DtTermProcessUnlock();
	return;
    }

    /* this is where we will actually perform a pending scroll and
     * text refresh...
     */
    if (tw->term.jumpScroll && tpd->scroll.jump.scrolled) {
	/* make sure we don't end up in an infinite loop... */
	alreadyActive = True;
	Debug('t', fprintf(stderr,
		">>_DtTermPrimCursorOn() calling _DtTermPrimScrollWait()\n"));
	(void) _DtTermPrimScrollWait(w);
	alreadyActive = False;
    }
    _DtTermProcessUnlock();

#ifdef	DISOWN_SELECTION_ON_CURSOR_ON_OR_OFF 
    if ( _DtTermPrimSelectIsAboveSelection(w,tpd->cursorRow,
	    tpd->cursorColumn)) {
        _DtTermPrimSelectDisown(w) ;
    }
#endif	/* DISOWN_SELECTION_ON_CURSOR_ON_OR_OFF */

    /* update the input method spot location...
     */
    if ((tpd->IMCursorColumn != tpd->cursorColumn) ||
	    (tpd->IMCursorRow != tpd->cursorRow)) {
	tpd->IMCursorColumn = tpd->cursorColumn;
	tpd->IMCursorRow = tpd->cursorRow;
	point.x = tpd->cursorColumn * tpd->cellWidth + tpd->offsetX;
	point.y = tpd->cursorRow * tpd->cellHeight + tpd->offsetY + tpd->ascent;
	DebugF('F', 1, fprintf(stderr,
		"%s() %s calling %s\n",
		"_DtTermPrimCursorOn",
		"dont care",
		"XmImVaSetValues()"));
	(void) XmImVaSetValues(w,
		XmNspotLocation, &point,
		NULL);
    }
#ifdef	NOT_NEEDED
    if (!tw->term.hasFocus) {
	(void) fprintf(stderr,
		"%s() %s calling %s\n",
		"_DtTermPrimCursorOn",
		"!hasFocus",
		"XmImUnsetFocus()");
	(void) XmImUnsetFocus(w);
    }
#endif	/* NOT_NEEDED */

    /* update the scrollbar and position indicator... */
    (void) _DtTermPrimCursorUpdate(w);

    /* if the cursor is not visible, we are done now... */
    if (!tpd->cursorVisible) {
	return;
    }

    /* set up the GC... */
    if (!tpd->cursorGC.gc) {
	tpd->cursorGC.foreground =
		tw->primitive.foreground ^ tw->core.background_pixel;
	values.foreground = tpd->cursorGC.foreground;
	values.function = GXxor;
	tpd->cursorGC.gc = XCreateGC(XtDisplay(w), XtWindow(w),
		GCForeground | GCFunction, &values);
    }

    /* update the cursor's foreground and background...
     */
    /* if we are past the lastUsedRow, or the column > width, use color
     * pair 0...
     */

    /* reasonable defaults... */
    enhInfo.fg = tw->primitive.foreground;
    enhInfo.bg = tw->core.background_pixel;
    if (!((tpd->lastUsedRow <= tpd->topRow + tpd->cursorRow) ||
	    (_DtTermPrimBufferGetLineWidth(tpd->termBuffer,
		    tpd->topRow + tpd->cursorRow) <= MIN(tpd->cursorColumn,
		    tw->term.columns - 1)))) {
	/* get the current enhancement to determine the color pair to use...
	 */
	(void) _DtTermPrimBufferGetEnhancement(tpd->termBuffer,
						/* TermBuffer		*/
		    tpd->topRow + tpd->cursorRow,
						/* row			*/
		    MIN(tpd->cursorColumn, tw->term.columns - 1),
						/* col			*/
		    &enhancements,		/* enhancements		*/
		    &chunkWidth,		/* width		*/
		    countNew);			/* countWhich		*/
	/* set our font and color from the enhancements... */
	if (ENH_PROC(tpd->termBuffer)) {
	    (void) (*(ENH_PROC(tpd->termBuffer)))(w, enhancements, &enhInfo);
	}
    }

    /* set the GC... */
    if (tpd->cursorGC.foreground != enhInfo.fg ^ enhInfo.bg) {
	tpd->cursorGC.foreground = enhInfo.fg ^ enhInfo.bg;
	values.foreground = enhInfo.fg ^ enhInfo.bg;
	valueMask |= GCForeground;
    }
    if (valueMask) {
	(void) XChangeGC(XtDisplay(w), tpd->cursorGC.gc, valueMask, &values);
    }

    if (tpd->cursorState != CURSORoff) {
	return;
    }

    tpd->cursorState = CURSORon;
    (void) cursorToggle(w);

    if (tw->term.hasFocus) {
	/* add a timeout... */
	if (tw->term.blinkRate > 0) {
	    tpd->cursorTimeoutId =
		    XtAppAddTimeOut(XtWidgetToApplicationContext(w),
		    tw->term.blinkRate, (XtTimerCallbackProc) timeoutCallback,
		    (XtPointer) w);
	}
    }

}
Example #15
0
pid_t
_DtTermPrimSubprocExec(Widget		  w,
		       char		 *ptyName,
		       Boolean		  consoleMode,
		       char		 *cwd,
		       char		 *cmd,
		       char		**argv,
		       Boolean		  loginShell)
{
    DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
    static char *defaultCmd = (char *) 0;
    int i;
    int pty;
    pid_t pid;
    char *c;
    int err;
#ifdef	MOVE_FDS
    int saveFd[3];
#else	/* MOVE_FDS */
    int savedStderr;
#endif	/* MOVE_FDS */
    Boolean argvFree = False;
    struct sigaction sa;
    sigset_t ss;
    char buffer[BUFSIZ];
    Widget parent;
    char *namebuf;
    struct passwd * pw;
    _Xgetpwparams pw_buf;
    _Xgetloginparams login_buf;

#ifdef  ALPHA_ARCHITECTURE
    /* merge code from xterm, ignore so that TIOCSWINSZ doesn't block */
    signal(SIGTTOU, SIG_IGN);
#endif /* ALPHA_ARCHITECTURE */

    /* build a default exec command and argv list if one wasn't supplied...
     */
    /* cmd... */
    /* the command will be taken as follows:
     *	    - from the passed in cmd,
     *	    - from $SHELL,
     *	    - from the /etc/passwd entry for the /etc/utmp entry for this
     *        terminal,
     *	    - from the /etc/passwd entry for this userid, or
     *	    - /bin/sh.
     */
    if (!cmd || !*cmd) {
	if (!defaultCmd) {
	    /* from $SHELL... */
	    c = getenv("SHELL");

	    /* if not valid, try the /etc/passwd entry for the username
	     * associated with the /etc/utmp entry for this tty...
	     */
	    if (!c || !*c) {
		/* get the /etc/passwd entry for the username associated with
		 * /etc/utmp...
		 */
		if ((namebuf = _XGetlogin(login_buf)) != NULL) {
		    /* get the user's passwd entry... */
		    pw = _XGetpwnam(namebuf, pw_buf);
		    /* if we weren't able to come up with one for the
		     * username...
		     */
		    if (pw != NULL)
			c = pw->pw_shell;
		}
	    }

	    /* if not valid, try the /etc/passwd entry for the username
	     * associate with the real uid...
	     */
	    if (!c || !*c) {
		/* if we weren't able to come up with one for the userid... */
		pw = _XGetpwuid(getuid(), pw_buf);
		if (pw != NULL) {
		    c = pw->pw_shell;
		}
	    }

	    /* if not valid, use /bin/sh... */
	    if (!c || !*c) {
		c = DEFAULT_SHELL;
	    }

	    /* malloc space for this string.  It will be free'ed in the
	     * destroy function...
	     */
	    defaultCmd = XtMalloc(strlen(c) + 1);
	    (void) strcpy(defaultCmd, c);
	}

	cmd = defaultCmd;
    }

    if (!argv) {
	/* base it on cmd... */
	argv = (char **) XtMalloc(2 * sizeof(char *));
	/* if loginShell is set, then pre-pend a '-' to argv[0].  That's
	 * also why we allocate an extra byte in argv[0]...
	 */
	argv[0] = XtMalloc(strlen(cmd) + 2);
	*argv[0] = '\0';
	if (loginShell) {
	    /* pre-pend an '-' for loginShell... */
	    (void) strcat(argv[0], "-");
	    if (c = strrchr(cmd, '/')) {
		strcat(argv[0], ++c);
	    } else {
		strcat(argv[0], cmd);
	    }
	} else {
	    (void) strcat(argv[0], cmd);
	}
	/* null term the list... */
	argv[1] = (char *) 0;

	/* we will need to free it up later... */
	argvFree = True;
    }

#ifdef	OLDCODE
    /* this is left around from when we were using vfork().... */
    /* open the pty slave so that we can set the modes.
     *
     * NOTE: this code depends on support for the O_NOCTTY ioctl.  This
     *     ioctl allows us to open the device without becoming the
     *     session group leader for it.  If that can't be done, it may
     *     be necessary to rethink the way we open the pty slave...
     */
    if ((pty = open(ptyName, O_RDWR | O_NOCTTY, 0)) < 0) {
	(void) perror(ptyName);
	return((pid_t) -1);
    }
#endif	/* OLDCODE */

#ifdef	MOVE_FDS
    /* move fd[0:2] out of the way for now... */
    for (i = 0; i <= 2; i++) {
	saveFd[i] = fcntl(i, F_DUPFD, 3);
	(void) close(i);
    }
#else	/* MOVE_FDS */
    savedStderr = fcntl(2, F_DUPFD, 3);
#endif	/* MOVE_FDS */

    /* set close on exec flags on all files... */
    for (i = 0; i < _NFILE; i++) {
	(void) fcntl(i, F_SETFD, 1);
    }

    /* fork.  We can't use vfork() since we need to do lots of stuff
     * below...
     */
    if (isDebugSet('T')) {
#ifdef	BBA
#pragma BBA_IGNORE
#endif	/*BBA*/
	(void) timeStamp("about to fork()");
    }

    _DtTermProcessLock();
    for (i = 0; ((pid = FakeFork()) < 0) && (i < 10); i++) {
	/* if we are out of process slots, then let's sleep a bit and
	 * try again...
	 */
	if (errno != EAGAIN) {
	    break;
	}

	/* give it a chance to clear up... */
	(void) sleep((unsigned long) 2);
    }

    if (pid < 0) {
	(void) perror("fork()");
#ifdef	OLDCODE
	/* this is left around from when we were using vfork().... */
	(void) close(pty);
#endif	/* OLDCODE */
	return((pid_t) - 1);
    } else if (pid == 0) {
	/* child...
	 */
        _DtTermProcessUnlock();
#if defined(ALPHA_ARCHITECTURE) || defined(CSRG_BASED) || defined(LINUX_ARCHITECTURE)
        /* establish a new session for child */
        setsid();
#else
	/* do a setpgrp() so that we can... */
	(void) setpgrp();
#endif /* ALPHA_ARCHITECTURE */

#if defined(LINUX_ARCHITECTURE)
	/* set the ownership and mode of the pty... */
	(void) _DtTermPrimSetupPty(ptyName, pty);
#endif

	/* open the pty slave as our controlling terminal... */
	pty = open(ptyName, O_RDWR, 0);

	if (pty < 0) {
	    (void) perror(ptyName);
	    (void) _exit(1);
	}

#if defined(ALPHA_ARCHITECTURE) || defined(CSRG_BASED) || defined(LINUX_ARCHITECTURE)
        /* BSD needs to do this to acquire pty as controlling terminal */
        if (ioctl(pty, TIOCSCTTY, (char *)NULL) < 0) {
	    (void) close(pty);
	    (void) perror("Error acquiring pty slave as controlling terminal");
	    /* exit the subprocess */
	    _exit(1);
        }

        /* Do it when no controlling terminal doesn't work for OSF/1 */
        _DtTermPrimPtyGetDefaultModes();
#endif /* ALPHA_ARCHITECTURE */

#if !defined(LINUX_ARCHITECTURE)
	/* set the ownership and mode of the pty... */
	(void) _DtTermPrimSetupPty(ptyName, pty);
#endif /* LINUX_ARCHITECTURE */

	/* apply the ttyModes... */
	_DtTermPrimPtyInit(pty, tw->term.ttyModes, tw->term.csWidth);
	/* set the window size... */
	_DtTermPrimPtySetWindowSize(pty,
		tw->term.columns * tw->term.widthInc +
		(2 * (tw->primitive.shadow_thickness +
		      tw->primitive.highlight_thickness +
		      tw->term.marginWidth)),
		tw->term.rows * tw->term.heightInc +
		(2 * (tw->primitive.shadow_thickness +
		      tw->primitive.highlight_thickness +
		      tw->term.marginHeight)),
		tw->term.rows, tw->term.columns);

	/* if we are in console mode, turn it on... */
	if (consoleMode) {
	    _DtTermPrimPtyConsoleModeEnable(pty);
	}

#ifdef	MOVE_FDS
	/* that should have open'ed into fd 0.  Dup it into fd's 1 and 2... */
	(void) dup(pty);
	(void) dup(pty);
#else	/* MOVE_FDS */
	/* dup pty into fd's 0, 1, and 2... */
	for (i = 0; i < 3; i++) {
	    if (i != pty) {
		(void) close(i);
		(void) dup(pty);
	    }
	}
	if (pty >= 3) {
	    (void) close(pty);
	}
#endif	/* MOVE_FDS */

	/* reset any alarms... */
	(void) alarm(0);

	/* reset all signal handlers... */
	sa.sa_handler = SIG_DFL;
	(void) sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	for (i = 1; i < NSIG; i++) {
	    (void) sigaction(i, &sa, (struct sigaction *) 0);
	}

	/* unblock all signals... */
	(void) sigemptyset(&ss);
	(void) sigprocmask(SIG_SETMASK, &ss, (sigset_t *) 0);

	/*
	** Restore the original (pre-DT) environment, removing any
	** DT-specific environment variables that were added before
	** we...
	*/
#if defined(HPVUE)
#if       (OSMINORVERSION > 01)
	(void) VuEnvControl(VUE_ENV_RESTORE_PRE_VUE);
#endif /* (OSMINORVERSION > 01) */
#else   /* (HPVUE) */  
	(void) _DtEnvControl(DT_ENV_RESTORE_PRE_DT);
#endif  /* (HPVUE) */  
            
	/*
	** set a few environment variables of our own...
	*/
	for (parent = w; !XtIsShell(parent); parent = XtParent(parent))
	    ;
	(void) sprintf(buffer, "%ld", XtWindow(parent));
	_DtTermPrimPutEnv("WINDOWID=", buffer);
	_DtTermPrimPutEnv("DISPLAY=", XDisplayString(XtDisplay(w)));
	if (((DtTermPrimitiveWidget)w)->term.emulationId) {
	    _DtTermPrimPutEnv("TERMINAL_EMULATOR=",
			      ((DtTermPrimitiveWidget)w)->term.emulationId);
	}
		 
	/* set our utmp entry... */
	(void) _DtTermPrimUtmpEntryCreate(w, getpid(),
		((DtTermPrimitiveWidget)w)->term.tpd->utmpId);

	if (isDebugSet('T')) {
#ifdef	BBA
#pragma BBA_IGNORE
#endif	/*BBA*/
	    (void) timeStamp("about to execvp()");
	}

	/* turn off suid forever...
	 */
	_DtTermPrimRemoveSuidRoot();

	/* change to the requested directory... */
	if (cwd && *cwd) {
	    (void) chdir(cwd);
	}

#ifdef	BBA
	_bA_dump();
#endif	/* BBA */
	_DtEnvControl(DT_ENV_RESTORE_PRE_DT);
	(void) execvp(cmd, argv);
	/* if we got to this point we error'ed out.  Let's write out the
	 * error...
	 */
	err = errno;
	/* restore stderr... */
	(void) close(2);
	(void) dup(savedStderr);
	/* restore errno... */
	errno = err;
	(void) perror(cmd);
	/* and we need to exit the subprocess... */
	_exit(1);
    }

    /* parent...
     */
    _DtTermProcessUnlock();
    if (isDebugSet('T')) {
#ifdef	BBA
#pragma BBA_IGNORE
#endif	/*BBA*/
	(void) timeStamp("parent resuming");
    }
#ifdef	MOVE_FDS
    /* DKS: we should check this out and see if it is necessary... */
    (void) close(0);
    (void) close(1);
    (void) close(2);
    /* move fd[0:2] back in place... */
    for (i = 0; i <= 2; i++) {
	if (saveFd[i] >= 0) { 
	    (void) fcntl(saveFd[i], F_DUPFD, i);
	    (void) close(saveFd[i]);
	}
    }
#else	/* MOVE_FDS */
    (void) close(savedStderr);
#endif	/* MOVE_FDS */

    /* clean up malloc'ed memory... */
    if (argvFree) {
	(void) XtFree(argv[0]);
	(void) XtFree((char *) argv);
    }

#ifdef	OLDCODE
    /* since we no longer open it in the parent, we probably don't want
     * to close it either...
     */
    (void) close(pty);
#endif	/* OLDCODE */

    /* assume that our child set up a utmp entry (since we have no way
     * for it to report to us) and add it to the list to cleanup)...
     */
    _DtTermPrimUtmpAddEntry(((DtTermPrimitiveWidget)w)->term.tpd->utmpId);

    return(pid);
}