From c2c7860fff001667b59e0674a50ee7eea0bf8515 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 26 Mar 2012 11:24:51 +0000 Subject: [PATCH] * fhandler.h (class fhandler_dev_clipboard): Add fstat method. * fhandler_clipboard.cc (cygcb_t): New type for Cygwin-specific clipboard format. (set_clipboard): Use new clipboard format to allow setting a timestamp. (fhandler_dev_clipboard::fstat): New method. Read modification and access timestamp as well as length from clipboard data. (fhandler_dev_clipboard::read): Use new clipboard format. --- winsup/cygwin/ChangeLog | 10 ++++ winsup/cygwin/fhandler.h | 1 + winsup/cygwin/fhandler_clipboard.cc | 75 +++++++++++++++++++++++------ 3 files changed, 72 insertions(+), 14 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 36b87e67f..a918759da 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,13 @@ +2012-03-26 Corinna Vinschen + + * fhandler.h (class fhandler_dev_clipboard): Add fstat method. + * fhandler_clipboard.cc (cygcb_t): New type for Cygwin-specific + clipboard format. + (set_clipboard): Use new clipboard format to allow setting a timestamp. + (fhandler_dev_clipboard::fstat): New method. Read modification and + access timestamp as well as length from clipboard data. + (fhandler_dev_clipboard::read): Use new clipboard format. + 2012-03-26 Corinna Vinschen * hires.h (hires_ms::dmsecs): Drop unused method. diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 3eeb4d561..533a9d4a4 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1685,6 +1685,7 @@ class fhandler_dev_clipboard: public fhandler_base fhandler_dev_clipboard (); int is_windows () { return 1; } int open (int flags, mode_t mode = 0); + int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); ssize_t __stdcall write (const void *ptr, size_t len); void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); _off64_t lseek (_off64_t offset, int whence); diff --git a/winsup/cygwin/fhandler_clipboard.cc b/winsup/cygwin/fhandler_clipboard.cc index b8438c8a7..203af58bb 100644 --- a/winsup/cygwin/fhandler_clipboard.cc +++ b/winsup/cygwin/fhandler_clipboard.cc @@ -1,6 +1,7 @@ /* fhandler_dev_clipboard: code to access /dev/clipboard - Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2011 Red Hat, Inc + Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2011, + 2012 Red Hat, Inc Written by Charles Wilson (cwilson@ece.gatech.edu) @@ -32,6 +33,13 @@ static const NO_COPY WCHAR *CYGWIN_NATIVE = L"CYGWIN_NATIVE_CLIPBOARD"; /* this is MT safe because windows format id's are atomic */ static int cygnativeformat; +typedef struct +{ + timestruc_t timestamp; + size_t len; + char data[1]; +} cygcb_t; + fhandler_dev_clipboard::fhandler_dev_clipboard () : fhandler_base (), pos (0), membuffer (NULL), msize (0), eof (true) @@ -77,20 +85,24 @@ static int set_clipboard (const void *buf, size_t len) { HGLOBAL hmem; - void *clipbuf; /* Native CYGWIN format */ if (OpenClipboard (NULL)) { - hmem = GlobalAlloc (GMEM_MOVEABLE, len + sizeof (size_t)); + cygcb_t *clipbuf; + + hmem = GlobalAlloc (GMEM_MOVEABLE, sizeof (cygcb_t) + len); if (!hmem) { __seterrno (); CloseClipboard (); return -1; } - clipbuf = GlobalLock (hmem); - memcpy ((unsigned char *) clipbuf + sizeof (size_t), buf, len); - *(size_t *) (clipbuf) = len; + clipbuf = (cygcb_t *) GlobalLock (hmem); + + clock_gettime (CLOCK_REALTIME, &clipbuf->timestamp); + clipbuf->len = len; + memcpy (clipbuf->data, buf, len); + GlobalUnlock (hmem); EmptyClipboard (); if (!cygnativeformat) @@ -116,6 +128,8 @@ set_clipboard (const void *buf, size_t len) } if (OpenClipboard (NULL)) { + PWCHAR clipbuf; + hmem = GlobalAlloc (GMEM_MOVEABLE, (len + 1) * sizeof (WCHAR)); if (!hmem) { @@ -123,8 +137,8 @@ set_clipboard (const void *buf, size_t len) CloseClipboard (); return -1; } - clipbuf = GlobalLock (hmem); - sys_mbstowcs ((PWCHAR) clipbuf, len + 1, (const char *) buf); + clipbuf = (PWCHAR) GlobalLock (hmem); + sys_mbstowcs (clipbuf, len + 1, (const char *) buf); GlobalUnlock (hmem); HANDLE ret = SetClipboardData (CF_UNICODETEXT, hmem); CloseClipboard (); @@ -178,6 +192,40 @@ fhandler_dev_clipboard::write (const void *buf, size_t len) } } +int __stdcall +fhandler_dev_clipboard::fstat (struct __stat64 *buf) +{ + buf->st_mode = S_IFCHR | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH; + buf->st_uid = geteuid32 (); + buf->st_gid = getegid32 (); + buf->st_nlink = 1; + buf->st_blksize = PREFERRED_IO_BLKSIZE; + + buf->st_ctim.tv_sec = 1164931200L; /* Arbitrary value: 2006-12-01 */ + buf->st_ctim.tv_nsec = 0L; + buf->st_birthtim = buf->st_atim = buf->st_mtim = buf->st_ctim; + + if (OpenClipboard (NULL)) + { + UINT formatlist[1] = { cygnativeformat }; + int format; + HGLOBAL hglb; + cygcb_t *clipbuf; + + if ((format = GetPriorityClipboardFormat (formatlist, 1)) > 0 + && (hglb = GetClipboardData (format)) + && (clipbuf = (cygcb_t *) GlobalLock (hglb))) + { + buf->st_atim = buf->st_mtim = clipbuf->timestamp; + buf->st_size = clipbuf->len; + GlobalUnlock (hglb); + } + CloseClipboard (); + } + + return 0; +} + void __stdcall fhandler_dev_clipboard::read (void *ptr, size_t& len) { @@ -206,18 +254,17 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len) } if (format == cygnativeformat) { - unsigned char *buf; + cygcb_t *clipbuf; - if (!(buf = (unsigned char *) GlobalLock (hglb))) + if (!(clipbuf = (cygcb_t *) 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); + ret = ((plen > (clipbuf->len - pos)) ? (clipbuf->len - pos) : plen); + memcpy (ptr, clipbuf->data + pos , ret); pos += ret; - if (pos + plen - ret >= buflen) + if (pos + plen - ret >= clipbuf->len) eof = true; } else