mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
737 lines
19 KiB
C
737 lines
19 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/* *
|
|
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
|
|
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
|
|
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
|
|
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
|
|
* (c) Copyright 1996 Digital Equipment Corporation. *
|
|
* (c) Copyright 1996 FUJITSU LIMITED. *
|
|
* (c) Copyright 1996 Hitachi. *
|
|
*/
|
|
|
|
|
|
#include "TermHeader.h"
|
|
#include "TermPrimOSDepI.h"
|
|
#include "TermPrimDebug.h"
|
|
|
|
#include <fcntl.h>
|
|
#include <termios.h>
|
|
|
|
#if defined (USE_SETCSMAP)
|
|
#include <langinfo.h>
|
|
#include <sys/param.h>
|
|
#endif /* (USE_SETCSMAP) */
|
|
|
|
#ifdef USE_SRIOCSREDIR
|
|
#include <sys/strredir.h>
|
|
#include <sys/stat.h>
|
|
#endif /* USE_SRIOCSREDIR */
|
|
|
|
#ifdef USE_TIOCCONS
|
|
#ifdef IBM_ARCHITECTURE
|
|
#include <sys/ioctl.h>
|
|
#endif /* IBM_ARCHITECTURE */
|
|
#include <sys/stat.h>
|
|
#endif /* USE_TIOCCONS */
|
|
|
|
#if defined(LINUX_ARCHITECTURE) || defined(CSRG_BASED)
|
|
#include <sys/ioctl.h>
|
|
#endif /* LINUX_ARCHITECTURE */
|
|
|
|
#ifdef USE_STREAMS
|
|
#include <sys/types.h>
|
|
#include <stropts.h>
|
|
#include <sys/conf.h>
|
|
#endif /* USE_STREAMS */
|
|
|
|
#if defined (USE_CSWIDTH)
|
|
#include <sys/ioctl.h>
|
|
#include <sys/eucioctl.h>
|
|
#endif /* (USE_CSWIDTH) */
|
|
|
|
#include <sys/wait.h>
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
#include <signal.h>
|
|
#include <Xm/Xm.h>
|
|
|
|
#include <Dt/Term.h>
|
|
#include "TermPrimUtil.h"
|
|
|
|
|
|
#define XTTYMODE_intr 0
|
|
#define XTTYMODE_quit 1
|
|
#define XTTYMODE_erase 2
|
|
#define XTTYMODE_kill 3
|
|
#define XTTYMODE_eof 4
|
|
#define XTTYMODE_eol 5
|
|
#define XTTYMODE_swtch 6
|
|
#define XTTYMODE_start 7
|
|
#define XTTYMODE_stop 8
|
|
#define XTTYMODE_brk 9
|
|
#define XTTYMODE_susp 10
|
|
#define XTTYMODE_dsusp 11
|
|
#define XTTYMODE_rprnt 12
|
|
#define XTTYMODE_flush 13
|
|
#define XTTYMODE_weras 14
|
|
#define XTTYMODE_lnext 15
|
|
#define NXTTYMODES 16
|
|
|
|
#if defined(CSRG_BASED)
|
|
#ifdef TAB3
|
|
#undef TAB3
|
|
#endif
|
|
#ifdef TABDLY
|
|
#undef TABDLY
|
|
#endif
|
|
#define TAB3 0x00000000
|
|
#define NLDLY 0x00000000
|
|
#define CRDLY 0x00000000
|
|
#define TABDLY 0x00000000
|
|
#define BSDLY 0x00000000
|
|
#define VTDLY 0x00000000
|
|
#define FFDLY 0x00000000
|
|
#define CBAUD 0x00000000
|
|
#endif
|
|
typedef struct _ttyMode
|
|
{
|
|
char *name;
|
|
int len;
|
|
int set;
|
|
char value;
|
|
}
|
|
ttyMode;
|
|
|
|
ttyMode _DtTermPrimTtyModeList[] =
|
|
{
|
|
{ "intr" , 4, 0, '\0' }, /* tchars.t_intrc ; VINTR */
|
|
{ "quit" , 4, 0, '\0' }, /* tchars.t_quitc ; VQUIT */
|
|
{ "erase", 5, 0, '\0' }, /* sgttyb.sg_erase ; VERASE */
|
|
{ "kill" , 4, 0, '\0' }, /* sgttyb.sg_kill ; VKILL */
|
|
{ "eof" , 3, 0, '\0' }, /* tchars.t_eofc ; VEOF */
|
|
{ "eol" , 3, 0, '\0' }, /* VEOL */
|
|
{ "swtch", 5, 0, '\0' }, /* VSWTCH */
|
|
{ "start", 5, 0, '\0' }, /* tchars.t_startc */
|
|
{ "stop" , 4, 0, '\0' }, /* tchars.t_stopc */
|
|
{ "brk" , 3, 0, '\0' }, /* tchars.t_brkc */
|
|
{ "susp" , 4, 0, '\0' }, /* ltchars.t_suspc */
|
|
{ "dsusp", 5, 0, '\0' }, /* ltchars.t_dsuspc */
|
|
{ "rprnt", 5, 0, '\0' }, /* ltchars.t_rprntc */
|
|
{ "flush", 5, 0, '\0' }, /* ltchars.t_flushc */
|
|
{ "weras", 5, 0, '\0' }, /* ltchars.t_werasc */
|
|
{ "lnext", 5, 0, '\0' }, /* ltchars.t_lnextc */
|
|
{ NULL, 0, 0, '\0' }, /* NULL terminate the array */
|
|
};
|
|
|
|
static int
|
|
parseTtyModes
|
|
(
|
|
char *modeString,
|
|
ttyMode *modeList
|
|
)
|
|
{
|
|
ttyMode *pMode;
|
|
int c;
|
|
int modeCount = 0;
|
|
|
|
/*
|
|
** Search to the end of the.
|
|
*/
|
|
|
|
while (1) {
|
|
/*
|
|
** Skip white space, if this is the end of the list,
|
|
** return.
|
|
*/
|
|
while (*modeString && isascii(*modeString) && isspace(*modeString))
|
|
{
|
|
modeString++;
|
|
}
|
|
|
|
if (!*modeString)
|
|
{
|
|
DebugF('p', 2, fprintf(stderr,
|
|
">>parseTtyModes() hit end of mode string, return=%d\n",
|
|
modeCount));
|
|
return(modeCount);
|
|
}
|
|
|
|
/*
|
|
** Otherwise, see if 'modeString' is in the list of mode names.
|
|
*/
|
|
for (pMode = modeList; pMode->name; pMode++)
|
|
{
|
|
DebugF('p', 2, fprintf(stderr,
|
|
">>parseTtyModes() comparing %.*s to %s\n",
|
|
pMode->len, modeString, pMode->name));
|
|
if (strncmp(modeString, pMode->name, pMode->len) == 0)
|
|
{
|
|
DebugF('p', 2, fprintf(stderr, ">>parseTtyModes() match!\n"));
|
|
break;
|
|
}
|
|
}
|
|
if (!pMode->name)
|
|
{
|
|
DebugF('p', 2, fprintf(stderr, ">>parseTtyModes() no match\n"));
|
|
return(-1);
|
|
}
|
|
|
|
/*
|
|
** Now look for a value for the setting.
|
|
** (Skip white space, return an error if no value.)
|
|
*/
|
|
modeString += pMode->len;
|
|
while (*modeString && isascii(*modeString) && isspace(*modeString))
|
|
{
|
|
modeString++;
|
|
}
|
|
if (!*modeString)
|
|
{
|
|
DebugF('p', 2, fprintf(stderr,
|
|
">>parseTtyModes() missing value\n"));
|
|
return(-1);
|
|
}
|
|
/*
|
|
** Make sure we handle control characters correctly.
|
|
*/
|
|
if (*modeString == '^')
|
|
{
|
|
modeString++;
|
|
/*
|
|
** keep control bits
|
|
*/
|
|
c = ((*modeString == '?') ? 0177 : *modeString & 31);
|
|
}
|
|
else
|
|
{
|
|
c = *modeString;
|
|
}
|
|
/*
|
|
** Set the values, and get go back for more.
|
|
*/
|
|
pMode->value = c;
|
|
pMode->set = 1;
|
|
modeCount++;
|
|
modeString++;
|
|
}
|
|
/* return(modeCount); */
|
|
}
|
|
|
|
#if defined (USE_CSWIDTH)
|
|
#define FIND_NUMBER(x, cp) \
|
|
{ \
|
|
x = 0; \
|
|
while (*cp && isdigit(*cp)) \
|
|
{ \
|
|
x *= 10; \
|
|
x += (*cp - '0'); \
|
|
cp++; \
|
|
} \
|
|
}
|
|
|
|
/*
|
|
** parse the cswidth string
|
|
** it should be in the form: X1[[:Y1][,X2[:Y2][,X3[:Y3]]]]
|
|
*/
|
|
static void
|
|
parseCSWidth
|
|
(
|
|
char *cp,
|
|
eucioc_t *wp
|
|
)
|
|
{
|
|
int x;
|
|
int i;
|
|
|
|
/*
|
|
** set all cs widths to 0
|
|
*/
|
|
wp->eucw[1] = wp->eucw[2] = wp->eucw[3] = 0;
|
|
wp->scrw[1] = wp->scrw[2] = wp->scrw[3] = 0;
|
|
if (!cp)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DebugF('p', 4, fprintf(stderr,
|
|
">>parseCSWidth(): csWidthString %s\n", cp));
|
|
|
|
for (i = 1; i <= 3; i++)
|
|
{
|
|
/*
|
|
** read Xn
|
|
*/
|
|
FIND_NUMBER(x, cp);
|
|
wp->eucw[i] = x;
|
|
if (!*cp)
|
|
{
|
|
wp->scrw[i] = wp->eucw[i];
|
|
return;
|
|
}
|
|
|
|
/*
|
|
** Yn might exist
|
|
*/
|
|
if (*cp == ':')
|
|
{
|
|
cp++;
|
|
FIND_NUMBER(x, cp);
|
|
wp->scrw[i] = x;
|
|
if (!*cp)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wp->scrw[i] = wp->eucw[i];
|
|
}
|
|
cp++;
|
|
}
|
|
DebugF('p', 4, fprintf(stderr,"parseCSWidth():"));
|
|
DebugF('p', 4, fprintf(stderr,
|
|
" eucw[1] : %d, scrw[1] : %d\n", wp->eucw[1], wp->scrw[1]));
|
|
DebugF('p', 4, fprintf(stderr,
|
|
" eucw[2] : %d, scrw[2] : %d\n", wp->eucw[2], wp->scrw[2]));
|
|
DebugF('p', 4, fprintf(stderr,
|
|
" eucw[3] : %d, scrw[3] : %d\n", wp->eucw[3], wp->scrw[3]));
|
|
}
|
|
#endif /* (USE_CSWIDTH) */
|
|
|
|
void _DtTermPrimPtySendBreak(int pty, int msec)
|
|
{
|
|
#if defined(USE_TIOCBREAK)
|
|
(void) ioctl(pty, TIOCBREAK, 0);
|
|
#elif defined(USE_TCSBRK)
|
|
(void) ioctl(pty, TCSBRK, 0);
|
|
#elif defined(USE_TCSENDBREAK)
|
|
(void) tcsendbreak(pty, 0);
|
|
#else /* none specified... */
|
|
#error "There is no RS232 break code specified for this architecture. See TermPrimOSDepI.h for a list of #defines..."
|
|
#endif /* rs232 break definition... */
|
|
}
|
|
|
|
void _DtTermPrimPtySetWindowSize(int pty, short pixelWidth, short pixelHeight,
|
|
short characterRows, short characterColumns)
|
|
{
|
|
struct winsize ws;
|
|
|
|
ws.ws_row = characterRows;
|
|
ws.ws_col = characterColumns;
|
|
ws.ws_xpixel = pixelWidth;
|
|
ws.ws_ypixel = pixelHeight;
|
|
(void) ioctl(pty, TIOCSWINSZ, &ws);
|
|
}
|
|
|
|
static struct termios refTio;
|
|
static int refValid = 0;
|
|
|
|
#if defined (USE_CSWIDTH)
|
|
/*
|
|
** default width settings for ldterm
|
|
*/
|
|
static eucioc_t refWp;
|
|
#endif /* (USE_CSWIDTH) */
|
|
|
|
void
|
|
_DtTermPrimPtyGetDefaultModes(void)
|
|
{
|
|
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"));
|
|
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();
|
|
}
|
|
|
|
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 | OPOST;
|
|
|
|
/* 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(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]);
|
|
|
|
#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 *)℘
|
|
(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) */
|
|
}
|
|
|
|
|
|
#if defined(USE_TIOCCONS)
|
|
#ifndef CONSOLE_DEVICE
|
|
#define CONSOLE_DEVICE "/dev/console"
|
|
#endif /* CONSOLE_DEVICE */
|
|
void _DtTermPrimPtyConsoleModeEnable(int pty)
|
|
{
|
|
struct stat st;
|
|
int one = 1;
|
|
|
|
/* check to see if we are the owner of the device... */
|
|
if (!stat(CONSOLE_DEVICE, &st)) {
|
|
/* stat succeeded... */
|
|
if (st.st_uid == getuid()) {
|
|
/* we are the owner, check the access... */
|
|
if (!access(CONSOLE_DEVICE, R_OK | W_OK)) {
|
|
/* and we can read/write it... */
|
|
/* we need to be setuid root... */
|
|
(void) _DtTermPrimToggleSuidRoot(True);
|
|
|
|
if (ioctl(pty, TIOCCONS, &one)) {
|
|
/* failure, errno was set... */
|
|
(void) perror(CONSOLE_DEVICE);
|
|
(void) fprintf(stderr,
|
|
"attempt to make tty the console failed\n");
|
|
}
|
|
/* we no longer need to be suid root... */
|
|
(void) _DtTermPrimToggleSuidRoot(False);
|
|
} else {
|
|
/* we can't read/write it... */
|
|
(void) perror(CONSOLE_DEVICE);
|
|
(void) fprintf(stderr, "-C console access denied\n");
|
|
}
|
|
} else {
|
|
/* we are not the owner -- return an access owner... */
|
|
errno = EACCES;
|
|
(void) perror(CONSOLE_DEVICE);
|
|
(void) fprintf(stderr, "-C console access denied\n");
|
|
}
|
|
} else {
|
|
/* we were unable to stat the file, errno is already set,
|
|
* failure...
|
|
*/
|
|
(void) perror(CONSOLE_DEVICE);
|
|
(void) fprintf(stderr, "-C console access denied\n");
|
|
}
|
|
}
|
|
|
|
|
|
#elif defined(USE_SRIOCSREDIR)
|
|
#ifndef CONSOLE_DEVICE
|
|
#define CONSOLE_DEVICE "/dev/console"
|
|
#endif /* CONSOLE_DEVICE */
|
|
void _DtTermPrimPtyConsoleModeEnable(int pty)
|
|
{
|
|
struct stat st;
|
|
int consoleFd;
|
|
|
|
/* check to see if we are the owner of the device... */
|
|
if (!stat(CONSOLE_DEVICE, &st)) {
|
|
/* stat succeeded... */
|
|
if (st.st_uid == getuid()) {
|
|
/* we are the owner, open the file... */
|
|
if ((consoleFd = open("/dev/console", O_RDWR | O_NOCTTY)) >= 0) {
|
|
if (ioctl(consoleFd, SRIOCSREDIR, pty) == -1) {
|
|
(void) perror(CONSOLE_DEVICE);
|
|
(void) fprintf(stderr,
|
|
"attempt to make tty the console failed\n");
|
|
}
|
|
(void) close(consoleFd);
|
|
} else {
|
|
/* we can't open it for reading and writing... */
|
|
(void) perror(CONSOLE_DEVICE);
|
|
(void) fprintf(stderr, "-C console access denied\n");
|
|
}
|
|
} else {
|
|
/* we are not the owner -- return an access owner... */
|
|
errno = EACCES;
|
|
(void) perror(CONSOLE_DEVICE);
|
|
(void) fprintf(stderr, "-C console access denied\n");
|
|
}
|
|
} else {
|
|
/* we were unable to stat the file, errno is already set,
|
|
* failure...
|
|
*/
|
|
(void) perror(CONSOLE_DEVICE);
|
|
(void) fprintf(stderr, "-C console access denied\n");
|
|
}
|
|
}
|
|
|
|
|
|
#else
|
|
void _DtTermPrimPtyConsoleModeEnable(int pty)
|
|
{
|
|
(void) fprintf(stderr,
|
|
"-C console access not supported on this architecture\n");
|
|
}
|
|
#endif
|