示例#1
0
        private static int StatAt64(Thread current, UserPtr filenamePtr, UserPtr buf, bool followSymlink)
        {
            var proc = current.Parent;
            int err;

            filenamePtr.ReadString(current, Globals.LinuxIPCBuffer);
            if (followSymlink)
            {
                err = Arch.IPCStubs.linux_sys_stat64(proc.helperPid);
            }
            else
            {
                err = Arch.IPCStubs.linux_sys_lstat64(proc.helperPid);
            }
            if (err != 0)
            {
                return(err);
            }

            if (buf.Write(current, new Pointer(Globals.LinuxIPCBuffer.Location), SIZE_OF_STAT64) != 0)
            {
                return(-ErrorCode.EFAULT);
            }

            return(0);
        }
示例#2
0
        public static int Access(Thread current, ref Arch.ExceptionRegisters regs, UserPtr filenamePtr, int mode)
        {
            // XXX: This is vfs related, now let's assume that we're dealing with pass through fs.

            var buf = Globals.AllocateAlignedCompletionBuffer(PATH_MAX);

            if (!buf.isValid)
                return -ErrorCode.ENOMEM;

            var ret = filenamePtr.ReadString(current, buf);

            var accessCompletion = new BridgeCompletion(current, buf);

            ret = Arch.IPCStubs.AccessAsync(current.Parent.helperPid, current.impl._value.thread._value, new Pointer(buf.Location), mode);

            if (ret < 0)
            {
                accessCompletion.Dispose();
                return ret;
            }

            Globals.CompletionQueue.Enqueue(accessCompletion);
            current.SaveState(ref regs);
            current.AsyncReturn = true;
            return 0;
        }
示例#3
0
        public static int Access(Thread current, ref Arch.ExceptionRegisters regs, UserPtr filenamePtr, int mode)
        {
            // XXX: This is vfs related, now let's assume that we're dealing with pass through fs.

            var buf = Globals.AllocateAlignedCompletionBuffer(PATH_MAX);

            if (!buf.isValid)
            {
                return(-ErrorCode.ENOMEM);
            }

            var ret = filenamePtr.ReadString(current, buf);

            var accessCompletion = new BridgeCompletion(current, buf);

            ret = Arch.IPCStubs.AccessAsync(current.Parent.helperPid, current.impl._value.thread._value, new Pointer(buf.Location), mode);

            if (ret < 0)
            {
                accessCompletion.Dispose();
                return(ret);
            }

            Globals.CompletionQueue.Enqueue(accessCompletion);
            current.SaveState(ref regs);
            current.AsyncReturn = true;
            return(0);
        }
示例#4
0
        internal static int AshmemIoctl(GenericINode generic_inode, Thread current, uint cmd, UserPtr arg1)
        {
            Contract.Requires(Globals.LinuxIPCBuffer.Length >= AshmemINode.ASHMEM_PIN_SIZE);

            int ret = 0;

            switch (cmd)
            {
                case AshmemINode.ASHMEM_SET_NAME:
                    arg1.ReadString(current, Globals.LinuxIPCBuffer);
                    break;

                case AshmemINode.ASHMEM_PIN:
                case AshmemINode.ASHMEM_UNPIN:
                    if (arg1.Read(current, Globals.LinuxIPCBuffer, AshmemINode.ASHMEM_PIN_SIZE) != 0)
                        ret = -ErrorCode.EFAULT;
                    break;

                case AshmemINode.ASHMEM_GET_NAME:
                case AshmemINode.ASHMEM_SET_SIZE:
                case AshmemINode.ASHMEM_GET_SIZE:
                case AshmemINode.ASHMEM_SET_PROT_MASK:
                case AshmemINode.ASHMEM_GET_PROT_MASK:
                case AshmemINode.ASHMEM_GET_PIN_STATUS:
                case AshmemINode.ASHMEM_PURGE_ALL_CACHES:
                    break;

                default:
                    ret = -ErrorCode.ENOSYS;
                    break;
            }

            if (ret < 0)
                return ret;

            var linux_fd = generic_inode.LinuxFd;

            ret = Arch.IPCStubs.linux_sys_vfs_ashmem_ioctl(current.Parent.helperPid, linux_fd, cmd, arg1.Value.ToInt32());

            if (ret < 0)
                  return ret;

            // unmarshal if necessary
            if (cmd == AshmemINode.ASHMEM_GET_NAME)
            {
                var length = Util.Strnlen(Globals.LinuxIPCBuffer, AshmemINode.ASHMEM_NAME_LEN);
                // include terminator
                if (length < AshmemINode.ASHMEM_NAME_LEN)
                    length++;

                var buf = Globals.LinuxIPCBuffer.Slice(0, length);
                if (arg1.Write(current, Globals.LinuxIPCBuffer) != 0)
                    return -ErrorCode.EFAULT;
            }

            return ret;
        }
示例#5
0
        private static int StatAt64(Thread current, UserPtr filenamePtr, UserPtr buf, bool followSymlink)
        {
            var proc = current.Parent;
            int err;
            filenamePtr.ReadString(current, Globals.LinuxIPCBuffer);
            if (followSymlink)
            {
                err = Arch.IPCStubs.linux_sys_stat64(proc.helperPid);
            }
            else
            {
                err = Arch.IPCStubs.linux_sys_lstat64(proc.helperPid);
            }
            if (err != 0)
                return err;

            if (buf.Write(current, new Pointer(Globals.LinuxIPCBuffer.Location), SIZE_OF_STAT64) != 0)
                return -ErrorCode.EFAULT;

            return 0;
        }
示例#6
0
 public static int Unlink(Thread current, UserPtr pathname)
 {
     pathname.ReadString(current, Globals.LinuxIPCBuffer);
     return Arch.IPCStubs.Unlink(current.Parent.helperPid);
 }
示例#7
0
        public static int Open(Thread current, ref Arch.ExceptionRegisters regs, UserPtr filenamePtr, int flags, int mode)
        {
            // TODO: Deal with current path
            var filenameBuf = new byte[PATH_MAX];
            var ret = filenamePtr.ReadString(current, filenameBuf);

            var proc = current.Parent;
            int fd = 0;
            GenericINode inode = null;

            var startTime = Arch.NativeMethods.l4api_get_system_clock();

            if (Util.ByteStringCompare(filenameBuf, IPCFilename.GetByteString()) == 0)
            {
                fd = proc.GetUnusedFd();
                inode = BinderINode.Instance;
            }
            else if (Util.ByteStringCompare(filenameBuf, AshmemFileName.GetByteString()) == 0)
            {
                var linux_fd = Arch.ArchFS.OpenAndReturnLinuxFd(current.Parent.helperPid, new ASCIIString(filenameBuf), flags, mode);
                if (linux_fd < 0)
                    return linux_fd;

                inode = new AshmemINode(linux_fd, current.Parent.helperPid);
                fd = proc.GetUnusedFd();
            }
            else if (SecureFS.IsSecureFS(current, filenameBuf))
            {
                var completion = SecureFS.OpenAndReadPagesAsync(current, filenameBuf, flags, mode);
                if (completion == null)
                    return -ErrorCode.ENOMEM;

                Globals.CompletionQueue.Enqueue(completion);
                current.SaveState(ref regs);
                current.AsyncReturn = true;
                return 0;
            }
            else
            {
                var filename_len = ret;

                var completion = Arch.ArchFS.OpenAndGetSizeAsync(current, filenameBuf, flags, mode);
                if (completion == null)
                    return -ErrorCode.ENOMEM;

                Globals.CompletionQueue.Enqueue(completion);
                current.SaveState(ref regs);
                current.AsyncReturn = true;
                return 0;
            }

            if (fd > 0)
            {
                var file = new File(proc, inode, flags, mode);
                proc.InstallFd(fd, file);
            }

            if (SyscallProfiler.Enable)
            {
                var endTime = Arch.NativeMethods.l4api_get_system_clock();
                SyscallProfiler.AccountOpen((int)inode.kind, (long)(endTime - startTime));
            }

            return fd;
        }
示例#8
0
 public static int Mkdir(Thread current, UserPtr pathname, int mode)
 {
     pathname.ReadString(current, Globals.LinuxIPCBuffer);
     return Arch.IPCStubs.Mkdir(current.Parent.helperPid, mode);
 }
示例#9
0
        internal static int AshmemIoctl(GenericINode generic_inode, Thread current, uint cmd, UserPtr arg1)
        {
            Contract.Requires(Globals.LinuxIPCBuffer.Length >= AshmemINode.ASHMEM_PIN_SIZE);

            int ret = 0;

            switch (cmd)
            {
            case AshmemINode.ASHMEM_SET_NAME:
                arg1.ReadString(current, Globals.LinuxIPCBuffer);
                break;

            case AshmemINode.ASHMEM_PIN:
            case AshmemINode.ASHMEM_UNPIN:
                if (arg1.Read(current, Globals.LinuxIPCBuffer, AshmemINode.ASHMEM_PIN_SIZE) != 0)
                {
                    ret = -ErrorCode.EFAULT;
                }
                break;

            case AshmemINode.ASHMEM_GET_NAME:
            case AshmemINode.ASHMEM_SET_SIZE:
            case AshmemINode.ASHMEM_GET_SIZE:
            case AshmemINode.ASHMEM_SET_PROT_MASK:
            case AshmemINode.ASHMEM_GET_PROT_MASK:
            case AshmemINode.ASHMEM_GET_PIN_STATUS:
            case AshmemINode.ASHMEM_PURGE_ALL_CACHES:
                break;

            default:
                ret = -ErrorCode.ENOSYS;
                break;
            }

            if (ret < 0)
            {
                return(ret);
            }

            var linux_fd = generic_inode.LinuxFd;

            ret = Arch.IPCStubs.linux_sys_vfs_ashmem_ioctl(current.Parent.helperPid, linux_fd, cmd, arg1.Value.ToInt32());

            if (ret < 0)
            {
                return(ret);
            }

            // unmarshal if necessary
            if (cmd == AshmemINode.ASHMEM_GET_NAME)
            {
                var length = Util.Strnlen(Globals.LinuxIPCBuffer, AshmemINode.ASHMEM_NAME_LEN);
                // include terminator
                if (length < AshmemINode.ASHMEM_NAME_LEN)
                {
                    length++;
                }

                var buf = Globals.LinuxIPCBuffer.Slice(0, length);
                if (arg1.Write(current, Globals.LinuxIPCBuffer) != 0)
                {
                    return(-ErrorCode.EFAULT);
                }
            }

            return(ret);
        }
示例#10
0
 public static int Unlink(Thread current, UserPtr pathname)
 {
     pathname.ReadString(current, Globals.LinuxIPCBuffer);
     return(Arch.IPCStubs.Unlink(current.Parent.helperPid));
 }
示例#11
0
 public static int Mkdir(Thread current, UserPtr pathname, int mode)
 {
     pathname.ReadString(current, Globals.LinuxIPCBuffer);
     return(Arch.IPCStubs.Mkdir(current.Parent.helperPid, mode));
 }
示例#12
0
        public static int Open(Thread current, ref Arch.ExceptionRegisters regs, UserPtr filenamePtr, int flags, int mode)
        {
            // TODO: Deal with current path
            var filenameBuf = new byte[PATH_MAX];
            var ret         = filenamePtr.ReadString(current, filenameBuf);

            var          proc  = current.Parent;
            int          fd    = 0;
            GenericINode inode = null;

            var startTime = Arch.NativeMethods.l4api_get_system_clock();

            if (Util.ByteStringCompare(filenameBuf, IPCFilename.GetByteString()) == 0)
            {
                fd    = proc.GetUnusedFd();
                inode = BinderINode.Instance;
            }
            else if (Util.ByteStringCompare(filenameBuf, AshmemFileName.GetByteString()) == 0)
            {
                var linux_fd = Arch.ArchFS.OpenAndReturnLinuxFd(current.Parent.helperPid, new ASCIIString(filenameBuf), flags, mode);
                if (linux_fd < 0)
                {
                    return(linux_fd);
                }

                inode = new AshmemINode(linux_fd, current.Parent.helperPid);
                fd    = proc.GetUnusedFd();
            }
            else if (SecureFS.IsSecureFS(current, filenameBuf))
            {
                var completion = SecureFS.OpenAndReadPagesAsync(current, filenameBuf, flags, mode);
                if (completion == null)
                {
                    return(-ErrorCode.ENOMEM);
                }

                Globals.CompletionQueue.Enqueue(completion);
                current.SaveState(ref regs);
                current.AsyncReturn = true;
                return(0);
            }
            else
            {
                var filename_len = ret;

                var completion = Arch.ArchFS.OpenAndGetSizeAsync(current, filenameBuf, flags, mode);
                if (completion == null)
                {
                    return(-ErrorCode.ENOMEM);
                }

                Globals.CompletionQueue.Enqueue(completion);
                current.SaveState(ref regs);
                current.AsyncReturn = true;
                return(0);
            }

            if (fd > 0)
            {
                var file = new File(proc, inode, flags, mode);
                proc.InstallFd(fd, file);
            }

            if (SyscallProfiler.Enable)
            {
                var endTime = Arch.NativeMethods.l4api_get_system_clock();
                SyscallProfiler.AccountOpen((int)inode.kind, (long)(endTime - startTime));
            }

            return(fd);
        }