diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2012-07-03 00:17:27 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2012-07-03 00:17:27 +0400 |
commit | 8fd8f9e72b5732296f54c3dda3fe90d9e0d813e2 (patch) | |
tree | ba00f6a89b25654d9d2a827734de7743464b7bba /winsup/cygwin/fhandler_clipboard.cc | |
parent | ceec584ad39bca6caa6704bde22af58551bb139f (diff) |
* fhandler.h (class fhandler_dev_clipboard): Remove member eof.
* fhandler_clipboard.cc: Throughout remove handling of eof member.
(fhandler_dev_clipboard::write): Handle EOF condition immediately,
rather than pushing it erroneously to the next read call. Rearrange
code. Fix bug in CF_UNICODETEXT case which potentially dropped single
bytes at the end of the buffer. Add comment.
* strfuncs.cc (sys_cp_wcstombs): Allow returning non-NUL-terminated
buffer if dst != NULL and len == (size_t) -1. Extend leading comment
to explain what's returned in more detail.
Diffstat (limited to 'winsup/cygwin/fhandler_clipboard.cc')
-rw-r--r-- | winsup/cygwin/fhandler_clipboard.cc | 129 |
1 files changed, 57 insertions, 72 deletions
diff --git a/winsup/cygwin/fhandler_clipboard.cc b/winsup/cygwin/fhandler_clipboard.cc index 203af58bb..86f126c24 100644 --- a/winsup/cygwin/fhandler_clipboard.cc +++ b/winsup/cygwin/fhandler_clipboard.cc @@ -41,8 +41,7 @@ typedef struct } cygcb_t; fhandler_dev_clipboard::fhandler_dev_clipboard () - : fhandler_base (), pos (0), membuffer (NULL), msize (0), - eof (true) + : fhandler_base (), pos (0), membuffer (NULL), msize (0) { /* FIXME: check for errors and loop until we can open the clipboard */ OpenClipboard (NULL); @@ -69,7 +68,6 @@ int fhandler_dev_clipboard::open (int flags, mode_t) { set_flags (flags | O_TEXT); - eof = false; pos = 0; if (membuffer) free (membuffer); @@ -158,38 +156,28 @@ set_clipboard (const void *buf, size_t len) ssize_t __stdcall fhandler_dev_clipboard::write (const void *buf, size_t len) { - if (!eof) + /* write to our membuffer */ + size_t cursize = msize; + void *tempbuffer = realloc (membuffer, cursize + len); + if (!tempbuffer) { - /* write to our membuffer */ - size_t cursize = msize; - void *tempbuffer = realloc (membuffer, cursize + len); - if (!tempbuffer) - { - debug_printf ("Couldn't realloc() clipboard buffer for write"); - return -1; - } - membuffer = tempbuffer; - msize = cursize + len; - memcpy ((unsigned char *) membuffer + cursize, buf, len); - - /* now pass to windows */ - if (set_clipboard (membuffer, msize)) - { - /* FIXME: membuffer is now out of sync with pos, but msize - is used above */ - return -1; - } - - pos = msize; - - eof = false; - return len; + debug_printf ("Couldn't realloc() clipboard buffer for write"); + return -1; } - else + membuffer = tempbuffer; + msize = cursize + len; + memcpy ((unsigned char *) membuffer + cursize, buf, len); + + /* now pass to windows */ + if (set_clipboard (membuffer, msize)) { - /* FIXME: return 0 bytes written, file not open */ - return 0; + /* FIXME: membuffer is now out of sync with pos, but msize + is used above */ + return -1; } + + pos = msize; + return len; } int __stdcall @@ -230,66 +218,65 @@ void __stdcall fhandler_dev_clipboard::read (void *ptr, size_t& len) { HGLOBAL hglb; - size_t ret; + size_t ret = 0; UINT formatlist[2]; int format; - size_t plen = len; + LPVOID cb_data; - len = 0; - if (eof) - return; if (!OpenClipboard (NULL)) - return; - formatlist[0] = cygnativeformat; - formatlist[1] = CF_UNICODETEXT; - if ((format = GetPriorityClipboardFormat (formatlist, 2)) <= 0) { - CloseClipboard (); + len = 0; return; } - if (!(hglb = GetClipboardData (format))) + formatlist[0] = cygnativeformat; + formatlist[1] = CF_UNICODETEXT; + if ((format = GetPriorityClipboardFormat (formatlist, 2)) <= 0 + || !(hglb = GetClipboardData (format)) + || !(cb_data = GlobalLock (hglb))) { CloseClipboard (); + len = 0; return; } if (format == cygnativeformat) { - cygcb_t *clipbuf; + cygcb_t *clipbuf = (cygcb_t *) cb_data; - if (!(clipbuf = (cygcb_t *) GlobalLock (hglb))) - { - CloseClipboard (); - return; + if (pos < clipbuf->len) + { + ret = ((len > (clipbuf->len - pos)) ? (clipbuf->len - pos) : len); + memcpy (ptr, clipbuf->data + pos , ret); + pos += ret; } - ret = ((plen > (clipbuf->len - pos)) ? (clipbuf->len - pos) : plen); - memcpy (ptr, clipbuf->data + pos , ret); - pos += ret; - if (pos + plen - ret >= clipbuf->len) - eof = true; } else { - int wret; - PWCHAR buf; + wchar_t *buf = (wchar_t *) cb_data; - if (!(buf = (PWCHAR) GlobalLock (hglb))) + size_t glen = GlobalSize (hglb) / sizeof (WCHAR) - 1; + if (pos < glen) { - CloseClipboard (); - return; + /* Comparing apples and oranges here, but the below loop could become + extremly slow otherwise. We rather return a few bytes less than + possible instead of being even more slow than usual... */ + if (glen > pos + len) + glen = pos + len; + /* This loop is necessary because the number of bytes returned by + sys_wcstombs does not indicate the number of wide chars used for + it, so we could potentially drop wide chars. */ + while ((ret = sys_wcstombs (NULL, 0, buf + pos, glen - pos)) + != (size_t) -1 + && ret > len) + --glen; + if (ret == (size_t) -1) + ret = 0; + else + { + ret = sys_wcstombs ((char *) ptr, (size_t) -1, + buf + pos, glen - pos); + pos = glen; + } } - size_t glen = GlobalSize (hglb) / sizeof (WCHAR) - 1; - /* This loop is necessary because the number of bytes returned by - sys_wcstombs does not indicate the number of wide chars used for - it, so we could potentially drop wide chars. */ - if (glen - pos > plen) - glen = pos + plen; - while ((wret = sys_wcstombs (NULL, 0, buf + pos, glen - pos)) != -1 - && (size_t) wret > plen) - --glen; - ret = sys_wcstombs ((char *) ptr, plen, buf + pos, glen - pos); - pos += ret; - if (pos + plen - ret >= wcslen (buf)) - eof = true; } GlobalUnlock (hglb); CloseClipboard (); @@ -316,7 +303,6 @@ fhandler_dev_clipboard::close () { if (!have_execed) { - eof = true; pos = 0; if (membuffer) { @@ -333,7 +319,6 @@ fhandler_dev_clipboard::fixup_after_exec () { if (!close_on_exec ()) { - eof = false; pos = msize = 0; membuffer = NULL; } |