summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/syscalls/linux/vfs2/mq.go
diff options
context:
space:
mode:
authorZyad A. Ali <zyad.ali.me@gmail.com>2021-08-03 07:48:24 +0200
committerZyad A. Ali <zyad.ali.me@gmail.com>2021-09-28 20:43:52 +0200
commitf03dc73f0f46d0ff1ae209fefc98ee3d7fc725d2 (patch)
treeee84a03ddfd6c96c8be7d2a4050caf2875127fb9 /pkg/sentry/syscalls/linux/vfs2/mq.go
parent9bde727f4f2e5b7cf52211a3a4fe71c7a0e4f1ea (diff)
Implement stubs for mq_open(2) and mq_unlink(2).
Support mq_open and mq_unlink, and enable syscall tests. Updates #136
Diffstat (limited to 'pkg/sentry/syscalls/linux/vfs2/mq.go')
-rw-r--r--pkg/sentry/syscalls/linux/vfs2/mq.go98
1 files changed, 98 insertions, 0 deletions
diff --git a/pkg/sentry/syscalls/linux/vfs2/mq.go b/pkg/sentry/syscalls/linux/vfs2/mq.go
new file mode 100644
index 000000000..d5d81c6e2
--- /dev/null
+++ b/pkg/sentry/syscalls/linux/vfs2/mq.go
@@ -0,0 +1,98 @@
+// Copyright 2021 The gVisor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package vfs2
+
+import (
+ "gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/sentry/arch"
+ "gvisor.dev/gvisor/pkg/sentry/kernel"
+ "gvisor.dev/gvisor/pkg/sentry/kernel/mq"
+)
+
+// MqOpen implements mq_open(2).
+func MqOpen(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ nameAddr := args[0].Pointer()
+ flag := args[1].Int()
+ mode := args[2].ModeT()
+ attrAddr := args[3].Pointer()
+
+ name, err := t.CopyInString(nameAddr, mq.MaxName)
+ if err != nil {
+ return 0, nil, err
+ }
+
+ rOnly := flag&linux.O_RDONLY == linux.O_RDONLY
+ wOnly := flag&linux.O_WRONLY == linux.O_WRONLY
+ readWrite := flag&linux.O_RDWR == linux.O_RDWR
+
+ create := flag&linux.O_CREAT == linux.O_CREAT
+ exclusive := flag&linux.O_EXCL == linux.O_EXCL
+ block := flag&linux.O_NONBLOCK != linux.O_NONBLOCK
+
+ var attr linux.MqAttr
+ var attrPtr *linux.MqAttr
+ if attrAddr != 0 {
+ if _, err := attr.CopyIn(t, attrAddr); err != nil {
+ return 0, nil, err
+ }
+ attrPtr = &attr
+ }
+
+ opts := openOpts(name, rOnly, wOnly, readWrite, create, exclusive, block)
+
+ r := t.IPCNamespace().PosixQueues()
+ queue, err := r.FindOrCreate(t, opts, linux.FileMode(mode), attrPtr)
+ if err != nil {
+ return 0, nil, err
+ }
+
+ fd, err := t.NewFDFromVFS2(0, queue, kernel.FDFlags{
+ CloseOnExec: flag&linux.O_CLOEXEC != 0,
+ })
+ if err != nil {
+ return 0, nil, err
+ }
+ return uintptr(fd), nil, nil
+}
+
+// MqUnlink implements mq_unlink(2).
+func MqUnlink(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ nameAddr := args[0].Pointer()
+ name, err := t.CopyInString(nameAddr, mq.MaxName)
+ if err != nil {
+ return 0, nil, err
+ }
+ return 0, nil, t.IPCNamespace().PosixQueues().Remove(t, name)
+}
+
+func openOpts(name string, rOnly, wOnly, readWrite, create, exclusive, block bool) mq.OpenOpts {
+ var access mq.AccessType
+ switch {
+ case readWrite:
+ access = mq.ReadWrite
+ case wOnly:
+ access = mq.WriteOnly
+ case rOnly:
+ access = mq.ReadOnly
+ }
+
+ return mq.OpenOpts{
+ Name: name,
+ Access: access,
+ Create: create,
+ Exclusive: exclusive,
+ Block: block,
+ }
+}