summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/kernel/msgqueue
diff options
context:
space:
mode:
authorZyad A. Ali <zyad.ali.me@gmail.com>2021-06-21 13:53:48 +0200
committerZyad A. Ali <zyad.ali.me@gmail.com>2021-08-03 18:13:24 +0200
commit6ef2f177fbaff7ff29f46a97e2e3dc9199a42d0d (patch)
tree58db0c9c9a6e89aa59b7f0e76d6b41714a4d3ab2 /pkg/sentry/kernel/msgqueue
parenteb638ee583ba29a879202451692fadfed7c3fdd0 (diff)
Implement MSG_COPY option for msgrcv(2).
Implement Queue.Copy and add more tests for it. Updates #135
Diffstat (limited to 'pkg/sentry/kernel/msgqueue')
-rw-r--r--pkg/sentry/kernel/msgqueue/msgqueue.go27
1 files changed, 23 insertions, 4 deletions
diff --git a/pkg/sentry/kernel/msgqueue/msgqueue.go b/pkg/sentry/kernel/msgqueue/msgqueue.go
index 28520b19a..c111297d7 100644
--- a/pkg/sentry/kernel/msgqueue/msgqueue.go
+++ b/pkg/sentry/kernel/msgqueue/msgqueue.go
@@ -386,13 +386,21 @@ func (q *Queue) pop(ctx context.Context, creds *auth.Credentials, mType int64, m
return msg, nil
}
-// Copy copies a message from the queue without deleting it. See
-// msgrcv(MSG_COPY).
-func (q *Queue) Copy() (*Message, error) {
+// Copy copies a message from the queue without deleting it. If no message
+// exists, an error is returned. See msgrcv(MSG_COPY).
+func (q *Queue) Copy(mType int64) (*Message, error) {
q.mu.Lock()
defer q.mu.Unlock()
- return nil, linuxerr.ENOSYS
+ if mType < 0 || q.messages.Empty() {
+ return nil, linuxerr.ENOMSG
+ }
+
+ msg := q.msgAtIndex(mType)
+ if msg == nil {
+ return nil, linuxerr.ENOMSG
+ }
+ return msg, nil
}
// msgOfType returns the first message with the specified type, nil if no
@@ -433,6 +441,17 @@ func (q *Queue) msgOfTypeLessThan(mType int64) (m *Message) {
return m
}
+// msgAtIndex returns a pointer to a message at given index, nil if non exits.
+//
+// Precondition: caller must hold q.mu.
+func (q *Queue) msgAtIndex(mType int64) *Message {
+ msg := q.messages.Front()
+ for ; mType != 0 && msg != nil; mType-- {
+ msg = msg.Next()
+ }
+ return msg
+}
+
// Lock implements ipc.Mechanism.Lock.
func (q *Queue) Lock() {
q.mu.Lock()