diff options
Diffstat (limited to 'erts/emulator/drivers/unix')
| -rw-r--r-- | erts/emulator/drivers/unix/ttsl_drv.c | 55 | ||||
| -rw-r--r-- | erts/emulator/drivers/unix/unix_efile.c | 13 | 
2 files changed, 57 insertions, 11 deletions
| diff --git a/erts/emulator/drivers/unix/ttsl_drv.c b/erts/emulator/drivers/unix/ttsl_drv.c index 8912d148a5..491e0a090e 100644 --- a/erts/emulator/drivers/unix/ttsl_drv.c +++ b/erts/emulator/drivers/unix/ttsl_drv.c @@ -42,6 +42,9 @@ static ErlDrvData ttysl_start(ErlDrvPort, char*);  #include <locale.h>  #include <unistd.h>  #include <termios.h> +#ifdef HAVE_WCWIDTH +#include <wchar.h> +#endif  #ifdef HAVE_FCNTL_H  #include <fcntl.h>  #endif @@ -95,6 +98,9 @@ static int lpos;                /* The current "cursor position" in the line buf   */  #define CONTROL_TAG 0x10000000U /* Control character, value in first position */  #define ESCAPED_TAG 0x01000000U /* Escaped character, value in first position */ +#ifdef HAVE_WCWIDTH +#define WIDE_TAG    0x02000000U /* Wide character, value in first position    */ +#endif  #define TAG_MASK    0xFF000000U  #define MAXSIZE (1 << 16) @@ -597,12 +603,20 @@ static int check_buf_size(byte *s, int n)  	}   	if (utf8_mode) { /* That is, terminal is UTF8 compliant */  	    if (ch >= 128 || isprint(ch)) { -		DEBUGLOG(("Printable(UTF-8:%d):%d",(pos - opos),ch)); -		size++; /* Buffer contains wide characters... */ +#ifdef HAVE_WCWIDTH +		int width; +#endif +		DEBUGLOG(("Printable(UTF-8:%d):%d",pos,ch)); +		size++; +#ifdef HAVE_WCWIDTH +		if ((width = wcwidth(ch)) > 1) { +		    size += width - 1; +		} +#endif  	    } else if (ch == '\t') {  		size += 8;  	    } else { -		DEBUGLOG(("Magic(UTF-8:%d):%d",(pos - opos),ch)); +		DEBUGLOG(("Magic(UTF-8:%d):%d",pos,ch));  		size += 2;  	    }  	} else { @@ -731,7 +745,7 @@ static Sint16 get_sint16(char *s)  {      return ((*s << 8) | ((byte*)s)[1]);  } - +  static int start_lbuf(void)  {      if (!lbuf && !(lbuf = ( Uint32*) driver_alloc(lbuf_size * sizeof(Uint32)))) @@ -823,7 +837,7 @@ static int del_chars(int n)  	r = llen - lpos - l;	/* Characters after deleted */  	/* Fix up buffer and buffer pointers. */  	if (r > 0) -	    memcpy(lbuf + lpos, lbuf + pos, r * sizeof(Uint32)); +	    memmove(lbuf + lpos, lbuf + pos, r * sizeof(Uint32));  	llen -= l;  	/* Write out characters after, blank the tail and jump back to lpos. */  	write_buf(lbuf + lpos, r); @@ -842,7 +856,7 @@ static int del_chars(int n)  	move_cursor(lpos, lpos-l);	/* Move back */  	/* Fix up buffer and buffer pointers. */  	if (r > 0) -	    memcpy(lbuf + pos, lbuf + lpos, r * sizeof(Uint32)); +	    memmove(lbuf + pos, lbuf + lpos, r * sizeof(Uint32));  	lpos -= l;  	llen -= l;  	/* Write out characters after, blank the tail and jump back to lpos. */ @@ -868,12 +882,22 @@ static int step_over_chars(int n)      end = lbuf + llen;      c = lbuf + lpos;      for ( ; n > 0 && c < end; --n) { +#ifdef HAVE_WCWIDTH +	while (*c & WIDE_TAG) { +	    c++; +	} +#endif  	c++;  	while (c < end && (*c & TAG_MASK) && ((*c & ~TAG_MASK) == 0))  	    c++;      }      for ( ; n < 0 && c > beg; n++) {  	--c; +#ifdef HAVE_WCWIDTH +	while (c > beg + 1 && (c[-1] & WIDE_TAG)) { +	    --c; +	} +#endif  	while (c > beg && (*c & TAG_MASK) && ((*c & ~TAG_MASK) == 0))  	    --c;      } @@ -899,6 +923,15 @@ static int insert_buf(byte *s, int n)  	    ++pos;  	}  	if ((utf8_mode && (ch >= 128 || isprint(ch))) || (ch <= 255 && isprint(ch))) { +#ifdef HAVE_WCWIDTH +	    int width; +	    if ((width = wcwidth(ch)) > 1) { +		while (--width) { +		    DEBUGLOG(("insert_buf: Wide(UTF-8):%d,%d",width,ch)); +		    lbuf[lpos++] = (WIDE_TAG | ((Uint32) ch)); +		} +	    } +#endif  	    DEBUGLOG(("insert_buf: Printable(UTF-8):%d",ch));  	    lbuf[lpos++] = (Uint32) ch;  	} else if (ch >= 128) { /* not utf8 mode */ @@ -1006,6 +1039,10 @@ static int write_buf(Uint32 *s, int n)  	    if (octbuff != octtmp) {  		driver_free(octbuff);  	    } +#ifdef HAVE_WCWIDTH +	} else if (*s & WIDE_TAG) { +	    --n; s++; +#endif  	} else {  	    DEBUGLOG(("Very unexpected character %d",(int) *s));  	    ++n; @@ -1054,7 +1091,7 @@ static int move_cursor(int from, int to)        move_left(-dc);      return TRUE;  } - +  static int start_termcap(void)  {      int eres; @@ -1150,7 +1187,7 @@ static int move_down(int n)        tputs(down, 1, outc);      return TRUE;  } -		     +  /*   * Updates cols if terminal has resized (SIGWINCH). Should be called @@ -1172,7 +1209,7 @@ static void update_cols(void)  	cols = width;      }  } -		     +  /*   * Put a terminal device into non-canonical mode with ECHO off. diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c index 558651fff9..8ffc05da99 100644 --- a/erts/emulator/drivers/unix/unix_efile.c +++ b/erts/emulator/drivers/unix/unix_efile.c @@ -1,7 +1,7 @@  /*   * %CopyrightBegin%   * - * Copyright Ericsson AB 1997-2012. All Rights Reserved. + * Copyright Ericsson AB 1997-2013. All Rights Reserved.   *   * The contents of this file are subject to the Erlang Public License,   * Version 1.1, (the "License"); you may not use this file except in @@ -405,6 +405,15 @@ efile_openfile(Efile_error* errInfo,	/* Where to return error codes. */  	mode |= O_EXCL;      } +    if (flags & EFILE_MODE_SYNC) { +#ifdef O_SYNC +	mode |= O_SYNC; +#else +	errno = ENOTSUP; +	return check_error(-1, errInfo); +#endif +    } +      fd = open(name, mode, FILE_MODE);      if (!check_error(fd, errInfo)) @@ -629,7 +638,7 @@ efile_writev(Efile_error* errInfo,   /* Where to return error codes */  		    if (w < iov[cnt].iov_len) {  			/* Adjust the buffer for next write */  			iov[cnt].iov_len -= w; -			iov[cnt].iov_base += w; +			iov[cnt].iov_base = ((char *)iov[cnt].iov_base) + w;  			w = 0;  			break;  		    } else { | 
