[PATCH luit] Integrate changes from Thomas Dickey's luit-20100601 fork

Jeremy Huddleston jeremyhu at apple.com
Sun Jun 27 21:27:52 PDT 2010


On Jun 6, 2010, at 11:11, Alan Coopersmith wrote:

> I note a lot of "NULL" changing back to "0" - sparse likes to complain
> about it, but it's mostly a style thing.   (On Solaris, NULL is defined
> as just 0, though I know some other platforms define it as (void *) 0.)
> 
> A couple other changes from our fork that I note got lost in the merge:
> 
> - declaring global variables static if they're only used in one file
> 	(from pcpa in commit 638f4ac8)
> 
> - Juliusz's email address changed in the man page
> 
> The rest seems fine.   (I can't claim to fully understand the terminal
> handling intricacies, but I see nothing to object to in them.)

Ok, this should address the two points you made above.  In order to minimize the whitespace noise, this is just the diff from git diff -w -b HEAD^ HEAD

diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644
index 0000000..7e579f5
--- /dev/null
+++ b/acinclude.m4
@@ -0,0 +1,116 @@
+dnl ---------------------------------------------------------------------------
+dnl
+dnl Copyright 2006-2009,2010 by Thomas E. Dickey
+dnl
+dnl                         All Rights Reserved
+dnl
+dnl Permission to use, copy, modify, and distribute this software and its
+dnl documentation for any purpose and without fee is hereby granted,
+dnl provided that the above copyright notice appear in all copies and that
+dnl both that copyright notice and this permission notice appear in
+dnl supporting documentation, and that the name of the above listed
+dnl copyright holder(s) not be used in advertising or publicity pertaining
+dnl to distribution of the software without specific, written prior
+dnl permission.
+dnl
+dnl THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+dnl TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+dnl AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE
+dnl LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+dnl WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+dnl ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+dnl OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+dnl
+dnl ---------------------------------------------------------------------------
+
+dnl ---------------------------------------------------------------------------
+dnl CF_FUNC_POLL version: 4 updated: 2006/12/16 12:33:30
+dnl ------------
+dnl See if the poll function really works.  Some platforms have poll(), but
+dnl it does not work for terminals or files.
+AC_DEFUN([CF_FUNC_POLL],[
+AC_CACHE_CHECK(if poll really works,cf_cv_working_poll,[
+AC_TRY_RUN([
+#include <stdio.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#else
+#include <sys/poll.h>
+#endif
+int main() {
+	struct pollfd myfds;
+	int ret;
+
+	myfds.fd = 0;
+	myfds.events = POLLIN;
+
+	ret = poll(&myfds, 1, 100);
+	${cf_cv_main_return:-return}(ret != 0);
+}],
+	[cf_cv_working_poll=yes],
+	[cf_cv_working_poll=no],
+	[cf_cv_working_poll=unknown])])
+test "$cf_cv_working_poll" = "yes" && AC_DEFINE(HAVE_WORKING_POLL, 1, [poll() works])
+])dnl
+
+dnl ---------------------------------------------------------------------------
+dnl CF_SIGWINCH version: 1 updated: 2006/04/02 16:41:09
+dnl -----------
+dnl Use this macro after CF_XOPEN_SOURCE, but do not require it (not all
+dnl programs need this test).
+dnl
+dnl This is really a MacOS X 10.4.3 workaround.  Defining _POSIX_C_SOURCE
+dnl forces SIGWINCH to be undefined (breaks xterm, ncurses).  Oddly, the struct
+dnl winsize declaration is left alone - we may revisit this if Apple choose to
+dnl break that part of the interface as well.
+AC_DEFUN([CF_SIGWINCH],
+[
+AC_CACHE_CHECK(if SIGWINCH is defined,cf_cv_define_sigwinch,[
+	AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/signal.h>
+],[int x = SIGWINCH],
+	[cf_cv_define_sigwinch=yes],
+	[AC_TRY_COMPILE([
+#undef _XOPEN_SOURCE
+#undef _POSIX_SOURCE
+#undef _POSIX_C_SOURCE
+#include <sys/types.h>
+#include <sys/signal.h>
+],[int x = SIGWINCH],
+	[cf_cv_define_sigwinch=maybe],
+	[cf_cv_define_sigwinch=no])
+])
+])
+
+if test "$cf_cv_define_sigwinch" = maybe ; then
+AC_CACHE_CHECK(for actual SIGWINCH definition,cf_cv_fixup_sigwinch,[
+cf_cv_fixup_sigwinch=unknown
+cf_sigwinch=32
+while test $cf_sigwinch != 1
+do
+	AC_TRY_COMPILE([
+#undef _XOPEN_SOURCE
+#undef _POSIX_SOURCE
+#undef _POSIX_C_SOURCE
+#include <sys/types.h>
+#include <sys/signal.h>
+],[
+#if SIGWINCH != $cf_sigwinch
+make an error
+#endif
+int x = SIGWINCH],
+	[cf_cv_fixup_sigwinch=$cf_sigwinch
+	 break])
+
+cf_sigwinch=`expr $cf_sigwinch - 1`
+done
+])
+
+	if test "$cf_cv_fixup_sigwinch" != unknown ; then
+		CPPFLAGS="$CPPFLAGS -DSIGWINCH=$cf_cv_fixup_sigwinch"
+	fi
+fi
+])dnl
+
+
diff --git a/charset.c b/charset.c
index 7424ac3..c74f262 100644
--- a/charset.c
+++ b/charset.c
@@ -19,13 +19,17 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
-/* $XFree86: xc/programs/luit/charset.c,v 1.8 2003/12/22 17:48:12 tsi Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
-#include <X11/fonts/fontenc.h>
+
+#include "sys.h"
 #include "other.h"
 #include "charset.h"
 #include "parser.h"
@@ -35,22 +39,28 @@ THE SOFTWARE.
 #endif
 
 static unsigned int
-IdentityRecode(unsigned int n, CharsetPtr self)
+IdentityRecode(unsigned int n, const CharsetRec * self GCC_UNUSED)
 {
     return n;
 }
 
 #ifdef UNUSED
 static int
-IdentityReverse(unsigned int n, CharsetPtr self)
+IdentityReverse(unsigned int n, const CharsetRec * self)
 {
 #define IS_GL(n) ((n) >= 0x20 && (n) < 0x80)
     switch(self->type) {
     case T_94:
     case T_96:
-        if (IS_GL(n)) return n; else return -1;
+	if (IS_GL(n))
+	    return n;
+	else
+	    return -1;
     case T_128:
-        if (n < 0x80) return n; else return -1;
+	if (n < 0x80)
+	    return n;
+	else
+	    return -1;
     case T_9494:
     case T_9696:
         if(IS_GL(n>>8) && IS_GL(n&0xFF))
@@ -64,114 +74,118 @@ IdentityReverse(unsigned int n, CharsetPtr self)
             return -1;
     default:
         abort();
+	/* NOTREACHED */
     }
 #undef IS_GL
 }
 #endif
 
 static int
-NullReverse(unsigned int n, CharsetPtr self)
+NullReverse(unsigned int n GCC_UNUSED, const CharsetRec * self GCC_UNUSED)
 {
     return -1;
 }
 
-static CharsetRec Unknown94Charset = 
-{ "Unknown (94)", T_94, 0, IdentityRecode, NullReverse, NULL, NULL};
-static CharsetRec Unknown96Charset = 
-{ "Unknown (96)", T_96, 0, IdentityRecode, NullReverse, NULL, NULL};
-static CharsetRec Unknown9494Charset = 
-{ "Unknown (94x94)", T_9494, 0, IdentityRecode, NullReverse, NULL, NULL};
-static CharsetRec Unknown9696Charset = 
-{ "Unknown (96x96)", T_9696, 0, IdentityRecode, NullReverse, NULL, NULL};
+static const CharsetRec Unknown94Charset =
+{"Unknown (94)", T_94, 0, IdentityRecode, NullReverse, 0, 0, 0, 0, 0, 0};
+static const CharsetRec Unknown96Charset =
+{"Unknown (96)", T_96, 0, IdentityRecode, NullReverse, 0, 0, 0, 0, 0, 0};
+static const CharsetRec Unknown9494Charset =
+{"Unknown (94x94)", T_9494, 0, IdentityRecode, NullReverse, 0, 0, 0, 0, 0, 0};
+static const CharsetRec Unknown9696Charset =
+{"Unknown (96x96)", T_9696, 0, IdentityRecode, NullReverse, 0, 0, 0, 0, 0, 0};
 
 typedef struct _FontencCharset {
-    char *name;
+    const char *name;
     int type;
     unsigned char final;
-    char *xlfd;
-    int shift;
+    const char *xlfd;
+    unsigned shift;
     FontMapPtr mapping;
     FontMapReversePtr reverse;
 } FontencCharsetRec, *FontencCharsetPtr;
-
-static FontencCharsetRec fontencCharsets[] = {
-    {"ISO 646 (1973)", T_94, '@', "iso646.1973-0", 0x00, NULL, NULL},
-    {"ASCII", T_94, 'B', "iso8859-1", 0x00, NULL, NULL},
-    {"JIS X 0201:GL", T_94, 'J', "jisx0201.1976-0", 0x00, NULL, NULL},
-    {"JIS X 0201:GR", T_94, 'I', "jisx0201.1976-0", 0x80, NULL, NULL},
-    {"DEC Special", T_94, '0', "dec-special", 0x00, NULL, NULL},
-    {"DEC Technical", T_94, '>', "dec-dectech", 0x00, NULL, NULL},
-
-    {"ISO 8859-1", T_96, 'A', "iso8859-1", 0x80, NULL, NULL},
-    {"ISO 8859-2", T_96, 'B', "iso8859-2", 0x80, NULL, NULL},
-    {"ISO 8859-3", T_96, 'C', "iso8859-3", 0x80, NULL, NULL},
-    {"ISO 8859-4", T_96, 'D', "iso8859-4", 0x80, NULL, NULL},
-    {"ISO 8859-5", T_96, 'L', "iso8859-5", 0x80, NULL, NULL},
-    {"ISO 8859-6", T_96, 'G', "iso8859-6", 0x80, NULL, NULL},
-    {"ISO 8859-7", T_96, 'F', "iso8859-7", 0x80, NULL, NULL},
-    {"ISO 8859-8", T_96, 'H', "iso8859-8", 0x80, NULL, NULL},
-    {"ISO 8859-9", T_96, 'M', "iso8859-9", 0x80, NULL, NULL},
-    {"ISO 8859-10", T_96, 'V', "iso8859-10", 0x80, NULL, NULL},
-    {"ISO 8859-11", T_96, 'T', "iso8859-11", 0x80, NULL, NULL},
-    {"TIS 620", T_96, 'T', "iso8859-11", 0x80, NULL, NULL},
-    {"ISO 8859-13", T_96, 'Y', "iso8859-13", 0x80, NULL, NULL},
-    {"ISO 8859-14", T_96, '_', "iso8859-14", 0x80, NULL, NULL},
-    {"ISO 8859-15", T_96, 'b', "iso8859-15", 0x80, NULL, NULL},
-    {"ISO 8859-16", T_96, 'f', "iso8859-16", 0x80, NULL, NULL},
-    {"KOI8-E", T_96, '@', "koi8-e", 0x80, NULL, NULL},
-    {"TCVN", T_96, 'Z', "tcvn-0", 0x80, NULL, NULL},
-
-    {"GB 2312", T_9494, 'A', "gb2312.1980-0", 0x0000, NULL, NULL},
-    {"JIS X 0208", T_9494, 'B', "jisx0208.1990-0", 0x0000, NULL, NULL},
-    {"KSC 5601", T_9494, 'C', "ksc5601.1987-0", 0x0000, NULL, NULL},
-    {"JIS X 0212", T_9494, 'D', "jisx0212.1990-0", 0x0000, NULL, NULL},
-
-    {"GB 2312", T_9696, 'A', "gb2312.1980-0", 0x0000, NULL, NULL},
-    {"JIS X 0208", T_9696, 'B', "jisx0208.1990-0", 0x0000, NULL, NULL},
-    {"KSC 5601", T_9696, 'C', "ksc5601.1987-0", 0x0000, NULL, NULL},
-    {"JIS X 0212", T_9696, 'D', "jisx0212.1990-0", 0x0000, NULL, NULL},
-
-    {"KOI8-R", T_128, 0, "koi8-r", 0x80, NULL, NULL},
-    {"KOI8-U", T_128, 0, "koi8-u", 0x80, NULL, NULL},
-    {"KOI8-RU", T_128, 0, "koi8-ru", 0x80, NULL, NULL},
-    {"CP 1252", T_128, 0, "microsoft-cp1252", 0x80, NULL, NULL},
-    {"CP 1251", T_128, 0, "microsoft-cp1251", 0x80, NULL, NULL},
-    {"CP 1250", T_128, 0, "microsoft-cp1250", 0x80, NULL, NULL},
-
-    {"CP 437", T_128, 0, "ibm-cp437", 0x80, NULL, NULL},
-    {"CP 850", T_128, 0, "ibm-cp850", 0x80, NULL, NULL},
-    {"CP 866", T_128, 0, "ibm-cp866", 0x80, NULL, NULL},
-
-    {"Big 5", T_94192, 0, "big5.eten-0", 0x8000, NULL, NULL},
-    {NULL, 0, 0, NULL, 0, NULL, NULL}
+/* *INDENT-OFF* */
+static FontencCharsetRec fontencCharsets[] =
+{
+    {"ISO 646 (1973)", T_94,    '@', "iso646.1973-0",    0x00,   0, 0},
+    {"ASCII",          T_94,    'B', "iso8859-1",        0x00,   0, 0},
+    {"JIS X 0201:GL",  T_94,    'J', "jisx0201.1976-0",  0x00,   0, 0},
+    {"JIS X 0201:GR",  T_94,    'I', "jisx0201.1976-0",  0x80,   0, 0},
+    {"DEC Special",    T_94,    '0', "dec-special",      0x00,   0, 0},
+    {"DEC Technical",  T_94,    '>', "dec-dectech",      0x00,   0, 0},
+
+    {"ISO 8859-1",     T_96,    'A', "iso8859-1",        0x80,   0, 0},
+    {"ISO 8859-2",     T_96,    'B', "iso8859-2",        0x80,   0, 0},
+    {"ISO 8859-3",     T_96,    'C', "iso8859-3",        0x80,   0, 0},
+    {"ISO 8859-4",     T_96,    'D', "iso8859-4",        0x80,   0, 0},
+    {"ISO 8859-5",     T_96,    'L', "iso8859-5",        0x80,   0, 0},
+    {"ISO 8859-6",     T_96,    'G', "iso8859-6",        0x80,   0, 0},
+    {"ISO 8859-7",     T_96,    'F', "iso8859-7",        0x80,   0, 0},
+    {"ISO 8859-8",     T_96,    'H', "iso8859-8",        0x80,   0, 0},
+    {"ISO 8859-9",     T_96,    'M', "iso8859-9",        0x80,   0, 0},
+    {"ISO 8859-10",    T_96,    'V', "iso8859-10",       0x80,   0, 0},
+    {"ISO 8859-11",    T_96,    'T', "iso8859-11",       0x80,   0, 0},
+    {"TIS 620",        T_96,    'T', "iso8859-11",       0x80,   0, 0},
+    {"ISO 8859-13",    T_96,    'Y', "iso8859-13",       0x80,   0, 0},
+    {"ISO 8859-14",    T_96,    '_', "iso8859-14",       0x80,   0, 0},
+    {"ISO 8859-15",    T_96,    'b', "iso8859-15",       0x80,   0, 0},
+    {"ISO 8859-16",    T_96,    'f', "iso8859-16",       0x80,   0, 0},
+    {"KOI8-E",         T_96,    '@', "koi8-e",           0x80,   0, 0},
+    {"TCVN",           T_96,    'Z', "tcvn-0",           0x80,   0, 0},
+
+    {"GB 2312",        T_9494,  'A', "gb2312.1980-0",    0x0000, 0, 0},
+    {"JIS X 0208",     T_9494,  'B', "jisx0208.1990-0",  0x0000, 0, 0},
+    {"KSC 5601",       T_9494,  'C', "ksc5601.1987-0",   0x0000, 0, 0},
+    {"JIS X 0212",     T_9494,  'D', "jisx0212.1990-0",  0x0000, 0, 0},
+
+    {"GB 2312",        T_9696,  'A', "gb2312.1980-0",    0x0000, 0, 0},
+    {"JIS X 0208",     T_9696,  'B', "jisx0208.1990-0",  0x0000, 0, 0},
+    {"KSC 5601",       T_9696,  'C', "ksc5601.1987-0",   0x0000, 0, 0},
+    {"JIS X 0212",     T_9696,  'D', "jisx0212.1990-0",  0x0000, 0, 0},
+
+    {"KOI8-R",         T_128,   0,   "koi8-r",           0x80,   0, 0},
+    {"KOI8-U",         T_128,   0,   "koi8-u",           0x80,   0, 0},
+    {"KOI8-RU",        T_128,   0,   "koi8-ru",          0x80,   0, 0},
+    {"CP 1252",        T_128,   0,   "microsoft-cp1252", 0x80,   0, 0},
+    {"CP 1251",        T_128,   0,   "microsoft-cp1251", 0x80,   0, 0},
+    {"CP 1250",        T_128,   0,   "microsoft-cp1250", 0x80,   0, 0},
+
+    {"CP 437",         T_128,   0,   "ibm-cp437",        0x80,   0, 0},
+    {"CP 850",         T_128,   0,   "ibm-cp850",        0x80,   0, 0},
+    {"CP 866",         T_128,   0,   "ibm-cp866",        0x80,   0, 0},
+
+    {"Big 5",          T_94192, 0,   "big5.eten-0",      0x8000, 0, 0},
+    {0,                0,       0,   0,                  0,      0, 0}
 };
+/* *INDENT-ON* */
 
 typedef struct _OtherCharset {
-    char *name;
+    const char *name;
     int (*init)(OtherStatePtr);
     unsigned int (*mapping)(unsigned int, OtherStatePtr);
     unsigned int (*reverse)(unsigned int, OtherStatePtr);
-    int (*stack)(unsigned char, OtherStatePtr);
+    int (*stack) (unsigned, OtherStatePtr);
 } OtherCharsetRec, *OtherCharsetPtr;
 
-static OtherCharsetRec otherCharsets[] = {
+static const OtherCharsetRec otherCharsets[] =
+{
     {"GBK", init_gbk, mapping_gbk, reverse_gbk, stack_gbk},
     {"UTF-8", init_utf8, mapping_utf8, reverse_utf8, stack_utf8},
     {"SJIS", init_sjis, mapping_sjis, reverse_sjis, stack_sjis},
     {"BIG5-HKSCS", init_hkscs, mapping_hkscs, reverse_hkscs, stack_hkscs},
     {"GB18030", init_gb18030, mapping_gb18030, reverse_gb18030, stack_gb18030},
-    {NULL, NULL, NULL, NULL, NULL}
+    {0, 0, 0, 0, 0}
 };
 
 static int
 compare(const char *s, const char *t)
 {
     while(*s || *t) {
-        if(*s && (isspace(*s) || *s == '-' || *s == '_'))
+	if (*s && (isspace(UChar(*s)) || *s == '-' || *s == '_'))
             s++;
-        else if(*t && (isspace(*t) || *t == '-' || *t == '_'))
+	else if (*t && (isspace(UChar(*t)) || *t == '-' || *t == '_'))
             t++;
-        else if(*s && *t && tolower(*s) == tolower(*t)) {
+	else if (*s && *t && tolower(UChar(*s)) == tolower(UChar(*t))) {
             s++; 
             t++;
         } else
@@ -181,18 +195,18 @@ compare(const char *s, const char *t)
 }
 
 static unsigned int
-FontencCharsetRecode(unsigned int n, CharsetPtr self)
+FontencCharsetRecode(unsigned int n, const CharsetRec * self)
 {
-    FontencCharsetPtr fc = (FontencCharsetPtr)(self->data);
+    const FontencCharsetRec *fc = (const FontencCharsetRec *) (self->data);
 
     return FontEncRecode(n + fc->shift, fc->mapping);
 }
 
 static int
-FontencCharsetReverse(unsigned int i, CharsetPtr self)
+FontencCharsetReverse(unsigned int i, const CharsetRec * self)
 {
-    FontencCharsetPtr fc = (FontencCharsetPtr)(self->data);
-    int n;
+    const FontencCharsetRec *fc = (const FontencCharsetRec *) (self->data);
+    unsigned n;
 
     n = fc->reverse->reverse(i, fc->reverse->data);
     if(n == 0 || n < fc->shift)
@@ -202,34 +216,39 @@ FontencCharsetReverse(unsigned int i, CharsetPtr self)
 
 #define IS_GL(n) ((n) >= 0x20 && (n) < 0x80)
     switch(self->type) {
-    case T_94: case T_96:
-        if (IS_GL(n)) return n; else return -1;
-        break;
+    case T_94:
+    case T_96:
+	if (IS_GL(n))
+	    return (int) n;
+	else
+	    return -1;
     case T_128:
-        if (n < 0x80) return n; else return -1;
-    case T_9494: case T_9696:
+	if (n < 0x80)
+	    return (int) n;
+	else
+	    return -1;
+    case T_9494:
+    case T_9696:
         if(IS_GL(n>>8) && IS_GL(n&0xFF))
-            return n;
+	    return (int) n;
         else
             return -1;
-        break;
     case T_94192:
         if(IS_GL(n>>8) && IS_GL(n&0x7F))
-            return n;
+	    return (int) n;
         else
             return -1;
-        break;
     default:
         abort();
+	/* NOTREACHED */
     }
 #undef IS_GL
 }
 
-
 static CharsetPtr cachedCharsets = NULL;
 
 static CharsetPtr 
-getCachedCharset(unsigned char final, int type, const char *name)
+getCachedCharset(unsigned final, int type, const char *name)
 {
     CharsetPtr c;
     for(c = cachedCharsets; c; c = c->next) {
@@ -242,13 +261,14 @@ getCachedCharset(unsigned char final, int type, const char *name)
 }
 
 static void
-cacheCharset(CharsetPtr c) {
+cacheCharset(CharsetPtr c)
+{
     c->next = cachedCharsets;
     cachedCharsets = c;
 }
 
 static CharsetPtr
-getFontencCharset(unsigned char final, int type, const char *name)
+getFontencCharset(unsigned final, int type, const char *name)
 {
     FontencCharsetPtr fc;
     CharsetPtr c;
@@ -300,7 +320,7 @@ getFontencCharset(unsigned char final, int type, const char *name)
 static CharsetPtr
 getOtherCharset(const char *name)
 {
-    OtherCharsetPtr fc;
+    const OtherCharsetRec *fc;
     CharsetPtr c;
     OtherStatePtr s;
 
@@ -342,22 +362,27 @@ getOtherCharset(const char *name)
     return c;
 }
 
-CharsetPtr 
+const CharsetRec *
 getUnknownCharset(int type)
 {
     switch(type) {
-    case T_94: return &Unknown94Charset;
-    case T_96: return &Unknown96Charset;
-    case T_9494: return &Unknown9494Charset;
-    case T_9696: return &Unknown9696Charset;
-    default: return &Unknown94Charset;
+    case T_94:
+	return &Unknown94Charset;
+    case T_96:
+	return &Unknown96Charset;
+    case T_9494:
+	return &Unknown9494Charset;
+    case T_9696:
+	return &Unknown9696Charset;
+    default:
+	return &Unknown94Charset;
     }
 }
 
-CharsetPtr 
-getCharset(unsigned char final, int type)
+const CharsetRec *
+getCharset(unsigned final, int type)
 {
-    CharsetPtr c;
+    const CharsetRec *c;
 
     c = getCachedCharset(final, type, NULL);
     if(c)
@@ -370,10 +395,10 @@ getCharset(unsigned char final, int type)
     return getUnknownCharset(type);
 }
 
-CharsetPtr 
+const CharsetRec *
 getCharsetByName(const char *name)
 {
-    CharsetPtr c;
+    const CharsetRec *c;
 
     if(name == NULL)
         return getUnknownCharset(T_94);
@@ -392,8 +417,9 @@ getCharsetByName(const char *name)
 
     return getUnknownCharset(T_94);
 }
-
-static const LocaleCharsetRec localeCharsets[] = {
+/* *INDENT-OFF* */
+static const LocaleCharsetRec localeCharsets[] =
+{
     { "C", 0, 2, "ASCII", NULL, "ISO 8859-1", NULL, NULL},
     { "POSIX", 0, 2, "ASCII", NULL, "ISO 8859-1", NULL, NULL},
     { "ISO8859-1", 0, 2, "ASCII", NULL, "ISO 8859-1", NULL, NULL},
@@ -426,8 +452,9 @@ static const LocaleCharsetRec localeCharsets[] = {
     { "SJIS", 0, 1, NULL, NULL, NULL, NULL, "SJIS"},
     { "Big5-HKSCS", 0, 1, NULL, NULL, NULL, NULL, "BIG5-HKSCS"},
     { "gb18030", 0, 1, NULL, NULL, NULL, NULL, "GB18030"},
-    { NULL, 0, 0, NULL, NULL, NULL, NULL, NULL}
+    {0,            0, 0, 0,       0,            0,               0,            0}
 };
+/* *INDENT-ON* */
 
 void
 reportCharsets(void)
@@ -441,10 +468,14 @@ reportCharsets(void)
 	    continue;
         }
         printf("  %s: GL -> G%d, GR -> G%d", p->name, p->gl, p->gr);
-        if(p->g0) printf(", G0: %s", p->g0);
-        if(p->g1) printf(", G1: %s", p->g1);
-        if(p->g2) printf(", G2: %s", p->g2);
-        if(p->g3) printf(", G3: %s", p->g3);
+	if (p->g0)
+	    printf(", G0: %s", p->g0);
+	if (p->g1)
+	    printf(", G1: %s", p->g1);
+	if (p->g2)
+	    printf(", G2: %s", p->g2);
+	if (p->g3)
+	    printf(", G3: %s", p->g3);
         printf("\n");
     }
 
@@ -455,13 +486,17 @@ reportCharsets(void)
 }
 
 int
-getLocaleState(const char *locale, char *charset,
+getLocaleState(const char *locale,
+	       const char *charset,
                int *gl_return, int *gr_return,
-               CharsetPtr *g0_return, CharsetPtr *g1_return,
-               CharsetPtr *g2_return, CharsetPtr *g3_return,
-               CharsetPtr *other_return)
+	       const CharsetRec * *g0_return,
+	       const CharsetRec * *g1_return,
+	       const CharsetRec * *g2_return,
+	       const CharsetRec * *g3_return,
+	       const CharsetRec * *other_return)
 {
-    char *resolved = NULL;
+    int result = 0;
+    char *resolved = 0;
     const LocaleCharsetRec *p;
 
     if(!charset) {
@@ -481,10 +516,8 @@ getLocaleState(const char *locale, char *charset,
     }
 
     if(p->name == NULL) {
-	if (resolved != NULL)
-	    free(resolved);
-        return -1;
-    }
+	result = -1;
+    } else {
 
     *gl_return = p->gl;
     *gr_return = p->gr;
@@ -496,6 +529,63 @@ getLocaleState(const char *locale, char *charset,
         *other_return = getCharsetByName(p->other);
     else
         *other_return = NULL;
-    return 0;
+    }
+    if (resolved != 0)
+	free(resolved);
+    return result;
 }
 
+#ifdef NO_LEAKS
+static int
+isUnknownCharsetPtr(CharsetPtr p)
+{
+    return (p == &Unknown94Charset
+	    || p == &Unknown96Charset
+	    || p == &Unknown9494Charset
+	    || p == &Unknown9696Charset);
+}
+
+static void
+destroyFontencCharsetPtr(FontencCharsetPtr p)
+{
+    p->mapping = 0;
+
+    /*
+     * This should, but does not work -
+     *     FontMapReverseFree(p->reverse)
+     *
+     * The iteration for map[] is based on reading the source of
+     * FontMapReverse().
+     */
+    if (p->reverse) {
+	int n;
+	unsigned **map = p->reverse->data;
+	for (n = 0; n < 256; ++n) {
+	    if (map[n])
+		free(map[n]);
+	}
+	free(p->reverse->data);
+	free(p->reverse);
+	p->reverse = 0;
+    }
+}
+
+static void
+destroyCharset(CharsetPtr p)
+{
+    if (!isUnknownCharsetPtr(p)) {
+	destroyFontencCharsetPtr(p->data);
+	free(p);
+    }
+}
+
+void
+charset_leaks(void)
+{
+    while (cachedCharsets != 0) {
+	CharsetPtr next = cachedCharsets->next;
+	destroyCharset(cachedCharsets);
+	cachedCharsets = next;
+    }
+}
+#endif
diff --git a/charset.h b/charset.h
index 7842ea9..3600329 100644
--- a/charset.h
+++ b/charset.h
@@ -19,7 +19,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
-/* $XFree86: xc/programs/luit/charset.h,v 1.3 2002/07/01 02:25:59 tsi Exp $ */
+/* $XFree86: xc/programs/luit/charset.h,v 1.4 2002/10/17 01:06:09 dawes Exp $ */
+
+#ifndef LUIT_CHARSET_H
+#define LUIT_CHARSET_H 1
+
+#include "other.h"
 
 #define T_FAILED 0
 #define T_94 1
@@ -36,13 +41,13 @@ THE SOFTWARE.
 #define CHARSET_REGULAR(c) ((c)->type != T_128)
 
 typedef struct _Charset {
-    char *name;
+    const char *name;
     int type;
     unsigned char final;
-    unsigned int (*recode)(unsigned int, struct _Charset *self);
-    int (*reverse)(unsigned int, struct _Charset *self);
-    void *data;
-    int (*other_stack)(unsigned char c, OtherStatePtr aux);
+    unsigned int (*recode) (unsigned int, const struct _Charset * self);
+    int (*reverse) (unsigned int, const struct _Charset * self);
+    const void *data;
+    int (*other_stack) (unsigned c, OtherStatePtr aux);
     OtherState *other_aux;
     unsigned int (*other_recode)(unsigned int c, OtherStatePtr aux);
     unsigned int (*other_reverse)(unsigned int c, OtherStatePtr aux);
@@ -60,12 +65,16 @@ typedef struct _LocaleCharset {
     const char *other;
 } LocaleCharsetRec, *LocaleCharsetPtr;
 
-CharsetPtr getUnknownCharset(int);
-CharsetPtr getCharset(unsigned char, int);
-CharsetPtr getCharsetByName(const char*);
+const CharsetRec *getUnknownCharset(int);
+const CharsetRec *getCharset(unsigned, int);
+const CharsetRec *getCharsetByName(const char *);
 void reportCharsets(void);
-int getLocaleState(const char *locale, char *charset,
+int getLocaleState(const char *locale, const char *charset,
                    int *gl_return, int *gr_return,
-                   CharsetPtr *g0_return, CharsetPtr *g1_return,
-                   CharsetPtr *g2_return, CharsetPtr *g3_return,
-                   CharsetPtr *other_return);
+		   const CharsetRec * *g0_return,
+		   const CharsetRec * *g1_return,
+		   const CharsetRec * *g2_return,
+		   const CharsetRec * *g3_return,
+		   const CharsetRec * *other_return);
+
+#endif /* LUIT_CHARSET_H */
diff --git a/configure.ac b/configure.ac
index f67ea4a..e8d960a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,3 @@
-
 dnl  Copyright 2005 Red Hat, Inc.
 dnl 
 dnl  Permission to use, copy, modify, distribute, and sell this software and its
@@ -71,6 +70,25 @@ case $host_os in
         ;;
 esac
 
+AC_CHECK_HEADERS([pty.h stropts.h sys/ioctl.h sys/param.h sys/poll.h sys/select.h sys/time.h termios.h]) 
+AC_CHECK_FUNCS([grantpt putenv select strdup])
+
+if test "x$ac_cv_func_grantpt" != "xyes" ; then
+        AC_CHECK_LIB(util, openpty, [cf_have_openpty=yes],[cf_have_openpty=no])
+        if test "$cf_have_openpty" = yes ; then
+                LIBS="-lutil $LIBS"
+                AC_DEFINE(HAVE_OPENPTY, 1, [Have openpty in libutil])
+                AC_CHECK_HEADERS( \
+                        util.h \
+                        libutil.h \
+                        pty.h \
+                )
+        fi
+fi
+
+CF_FUNC_POLL
+CF_SIGWINCH
+
 LUIT_CFLAGS="$LUIT_CFLAGS $OS_CFLAGS"
 AC_SUBST(LUIT_CFLAGS)
 AC_SUBST(LUIT_LIBS)
diff --git a/iso2022.c b/iso2022.c
index ac2f5dd..1e551d5 100644
--- a/iso2022.c
+++ b/iso2022.c
@@ -19,7 +19,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
-/* $XFree86: xc/programs/luit/iso2022.c,v 1.8 2002/10/17 01:06:09 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -29,11 +32,9 @@ THE SOFTWARE.
 #include <sys/types.h>
 #include <unistd.h>
 #include <errno.h>
-#include <X11/fonts/fontenc.h>
 #include "luit.h"
 #include "sys.h"
 #include "other.h"
-#include "charset.h"
 #include "iso2022.h"
 
 #define BUFFERED_INPUT_SIZE 4
@@ -41,17 +42,17 @@ static unsigned char buffered_input[BUFFERED_INPUT_SIZE];
 static int buffered_input_count = 0;
 
 static void
-FatalError(char *f, ...)
+FatalError(const char *f,...)
 {
     va_list args;
     va_start(args, f);
     vfprintf(stderr, f, args);
     va_end(args);
-    exit(1);
+    ExitProgram(1);
 }
 
 static void
-ErrorF(char *f, ...)
+ErrorF(const char *f,...)
 {
     va_list args;
     va_start(args, f);
@@ -63,20 +64,19 @@ ErrorF(char *f, ...)
 #define OUTBUF_MAKE_FREE(is, fd, count) \
     if(!OUTBUF_FREE((is), (count))) outbuf_flush((is), (fd))
 
-
 static void
 outbuf_flush(Iso2022Ptr is, int fd)
 {
     int rc;
-    int i = 0;
+    unsigned i = 0;
 
     if(olog >= 0)
-        write(olog, is->outbuf, is->outbuf_count);
+	IGNORE_RC(write(olog, is->outbuf, is->outbuf_count));
 
     while(i < is->outbuf_count) {
-        rc = write(fd, is->outbuf + i, is->outbuf_count - i);
+	rc = (int) write(fd, is->outbuf + i, is->outbuf_count - i);
         if(rc > 0) {
-            i += rc;
+	    i += (unsigned) rc;
         } else {
             if(rc < 0 && errno == EINTR)
                 continue;
@@ -94,7 +94,7 @@ static void
 outbufOne(Iso2022Ptr is, int fd, unsigned c)
 {
     OUTBUF_MAKE_FREE(is, fd, 1);
-    is->outbuf[is->outbuf_count++] = c;
+    is->outbuf[is->outbuf_count++] = UChar(c);
 }
 
 /* Discards null codepoints */
@@ -106,27 +106,27 @@ outbufUTF8(Iso2022Ptr is, int fd, unsigned c)
 
     if(c <= 0x7F) {
         OUTBUF_MAKE_FREE(is, fd, 1);
-        is->outbuf[is->outbuf_count++] = c;
+	is->outbuf[is->outbuf_count++] = UChar(c);
     } else if(c <= 0x7FF) {
         OUTBUF_MAKE_FREE(is, fd, 2);
-        is->outbuf[is->outbuf_count++] = 0xC0 | ((c >> 6) & 0x1F);
-        is->outbuf[is->outbuf_count++] = 0x80 | (c & 0x3F);
+	is->outbuf[is->outbuf_count++] = UChar(0xC0 | ((c >> 6) & 0x1F));
+	is->outbuf[is->outbuf_count++] = UChar(0x80 | (c & 0x3F));
     } else {
         OUTBUF_MAKE_FREE(is, fd, 3);
-        is->outbuf[is->outbuf_count++] = 0xE0 | ((c >> 12) & 0x0F);
-        is->outbuf[is->outbuf_count++] = 0x80 | ((c >> 6) & 0x3F);
-        is->outbuf[is->outbuf_count++] = 0x80 | (c & 0x3F);
+	is->outbuf[is->outbuf_count++] = UChar(0xE0 | ((c >> 12) & 0x0F));
+	is->outbuf[is->outbuf_count++] = UChar(0x80 | ((c >> 6) & 0x3F));
+	is->outbuf[is->outbuf_count++] = UChar(0x80 | (c & 0x3F));
     }
 }
 
 static void
-buffer(Iso2022Ptr is, char c)
+buffer(Iso2022Ptr is, unsigned c)
 {
     if(is->buffered == NULL) {
-        is->buffered = malloc(10);
+	is->buffered_len = 10;
+	is->buffered = malloc(is->buffered_len);
         if(is->buffered == NULL)
             FatalError("Couldn't allocate buffered.\n");
-        is->buffered_len = 10;
     }
 
     if(is->buffered_count >= is->buffered_len) {
@@ -137,14 +137,14 @@ buffer(Iso2022Ptr is, char c)
         is->buffered_len = 2 * is->buffered_len + 1;
     }
 
-    is->buffered[is->buffered_count++] = c;
+    is->buffered[is->buffered_count++] = UChar(c);
 }
 
 static void
 outbuf_buffered_carefully(Iso2022Ptr is, int fd)
 {
     /* This should never happen in practice */
-    int i = 0;
+    unsigned i = 0;
 
     while(i < is->buffered_count) {
         OUTBUF_MAKE_FREE(is, fd, 1);
@@ -193,7 +193,7 @@ allocIso2022(void)
 
     is->buffered_ku = -1;
 
-    is->outbuf = malloc(BUFFER_SIZE);
+    is->outbuf = malloc((size_t) BUFFER_SIZE);
     if(!is->outbuf) {
         free(is);
         return NULL;
@@ -214,18 +214,20 @@ destroyIso2022(Iso2022Ptr is)
 }
 
 static int
-identifyCharset(Iso2022Ptr i, CharsetPtr *p)
+identifyCharset(Iso2022Ptr i, const CharsetRec * *p)
 {
-    if(p == &G0(i))
+    if (p == &G0(i)) {
         return 0;
-    else if(p == &G1(i))
+    } else if (p == &G1(i)) {
         return 1;
-    else if(p == &G2(i))
+    } else if (p == &G2(i)) {
         return 2;
-    else if(p == &G3(i))
+    } else if (p == &G3(i)) {
         return 3;
-    else
+    } else {
         abort();
+	/* NOTREACHED */
+    }
 }
 
 void
@@ -244,10 +246,14 @@ reportIso2022(Iso2022Ptr i)
 }
 
 int
-initIso2022(char *locale, char *charset, Iso2022Ptr i)
+initIso2022(const char *locale, const char *charset, Iso2022Ptr i)
 {
     int gl = 0, gr = 2;
-    CharsetPtr g0 = NULL, g1 = NULL, g2 = NULL, g3 = NULL, other = NULL;
+    const CharsetRec *g0 = NULL;
+    const CharsetRec *g1 = NULL;
+    const CharsetRec *g2 = NULL;
+    const CharsetRec *g3 = NULL;
+    const CharsetRec *other = NULL;
     int rc;
     
     rc = getLocaleState(locale, charset, &gl, &gr, &g0, &g1, &g2, &g3, &other);
@@ -311,7 +317,7 @@ mergeIso2022(Iso2022Ptr d, Iso2022Ptr s)
 }
 
 static int
-utf8Count(unsigned char c)
+utf8Count(unsigned c)
 {
     /* All return values must be less than BUFFERED_INPUT_SIZE */
     if((c & 0x80) == 0)
@@ -338,14 +344,14 @@ fromUtf8(unsigned char *b)
     else if((b[0] & 0x60) == 0x40)
         return ((b[0] & 0x1F) << 6) | (b[1] & 0x3F);
     else if((b[0] & 0x70) == 0x60)
-        return ((b[0] & 0x0F) << 12)
-            | ((b[1] & 0x3F) << 6)
-            | (b[2] & 0x3F);
+	return (((b[0] & 0x0F) << 12) |
+		((b[1] & 0x3F) << 6) |
+		((b[2] & 0x3F)));
     else if((b[0] & 0x78) == 0x70)
-        return ((b[0] & 0x03) << 18)
-            | ((b[1] & 0x3F) << 12)
-            | ((b[2] & 0x3F) << 6)
-            | ((b[3] & 0x3F));
+	return (((b[0] & 0x03) << 18) |
+		((b[1] & 0x3F) << 12) |
+		((b[2] & 0x3F) << 6) |
+		((b[3] & 0x3F)));
     else
         return -1;
 }
@@ -417,86 +423,142 @@ copyIn(Iso2022Ptr is, int fd, unsigned char *buf, int count)
 
         if(codepoint >= 0) {
             int i;
+	    unsigned ucode = (unsigned) codepoint;
             unsigned char obuf[4];
-#define WRITE_1(i) do {obuf[0]=(i); write(fd, obuf, 1);} while(0)
-#define WRITE_2(i) do \
-      {obuf[0]=((i)>>8)&0xFF; obuf[1]=(i)&0xFF; write(fd, obuf, 2);} \
-    while(0)
-#define WRITE_3(i) do \
-      {obuf[0]=((i)>>16)&0xFF; obuf[1]=((i)>>8)&0xFF; obuf[2]=(i)&0xFF; \
-       write(fd, obuf, 3);} \
-    while(0)
-#define WRITE_4(i) do \
-      {obuf[0]=((i)>>24)&0xFF; obuf[1]=((i)>>16)&0xFF; obuf[2]=((i)>>8)&0xFF; \
-       obuf[3]=(i)&0xFF; write(fd, obuf, 4);} \
-    while(0)
-#define WRITE_1_P_8bit(p, i) \
-    {obuf[0]=(p); obuf[1]=(i); write(fd, obuf, 2);}
-#define WRITE_1_P_7bit(p, i) \
-    {obuf[0]=ESC; obuf[1]=(p)-0x40; obuf[2]=(i); write(fd, obuf, 3);}
-#define WRITE_1_P(p,i) do \
-      {if(is->inputFlags & IF_EIGHTBIT) \
+
+#define WRITE_1(i) do { \
+	    obuf[0] = UChar(i); \
+	    IGNORE_RC(write(fd, obuf, (size_t) 1)); \
+	} while(0)
+#define WRITE_2(i) do { \
+	    obuf[0] = UChar(((i) >> 8) & 0xFF); \
+	    obuf[1] = UChar((i) & 0xFF); \
+	    IGNORE_RC(write(fd, obuf, (size_t) 2)); \
+	} while(0)
+
+#define WRITE_3(i) do { \
+	    obuf[0] = UChar(((i) >> 16) & 0xFF); \
+	    obuf[1] = UChar(((i) >>  8) & 0xFF); \
+	    obuf[2] = UChar((i) & 0xFF); \
+	    IGNORE_RC(write(fd, obuf, (size_t) 3)); \
+	} while(0)
+
+#define WRITE_4(i) do { \
+	    obuf[0] = UChar(((i) >> 24) & 0xFF); \
+	    obuf[1] = UChar(((i) >> 16) & 0xFF); \
+	    obuf[2] = UChar(((i) >>  8) & 0xFF); \
+	    obuf[3] = UChar((i) & 0xFF); \
+	    IGNORE_RC(write(fd, obuf, (size_t) 4)); \
+       } while(0)
+
+#define WRITE_1_P_8bit(p, i) { \
+	    obuf[0] = UChar(p); \
+	    obuf[1] = UChar(i); \
+	    IGNORE_RC(write(fd, obuf, (size_t) 2)); \
+	}
+
+#define WRITE_1_P_7bit(p, i) { \
+	    obuf[0] = ESC; \
+	    obuf[1] = UChar((p) - 0x40); \
+	    obuf[2] = UChar(i); \
+	    IGNORE_RC(write(fd, obuf, (size_t) 3)); \
+	}
+
+#define WRITE_1_P(p,i) do { \
+	if(is->inputFlags & IF_EIGHTBIT) \
          WRITE_1_P_8bit(p,i) else \
-         WRITE_1_P_7bit(p,i) } \
-    while(0)
-#define WRITE_2_P_8bit(p, i) \
-    {obuf[0]=(p); obuf[1]=((i)>>8)&0xFF; obuf[2]=(i)&0xFF; write(fd, obuf, 3);}
-#define WRITE_2_P_7bit(p, i) \
-    {obuf[0]=ESC; obuf[1]=(p)-0x40; obuf[2]=((i)>>8)&0xFF; obuf[3]=(i)&0xFF; \
-     write(fd, obuf, 4);}
-#define WRITE_2_P(p,i) do \
-      {if(is->inputFlags & IF_EIGHTBIT) \
-         WRITE_2_P_8bit(p,i) else \
-         WRITE_2_P_7bit(p,i)} \
-    while(0)
-#define WRITE_1_P_S(p,i,s) do \
-      {obuf[0]=(p); obuf[1]=(i)&0xFF; obuf[2]=(s); write(fd, obuf, 3);} \
-    while(0)
-#define WRITE_2_P_S(p,i,s) do \
-      {obuf[0]=(p); obuf[1]=(((i)>>8)&0xFF); obuf[2]=(i)&0xFF; obuf[3]=(s); \
-       write(fd, obuf, 4);} \
-    while(0)
-
-            if(codepoint < 0x20 ||
+	    WRITE_1_P_7bit(p,i) \
+	} while(0)
+
+#define WRITE_2_P_8bit(p, i) { \
+	    obuf[0] = UChar(p); \
+	    obuf[1] = UChar(((i) >> 8) & 0xFF); \
+	    obuf[2] = UChar((i) & 0xFF); \
+	    IGNORE_RC(write(fd, obuf, (size_t) 3)); \
+	}
+
+#define WRITE_2_P_7bit(p, i) { \
+	    obuf[0] = ESC; \
+	    obuf[1] = UChar((p) - 0x40); \
+	    obuf[2] = UChar(((i) >> 8) & 0xFF); \
+	    obuf[3] = UChar((i) & 0xFF); \
+	    IGNORE_RC(write(fd, obuf, (size_t) 4)); \
+	}
+
+#define WRITE_2_P(p,i) do { \
+	    if(is->inputFlags & IF_EIGHTBIT) \
+		WRITE_2_P_8bit(p,i) \
+	    else \
+		WRITE_2_P_7bit(p,i) \
+	} while(0)
+
+#define WRITE_1_P_S(p,i,s) do { \
+	    obuf[0] = UChar(p); \
+	    obuf[1] = UChar((i) & 0xFF); \
+	    obuf[2] = UChar(s); \
+	    IGNORE_RC(write(fd, obuf, (size_t) 3)); \
+	} while(0)
+
+#define WRITE_2_P_S(p,i,s) do { \
+	    obuf[0] = UChar(p); \
+	    obuf[1] = UChar(((i) >> 8) & 0xFF); \
+	    obuf[2] = UChar((i) & 0xFF); \
+	    obuf[3] = UChar(s); \
+	    IGNORE_RC(write(fd, obuf, (size_t) 4)); \
+	} while(0)
+
+	    if (ucode < 0x20 ||
                (OTHER(is) == NULL && CHARSET_REGULAR(GR(is)) &&
-                (codepoint >= 0x80 && codepoint < 0xA0))) {
-                WRITE_1(codepoint);
+		 (ucode >= 0x80 && ucode < 0xA0))) {
+		WRITE_1(ucode);
                 continue;
             }
             if(OTHER(is) != NULL) {
-                unsigned int c;
-                c = OTHER(is)->other_reverse(codepoint, OTHER(is)->other_aux);
-                if(c>>24) WRITE_4(c);
-                else if (c>>16) WRITE_3(c);
-                else if (c>>8) WRITE_2(c);
-                else if (c) WRITE_1(c);
+		unsigned int c2;
+		c2 = OTHER(is)->other_reverse(ucode, OTHER(is)->other_aux);
+		if (c2 >> 24)
+		    WRITE_4(c2);
+		else if (c2 >> 16)
+		    WRITE_3(c2);
+		else if (c2 >> 8)
+		    WRITE_2(c2);
+		else if (c2)
+		    WRITE_1(c2);
                 continue;
             }
-            i = (GL(is)->reverse)(codepoint, GL(is));
+	    i = (GL(is)->reverse) (ucode, GL(is));
             if(i >= 0) {
                 switch(GL(is)->type) {
-                case T_94: case T_96: case T_128:
+		case T_94:
+		case T_96:
+		case T_128:
                     if(i >= 0x20)
                         WRITE_1(i);
                     break;
-                case T_9494: case T_9696: case T_94192:
+		case T_9494:
+		case T_9696:
+		case T_94192:
                     if(i >= 0x2020)
                         WRITE_2(i);
                     break;
                 default:
                     abort();
+		    /* NOTREACHED */
                 }
                 continue;
             }
             if(is->inputFlags & IF_EIGHTBIT) {
-                i = GR(is)->reverse(codepoint, GR(is));
+		i = GR(is)->reverse(ucode, GR(is));
                 if(i >= 0) {
                     switch(GR(is)->type) {
-                    case T_94: case T_96: case T_128:
+		    case T_94:
+		    case T_96:
+		    case T_128:
                         /* we allow C1 characters if T_128 in GR */
                         WRITE_1(i | 0x80);
                         break;
-                    case T_9494: case T_9696:
+		    case T_9494:
+		    case T_9696:
                         WRITE_2(i | 0x8080);
                         break;
                     case T_94192:
@@ -504,15 +566,18 @@ copyIn(Iso2022Ptr is, int fd, unsigned char *buf, int count)
                         break;
                     default:
                         abort();
+			/* NOTREACHED */
                     }
                     continue;
                 }
             }
             if(is->inputFlags & IF_SS) {
-                i = G2(is)->reverse(codepoint, G2(is));
+		i = G2(is)->reverse(ucode, G2(is));
                 if(i >= 0) {
                     switch(GR(is)->type) {
-                    case T_94: case T_96: case T_128:
+		    case T_94:
+		    case T_96:
+		    case T_128:
                         if(i >= 0x20) {
                             if((is->inputFlags & IF_EIGHTBIT) &&
                                (is->inputFlags & IF_SSGR))
@@ -520,7 +585,8 @@ copyIn(Iso2022Ptr is, int fd, unsigned char *buf, int count)
                             WRITE_1_P(SS2, i);
                         }
                         break;
-                    case T_9494: case T_9696:
+		    case T_9494:
+		    case T_9696:
                         if(i >= 0x2020) {
                             if((is->inputFlags & IF_EIGHTBIT) &&
                                (is->inputFlags & IF_SSGR))
@@ -538,14 +604,17 @@ copyIn(Iso2022Ptr is, int fd, unsigned char *buf, int count)
                         break;
                     default:
                         abort();
+			/* NOTREACHED */
                     }
                     continue;
                 }
             }
             if(is->inputFlags & IF_SS) {
-                i = G3(is)->reverse(codepoint, G3(is));
+		i = G3(is)->reverse(ucode, G3(is));
                     switch(GR(is)->type) {
-                    case T_94: case T_96: case T_128:
+		case T_94:
+		case T_96:
+		case T_128:
                         if(i >= 0x20) {
                             if((is->inputFlags & IF_EIGHTBIT) &&
                                (is->inputFlags & IF_SSGR))
@@ -553,7 +622,8 @@ copyIn(Iso2022Ptr is, int fd, unsigned char *buf, int count)
                             WRITE_1_P(SS3, i);
                         }
                         break;
-                    case T_9494: case T_9696:
+		case T_9494:
+		case T_9696:
                         if(i >= 0x2020) {
                             if((is->inputFlags & IF_EIGHTBIT) &&
                                (is->inputFlags & IF_SSGR))
@@ -571,17 +641,21 @@ copyIn(Iso2022Ptr is, int fd, unsigned char *buf, int count)
                         break;
                     default:
                         abort();
+		    /* NOTREACHED */
                     }
                     continue;
             }
             if(is->inputFlags & IF_LS)  {
-                i = GR(is)->reverse(codepoint, GR(is));
+		i = GR(is)->reverse(ucode, GR(is));
                 if(i >= 0) {
                     switch(GR(is)->type) {
-                    case T_94: case T_96: case T_128:
+		    case T_94:
+		    case T_96:
+		    case T_128:
                         WRITE_1_P_S(LS1, i, LS0);
                         break;
-                    case T_9494: case T_9696:
+		    case T_9494:
+		    case T_9696:
                         WRITE_2_P_S(LS1, i, LS0);
                         break;
                     case T_94192:
@@ -589,6 +663,7 @@ copyIn(Iso2022Ptr is, int fd, unsigned char *buf, int count)
                         break;
                     default:
                         abort();
+			/* NOTREACHED */
                     }
                     continue;
                 }
@@ -605,13 +680,15 @@ copyIn(Iso2022Ptr is, int fd, unsigned char *buf, int count)
     }
 }
 
+#define PAIR(a,b) ((unsigned) ((a) << 8) | (b))
+
 void
-copyOut(Iso2022Ptr is, int fd, unsigned char *buf, int count)
+copyOut(Iso2022Ptr is, int fd, unsigned char *buf, unsigned count)
 {
     unsigned char *s = buf;
 
     if(ilog >= 0)
-        write(ilog, buf, count);
+	IGNORE_RC(write(ilog, buf, (size_t) count));
 
     while(s < buf + count) {
         switch(is->parserState) {
@@ -624,14 +701,19 @@ copyOut(Iso2022Ptr is, int fd, unsigned char *buf, int count)
                 } else if(OTHER(is) != NULL) {
                     int c = OTHER(is)->other_stack(*s, OTHER(is)->other_aux);
                     if(c >= 0) {
-                        outbufUTF8(is, fd, OTHER(is)->other_recode(c, OTHER(is)->other_aux));
+			unsigned ucode = (unsigned) c;
+			outbufUTF8(is, fd,
+				   OTHER(is)->other_recode(ucode, OTHER(is)->other_aux));
                         is->shiftState = S_NORMAL;
                     }
                     s++;
                 } else if(*s == CSI && CHARSET_REGULAR(GR(is))) {
                     buffer(is, *s++);
                     is->parserState = P_CSI;
-                } else if((*s == SS2 || *s == SS3 || *s == LS0 || *s == LS1) &&
+		} else if ((*s == SS2 ||
+			    *s == SS3 ||
+			    *s == LS0 ||
+			    *s == LS1) &&
                           CHARSET_REGULAR(GR(is))) {
                     buffer(is, *s++);
                     terminate(is, fd);
@@ -641,24 +723,40 @@ copyOut(Iso2022Ptr is, int fd, unsigned char *buf, int count)
                     outbufOne(is, fd, *s);
                     s++;
                 } else {
-                    CharsetPtr charset;
+		    const CharsetRec *charset;
                     unsigned char code = 0;
                     if(*s <= 0x7F) {
                         switch(is->shiftState) {
-                        case S_NORMAL: charset = GL(is); break;
-                        case S_SS2: charset = G2(is); break;
-                        case S_SS3: charset = G3(is); break;
-                        default: abort();
+			case S_NORMAL:
+			    charset = GL(is);
+			    break;
+			case S_SS2:
+			    charset = G2(is);
+			    break;
+			case S_SS3:
+			    charset = G3(is);
+			    break;
+			default:
+			    abort();
+			    /* NOTREACHED */
                         }
                         code = *s;
                     } else {
                         switch(is->shiftState) {
-                        case S_NORMAL: charset = GR(is); break;
-                        case S_SS2: charset = G2(is); break;
-                        case S_SS3: charset = G3(is); break;
-                        default: abort();
+			case S_NORMAL:
+			    charset = GR(is);
+			    break;
+			case S_SS2:
+			    charset = G2(is);
+			    break;
+			case S_SS3:
+			    charset = G3(is);
+			    break;
+			default:
+			    abort();
+			    /* NOTREACHED */
                         }
-                        code = *s - 0x80;
+			code = UChar(*s - 0x80);
                     }
 
                     switch(charset->type) {
@@ -690,41 +788,57 @@ copyOut(Iso2022Ptr is, int fd, unsigned char *buf, int count)
                     }
                 }
             } else {        /* buffered_ku */
-                CharsetPtr charset;
+		const CharsetRec *charset;
                 unsigned char ku_code;
                 unsigned code = 0;
                 if(is->buffered_ku <= 0x7F) {
                     switch(is->shiftState) {
-                    case S_NORMAL: charset = GL(is); break;
-                    case S_SS2: charset = G2(is); break;
-                    case S_SS3: charset = G3(is); break;
-                    default: abort();
+		    case S_NORMAL:
+			charset = GL(is);
+			break;
+		    case S_SS2:
+			charset = G2(is);
+			break;
+		    case S_SS3:
+			charset = G3(is);
+			break;
+		    default:
+			abort();
+			/* NOTREACHED */
                     }
-                    ku_code = is->buffered_ku;
+		    ku_code = UChar(is->buffered_ku);
                     if(*s < 0x80)
                         code = *s;
                 } else {
                     switch(is->shiftState) {
-                    case S_NORMAL: charset = GR(is); break;
-                    case S_SS2: charset = G2(is); break;
-                    case S_SS3: charset = G3(is); break;
-                    default: abort();
+		    case S_NORMAL:
+			charset = GR(is);
+			break;
+		    case S_SS2:
+			charset = G2(is);
+			break;
+		    case S_SS3:
+			charset = G3(is);
+			break;
+		    default:
+			abort();
+			/* NOTREACHED */
                     }
-                    ku_code = is->buffered_ku - 0x80;
+		    ku_code = UChar(is->buffered_ku - 0x80);
                     if(*s >= 0x80)
-                        code = *s - 0x80;
+			code = UChar(*s - 0x80);
                 }
                 switch(charset->type) {
                 case T_94:
                 case T_96:
                 case T_128:
                     abort();
+		    /* NOTREACHED */
                     break;
                 case T_9494:
                     if(code >= 0x21 && code <= 0x7E) {
                         outbufUTF8(is, fd,
-                                   charset->recode(ku_code << 8 | code,
-                                                   charset));
+				   charset->recode(PAIR(ku_code, code), charset));
                         is->buffered_ku = -1;
                         is->shiftState = S_NORMAL;
                     } else {
@@ -737,8 +851,7 @@ copyOut(Iso2022Ptr is, int fd, unsigned char *buf, int count)
                 case T_9696:
                     if(code >= 0x20) {
                         outbufUTF8(is, fd,
-                                   charset->recode(ku_code << 8 | code,
-                                                   charset));
+				   charset->recode(PAIR(ku_code, code), charset));
                         is->buffered_ku = -1;
                         is->shiftState = S_NORMAL;
                     } else {
@@ -752,9 +865,9 @@ copyOut(Iso2022Ptr is, int fd, unsigned char *buf, int count)
                     /* Use *s, not code */
                     if(((*s >= 0x21) && (*s <= 0x7E)) ||
                        ((*s >= 0xA1) && (*s <= 0xFE))) {
+			unsigned ucode = PAIR(ku_code, *s);
                         outbufUTF8(is, fd,
-                                   charset->recode(ku_code << 8 | *s,
-                                                   charset));
+				   charset->recode(ucode, charset));
                         is->buffered_ku = -1;
                         is->shiftState = S_NORMAL;
                     } else {
@@ -766,6 +879,7 @@ copyOut(Iso2022Ptr is, int fd, unsigned char *buf, int count)
                     break;
                 default:
                     abort();
+		    /* NOTREACHED */
                 }
             }
             break;
@@ -793,12 +907,14 @@ copyOut(Iso2022Ptr is, int fd, unsigned char *buf, int count)
             break;
         default:
             abort();
+	    /* NOTREACHED */
         }
     }
     outbuf_flush(is, fd);
 }
 
-void terminate(Iso2022Ptr is, int fd)
+void
+terminate(Iso2022Ptr is, int fd)
 {
     if(is->outputFlags & OF_PASSTHRU) {
         outbuf_buffered(is, fd);
@@ -865,7 +981,10 @@ void terminate(Iso2022Ptr is, int fd)
             discard_buffered(is);
             return;
         default:
-            terminateEsc(is, fd, is->buffered + 1, is->buffered_count - 1);
+	    terminateEsc(is, fd,
+			 is->buffered + 1,
+			 (unsigned) (is->buffered_count - 1));
+	    break;
         }
         return;
     default:
@@ -874,9 +993,9 @@ void terminate(Iso2022Ptr is, int fd)
 }
 
 void
-terminateEsc(Iso2022Ptr is, int fd, unsigned char *s_start, int count)
+terminateEsc(Iso2022Ptr is, int fd, unsigned char *s_start, unsigned count)
 {
-    CharsetPtr charset;
+    const CharsetRec *charset;
 
     /* ISO 2022 doesn't allow 2C, but Emacs/MULE uses it in 7-bit
        mode */
@@ -892,10 +1011,22 @@ terminateEsc(Iso2022Ptr is, int fd, unsigned char *s_start, int count)
             else
                 charset = getCharset(s_start[1], T_96);
             switch(s_start[0]) {
-            case 0x28: case 0x2C: G0(is) = charset; break;
-            case 0x29: case 0x2D: G1(is) = charset; break;
-            case 0x2A: case 0x2E: G2(is) = charset; break;
-            case 0x2B: case 0x2F: G3(is) = charset; break;
+	    case 0x28:
+	    case 0x2C:
+		G0(is) = charset;
+		break;
+	    case 0x29:
+	    case 0x2D:
+		G1(is) = charset;
+		break;
+	    case 0x2A:
+	    case 0x2E:
+		G2(is) = charset;
+		break;
+	    case 0x2B:
+	    case 0x2F:
+		G3(is) = charset;
+		break;
             }
         }
         discard_buffered(is);
@@ -917,13 +1048,31 @@ terminateEsc(Iso2022Ptr is, int fd, unsigned char *s_start, int count)
             else
                 charset = getCharset(s_start[2], T_9696);
             switch(s_start[1]) {
-            case 0x28:            G0(is) = charset; break;
-            case 0x29: case 0x2D: G1(is) = charset; break;
-            case 0x2A: case 0x2E: G2(is) = charset; break;
-            case 0x2B: case 0x2F: G3(is) = charset; break;
+	    case 0x28:
+		G0(is) = charset;
+		break;
+	    case 0x29:
+	    case 0x2D:
+		G1(is) = charset;
+		break;
+	    case 0x2A:
+	    case 0x2E:
+		G2(is) = charset;
+		break;
+	    case 0x2B:
+	    case 0x2F:
+		G3(is) = charset;
+		break;
             }
         }
         discard_buffered(is);
     } else
         outbuf_buffered(is, fd);
 }
+
+#ifdef NO_LEAKS
+void
+iso2022_leaks(void)
+{
+}
+#endif
diff --git a/iso2022.h b/iso2022.h
index 33097df..844cfdd 100644
--- a/iso2022.h
+++ b/iso2022.h
@@ -19,7 +19,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
-/* $XFree86: xc/programs/luit/iso2022.h,v 1.4 2002/07/01 02:25:59 tsi Exp $ */
+
+#ifndef LUIT_ISO2022_H
+#define LUIT_ISO2022_H 1
+
+#include "charset.h"
 
 #define ESC 0x1B
 #define CSI 0x9B
@@ -58,19 +62,20 @@ THE SOFTWARE.
 #define OF_PASSTHRU 8
 
 typedef struct _Iso2022 {
-    CharsetPtr *glp, *grp;
-    CharsetPtr g[4];
-    CharsetPtr other;
+    const CharsetRec **glp;
+    const CharsetRec **grp;
+    const CharsetRec *g[4];
+    const CharsetRec *other;
     int parserState;
     int shiftState;
     int inputFlags;
     int outputFlags;
     unsigned char *buffered;
-    int buffered_len;
-    int buffered_count;
+    size_t buffered_len;
+    size_t buffered_count;
     int buffered_ku;
     unsigned char *outbuf;
-    int outbuf_count;
+    size_t outbuf_count;
 } Iso2022Rec, *Iso2022Ptr;
 
 #define GL(i) (*(i)->glp)
@@ -85,10 +90,12 @@ typedef struct _Iso2022 {
 
 Iso2022Ptr allocIso2022(void);
 void destroyIso2022(Iso2022Ptr);
-int initIso2022(char *, char *, Iso2022Ptr);
+int initIso2022(const char *, const char *, Iso2022Ptr);
 int mergeIso2022(Iso2022Ptr, Iso2022Ptr);
 void reportIso2022(Iso2022Ptr);
 void terminate(Iso2022Ptr, int);
-void terminateEsc(Iso2022Ptr, int, unsigned char*, int);
+void terminateEsc(Iso2022Ptr, int, unsigned char *, unsigned);
 void copyIn(Iso2022Ptr, int, unsigned char*, int);
-void copyOut(Iso2022Ptr, int, unsigned char*, int);
+void copyOut(Iso2022Ptr, int, unsigned char *, unsigned);
+
+#endif /* LUIT_ISO2022_H */
diff --git a/luit.c b/luit.c
index 7fa7acf..6bd8775 100644
--- a/luit.c
+++ b/luit.c
@@ -19,7 +19,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
-/* $XFree86: xc/programs/luit/luit.c,v 1.9 2002/10/17 01:06:09 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -34,30 +37,28 @@ THE SOFTWARE.
 #include <sys/ioctl.h>
 #include <signal.h>
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#ifdef HAVE_STROPTS_H
-# include <stropts.h>
-#endif
-
-#include <X11/fonts/fontenc.h>
 #include "luit.h"
 #include "sys.h"
 #include "other.h"
-#include "charset.h"
+#include "parser.h"
 #include "iso2022.h"
 
+static int pipe_option = 0;
+static int p2c_waitpipe[2];
+static int c2p_waitpipe[2];
+
 static Iso2022Ptr inputState = NULL, outputState = NULL;
 
 static char *child_argv0 = NULL;
-static char *locale_name = NULL;
+static const char *locale_name = NULL;
+static int exitOnChild = 0;
+static int converter = 0;
+
+const char *locale_alias = LOCALE_ALIAS_FILE;
+
 int ilog = -1;
 int olog = -1;
 int verbose = 0;
-static int converter = 0;
-static int exitOnChild = 0;
 
 static volatile int sigwinch_queued = 0;
 static volatile int sigchld_queued = 0;
@@ -66,7 +67,7 @@ static int convert(int, int);
 static int condom(int, char**);
 
 static void
-ErrorF(char *f, ...)
+ErrorF(const char *f,...)
 {
     va_list args;
     va_start(args, f);
@@ -75,22 +76,21 @@ ErrorF(char *f, ...)
 }
 
 static void
-FatalError(char *f, ...)
+FatalError(const char *f,...)
 {
     va_list args;
     va_start(args, f);
     vfprintf(stderr, f, args);
     va_end(args);
-    exit(1);
+    ExitProgram(1);
 }
 
-
 static void
 help(void)
 {
     fprintf(stderr, 
             "luit\n"
-            "  [ -h ] [ -list ] [ -v ] [ -argv0 name ]\n"
+	    "  [ -V ] [ -h ] [ -list ] [ -v ] [ -argv0 name ]\n"
             "  [ -gl gn ] [-gr gk] "
             "[ -g0 set ] [ -g1 set ] "
             "[ -g2 set ] [ -g3 set ]\n"
@@ -100,12 +100,16 @@ help(void)
             "[ -kg0 set ] [ -kg1 set ] "
             "[ -kg2 set ] [ -kg3 set ]\n"
             "  [ -k7 ] [ +kss ] [ +kssgr ] [ -kls ]\n"
-            "  [ -c ] [ -x ] [ -ilog filename ] [ -olog filename ] [ -- ]\n"
+	    "  [ -c ] "
+	    "[ -p ] "
+	    "[ -x ] "
+	    "[ -ilog filename ] "
+	    "[ -olog filename ] "
+	    "[ -alias filename ] "
+	    "[ -- ]\n"
             "  [ program [ args ] ]\n");
-
 }
             
-
 static int
 parseOptions(int argc, char **argv)
 {
@@ -119,12 +123,15 @@ parseOptions(int argc, char **argv)
         } else if(!strcmp(argv[i], "-v")) {
             verbose++;
             i++;
+	} else if (!strcmp(argv[i], "-V")) {
+	    printf("%s - %s\n", argv[0], VERSION);
+	    ExitProgram(0);
         } else if(!strcmp(argv[i], "-h")) {
             help();
-            exit(0);
+	    ExitProgram(0);
         } else if(!strcmp(argv[i], "-list")) {
             reportCharsets();
-            exit(0);
+	    ExitProgram(0);
         } else if(!strcmp(argv[i], "+oss")) {
             outputState->outputFlags &= ~OF_SS;
             i++;
@@ -272,7 +279,7 @@ parseOptions(int argc, char **argv)
             ilog = open(argv[i + 1], O_WRONLY | O_CREAT | O_TRUNC, 0777);
             if(ilog < 0) {
                 perror("Couldn't open input log");
-                exit(1);
+		ExitProgram(1);
             }
             i += 2;
         } else if(!strcmp(argv[i], "-olog")) {
@@ -281,17 +288,22 @@ parseOptions(int argc, char **argv)
             olog = open(argv[i + 1], O_WRONLY | O_CREAT | O_TRUNC, 0777);
             if(olog < 0) {
                 perror("Couldn't open output log");
-                exit(1);
+		ExitProgram(1);
             }
             i += 2;
+	} else if (!strcmp(argv[i], "-alias")) {
+	    if (i + 1 >= argc)
+		FatalError("-alias requires an argument\n");
+	    locale_alias = argv[i + 1];
+	    i += 2;
         } else if(!strcmp(argv[i], "-encoding")) {
-            int rc;
             if(i + 1 >= argc)
                 FatalError("-encoding requires an argument\n");
-            rc = initIso2022(NULL, argv[i + 1], outputState);
-            if(rc < 0)
-                FatalError("Couldn't init output state\n");
+	    locale_name = argv[i + 1];
             i += 2;
+	} else if (!strcmp(argv[i], "-p")) {
+	    pipe_option = 1;
+	    i += 1;
         } else {
             FatalError("Unknown option %s\n", argv[i]);
         }
@@ -300,8 +312,10 @@ parseOptions(int argc, char **argv)
 }
 
 static int
-parseArgs(int argc, char **argv, char *argv0,
-          char **path_return, char ***argv_return)
+parseArgs(int argc, char **argv,
+	  char *argv0,
+	  char **path_return,
+	  char ***argv_return)
 {
     char *path = NULL;
     char **child_argv = NULL;
@@ -310,12 +324,14 @@ parseArgs(int argc, char **argv, char *argv0,
         char *shell;
         shell = getenv("SHELL");
         if(shell) {
-            path = strdup(shell);
+	    path = strmalloc(shell);
+	    if (!path)
+		goto bail;
         } else {
-            path = strdup("/bin/sh");
-        }
+	    path = strmalloc("/bin/sh");
         if(!path)
             goto bail;
+	}
         child_argv = malloc(2 * sizeof(char*));
         if(!child_argv)
             goto bail;
@@ -325,10 +341,10 @@ parseArgs(int argc, char **argv, char *argv0,
             child_argv[0] = my_basename(path);
         child_argv[1] = NULL;
     } else {
-        path = strdup(argv[0]);
+	path = strmalloc(argv[0]);
         if(!path)
             goto bail;
-        child_argv = malloc((argc + 1) * sizeof(char*));
+	child_argv = malloc((unsigned) (argc + 1) * sizeof(char *));
         if(!child_argv) {
             goto bail;
         }
@@ -336,7 +352,7 @@ parseArgs(int argc, char **argv, char *argv0,
             child_argv[0] = argv0;
         else
             child_argv[0] = my_basename(argv[0]);
-        memcpy(child_argv + 1, argv + 1, (argc - 1) * sizeof(char*));
+	memcpy(child_argv + 1, argv + 1, (unsigned) (argc - 1) * sizeof(char *));
         child_argv[argc] = NULL;
     }
 
@@ -352,7 +368,6 @@ parseArgs(int argc, char **argv, char *argv0,
     return -1;
 }
         
-
 int
 main(int argc, char **argv)
 {
@@ -360,6 +375,11 @@ main(int argc, char **argv)
     int i;
     char *l;
 
+#ifdef HAVE_PUTENV
+    if ((l = strmalloc("NCURSES_NO_UTF8_ACS=1")) != 0)
+	putenv(l);
+#endif
+
     l = setlocale(LC_ALL, "");
     if(!l)
         ErrorF("Warning: couldn't set locale.\n");
@@ -389,22 +409,27 @@ main(int argc, char **argv)
         locale_name = "C";
     }
 
-    rc = initIso2022(locale_name, NULL, outputState);
-    if(rc < 0)
-        FatalError("Couldn't init output state\n");
-
     i = parseOptions(argc, argv);
     if(i < 0)
         FatalError("Couldn't parse options\n");
 
+    rc = initIso2022(locale_name, NULL, outputState);
+    if (rc < 0)
+	FatalError("Couldn't init output state\n");
+
     rc = mergeIso2022(inputState, outputState);
     if(rc < 0)
         FatalError("Couldn't init input state\n");
 
     if(converter)
-        return convert(0, 1);
+	rc = convert(0, 1);
     else
-        return condom(argc - i, argv + i);
+	rc = condom(argc - i, argv + i);
+
+#ifdef NO_LEAKS
+    ExitProgram(rc);
+#endif
+    return rc;
 }
 
 static int
@@ -415,65 +440,44 @@ convert(int ifd, int ofd)
 
     rc = droppriv();
     if(rc < 0) {
-        perror("Couldn't drop priviledges");
-        exit(1);
+	perror("Couldn't drop privileges");
+	ExitProgram(1);
     }
 
     while(1) {
-        i = read(ifd, buf, BUFFER_SIZE);
+	i = (int) read(ifd, buf, (size_t) BUFFER_SIZE);
         if(i <= 0) {
             if(i < 0) {
                 perror("Read error");
-                exit(1);
+		ExitProgram(1);
             }
             break;
         }
-        copyOut(outputState, ofd, buf, i);
+	copyOut(outputState, ofd, buf, (unsigned) i);
     }
     return 0;
 }
         
+#ifdef SIGWINCH
 static void
-sigwinchHandler(int sig)
+sigwinchHandler(int sig GCC_UNUSED)
 {
     sigwinch_queued = 1;
 }
+#endif
 
 static void
-sigchldHandler(int sig)
+sigchldHandler(int sig GCC_UNUSED)
 {
     sigchld_queued = 1;
 }
 
 static int
-condom(int argc, char **argv)
+setup_io(int pty)
 {
-    int pty;
-    int pid;
-    char *line;
-    char *path;
-    char **child_argv;
     int rc;
     int val;
 
-    path = NULL;
-    child_argv = NULL;
-    rc = parseArgs(argc, argv, child_argv0,
-                   &path, &child_argv);
-    if(rc < 0)
-        FatalError("Couldn't parse arguments\n");
-
-    rc = allocatePty(&pty, &line);
-    if(rc < 0) {
-        perror("Couldn't allocate pty");
-        exit(1);
-    }
-
-    rc = droppriv();
-    if(rc < 0) {
-        perror("Couldn't drop priviledges");
-        exit(1);
-    }
 #ifdef SIGWINCH
     installHandler(SIGWINCH, sigwinchHandler);
 #endif
@@ -498,20 +502,97 @@ condom(int argc, char **argv)
 
     setWindowSize(0, pty);
 
+    return rc;
+}
+
+static void
+cleanup_io(int pty)
+{
+    int val;
+
+#ifdef SIGWINCH
+    installHandler(SIGWINCH, SIG_DFL);
+#endif
+    installHandler(SIGCHLD, SIG_DFL);
+
+    val = fcntl(0, F_GETFL, 0);
+    if (val >= 0) {
+	fcntl(0, F_SETFL, val & ~O_NONBLOCK);
+    }
+    val = fcntl(pty, F_GETFL, 0);
+    if (val >= 0) {
+	fcntl(pty, F_SETFL, val & ~O_NONBLOCK);
+    }
+}
+
+static void
+close_waitpipe(int which)
+{
+    close(p2c_waitpipe[which]);
+    close(c2p_waitpipe[!which]);
+}
+
+static void
+write_waitpipe(int fds[2])
+{
+    IGNORE_RC(write(fds[1], "1", (size_t) 1));
+}
+
+static void
+read_waitpipe(int fds[2])
+{
+    char tmp[10];
+    IGNORE_RC(read(fds[0], tmp, (size_t) 1));
+}
+
+static int
+condom(int argc, char **argv)
+{
+    int pty;
+    int pid;
+    char *line;
+    char *path = 0;
+    char **child_argv = 0;
+    int rc;
+
+    rc = parseArgs(argc, argv, child_argv0,
+		   &path, &child_argv);
+    if (rc < 0)
+	FatalError("Couldn't parse arguments\n");
+
+    rc = allocatePty(&pty, &line);
+    if (rc < 0) {
+	perror("Couldn't allocate pty");
+	ExitProgram(1);
+    }
+
+    rc = droppriv();
+    if (rc < 0) {
+	perror("Couldn't drop privileges");
+	ExitProgram(1);
+    }
+
+    if (pipe_option) {
+	IGNORE_RC(pipe(p2c_waitpipe));
+	IGNORE_RC(pipe(c2p_waitpipe));
+    }
+
     pid = fork();
     if(pid < 0) {
         perror("Couldn't fork");
-        exit(1);
+	ExitProgram(1);
     }
 
     if(pid == 0) {
         close(pty);
-#ifdef SIGWINCH
-        installHandler(SIGWINCH, SIG_DFL);
-#endif
-        installHandler(SIGCHLD, SIG_DFL);
+	if (pipe_option) {
+	    close_waitpipe(1);
+	}
         child(line, path, child_argv);
     } else {
+	if (pipe_option) {
+	    close_waitpipe(0);
+	}
         free(child_argv);
         free(path);
         free(line);
@@ -522,7 +603,7 @@ condom(int argc, char **argv)
 }
 
 void
-child(char *line, char *path, char **argv)
+child(char *line, char *path, char *const argv[])
 {
     int tty;
     int pgrp;
@@ -534,13 +615,16 @@ child(char *line, char *path, char **argv)
     pgrp = setsid();
     if(pgrp < 0) {
         kill(getppid(), SIGABRT);
-        exit(1);
+	ExitProgram(1);
     }
 
     tty = openTty(line);
     if(tty < 0) {
         kill(getppid(), SIGABRT);
-        exit(1);
+	ExitProgram(1);
+    }
+    if (pipe_option) {
+	write_waitpipe(c2p_waitpipe);
     }
     
     if(tty != 0)
@@ -553,21 +637,36 @@ child(char *line, char *path, char **argv)
     if(tty > 2)
         close(tty);
     
+    if (pipe_option) {
+	read_waitpipe(p2c_waitpipe);
+	close_waitpipe(0);
+    }
+
     execvp(path, argv);
     perror("Couldn't exec");
-    exit(1);
+    ExitProgram(1);
 }
 
 void
-parent(int pid, int pty)
+parent(int pid GCC_UNUSED, int pty)
 {
     unsigned char buf[BUFFER_SIZE];
     int i;
     int rc;
 
+    if (pipe_option) {
+	read_waitpipe(c2p_waitpipe);
+    }
+
     if(verbose) {
         reportIso2022(outputState);
     }
+    setup_io(pty);
+
+    if (pipe_option) {
+	write_waitpipe(p2c_waitpipe);
+	close_waitpipe(1);
+    }
 
     for(;;) {
         rc = waitForInput(0, pty);
@@ -582,14 +681,14 @@ parent(int pid, int pty)
 
         if(rc > 0) {
             if(rc & 2) {
-                i = read(pty, buf, BUFFER_SIZE);
+		i = (int) read(pty, buf, (size_t) BUFFER_SIZE);
                 if((i == 0) || ((i < 0) && (errno != EAGAIN)))
                     break;
                 if(i > 0)
-                    copyOut(outputState, 0, buf, i);
+		    copyOut(outputState, 0, buf, (unsigned) i);
             }
             if(rc & 1) {
-                i = read(0, buf, BUFFER_SIZE);
+		i = (int) read(0, buf, (size_t) BUFFER_SIZE);
                 if((i == 0) || ((i < 0) && (errno != EAGAIN)))
                     break;
                 if(i > 0)
@@ -599,4 +698,14 @@ parent(int pid, int pty)
     }
 
     restoreTermios();
+    cleanup_io(pty);
+}
+
+#ifdef NO_LEAKS
+void
+luit_leaks(void)
+{
+    destroyIso2022(inputState);
+    destroyIso2022(outputState);
 }
+#endif
diff --git a/luit.h b/luit.h
index 695751e..39be5d2 100644
--- a/luit.h
+++ b/luit.h
@@ -20,12 +20,17 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
 
+#ifndef LUIT_LUIT_H
+#define LUIT_LUIT_H 1
+
+extern const char *locale_alias;
 extern int iso2022;
 extern int verbose;
 extern int sevenbit;
 extern int ilog;
 extern int olog;
 
-void child(char*, char*, char**);
+void child(char *, char *, char *const *);
 void parent(int, int);
 
+#endif /* LUIT_LUIT_H */
diff --git a/luit.man b/luit.man
index 9610c30..c31269a 100644
--- a/luit.man
+++ b/luit.man
@@ -1,4 +1,12 @@
-.\" $XFree86: xc/programs/luit/luit.man,v 1.7 2003/02/24 01:10:25 dawes Exp $
+.\"
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds AQ \(aq
+.el       .ds AQ '
+.ie \n(.g .ds `` \(lq
+.el       .ds `` ``
+.ie \n(.g .ds '' \(rq
+.el       .ds '' ''
 .TH LUIT 1 __vendorversion__
 .SH NAME
 luit \- Locale and ISO\ 2022 support for Unicode terminals
@@ -38,12 +46,19 @@ Display some summary help and quit.
 .B \-list
 List the supported charsets and encodings, then quit.
 .TP
+.B \-V
+Print luit's version and quit.
+.TP
 .B \-v
 Be verbose.
 .TP
 .B \-c
 Function as a simple converter from standard input to standard output.
 .TP
+.B \-p
+In startup, establish a handshake between parent and child processes.
+This is needed for some systems, e.g., FreeBSD.
+.TP
 .B \-x
 Exit as soon as the child dies.  This may cause
 .B luit
@@ -132,6 +147,11 @@ Log into
 .I filename
 all the bytes sent to the terminal emulator.
 .TP
+.BI \-alias " filename"
+the locale alias file
+.br
+(default: __locale_alias__).
+.TP
 .B \-\-
 End of options.
 .SH EXAMPLES
@@ -177,18 +197,15 @@ M-x set-terminal-coding-system RET iso-2022-8bit-ss2 RET
 .PP
 .SH FILES
 .TP
-.B __projectroot__/lib/X11/fonts/encodings/encodings.dir
-The system-wide encodings directory.
-.TP
-.B __localealiasfile__
+.B __locale_alias__
 The file mapping locales to locale encodings.
 .SH SECURITY
-On systems with SVR4 (``Unix-98'') ptys (Linux version 2.2 and later,
+On systems with SVR4 (\*(``Unix-98\*('') ptys (Linux version 2.2 and later,
 SVR4),
 .B luit
 should be run as the invoking user.
 
-On systems without SVR4 (``Unix-98'') ptys (notably BSD variants),
+On systems without SVR4 (\*(``Unix-98\*('') ptys (notably BSD variants),
 running
 .B luit
 as an ordinary user will leave the tty world-writable; this is a
@@ -213,12 +230,17 @@ Charsets with a non-trivial intermediary byte are not yet supported.
 Selecting alternate sets of control characters is not supported and
 will never be.
 .SH SEE ALSO
-xterm(1), unicode(7), utf-8(7), charsets(7).
+xterm(__mansuffix__), unicode(7), utf-8(7), charsets(7).
+.nf
+.br
 .I Character Code Structure and Extension Techniques (ISO\ 2022, ECMA-35).
+.br
 .I Control Functions for Coded Character Sets (ISO\ 6429, ECMA-48).
+.fi
 .SH AUTHOR
 The version of
 .B Luit
 included in this X.Org Foundation release
 was originally written by Juliusz Chroboczek <jch at freedesktop.org>
-for the XFree86 Project.
+for the XFree86 Project and includes additional contributions from
+Thomas E. Dickey required for newer releases of xterm(__mansuffix__).
diff --git a/other.c b/other.c
index 99ca8c1..f70a78d 100644
--- a/other.c
+++ b/other.c
@@ -19,15 +19,16 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
-/* $XFree86: xc/programs/luit/other.c,v 1.1 2002/10/17 01:06:09 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
-#include <X11/fonts/fontenc.h>
 #include "other.h"
-#include "charset.h"
 
 #ifndef NULL
 #define NULL 0
@@ -40,10 +41,12 @@ init_gbk(OtherStatePtr s)
 {
     s->gbk.mapping =
         FontEncMapFind("gbk-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
-    if(!s->gbk.mapping) return 0;
+    if (!s->gbk.mapping)
+	return 0;
 
     s->gbk.reverse = FontMapReverse(s->gbk.mapping);
-    if(!s->gbk.reverse) return 0;
+    if (!s->gbk.reverse)
+	return 0;
 
     s->gbk.buf = -1;
     return 1;
@@ -53,8 +56,10 @@ unsigned int
 mapping_gbk(unsigned int n, OtherStatePtr s)
 {
     unsigned int r;
-    if(n < 128) return n;
-    if(n == 128) return EURO_10646;
+    if (n < 128)
+	return n;
+    if (n == 128)
+	return EURO_10646;
     r = FontEncRecode(n, s->gbk.mapping);
     return r;
 }
@@ -62,26 +67,29 @@ mapping_gbk(unsigned int n, OtherStatePtr s)
 unsigned int
 reverse_gbk(unsigned int n, OtherStatePtr s)
 {
-    if(n < 128) return n;
-    if(n == EURO_10646) return 128;
+    if (n < 128)
+	return n;
+    if (n == EURO_10646)
+	return 128;
     return s->gbk.reverse->reverse(n, s->gbk.reverse->data);
 }
 
 int
-stack_gbk(unsigned char c, OtherStatePtr s)
+stack_gbk(unsigned c, OtherStatePtr s)
 {
     if(s->gbk.buf < 0) {
-        if(c < 129) return c;
-        s->gbk.buf = c;
+	if (c < 129)
+	    return (int) c;
+	s->gbk.buf = (int) c;
 	return -1;
     } else {
         int b;
         if(c < 0x40 || c == 0x7F) {
             s->gbk.buf = -1;
-            return c;
+	    return (int) c;
         }
         if(s->gbk.buf < 0xFF && c < 0xFF)
-            b = (s->gbk.buf << 8) + c;
+	    b = (int) ((unsigned) (s->gbk.buf << 8) + c);
         else
             b = -1;
         s->gbk.buf = -1;
@@ -97,13 +105,13 @@ init_utf8(OtherStatePtr s)
 }
 
 unsigned int
-mapping_utf8(unsigned int n, OtherStatePtr s)
+mapping_utf8(unsigned int n, OtherStatePtr s GCC_UNUSED)
 {
     return n;
 }
 
 unsigned int
-reverse_utf8(unsigned int n, OtherStatePtr s)
+reverse_utf8(unsigned int n, OtherStatePtr s GCC_UNUSED)
 {
     if(n < 0x80)
         return n;
@@ -116,53 +124,67 @@ reverse_utf8(unsigned int n, OtherStatePtr s)
 }
 
 int
-stack_utf8(unsigned char c, OtherStatePtr s)
+stack_utf8(unsigned c, OtherStatePtr s)
 {
     int u;
 
     if(c < 0x80) {
         s->utf8.buf_ptr = 0;
-        return c;
+	return (int) c;
     }
     if(s->utf8.buf_ptr == 0) {
-        if((c & 0x40) == 0) return -1;
-        s->utf8.buf[s->utf8.buf_ptr++] = c;
-        if((c & 0x60) == 0x40) s->utf8.len = 2;
-        else if((c & 0x70) == 0x60) s->utf8.len = 3;
-        else if((c & 0x78) == 0x70) s->utf8.len = 4;
-        else s->utf8.buf_ptr = 0;
+	if ((c & 0x40) == 0)
+	    return -1;
+	s->utf8.buf[s->utf8.buf_ptr++] = UChar(c);
+	if ((c & 0x60) == 0x40)
+	    s->utf8.len = 2;
+	else if ((c & 0x70) == 0x60)
+	    s->utf8.len = 3;
+	else if ((c & 0x78) == 0x70)
+	    s->utf8.len = 4;
+	else
+	    s->utf8.buf_ptr = 0;
         return -1;
     }
     if((c & 0x40) != 0) {
         s->utf8.buf_ptr = 0;
         return -1;
     }
-    s->utf8.buf[s->utf8.buf_ptr++] = c;
-    if(s->utf8.buf_ptr < s->utf8.len) return -1;
+    s->utf8.buf[s->utf8.buf_ptr++] = UChar(c);
+    if (s->utf8.buf_ptr < s->utf8.len)
+	return -1;
     switch(s->utf8.len) {
     case 2:
         u = ((s->utf8.buf[0] & 0x1F) << 6) | (s->utf8.buf[1] & 0x3F);
         s->utf8.buf_ptr = 0;
-        if(u < 0x80) return -1; else return u;
+	if (u < 0x80)
+	    return -1;
+	else
+	    return u;
     case 3:
         u = ((s->utf8.buf[0] & 0x0F) << 12)
             | ((s->utf8.buf[1] & 0x3F) << 6)
             | (s->utf8.buf[2] & 0x3F);
         s->utf8.buf_ptr = 0;
-        if(u < 0x800) return -1; else return u;
+	if (u < 0x800)
+	    return -1;
+	else
+	    return u;
     case 4:
         u = ((s->utf8.buf[0] & 0x03) << 18)
             | ((s->utf8.buf[1] & 0x3F) << 12)
             | ((s->utf8.buf[2] & 0x3F) << 6)
             | ((s->utf8.buf[3] & 0x3F));
         s->utf8.buf_ptr = 0;
-        if(u < 0x10000) return -1; else return u;
+	if (u < 0x10000)
+	    return -1;
+	else
+	    return u;
     }
     s->utf8.buf_ptr = 0;
     return -1;
 }
 
-
 #define HALFWIDTH_10646 0xFF61
 #define YEN_SJIS 0x5C
 #define YEN_10646 0x00A5
@@ -174,17 +196,21 @@ init_sjis(OtherStatePtr s)
 {
     s->sjis.x0208mapping =
         FontEncMapFind("jisx0208.1990-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
-    if(!s->sjis.x0208mapping) return 0;
+    if (!s->sjis.x0208mapping)
+	return 0;
 
     s->sjis.x0208reverse = FontMapReverse(s->sjis.x0208mapping);
-    if(!s->sjis.x0208reverse) return 0;
+    if (!s->sjis.x0208reverse)
+	return 0;
 
     s->sjis.x0201mapping =
         FontEncMapFind("jisx0201.1976-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
-    if(!s->sjis.x0201mapping) return 0;
+    if (!s->sjis.x0201mapping)
+	return 0;
 
     s->sjis.x0201reverse = FontMapReverse(s->sjis.x0201mapping);
-    if(!s->sjis.x0201reverse) return 0;
+    if (!s->sjis.x0201reverse)
+	return 0;
 
     s->sjis.buf = -1;
     return 1;
@@ -194,14 +220,23 @@ unsigned int
 mapping_sjis(unsigned int n, OtherStatePtr s)
 {
     unsigned int j1, j2, s1, s2;
-    if(n == YEN_SJIS) return YEN_10646;
-    if(n == OVERLINE_SJIS) return OVERLINE_10646;
-    if(n < 0x80) return n;
-    if(n >= 0xA0 && n <= 0xDF) return FontEncRecode(n, s->sjis.x0201mapping);
+    if (n == YEN_SJIS)
+	return YEN_10646;
+    if (n == OVERLINE_SJIS)
+	return OVERLINE_10646;
+    if (n < 0x80)
+	return n;
+    if (n >= 0xA0 && n <= 0xDF)
+	return FontEncRecode(n, s->sjis.x0201mapping);
     s1 = ((n>>8)&0xFF);
     s2 = (n&0xFF);
-    j1 = (s1 << 1) - (s1 <= 0x9F ? 0xE0 : 0x160) - (s2 < 0x9F ? 1 : 0);
-    j2 = s2 - 0x1F - (s2 >= 0x7F ? 1 : 0) - (s2 >= 0x9F ? 0x5E : 0);
+    j1 = (s1 << 1)
+	- (unsigned) (s1 <= 0x9F ? 0xE0 : 0x160)
+	- (unsigned) (s2 < 0x9F ? 1 : 0);
+    j2 = s2
+	- 0x1F
+	- (unsigned) (s2 >= 0x7F ? 1 : 0)
+	- (unsigned) (s2 >= 0x9F ? 0x5E : 0);
     return FontEncRecode((j1<<8) + j2, s->sjis.x0208mapping);
 }
 
@@ -209,34 +244,40 @@ unsigned int
 reverse_sjis(unsigned int n, OtherStatePtr s)
 {
     unsigned int j, j1, j2, s1, s2;
-    if(n == YEN_10646) return YEN_SJIS;
-    if(n == OVERLINE_10646) return OVERLINE_SJIS;
-    if(n < 0x80) return n;
+    if (n == YEN_10646)
+	return YEN_SJIS;
+    if (n == OVERLINE_10646)
+	return OVERLINE_SJIS;
+    if (n < 0x80)
+	return n;
     if(n >= HALFWIDTH_10646)
         return s->sjis.x0201reverse->reverse(n, s->sjis.x0201reverse->data);
     j = s->sjis.x0208reverse->reverse(n, s->sjis.x0208reverse->data);
     j1 = ((j>>8)&0xFF);
     j2 = (j&0xFF);
-    s1 = ((j1 - 1) >> 1) + ((j1 <= 0x5E) ? 0x71 : 0xB1);
-    s2 = j2 + ((j1 & 1) ? ((j2 < 0x60) ? 0x1F : 0x20) : 0x7E);
+    s1 = ((j1 - 1) >> 1)
+	+ (unsigned) ((j1 <= 0x5E) ? 0x71 : 0xB1);
+    s2 = j2
+	+ (unsigned) ((j1 & 1) ? ((j2 < 0x60) ? 0x1F : 0x20) : 0x7E);
     return (s1<<8) + s2;
 }
 
 int
-stack_sjis(unsigned char c, OtherStatePtr s)
+stack_sjis(unsigned c, OtherStatePtr s)
 {
     if(s->sjis.buf < 0) {
-        if(c < 128 || (c >= 0xA0 && c <= 0xDF)) return c;
-        s->sjis.buf = c;
+	if (c < 128 || (c >= 0xA0 && c <= 0xDF))
+	    return (int) c;
+	s->sjis.buf = (int) c;
 	return -1;
     } else {
         int b;
         if(c < 0x40 || c == 0x7F) {
             s->sjis.buf = -1;
-            return c;
+	    return (int) c;
         }
         if(s->sjis.buf < 0xFF && c < 0xFF)
-            b = (s->sjis.buf << 8) + c;
+	    b = (int) ((unsigned) (s->sjis.buf << 8) + c);
         else
             b = -1;
         s->sjis.buf = -1;
@@ -249,10 +290,12 @@ init_hkscs(OtherStatePtr s)
 {
     s->hkscs.mapping =
         FontEncMapFind("big5hkscs-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
-    if(!s->hkscs.mapping) return 0;
+    if (!s->hkscs.mapping)
+	return 0;
 
     s->hkscs.reverse = FontMapReverse(s->hkscs.mapping);
-    if(!s->hkscs.reverse) return 0;
+    if (!s->hkscs.reverse)
+	return 0;
 
     s->hkscs.buf = -1;
     return 1;
@@ -262,8 +305,10 @@ unsigned int
 mapping_hkscs(unsigned int n, OtherStatePtr s)
 {
     unsigned int r;
-    if(n < 128) return n;
-    if(n == 128) return EURO_10646;
+    if (n < 128)
+	return n;
+    if (n == 128)
+	return EURO_10646;
     r = FontEncRecode(n, s->hkscs.mapping);
     return r;
 }
@@ -271,26 +316,29 @@ mapping_hkscs(unsigned int n, OtherStatePtr s)
 unsigned int
 reverse_hkscs(unsigned int n, OtherStatePtr s)
 {
-    if(n < 128) return n;
-    if(n == EURO_10646) return 128;
+    if (n < 128)
+	return n;
+    if (n == EURO_10646)
+	return 128;
     return s->hkscs.reverse->reverse(n, s->hkscs.reverse->data);
 }
 
 int
-stack_hkscs(unsigned char c, OtherStatePtr s)
+stack_hkscs(unsigned c, OtherStatePtr s)
 {
     if(s->hkscs.buf < 0) {
-        if(c < 129) return c;
-        s->hkscs.buf = c;
+	if (c < 129)
+	    return (int) c;
+	s->hkscs.buf = (int) c;
 	return -1;
     } else {
         int b;
         if(c < 0x40 || c == 0x7F) {
             s->hkscs.buf = -1;
-            return c;
+	    return (int) c;
         }
         if(s->hkscs.buf < 0xFF && c < 0xFF)
-            b = (s->hkscs.buf << 8) + c;
+	    b = (int) ((unsigned) (s->hkscs.buf << 8) + c);
         else
             b = -1;
         s->hkscs.buf = -1;
@@ -298,7 +346,6 @@ stack_hkscs(unsigned char c, OtherStatePtr s)
     }
 }
 
-
 /*
  *  Because of the 1 ~ 4 multi-bytes nature of GB18030.
  *  CharSet encoding is split to 2 subset (besides latin)
@@ -320,17 +367,21 @@ init_gb18030(OtherStatePtr s)
 {
     s->gb18030.cs0_mapping =
         FontEncMapFind("gb18030.2000-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
-    if(!s->gb18030.cs0_mapping) return 0;
+    if (!s->gb18030.cs0_mapping)
+	return 0;
 
     s->gb18030.cs0_reverse = FontMapReverse(s->gb18030.cs0_mapping);
-    if(!s->gb18030.cs0_reverse) return 0;
+    if (!s->gb18030.cs0_reverse)
+	return 0;
 
     s->gb18030.cs1_mapping =
         FontEncMapFind("gb18030.2000-1", FONT_ENCODING_UNICODE, -1, -1, NULL);
-    if(!s->gb18030.cs1_mapping) return 0;
+    if (!s->gb18030.cs1_mapping)
+	return 0;
 
     s->gb18030.cs1_reverse = FontMapReverse(s->gb18030.cs1_mapping);
-    if(!s->gb18030.cs1_reverse) return 0;
+    if (!s->gb18030.cs1_reverse)
+	return 0;
 
     s->gb18030.linear  = 0;
     s->gb18030.buf_ptr = 0;
@@ -340,8 +391,10 @@ init_gb18030(OtherStatePtr s)
 unsigned int
 mapping_gb18030(unsigned int n, OtherStatePtr s)
 {
-    if(n <= 0x80)   return n;       /* 0x80 is valid but unassigned codepoint */
-    if(n >= 0xFFFF) return '?';
+    if (n <= 0x80)
+	return n;		/* 0x80 is valid but unassigned codepoint */
+    if (n >= 0xFFFF)
+	return '?';
     
     return FontEncRecode(n,
             (s->gb18030.linear)?s->gb18030.cs1_mapping:s->gb18030.cs0_mapping);
@@ -353,7 +406,8 @@ reverse_gb18030(unsigned int n, OtherStatePtr s)
     /* when lookup in 2000-0 failed. */
     /* lookup in 2000-1 and then try to unlinear'd */
     unsigned int r;
-    if(n <= 0x80) return n;
+    if (n <= 0x80)
+	return n;
 
     r = s->gb18030.cs0_reverse->reverse(n, s->gb18030.cs0_reverse->data);
     if (r != 0)
@@ -363,10 +417,13 @@ reverse_gb18030(unsigned int n, OtherStatePtr s)
     if (r != 0) {
         unsigned char bytes[4];
 
-        bytes[3] = 0x30 + r % 10;   r /= 10;
-        bytes[2] = 0x81 + r % 126;  r /= 126;
-        bytes[1] = 0x30 + r % 10;   r /= 10;
-        bytes[0] = 0x81 + r;
+	bytes[3] = UChar(0x30 + r % 10);
+	r /= 10;
+	bytes[2] = UChar(0x81 + r % 126);
+	r /= 126;
+	bytes[1] = UChar(0x30 + r % 10);
+	r /= 10;
+	bytes[0] = UChar(0x81 + r);
 
         r  = (unsigned int)bytes[0] << 24;
         r |= (unsigned int)bytes[1] << 16;
@@ -377,14 +434,16 @@ reverse_gb18030(unsigned int n, OtherStatePtr s)
 }
 
 int
-stack_gb18030(unsigned char c, OtherStatePtr s)
+stack_gb18030(unsigned c, OtherStatePtr s)
 {
     /* if set gb18030.linear => True. the return value is "linear'd" */
     if(s->gb18030.buf_ptr == 0) {
-        if(c <= 0x80) return c;
-        if (c == 0xFF) return -1;
+	if (c <= 0x80)
+	    return (int) c;
+	if (c == 0xFF)
+	    return -1;
         s->gb18030.linear = 0;
-        s->gb18030.buf[s->gb18030.buf_ptr++] = c;
+	s->gb18030.buf[s->gb18030.buf_ptr++] = (int) c;
         return -1;
     } else if (s->gb18030.buf_ptr == 1) {
         if (c >= 0x40) {
@@ -392,21 +451,21 @@ stack_gb18030(unsigned char c, OtherStatePtr s)
             if ((c == 0x80) || (c == 0xFF))
                 return -1;
             else
-                return (s->gb18030.buf[0] << 8) + c;
+		return (int) ((unsigned) (s->gb18030.buf[0] << 8) + c);
         } else if (c >= 30) {   /* 2Byte is (0x30 -> 0x39) */
-            s->gb18030.buf[s->gb18030.buf_ptr++] = c;
+	    s->gb18030.buf[s->gb18030.buf_ptr++] = (int) c;
             return -1;
         } else {
             s->gb18030.buf_ptr = 0;
-            return c;
+	    return (int) c;
         }
     } else if (s->gb18030.buf_ptr == 2) {
         if ((c >= 0x81) && (c <= 0xFE)) {
-            s->gb18030.buf[s->gb18030.buf_ptr++] = c;
+	    s->gb18030.buf[s->gb18030.buf_ptr++] = (int) c;
             return -1;
         } else {
             s->gb18030.buf_ptr = 0;
-            return c;
+	    return (int) c;
         }
     } else {
         int r = 0;
@@ -416,10 +475,9 @@ stack_gb18030(unsigned char c, OtherStatePtr s)
             r = (((s->gb18030.buf[0] - 0x81) * 10
                         + (s->gb18030.buf[1] - 0x30)) * 126
                     + (s->gb18030.buf[2] - 0x81)) * 10
-                + (c - 0x30);
+		+ ((int) c - 0x30);
             return r;
         }
         return -1;
     }
 }
-
diff --git a/other.h b/other.h
index 8cb3a4d..9d814a3 100644
--- a/other.h
+++ b/other.h
@@ -19,7 +19,19 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
-/* $XFree86: xc/programs/luit/other.h,v 1.1 2002/10/17 01:06:09 dawes Exp $ */
+
+#ifndef LUIT_OTHER_H
+#define LUIT_OTHER_H 1
+
+#include "config.h"		/* include this, for self-contained headers */
+
+#ifndef GCC_UNUSED
+#define GCC_UNUSED		/* ARGSUSED */
+#endif
+
+#include <X11/fonts/fontenc.h>
+
+#define UChar(n) ((unsigned char)(n))
 
 typedef struct {
     FontMapPtr mapping;
@@ -69,25 +81,26 @@ typedef union {
 int init_gbk(OtherStatePtr);
 unsigned int mapping_gbk(unsigned int, OtherStatePtr);
 unsigned int reverse_gbk(unsigned int, OtherStatePtr);
-int stack_gbk(unsigned char, OtherStatePtr);
+int stack_gbk(unsigned, OtherStatePtr);
 
 int init_utf8(OtherStatePtr);
 unsigned int mapping_utf8(unsigned int, OtherStatePtr);
 unsigned int reverse_utf8(unsigned int, OtherStatePtr);
-int stack_utf8(unsigned char, OtherStatePtr);
+int stack_utf8(unsigned, OtherStatePtr);
 
 int init_sjis(OtherStatePtr);
 unsigned int mapping_sjis(unsigned int, OtherStatePtr);
 unsigned int reverse_sjis(unsigned int, OtherStatePtr);
-int stack_sjis(unsigned char, OtherStatePtr);
+int stack_sjis(unsigned, OtherStatePtr);
 
 int init_hkscs(OtherStatePtr);
 unsigned int mapping_hkscs(unsigned int, OtherStatePtr);
 unsigned int reverse_hkscs(unsigned int, OtherStatePtr);
-int stack_hkscs(unsigned char, OtherStatePtr);
+int stack_hkscs(unsigned, OtherStatePtr);
 
 int init_gb18030(OtherStatePtr);
 unsigned int mapping_gb18030(unsigned int, OtherStatePtr);
 unsigned int reverse_gb18030(unsigned int, OtherStatePtr);
-int stack_gb18030(unsigned char, OtherStatePtr);
+int stack_gb18030(unsigned, OtherStatePtr);
 
+#endif /* LUIT_OTHER_H */
diff --git a/parser.c b/parser.c
index 0c8023f..7e0e90b 100644
--- a/parser.c
+++ b/parser.c
@@ -19,13 +19,18 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
-/* $XFree86$ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 
+#include "luit.h"
 #include "parser.h"
+#include "sys.h"
 
 static char keyword[MAX_KEYWORD_LENGTH];
 
@@ -76,7 +81,7 @@ getString(FILE *f, int string_end, int *c_return)
             if(c == '\n')
                 continue;
         }
-        keyword[i++] = c;
+	keyword[i++] = (char) c;
         if(i >= MAX_KEYWORD_LENGTH)
             return TOK_ERROR;
         c = getc(f);
@@ -117,7 +122,7 @@ getToken(FILE *f, int c, int parse_assignments, int *c_return)
             if(c == '\n')
                 continue;
         }
-        keyword[i++] = c;
+	keyword[i++] = (char) c;
         if(i >= MAX_KEYWORD_LENGTH)
             return TOK_ERROR;
         c = getc(f);
@@ -130,7 +135,6 @@ getToken(FILE *f, int c, int parse_assignments, int *c_return)
     return TOK_KEYWORD;
 }
 
-
 /* Can parse both the old and new formats for locale.alias */
 static int
 parseTwoTokenLine(FILE *f, char *first, char *second)
@@ -146,7 +150,7 @@ parseTwoTokenLine(FILE *f, char *first, char *second)
     else if(tok == TOK_EOL)
         goto again;
     else if(tok == TOK_KEYWORD) {
-        int len = strlen(keyword);
+	size_t len = strlen(keyword);
         if(keyword[len - 1] == ':')
             keyword[len - 1] = '\0';
         strcpy(first, keyword);
@@ -173,37 +177,32 @@ resolveLocale(const char *locale)
     char first[MAX_KEYWORD_LENGTH], second[MAX_KEYWORD_LENGTH];
     char *resolved = NULL;
     int rc;
+    int found = 0;
 
-    f = fopen(LOCALE_ALIAS_FILE, "r");
-    if(f == NULL)
-        goto bail;
+    f = fopen(locale_alias, "r");
 
+    if (f != NULL) {
     do {
         rc = parseTwoTokenLine(f, first, second);
         if(rc < -1)
-            goto bail;
+		break;
         if(!strcmp(first, locale)) {
-            resolved = strdup(second);
-            if(resolved == NULL)
-                goto bail;
+		resolved = strmalloc(second);
+		found = 1;
             break;
         }
     } while(rc >= 0);
 
+	if (!found) {
     if(resolved == NULL) {
-        resolved = strdup(locale);
-        if(resolved == NULL)
-            goto bail;
+		resolved = strmalloc(locale);
+	    }
     }
 
     fclose(f);
+    } else {
+	perror(locale_alias);
+    }
 
     return resolved;
-
-  bail:
-    if(f != NULL)
-        fclose(f);
-    if(resolved != NULL)
-        free(resolved);
-    return NULL;
 }
diff --git a/parser.h b/parser.h
index 14b614c..5521de3 100644
--- a/parser.h
+++ b/parser.h
@@ -20,6 +20,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
 
+#ifndef LUIT_PARSER_H
+#define LUIT_PARSER_H 1
+
 #ifndef LOCALE_ALIAS_FILE
 #define LOCALE_ALIAS_FILE "/usr/X11R6/lib/X11/locale/locale.alias"
 #endif
@@ -33,3 +36,5 @@ THE SOFTWARE.
 #define TOK_KEYWORD 2
 
 char *resolveLocale(const char *locale);
+
+#endif /* LUIT_PARSER_H */
diff --git a/sys.c b/sys.c
index e22b69d..aca656a 100644
--- a/sys.c
+++ b/sys.c
@@ -19,7 +19,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
-/* $XFree86: xc/programs/luit/sys.c,v 1.9 2003/08/17 20:39:58 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
 #include <stdlib.h>
 #include <string.h>
@@ -34,18 +37,26 @@ THE SOFTWARE.
 #include <signal.h>
 #include <errno.h>
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#ifdef HAVE_POLL
+#ifdef HAVE_WORKING_POLL
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#else
 #include <sys/poll.h>
+#endif
 #undef HAVE_SELECT
 #endif
 
-#ifdef HAVE_SYS_SELECT_H
+#ifdef HAVE_SELECT
+#if !(defined(_MINIX) || defined(__BEOS__))
+#define HAVE_WORKING_SELECT 1
+#endif
+#endif
+
+#ifdef HAVE_WORKING_SELECT
+#if defined(HAVE_SYS_SELECT_H) && defined(HAVE_SYS_TIME_SELECT)
 # include <sys/select.h>
 #endif
+#endif
 
 #ifdef HAVE_PTY_H
 # include <pty.h>
@@ -55,20 +66,39 @@ THE SOFTWARE.
 # include <stropts.h>
 #endif
 
-#ifdef HAVE_SYS_PARAM_H
+#ifdef HAVE_SYS_PARAM
 # include <sys/param.h>
 #endif
 
+#ifdef HAVE_OPENPTY
+#if defined(HAVE_UTIL_H)
+#include <util.h>
+#elif defined(HAVE_LIBUTIL_H)
+#include <libutil.h>
+#elif defined(HAVE_PTY_H)
+#include <pty.h>
+#endif
+#endif /* HAVE_OPENPTY */
+
 #include "sys.h"
 
+#ifdef USE_IGNORE_RC
+int ignore_unused;
+#endif
+
+#if defined(HAVE_OPENPTY)
+static int opened_tty = -1;
+#endif
+
 static int saved_tio_valid = 0;
 static struct termios saved_tio;
 
-
-#ifdef HAVE_POLL
 int
 waitForOutput(int fd)
 {
+    int ret = 0;
+
+#if defined(HAVE_WORKING_POLL)
     struct pollfd pfd[1];
     int rc;
 
@@ -78,19 +108,37 @@ waitForOutput(int fd)
 
     rc = poll(pfd, 1, -1);
     if(rc < 0)
-        return -1;
+	ret = -1;
+    else if (pfd[0].revents & (POLLOUT | POLLERR | POLLHUP))
+	ret = 1;
 
-    if(pfd[0].revents & POLLOUT)
-        return 1;
+#elif defined(HAVE_WORKING_SELECT)
+    fd_set fds;
+    int rc;
 
-    return 0;
+    FD_ZERO(&fds);
+    FD_SET(fd, &fds);
+    rc = select(FD_SETSIZE, NULL, &fds, NULL, NULL);
+    if (rc < 0)
+	ret = -1;
+    else if (FD_ISSET(fd, &fds))
+	ret = 1;
+
+#else
+    ret = 1;
+#endif
+
+    return ret;
 }
 
 int
 waitForInput(int fd1, int fd2)
 {
+    int ret = 0;
+
+#if defined(HAVE_WORKING_POLL)
     struct pollfd pfd[2];
-    int ret, rc;
+    int rc;
 
     pfd[0].fd = fd1;
     pfd[1].fd = fd2;
@@ -98,78 +146,39 @@ waitForInput(int fd1, int fd2)
     pfd[0].revents = pfd[1].revents = 0;
 
     rc = poll(pfd, 2, -1);
-    if(rc < 0)
-        return -1;
-
-    ret = 0;
+    if (rc < 0) {
+	ret = -1;
+    } else {
     if(pfd[0].revents & (POLLIN | POLLERR | POLLHUP))
         ret |= 1;
     if(pfd[1].revents & (POLLIN | POLLERR | POLLHUP))
         ret |= 2;
-    return ret;
 }
-#endif
 
-#ifdef HAVE_SELECT
-int
-waitForOutput(int fd)
-{
+#elif defined(HAVE_WORKING_SELECT)
     fd_set fds;
     int rc;
 
     FD_ZERO(&fds);
-    FD_SET(fd, &fds);
-    rc = select(FD_SETSIZE, NULL, &fds, NULL, NULL);
-    if(rc < 0)
-        return -1;
-
-    if(FD_ISSET(fd, &fds))
-        return 1;
-
-    return 0;
-}
-
-int
-waitForInput(int fd1, int fd2)
-{
-    fd_set fds;
-    int ret, rc;
-
-    FD_ZERO(&fds);
     FD_SET(fd1, &fds);
     FD_SET(fd2, &fds);
     rc = select(FD_SETSIZE, &fds, NULL, NULL, NULL);
-    if(rc < 0)
-        return -1;
-
-    ret = 0;
+    if (rc < 0) {
+	ret = -1;
+    } else {
     if(FD_ISSET(fd1, &fds))
         ret |= 1;
     if(FD_ISSET(fd2, &fds))
         ret |= 2;
-    return ret;
 }
+#else
+    ret = (1 | 2);
 #endif
 
-#ifndef HAVE_POLL
-#ifndef HAVE_SELECT
-/* Busy looping implementation */
-int
-waitForOutput(int fd)
-{
-    return 1;
+    return ret;
 }
 
 int
-waitForInput(int fd1, int fd2)
-{
-    return 1|2;
-}
-#endif
-#endif
-
-
-int
 setWindowSize(int sfd, int dfd)
 {
 #ifdef TIOCGWINSZ
@@ -247,16 +256,16 @@ setRawTermios(void)
     rc = tcgetattr(0, &tio);
     if(rc < 0)
         return rc;
-    tio.c_lflag &= ~(ECHO|ICANON|ISIG);
-    tio.c_iflag &= ~(ICRNL|IXOFF|IXON|ISTRIP);
+    tio.c_lflag &= (unsigned) ~(ECHO | ICANON | ISIG);
+    tio.c_iflag &= (unsigned) ~(ICRNL | IXOFF | IXON | ISTRIP);
 #ifdef ONLCR
-    tio.c_oflag &= ~ONLCR;
+    tio.c_oflag &= (unsigned) ~ONLCR;
 #endif
 #ifdef OCRNL
-    tio.c_oflag &= ~OCRNL;
+    tio.c_oflag &= (unsigned) ~OCRNL;
 #endif
 #ifdef ONOCR
-    tio.c_oflag &= ~ONOCR;
+    tio.c_oflag &= (unsigned) ~ONOCR;
 #endif
 
 #ifdef VMIN
@@ -269,7 +278,6 @@ setRawTermios(void)
     return 0;
 }
 
-
 char *
 my_basename(char *path)
 {
@@ -288,12 +296,11 @@ fix_pty_perms(char *line)
 {
     int rc;
     struct stat s;
-    int uid = getuid(), gid = getgid();
 
     rc = stat(line, &s);
     if(rc < 0)
         return -1;
-    if(s.st_uid != uid || s.st_gid != gid) {
+    if (s.st_uid != getuid() || s.st_gid != getgid()) {
         rc = chown(line, getuid(), getgid());
         if(rc < 0) {
             fprintf(stderr, 
@@ -319,20 +326,16 @@ allocatePty(int *pty_return, char **line_return)
 {
     char name[12], *line = NULL;
     int pty = -1;
-    char *name1 = "pqrstuvwxyzPQRST", 
-        *name2 = "0123456789abcdefghijklmnopqrstuv";
-    char *p1, *p2;
+    const char *name1 = "pqrstuvwxyzPQRST";
+    char buffer[80];
+    char *name2 = strcpy(buffer, "0123456789abcdefghijklmnopqrstuv");
+    const char *p1;
+    char *p2;
 
-#ifdef HAVE_GRANTPT
-    char *temp_line;
+#if defined(HAVE_GRANTPT)
     int rc;
 
-#ifdef __APPLE__
-    pty = posix_openpt(O_RDWR);
-#else
     pty = open("/dev/ptmx", O_RDWR);
-#endif
-
     if(pty < 0)
         goto bsd;
 
@@ -348,15 +351,32 @@ allocatePty(int *pty_return, char **line_return)
         goto bsd;
     }
 
-    temp_line = ptsname(pty);
-    if(!temp_line) {
+    line = strmalloc(ptsname(pty));
+    if (!line) {
         close(pty);
         goto bsd;
     }
-    line = strdup(temp_line);
+
+    fix_pty_perms(line);
+
+    *pty_return = pty;
+    *line_return = line;
+    return 0;
+
+  bsd:
+#elif defined(HAVE_OPENPTY)
+    int rc;
+    char ttydev[80];		/* OpenBSD says at least 16 bytes */
+
+    rc = openpty(&pty, &opened_tty, ttydev, NULL, NULL);
+    if (rc < 0) {
+	close(pty);
+	goto bsd;
+    }
+    line = strmalloc(ttydev);
     if(!line) {
         close(pty);
-        return -1;
+	goto bsd;
     }
 
     fix_pty_perms(line);
@@ -366,7 +386,7 @@ allocatePty(int *pty_return, char **line_return)
     return 0;
 
   bsd:
-#endif /* HAVE_GRANTPT */
+#endif /* HAVE_GRANTPT, etc */
 
     strcpy(name, "/dev/pty??");
     for(p1 = name1; *p1; p1++) {
@@ -385,14 +405,13 @@ allocatePty(int *pty_return, char **line_return)
     goto bail;
 
   found:
-    line = strdup(name);
-    if(!line)
-	goto bail;
+    if ((line = strmalloc(name)) != 0) {
     line[5] = 't';
     fix_pty_perms(line);
     *pty_return = pty;
     *line_return = line;
     return 0;
+    }
 
   bail:
     if(pty >= 0)
@@ -408,29 +427,42 @@ openTty(char *line)
     int rc;
     int tty = -1;
 
-#if !defined(O_NOCTTY) || !defined(TIOCSCTTY)
-    /* e.g. Cygwin has a working O_NOCTTY but no TIOCSCTTY, so the tty
-       must be opened as controlling */
-    tty = open(line, O_RDWR);
-#else
-    /* The TIOCSCTTY ioctl below will fail if the process already has a
-       controlling tty (even if the current controlling tty is the same
-       as the tty you want to make controlling).  So we need to open
-       the tty with O_NOCTTY to make sure this doesn't happen. */
-    tty = open(line, O_RDWR | O_NOCTTY);
+    tty = open(line, O_RDWR
+#if defined(TIOCSCTTY) && defined(O_NOCTTY)
+    /*
+     * Do not make this our controlling terminal, yet just in case it fails
+     * in some intermediate state.  But do not add this flag if we haven't
+     * the corresponding ioctl.
+     */
+	       | O_NOCTTY
 #endif
+	);
 
     if(tty < 0)
         goto bail;
 
+#if defined(HAVE_OPENPTY)
+    if (opened_tty >= 0) {
+	close(opened_tty);
+	opened_tty = -1;
+    }
+#endif
+
 #ifdef TIOCSCTTY
+    /*
+     * Now that we've successfully opened the terminal, make it the controlling
+     * terminal.  This call works only if the process does not already have a
+     * controlling terminal.
+     *
+     * Cygwin as of 2009/10/12 lacks this call, but has O_NOCTTY.
+     */
     rc = ioctl(tty, TIOCSCTTY, (char *)0);
     if(rc < 0) {
         goto bail;
     }
 #endif
 
-#if defined(SVR4) || defined(__SVR4)
+#if defined(I_PUSH) && (defined(SVR4) || defined(__SVR4))
     rc = ioctl(tty, I_PUSH, "ptem");
     if(rc < 0)
         goto bail;
@@ -455,48 +487,69 @@ openTty(char *line)
 /* Post-4.4 BSD systems have POSIX semantics (_POSIX_SAVED_IDS
    or not, depending on the version).  4.3BSD and Minix do not have
    saved IDs at all, so there's no issue. */
-#if (defined(BSD) && !defined(_POSIX_SAVED_IDS)) || defined(_MINIX)
 int
 droppriv(void)
 {
     int rc;
+#if (defined(BSD) && !defined(_POSIX_SAVED_IDS)) || defined(_MINIX)
     rc = setuid(getuid());
-    if(rc < 0)
-        return rc;
-    return setgid(getgid());
+    if (rc >= 0) {
+	rc = setgid(getgid());
 }
 #elif defined(_POSIX_SAVED_IDS)
-int
-droppriv(void)
-{
-    int uid = getuid();
-    int euid = geteuid();
-    int gid = getgid();
-    int egid = getegid();
-    int rc;
+    uid_t uid = getuid();
+    uid_t euid = geteuid();
+    gid_t gid = getgid();
+    gid_t egid = getegid();
 
     if((uid != euid || gid != egid) && euid != 0) {
         errno = ENOSYS;
-        return -1;
-    }
+	rc = -1;
+    } else {
     rc = setuid(uid);
-    if(rc < 0)
-        return rc;
-    return setgid(gid);
+	if (rc >= 0)
+	    rc = setgid(gid);
 }
 #else
-int
-droppriv(void)
-{
-    int uid = getuid();
-    int euid = geteuid();
-    int gid = getgid();
-    int egid = getegid();
+    uid_t uid = getuid();
+    uid_t euid = geteuid();
+    gid_t gid = getgid();
+    gid_t egid = getegid();
 
     if(uid != euid || gid != egid) {
         errno = ENOSYS;
-        return -1;
+	rc = -1;
+    } else {
+	rc = 0;
     }
-    return 0;
+#endif
+    return rc;
+}
+
+char *
+strmalloc(const char *value)
+{
+    char *result = 0;
+
+    if (value != 0) {
+#ifdef HAVE_STRDUP
+	result = strdup(value);
+#else
+	result = malloc(strlen(value) + 1);
+	if (result != 0)
+	    strcpy(result, value);
+#endif
+    }
+    return result;
+}
+
+#ifdef NO_LEAKS
+void
+ExitProgram(int code)
+{
+    luit_leaks();
+    iso2022_leaks();
+    charset_leaks();
+    exit(code);
 }
 #endif    
diff --git a/sys.h b/sys.h
index 1de48fd..5bfe0d2 100644
--- a/sys.h
+++ b/sys.h
@@ -1,4 +1,3 @@
-/* $XFree86$ */
 /*
 Copyright (c) 2001 by Juliusz Chroboczek
 
@@ -21,6 +20,17 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
 
+#ifndef LUIT_SYS_H
+#define LUIT_SYS_H 1
+
+#if defined(__GNUC__) && defined(_FORTIFY_SOURCE)
+#define USE_IGNORE_RC
+extern int ignore_unused;
+#define IGNORE_RC(func) ignore_unused = (int) func
+#else
+#define IGNORE_RC(func) (void) func
+#endif /* gcc workarounds */
+
 int waitForOutput(int fd);
 int waitForInput(int fd1, int fd2);
 int setWindowSize(int sfd, int dfd);
@@ -33,3 +43,15 @@ char *my_basename(char *path);
 int allocatePty(int *pty_return, char **line_return);
 int openTty(char *line);
 int droppriv(void);
+char *strmalloc(const char *value);
+
+#ifdef NO_LEAKS
+void luit_leaks(void);
+void charset_leaks(void);
+void iso2022_leaks(void);
+void ExitProgram(int code);
+#else
+#define ExitProgram(code) exit(code)
+#endif
+
+#endif /* LUIT_SYS_H */



More information about the xorg-devel mailing list