* 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,69 +81,63 @@ 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));
if (!hmem)
{ {
system_printf ("Couldn't allocate global buffer for write"); hmem = GlobalAlloc (GMEM_MOVEABLE, len + sizeof (size_t));
return -1; if (!hmem)
} {
clipbuf = GlobalLock (hmem); __seterrno ();
memcpy ((unsigned char *) clipbuf + sizeof (size_t), buf, len); CloseClipboard ();
*(size_t *) (clipbuf) = len; return -1;
GlobalUnlock (hmem); }
EmptyClipboard (); clipbuf = GlobalLock (hmem);
if (!cygnativeformat) memcpy ((unsigned char *) clipbuf + sizeof (size_t), buf, len);
cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE); *(size_t *) (clipbuf) = len;
if (!SetClipboardData (cygnativeformat, hmem)) GlobalUnlock (hmem);
{ EmptyClipboard ();
system_printf if (!cygnativeformat)
("Couldn't write native format to the clipboard %04x %x", cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE);
cygnativeformat, hmem); HANDLE ret = SetClipboardData (cygnativeformat, hmem);
/* FIXME: return an appriate error code &| set_errno(); */ CloseClipboard ();
return -1; /* According to MSDN, hmem must not be free'd after transferring the
} data to the clipboard via SetClipboardData. */
CloseClipboard (); /* GlobalFree (hmem); */
if (GlobalFree (hmem)) if (!ret)
{ {
system_printf __seterrno ();
("Couldn't free global buffer after write to the clipboard"); return -1;
/* 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;
} }
hmem = GlobalAlloc (GMEM_MOVEABLE, (len + 1) * sizeof (WCHAR)); if (OpenClipboard (NULL))
if (!hmem)
{ {
system_printf ("Couldn't allocate global buffer for write"); hmem = GlobalAlloc (GMEM_MOVEABLE, (len + 1) * sizeof (WCHAR));
return -1; if (!hmem)
} {
clipbuf = GlobalLock (hmem); __seterrno ();
sys_mbstowcs ((PWCHAR) clipbuf, len, (const char *) buf); CloseClipboard ();
*((PWCHAR) clipbuf + len) = L'\0'; return -1;
GlobalUnlock (hmem); }
if (!SetClipboardData (CF_UNICODETEXT, hmem)) clipbuf = GlobalLock (hmem);
{ sys_mbstowcs ((PWCHAR) clipbuf, len + 1, (const char *) buf);
system_printf ("Couldn't write to the clipboard"); GlobalUnlock (hmem);
/* FIXME: return an appriate error code &| set_errno(); */ HANDLE ret = SetClipboardData (CF_UNICODETEXT, hmem);
return -1; CloseClipboard ();
} /* According to MSDN, hmem must not be free'd after transferring the
CloseClipboard (); data to the clipboard via SetClipboardData. */
if (GlobalFree (hmem)) /* GlobalFree (hmem); */
{ if (!ret)
system_printf {
("Couldn't free global buffer after write to the clipboard"); __seterrno ();
/* FIXME: return an appriate error code &| set_errno(); */ return -1;
}
} }
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;
size_t plen = len;
len = 0;
if (eof) if (eof)
len = 0; return;
if (!OpenClipboard (NULL))
return;
formatlist[0] = cygnativeformat;
formatlist[1] = CF_UNICODETEXT;
if ((format = GetPriorityClipboardFormat (formatlist, 2)) <= 0)
{
CloseClipboard ();
return;
}
if (!(hglb = GetClipboardData (format)))
{
CloseClipboard ();
return;
}
if (format == cygnativeformat)
{
unsigned char *buf;
if (!(buf = (unsigned char *) GlobalLock (hglb)))
{
CloseClipboard ();
return;
}
size_t buflen = (*(size_t *) buf);
ret = ((plen > (buflen - pos)) ? (buflen - pos) : plen);
memcpy (ptr, buf + sizeof (size_t)+ pos , ret);
pos += ret;
if (pos + plen - ret >= buflen)
eof = true;
}
else else
{ {
formatlist[0] = cygnativeformat; int wret;
formatlist[1] = CF_UNICODETEXT; PWCHAR buf;
OpenClipboard (0);
if ((format = GetPriorityClipboardFormat (formatlist, 2)) <= 0)
{
CloseClipboard ();
#if 0
system_printf ("a non-accepted format! %d", format);
#endif
len = 0;
}
else
{
hglb = GetClipboardData (format);
if (format == cygnativeformat)
{
unsigned char *buf = (unsigned char *) GlobalLock (hglb);
size_t buflen = (*(size_t *) buf);
ret = ((len > (buflen - pos)) ? (buflen - pos) : len);
memcpy (ptr, buf + sizeof (size_t)+ pos , ret);
pos += ret;
if (pos + len - ret >= buflen)
eof = true;
GlobalUnlock (hglb);
}
else
{
int wret;
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. */
if (glen - pos > len)
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);
}
CloseClipboard (); CloseClipboard ();
len = ret; return;
} }
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 ();
len = ret;
} }
_off64_t _off64_t