* fhandler_clipboard.cc: Avoid calling system_printf.

(set_clipboard): Add basic error checking.  Set errno here.  Per MSDN,
	don't call GlobalFree on data block transferred to clipboard.
	(fhandler_dev_clipboard::write): Drop setting errno after call to
	set_clipboard.
	(fhandler_dev_clipboard::read): Add basic error checking. Simplify code.
This commit is contained in:
Corinna Vinschen 2009-06-04 17:14:53 +00:00
parent 85401e530c
commit fbe1e28194
2 changed files with 114 additions and 105 deletions

View File

@ -1,3 +1,12 @@
2009-06-04 Corinna Vinschen <corinna@vinschen.de>
* fhandler_clipboard.cc: Avoid calling system_printf.
(set_clipboard): Add basic error checking. Set errno here. Per MSDN,
don't call GlobalFree on data block transferred to clipboard.
(fhandler_dev_clipboard::write): Drop setting errno after call to
set_clipboard.
(fhandler_dev_clipboard::read): Add basic error checking. Simplify code.
2009-06-04 Corinna Vinschen <corinna@vinschen.de> 2009-06-04 Corinna Vinschen <corinna@vinschen.de>
* fhandler_console.cc (set_console_title): Convert title string to * fhandler_console.cc (set_console_title): Convert title string to

View File

@ -81,11 +81,13 @@ set_clipboard (const void *buf, size_t len)
HGLOBAL hmem; HGLOBAL hmem;
void *clipbuf; void *clipbuf;
/* Native CYGWIN format */ /* Native CYGWIN format */
OpenClipboard (0); if (OpenClipboard (NULL))
{
hmem = GlobalAlloc (GMEM_MOVEABLE, len + sizeof (size_t)); hmem = GlobalAlloc (GMEM_MOVEABLE, len + sizeof (size_t));
if (!hmem) if (!hmem)
{ {
system_printf ("Couldn't allocate global buffer for write"); __seterrno ();
CloseClipboard ();
return -1; return -1;
} }
clipbuf = GlobalLock (hmem); clipbuf = GlobalLock (hmem);
@ -95,55 +97,47 @@ set_clipboard (const void *buf, size_t len)
EmptyClipboard (); EmptyClipboard ();
if (!cygnativeformat) if (!cygnativeformat)
cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE); cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE);
if (!SetClipboardData (cygnativeformat, hmem)) HANDLE ret = SetClipboardData (cygnativeformat, hmem);
CloseClipboard ();
/* According to MSDN, hmem must not be free'd after transferring the
data to the clipboard via SetClipboardData. */
/* GlobalFree (hmem); */
if (!ret)
{ {
system_printf __seterrno ();
("Couldn't write native format to the clipboard %04x %x",
cygnativeformat, hmem);
/* FIXME: return an appriate error code &| set_errno(); */
return -1; return -1;
} }
CloseClipboard ();
if (GlobalFree (hmem))
{
system_printf
("Couldn't free global buffer after write to the clipboard");
/* FIXME: return an appriate error code &| set_errno(); */
return 0;
} }
/* CF_TEXT/CF_OEMTEXT for copying to wordpad and the like */ /* CF_TEXT/CF_OEMTEXT for copying to wordpad and the like */
OpenClipboard (0);
len = sys_mbstowcs (NULL, 0, (const char *) buf, len); len = sys_mbstowcs (NULL, 0, (const char *) buf, len);
if (!len) if (!len)
{ {
system_printf ("Invalid string"); set_errno (EILSEQ);
return -1; return -1;
} }
if (OpenClipboard (NULL))
{
hmem = GlobalAlloc (GMEM_MOVEABLE, (len + 1) * sizeof (WCHAR)); hmem = GlobalAlloc (GMEM_MOVEABLE, (len + 1) * sizeof (WCHAR));
if (!hmem) if (!hmem)
{ {
system_printf ("Couldn't allocate global buffer for write"); __seterrno ();
CloseClipboard ();
return -1; return -1;
} }
clipbuf = GlobalLock (hmem); clipbuf = GlobalLock (hmem);
sys_mbstowcs ((PWCHAR) clipbuf, len, (const char *) buf); sys_mbstowcs ((PWCHAR) clipbuf, len + 1, (const char *) buf);
*((PWCHAR) clipbuf + len) = L'\0';
GlobalUnlock (hmem); GlobalUnlock (hmem);
if (!SetClipboardData (CF_UNICODETEXT, hmem)) HANDLE ret = SetClipboardData (CF_UNICODETEXT, hmem);
CloseClipboard ();
/* According to MSDN, hmem must not be free'd after transferring the
data to the clipboard via SetClipboardData. */
/* GlobalFree (hmem); */
if (!ret)
{ {
system_printf ("Couldn't write to the clipboard"); __seterrno ();
/* FIXME: return an appriate error code &| set_errno(); */
return -1; return -1;
} }
CloseClipboard ();
if (GlobalFree (hmem))
{
system_printf
("Couldn't free global buffer after write to the clipboard");
/* FIXME: return an appriate error code &| set_errno(); */
} }
return 0; return 0;
} }
@ -159,7 +153,7 @@ fhandler_dev_clipboard::write (const void *buf, size_t len)
void *tempbuffer = realloc (membuffer, cursize + len); void *tempbuffer = realloc (membuffer, cursize + len);
if (!tempbuffer) if (!tempbuffer)
{ {
system_printf ("Couldn't realloc() clipboard buffer for write"); debug_printf ("Couldn't realloc() clipboard buffer for write");
return -1; return -1;
} }
membuffer = tempbuffer; membuffer = tempbuffer;
@ -169,8 +163,8 @@ fhandler_dev_clipboard::write (const void *buf, size_t len)
/* now pass to windows */ /* now pass to windows */
if (set_clipboard (membuffer, msize)) if (set_clipboard (membuffer, msize))
{ {
/* FIXME: membuffer is now out of sync with pos, but msize is used above */ /* FIXME: membuffer is now out of sync with pos, but msize
set_errno (ENOSPC); is used above */
return -1; return -1;
} }
@ -193,62 +187,68 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len)
size_t ret; size_t ret;
UINT formatlist[2]; UINT formatlist[2];
int format; int format;
if (eof) size_t plen = len;
len = 0; len = 0;
else if (eof)
{ return;
if (!OpenClipboard (NULL))
return;
formatlist[0] = cygnativeformat; formatlist[0] = cygnativeformat;
formatlist[1] = CF_UNICODETEXT; formatlist[1] = CF_UNICODETEXT;
OpenClipboard (0);
if ((format = GetPriorityClipboardFormat (formatlist, 2)) <= 0) if ((format = GetPriorityClipboardFormat (formatlist, 2)) <= 0)
{ {
CloseClipboard (); CloseClipboard ();
#if 0 return;
system_printf ("a non-accepted format! %d", format);
#endif
len = 0;
} }
else if (!(hglb = GetClipboardData (format)))
{ {
hglb = GetClipboardData (format); CloseClipboard ();
return;
}
if (format == cygnativeformat) if (format == cygnativeformat)
{ {
unsigned char *buf = (unsigned char *) GlobalLock (hglb); unsigned char *buf;
if (!(buf = (unsigned char *) GlobalLock (hglb)))
{
CloseClipboard ();
return;
}
size_t buflen = (*(size_t *) buf); size_t buflen = (*(size_t *) buf);
ret = ((len > (buflen - pos)) ? (buflen - pos) : len); ret = ((plen > (buflen - pos)) ? (buflen - pos) : plen);
memcpy (ptr, buf + sizeof (size_t)+ pos , ret); memcpy (ptr, buf + sizeof (size_t)+ pos , ret);
pos += ret; pos += ret;
if (pos + len - ret >= buflen) if (pos + plen - ret >= buflen)
eof = true; eof = true;
GlobalUnlock (hglb);
} }
else else
{ {
int wret; int wret;
PWCHAR buf; PWCHAR buf;
buf = (PWCHAR) GlobalLock (hglb);
size_t glen = GlobalSize (hglb) / sizeof (WCHAR) - 1;
/* This loop is necessary because the number of bytes returned if (!(buf = (PWCHAR) GlobalLock (hglb)))
by WideCharToMultiByte does not indicate the number of wide {
chars used for it, so we could potentially drop wide chars. */ CloseClipboard ();
if (glen - pos > len) return;
glen = pos + len;
while ((wret = sys_wcstombs (NULL, 0, buf + pos, glen - pos))
!= -1
&& (size_t) wret > len)
--glen;
ret = sys_wcstombs ((char *) ptr, len, buf + pos, glen - pos);
//ret = snprintf((char *) ptr, len, "%s", buf);//+pos);
pos += ret;
if (pos + len - ret >= wcslen (buf))
eof = true;
GlobalUnlock (hglb);
} }
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 (); CloseClipboard ();
len = ret; len = ret;
}
}
} }
_off64_t _off64_t