The Pedigree Project 0.1
pipe-syscalls.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "pedigree/kernel/Subsystem.h"
21#include "pedigree/kernel/process/Process.h"
22#include "pedigree/kernel/processor/Processor.h"
23#include "pedigree/kernel/syscallError.h"
24
25#include <FileDescriptor.h>
26#include <PosixSubsystem.h>
27#include <fcntl.h>
28
29#include "file-syscalls.h"
30#include "modules/Module.h"
31#include "modules/system/vfs/Pipe.h"
32#include "modules/system/vfs/VFS.h"
33#include "pipe-syscalls.h"
34
35int posix_pipe(int filedes[2]) {
36 return posix_pipe2(filedes, 0);
37}
38
39int posix_pipe2(int filedes[2], int flags) {
40 if (flags & ~(O_CLOEXEC | O_NONBLOCK)) {
41 SYSCALL_ERROR(InvalidArgument);
42 return -1;
43 }
44
45 if (!PosixSubsystem::checkAddress(reinterpret_cast<uintptr_t>(filedes), sizeof(int) * 2,
46 PosixSubsystem::SafeWrite)) {
47 F_NOTICE("pipe -> invalid address");
48 SYSCALL_ERROR(BadAddress);
49 return -1;
50 }
51
52 F_NOTICE("pipe2");
53
54 Process* pProcess = Processor::information().getCurrentThread()->getParent();
55 PosixSubsystem* pSubsystem = static_cast<PosixSubsystem*>(pProcess->getSubsystem());
56 if (!pSubsystem) {
57 ERROR("No subsystem for the process!");
58 return -1;
59 }
60
61 size_t readFd = pSubsystem->getFd();
62 size_t writeFd = pSubsystem->getFd();
63
64 File* p = new Pipe(String(""), 0, 0, 0, 0, 0, 0, 0, true);
65
66 // Create the file descriptor for both
67 int descriptorFlags = (flags & O_CLOEXEC) ? FD_CLOEXEC : 0;
68 int statusFlags = flags & O_NONBLOCK;
69 FileDescriptor* read = new FileDescriptor(p, 0, readFd, descriptorFlags, O_RDONLY | statusFlags);
70 pSubsystem->addFileDescriptor(readFd, read);
71
72 FileDescriptor* write =
73 new FileDescriptor(p, 0, writeFd, descriptorFlags, O_WRONLY | statusFlags);
74 pSubsystem->addFileDescriptor(writeFd, write);
75
76 filedes[0] = readFd;
77 filedes[1] = writeFd;
78
79 F_NOTICE("pipe: returning " << readFd << " and " << writeFd << ".");
80
81 return 0;
82}
Definition File.h:75
Definition Pipe.h:36
size_t getFd(size_t minimum=0)
void addFileDescriptor(size_t fd, FileDescriptor *pFd)
static bool checkAddress(uintptr_t addr, size_t extent, size_t flags)
Process * getParent()
Definition Process.h:620
static ProcessorInformation & information()