diff options
Diffstat (limited to 'erts/emulator/drivers')
-rw-r--r-- | erts/emulator/drivers/common/efile_drv.c | 108 | ||||
-rw-r--r-- | erts/emulator/drivers/common/erl_efile.h | 16 | ||||
-rw-r--r-- | erts/emulator/drivers/common/inet_drv.c | 6 | ||||
-rw-r--r-- | erts/emulator/drivers/common/zlib_drv.c | 2 | ||||
-rw-r--r-- | erts/emulator/drivers/unix/ttsl_drv.c | 45 | ||||
-rw-r--r-- | erts/emulator/drivers/unix/unix_efile.c | 2 | ||||
-rw-r--r-- | erts/emulator/drivers/win32/ttsl_drv.c | 4 |
7 files changed, 93 insertions, 90 deletions
diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c index 69acfc9dfd..6cc1295973 100644 --- a/erts/emulator/drivers/common/efile_drv.c +++ b/erts/emulator/drivers/common/efile_drv.c @@ -397,7 +397,6 @@ struct t_pwritev { ErlDrvPort port; ErlDrvPDL q_mtx; size_t size; - size_t free_size; unsigned cnt; unsigned n; struct t_pbuf_spec specs[1]; @@ -462,7 +461,6 @@ struct t_data ErlDrvPort port; ErlDrvPDL q_mtx; size_t size; - size_t free_size; size_t reply_size; } writev; struct t_pwritev pwritev; @@ -1346,7 +1344,7 @@ static void invoke_preadv(void *data) = efile_pread(&d->errInfo, (int) d->fd, c->offsets[c->cnt] + c->size, - ev->iov[1 + c->cnt].iov_base + c->size, + ((char *)ev->iov[1 + c->cnt].iov_base) + c->size, read_size, &bytes_read))) { bytes_read_so_far += bytes_read; @@ -1532,26 +1530,24 @@ static void invoke_writev(void *data) { } EF_FREE(iov); - d->c.writev.free_size = size; - d->c.writev.size -= size; if (! d->result_ok) { d->again = 0; + MUTEX_LOCK(d->c.writev.q_mtx); + driver_deq(d->c.writev.port, d->c.writev.size); + MUTEX_UNLOCK(d->c.writev.q_mtx); } else { if (! segment) { d->again = 0; } + d->c.writev.size -= size; TRACE_F(("w%lu", (unsigned long)size)); - + MUTEX_LOCK(d->c.writev.q_mtx); + driver_deq(d->c.writev.port, size); + MUTEX_UNLOCK(d->c.writev.q_mtx); } - DTRACE_INVOKE_RETURN(FILE_WRITE); -} -static void free_writev(void *data) { - struct t_data *d = data; - MUTEX_LOCK(d->c.writev.q_mtx); - driver_deq(d->c.writev.port, d->c.writev.size + d->c.writev.free_size); - MUTEX_UNLOCK(d->c.writev.q_mtx); - EF_FREE(d); + + DTRACE_INVOKE_RETURN(FILE_WRITE); } static void invoke_pwd(void *data) @@ -1602,7 +1598,7 @@ static void invoke_pwritev(void *data) { struct t_pwritev *c = &d->c.pwritev; size_t p; int segment; - size_t size, write_size; + size_t size, write_size, written; DTRACE_INVOKE_SETUP(FILE_PWRITEV); segment = d->again && c->size >= 2*FILE_SEGMENT_WRITE; @@ -1622,39 +1618,35 @@ static void invoke_pwritev(void *data) { if (iovlen < 0) goto error; /* Port terminated */ - for (iovcnt = 0, c->free_size = 0; - c->cnt < c->n && iovcnt < iovlen && c->free_size < size; + for (iovcnt = 0, written = 0; + c->cnt < c->n && iovcnt < iovlen && written < size; c->cnt++) { int chop; write_size = c->specs[c->cnt].size; if (iov[iovcnt].iov_len - p < write_size) { - /* Mismatch between pos/size spec and what is queued */ - d->errInfo.posix_errno = EINVAL; - d->result_ok = 0; - d->again = 0; - goto done; + goto error; } - chop = segment && c->free_size + write_size >= 2*FILE_SEGMENT_WRITE; + chop = segment && written + write_size >= 2*FILE_SEGMENT_WRITE; if (chop) { - ASSERT(c->free_size < FILE_SEGMENT_WRITE); + ASSERT(written < FILE_SEGMENT_WRITE); write_size = FILE_SEGMENT_WRITE + FILE_SEGMENT_WRITE/2 - - c->free_size; + - written; } d->result_ok = efile_pwrite(&d->errInfo, (int) d->fd, - iov[iovcnt].iov_base + p, + (char *)(iov[iovcnt].iov_base) + p, write_size, c->specs[c->cnt].offset); if (! d->result_ok) { d->again = 0; - goto done; + goto deq_error; } - c->free_size += write_size; + written += write_size; c->size -= write_size; if (chop) { c->specs[c->cnt].offset += write_size; c->specs[c->cnt].size -= write_size; /* Schedule out (d->again != 0) */ - goto done; + break; } /* Move forward in buffer */ p += write_size; @@ -1676,25 +1668,28 @@ static void invoke_pwritev(void *data) { d->errInfo.posix_errno = EINVAL; d->result_ok = 0; d->again = 0; + deq_error: + MUTEX_LOCK(d->c.writev.q_mtx); + driver_deq(d->c.pwritev.port, c->size); + MUTEX_UNLOCK(d->c.writev.q_mtx); + + goto done; } else { - ASSERT(c->free_size == size); + ASSERT(written == size); d->again = 0; } - } + } else + ASSERT(written == FILE_SEGMENT_WRITE); + + MUTEX_LOCK(d->c.writev.q_mtx); + driver_deq(d->c.pwritev.port, size); + MUTEX_UNLOCK(d->c.writev.q_mtx); done: EF_FREE(iov); /* Free our copy of the vector, nothing to restore */ + DTRACE_INVOKE_RETURN(FILE_PWRITEV); } -static void free_pwritev(void *data) { - struct t_data *d = data; - - MUTEX_LOCK(d->c.writev.q_mtx); - driver_deq(d->c.pwritev.port, d->c.pwritev.free_size + d->c.pwritev.size); - MUTEX_UNLOCK(d->c.writev.q_mtx); - EF_FREE(d); -} - static void invoke_flstat(void *data) { struct t_data *d = (struct t_data *) data; @@ -2008,21 +2003,8 @@ static void try_free_read_bin(file_descriptor *desc) { static int try_again(file_descriptor *desc, struct t_data *d) { - if (! d->again) { + if (! d->again) return 0; - } - switch (d->command) { - case FILE_WRITE: - MUTEX_LOCK(d->c.writev.q_mtx); - driver_deq(d->c.writev.port, d->c.writev.free_size); - MUTEX_UNLOCK(d->c.writev.q_mtx); - break; - case FILE_PWRITEV: - MUTEX_LOCK(d->c.writev.q_mtx); - driver_deq(d->c.pwritev.port, d->c.pwritev.free_size); - MUTEX_UNLOCK(d->c.writev.q_mtx); - break; - } if (desc->timer_state != timer_idle) { driver_cancel_timer(desc->port); } @@ -2078,10 +2060,9 @@ static struct t_data *async_write(file_descriptor *desc, int *errp, } #endif d->reply = reply; - d->c.writev.free_size = 0; d->c.writev.reply_size = reply_size; d->invoke = invoke_writev; - d->free = free_writev; + d->free = free_data; d->level = 1; cq_enq(desc, d); desc->write_buffered = 0; @@ -2394,7 +2375,7 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data) desc->write_errInfo = d->errInfo; } } - free_writev(data); + free_data(data); break; case FILE_LSEEK: if (d->reply) { @@ -2524,7 +2505,7 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data) } else { reply_Uint(desc, d->c.pwritev.n); } - free_pwritev(data); + free_data(data); break; case FILE_PREADV: if (!d->result_ok) { @@ -2559,7 +2540,7 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data) reply_Sint64(desc, d->c.sendfile.written); desc->sendfile_state = not_sending; free_sendfile(data); - } else if (d->result_ok == 1) { // If we are using select to send the rest of the data + } else if (d->result_ok == 1) { /* If we are using select to send the rest of the data */ desc->sendfile_state = sending; desc->d = d; driver_select(desc->port, (ErlDrvEvent)(long)d->c.sendfile.out_fd, @@ -2581,7 +2562,7 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data) } DTRACE6(efile_drv_return, sched_i1, sched_i2, sched_utag, command, result_ok, posix_errno); - if (desc->write_buffered != 0 && desc->timer_state == timer_idle) { + if (desc->write_buffered != 0 && desc->timer_state == timer_idle ) { desc->timer_state = timer_write; driver_set_timer(desc->port, desc->write_delay); } @@ -3651,7 +3632,6 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) { #ifdef USE_VM_PROBES dt_i3 = d->c.pwritev.size; #endif - d->c.pwritev.free_size = 0; if (j == 0) { /* Trivial case - nothing to write */ EF_FREE(d); @@ -3675,7 +3655,7 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) { MUTEX_UNLOCK(desc->q_mtx); /* Execute the command */ d->invoke = invoke_pwritev; - d->free = free_pwritev; + d->free = free_data; d->level = 1; cq_enq(desc, d); } @@ -3813,7 +3793,7 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) { res_ev->iov[0].iov_base = res_ev->binv[0]->orig_bytes; /* Fill in the number of buffers in the header */ put_int32(0, res_ev->iov[0].iov_base); - put_int32(n, res_ev->iov[0].iov_base+4); + put_int32(n, (char *)(res_ev->iov[0].iov_base) + 4); /**/ res_ev->size = res_ev->iov[0].iov_len; if (n == 0) { @@ -4114,7 +4094,7 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) { } if (hd_len != 0 || tl_len != 0 || flags != 0) { - // We do not allow header, trailers and/or flags right now + /* We do not allow header, trailers and/or flags right now */ reply_posix_error(desc, EINVAL); goto done; } diff --git a/erts/emulator/drivers/common/erl_efile.h b/erts/emulator/drivers/common/erl_efile.h index b29b4f971c..bd85e43b8c 100644 --- a/erts/emulator/drivers/common/erl_efile.h +++ b/erts/emulator/drivers/common/erl_efile.h @@ -67,7 +67,7 @@ #define FILENAMES_16BIT 1 #endif -// We use sendfilev if it exist on solaris +/* We use sendfilev if it exist on solaris */ #if !defined(HAVE_SENDFILE) && defined(HAVE_SENDFILEV) #define HAVE_SENDFILE #endif @@ -88,20 +88,6 @@ typedef struct _Efile_error { } Efile_error; /* - * This structure contains date and time. - */ - -//typedef struct _Efile_time { -// unsigned year; /* (4 digits). */ -// unsigned month; /* (1..12). */ -// unsigned day; /* (1..31). */ -// unsigned hour; /* (0..23). */ -// unsigned minute; /* (0..59). */ -// unsigned second; /* (0..59). */ -//} Efile_time; - - -/* * Describes what is returned by file:file_info/1. */ diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 0fdd6934c2..301ce2d0e2 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -3854,8 +3854,10 @@ static void desc_close(inet_descriptor* desc) desc->forced_events = 0; desc->send_would_block = 0; #endif - // We should close the fd here, but the other driver might still - // be selecting on it. + /* + * We should close the fd here, but the other driver might still + * be selecting on it. + */ if (!desc->is_ignored) driver_select(desc->port,(ErlDrvEvent)(long)desc->event, ERL_DRV_USE, 0); diff --git a/erts/emulator/drivers/common/zlib_drv.c b/erts/emulator/drivers/common/zlib_drv.c index 60394b610b..89b7be14f2 100644 --- a/erts/emulator/drivers/common/zlib_drv.c +++ b/erts/emulator/drivers/common/zlib_drv.c @@ -119,7 +119,7 @@ static int zlib_deflate(ZLibData* d, int flush); #if defined(__WIN32__) static int i32(char* buf) #else -static inline int i32(char* buf) +static __inline__ int i32(char* buf) #endif { return (int) ( diff --git a/erts/emulator/drivers/unix/ttsl_drv.c b/erts/emulator/drivers/unix/ttsl_drv.c index 8912d148a5..d76401a790 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 { @@ -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,8 @@ static int write_buf(Uint32 *s, int n) if (octbuff != octtmp) { driver_free(octbuff); } + } else if (*s & WIDE_TAG) { + --n; s++; } else { DEBUGLOG(("Very unexpected character %d",(int) *s)); ++n; diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c index 558651fff9..2bd5177be1 100644 --- a/erts/emulator/drivers/unix/unix_efile.c +++ b/erts/emulator/drivers/unix/unix_efile.c @@ -629,7 +629,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 { diff --git a/erts/emulator/drivers/win32/ttsl_drv.c b/erts/emulator/drivers/win32/ttsl_drv.c index 1a74d21e99..8b5e3eeefd 100644 --- a/erts/emulator/drivers/win32/ttsl_drv.c +++ b/erts/emulator/drivers/win32/ttsl_drv.c @@ -414,12 +414,12 @@ 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)); + DEBUGLOG(("Printable(UTF-8:%d):%d",pos,ch)); size++; /* Buffer contains wide characters... */ } 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 { |