From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id F3AC33858038; Tue, 25 May 2021 18:20:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F3AC33858038 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] Cygwin: POSIX msg queues: implement read(2)/lseek(2) X-Act-Checkin: newlib-cygwin X-Git-Author: Corinna Vinschen X-Git-Refname: refs/heads/master X-Git-Oldrev: 517c7e79da0a64d8e732409d2c65693cbc931bf3 X-Git-Newrev: efef4b8bf1eadb17b2696d724106724dcd941305 Message-Id: <20210525182014.F3AC33858038@sourceware.org> Date: Tue, 25 May 2021 18:20:14 +0000 (GMT) X-BeenThere: cygwin-cvs@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Cygwin core component git logs List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 25 May 2021 18:20:15 -0000 https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=efef4b8bf1eadb17b2696d724106724dcd941305 commit efef4b8bf1eadb17b2696d724106724dcd941305 Author: Corinna Vinschen Date: Tue May 25 20:19:19 2021 +0200 Cygwin: POSIX msg queues: implement read(2)/lseek(2) reuse fhandler_virtual implementation to implement read and lseek. The output from read(2) is modelled after the output when reading from an mq file on Linux. Signed-off-by: Corinna Vinschen Diff: --- winsup/cygwin/fhandler.h | 14 ++++-- winsup/cygwin/fhandler_mqueue.cc | 101 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 110 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 7152482ed..5e298a82f 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -3106,6 +3106,10 @@ class fhandler_timerfd : public fhandler_base class fhandler_mqueue: public fhandler_disk_file { struct mq_info mqi; + /* Duplicate filebuf usage of fhandler_virtual */ + char *filebuf; + off_t filesize; + off_t position; struct mq_info *_mqinfo (SIZE_T, mode_t, int, bool); @@ -3115,6 +3119,8 @@ class fhandler_mqueue: public fhandler_disk_file int _dup (HANDLE parent, fhandler_mqueue *child); + bool fill_filebuf (); + int mutex_lock (HANDLE mtx, bool eintr); int mutex_unlock (HANDLE mtx); int cond_timedwait (HANDLE evt, HANDLE mtx, const struct timespec *abstime); @@ -3123,7 +3129,7 @@ class fhandler_mqueue: public fhandler_disk_file public: fhandler_mqueue (); fhandler_mqueue (void *) {} - ~fhandler_mqueue () {} + ~fhandler_mqueue (); fhandler_mqueue *is_mqueue () { return this; } @@ -3143,8 +3149,10 @@ public: void fixup_after_fork (HANDLE); - int __reg2 fstat (struct stat *buf); - int dup (fhandler_base *child, int); + void __reg3 read (void *, size_t&); + off_t lseek (off_t, int); + int __reg2 fstat (struct stat *); + int dup (fhandler_base *, int); int ioctl (unsigned int, void *); int close (); diff --git a/winsup/cygwin/fhandler_mqueue.cc b/winsup/cygwin/fhandler_mqueue.cc index d1aa8c8e3..04a6c3611 100644 --- a/winsup/cygwin/fhandler_mqueue.cc +++ b/winsup/cygwin/fhandler_mqueue.cc @@ -12,19 +12,28 @@ details. */ #include "fhandler.h" #include "dtable.h" #include "clock.h" +#include #include #include #define MSGSIZE(i) roundup((i), sizeof(long)) +#define FILESIZE 80 + struct mq_attr defattr = { 0, 10, 8192, 0 }; /* Linux defaults. */ fhandler_mqueue::fhandler_mqueue () : fhandler_disk_file () { + filebuf = (char *) ccalloc_abort (HEAP_BUF, 1, FILESIZE); close_on_exec (true); } +fhandler_mqueue::~fhandler_mqueue () +{ + cfree (filebuf); +} + int fhandler_mqueue::open (int flags, mode_t mode) { @@ -344,12 +353,97 @@ fhandler_mqueue::get_proc_fd_name (char *buf) return strcpy (buf, strrchr (get_name (), '/')); } +/* Do what fhandler_virtual does for read/lseek */ +bool +fhandler_mqueue::fill_filebuf () +{ + unsigned long qsize = 0; + int notify = 0; + int signo = 0; + int notify_pid = 0; + + if (mutex_lock (mqinfo ()->mqi_lock, true) == 0) + { + struct mq_hdr *mqhdr = mqinfo ()->mqi_hdr; + int8_t *mptr = (int8_t *) mqhdr; + struct msg_hdr *msghdr; + for (long index = mqhdr->mqh_head; index; index = msghdr->msg_next) + { + msghdr = (struct msg_hdr *) &mptr[index]; + qsize += msghdr->msg_len; + } + if (mqhdr->mqh_pid) + { + notify = mqhdr->mqh_event.sigev_notify; + if (notify == SIGEV_SIGNAL) + signo = mqhdr->mqh_event.sigev_signo; + notify_pid = mqhdr->mqh_pid; + } + mutex_unlock (mqinfo ()->mqi_lock); + } + /* QSIZE: bytes of all current msgs + NOTIFY: sigev_notify if there's a notifier + SIGNO: signal number if NOTIFY && sigev_notify == SIGEV_SIGNAL + NOTIFY_PID: if NOTIFY pid */ + snprintf (filebuf, FILESIZE, + "QSIZE:%-10lu NOTIFY:%-5d SIGNO:%-5d NOTIFY_PID:%-6d\n", + qsize, notify, signo, notify_pid); + filesize = strlen (filebuf); + return true; +} + +void __reg3 +fhandler_mqueue::read (void *in_ptr, size_t& len) +{ + if (len == 0) + return; + if (!filebuf[0] && !fill_filebuf ()) + { + len = (size_t) -1; + return; + } + if ((ssize_t) len > filesize - position) + len = (size_t) (filesize - position); + if ((ssize_t) len < 0) + len = 0; + else + memcpy (in_ptr, filebuf + position, len); + position += len; +} + +off_t +fhandler_mqueue::lseek (off_t offset, int whence) +{ + if (!fill_filebuf ()) + return (off_t) -1; + switch (whence) + { + case SEEK_SET: + position = offset; + break; + case SEEK_CUR: + position += offset; + break; + case SEEK_END: + position = filesize + offset; + break; + default: + set_errno (EINVAL); + return (off_t) -1; + } + return position; +} + + int __reg2 fhandler_mqueue::fstat (struct stat *buf) { int ret = fhandler_disk_file::fstat (buf); if (!ret) - buf->st_dev = FH_MQUEUE; + { + buf->st_size = FILESIZE; + buf->st_dev = FH_MQUEUE; + } return ret; } @@ -400,7 +494,10 @@ fhandler_mqueue::dup (fhandler_base *child, int flags) int ret = fhandler_disk_file::dup (child, flags); if (!ret) - ret = _dup (GetCurrentProcess (), fhc); + { + memcpy (fhc->filebuf, filebuf, FILESIZE); + ret = _dup (GetCurrentProcess (), fhc); + } return ret; }