diff --git a/headers/private/kernel/syscalls.h b/headers/private/kernel/syscalls.h index 1254bc4725..aeabb38eed 100644 --- a/headers/private/kernel/syscalls.h +++ b/headers/private/kernel/syscalls.h @@ -179,6 +179,7 @@ extern status_t _kern_unlink(int fd, const char *path); extern status_t _kern_rename(int oldDir, const char *oldpath, int newDir, const char *newpath); extern status_t _kern_create_fifo(const char *path, mode_t perms); +extern status_t _kern_create_pipe(int *fds); extern status_t _kern_access(const char *path, int mode); extern ssize_t _kern_select(int numfds, struct fd_set *readSet, struct fd_set *writeSet, struct fd_set *errorSet, diff --git a/headers/private/kernel/vfs.h b/headers/private/kernel/vfs.h index e871e39ec8..aaa3d6a363 100644 --- a/headers/private/kernel/vfs.h +++ b/headers/private/kernel/vfs.h @@ -172,6 +172,7 @@ status_t _user_unlink(int fd, const char *path); status_t _user_rename(int oldFD, const char *oldpath, int newFD, const char *newpath); status_t _user_create_fifo(const char *path, mode_t perms); +status_t _user_create_pipe(int *fds); status_t _user_access(const char *path, int mode); ssize_t _user_select(int numfds, fd_set *readSet, fd_set *writeSet, fd_set *errorSet, bigtime_t timeout, const sigset_t *sigMask); diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 384ca863dd..08c7247ead 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -8186,6 +8186,60 @@ _user_create_fifo(const char *userPath, mode_t perms) } +status_t +_user_create_pipe(int *userFDs) +{ + // rootfs should support creating FIFOs, but let's be sure + if (!HAS_FS_CALL(sRoot, create_special_node)) + return B_UNSUPPORTED; + + // create the node -- the FIFO sub node is set up automatically + fs_vnode superVnode; + ino_t nodeID; + status_t status = FS_CALL(sRoot, create_special_node, NULL, NULL, + S_IFIFO | S_IRUSR | S_IWUSR, 0, &superVnode, &nodeID); + if (status != B_OK) + return status; + + // We've got one reference to the node and need another one. + struct vnode* vnode; + status = get_vnode(sRoot->mount->id, nodeID, &vnode, true, false); + if (status != B_OK) { + // that should not happen + dprintf("_user_create_pipe(): Failed to lookup vnode (%ld, %lld)\n", + sRoot->mount->id, sRoot->id); + return status; + } + + // Everything looks good so far. Open two FDs for reading respectively + // writing. + int fds[2]; + fds[0] = open_vnode(vnode, O_RDONLY, false); + fds[1] = open_vnode(vnode, O_WRONLY, false); + + FDCloser closer0(fds[0], false); + FDCloser closer1(fds[1], false); + + status = (fds[0] >= 0 ? (fds[1] >= 0 ? B_OK : fds[1]) : fds[0]); + + // copy FDs to userland + if (status == B_OK) { + if (!IS_USER_ADDRESS(userFDs) + || user_memcpy(userFDs, fds, sizeof(fds)) != B_OK) { + status = B_BAD_ADDRESS; + } + } + + // keep FDs, if everything went fine + if (status == B_OK) { + closer0.Detach(); + closer1.Detach(); + } + + return status; +} + + status_t _user_access(const char *userPath, int mode) { diff --git a/src/system/kernel/fs/vfs_boot.cpp b/src/system/kernel/fs/vfs_boot.cpp index 86ed212ca9..6254a74680 100644 --- a/src/system/kernel/fs/vfs_boot.cpp +++ b/src/system/kernel/fs/vfs_boot.cpp @@ -453,12 +453,6 @@ vfs_bootstrap_file_systems(void) if (status < B_OK) panic("error mounting devfs\n"); - // bootstrap the pipefs - _kern_create_dir(-1, "/pipe", 0755); - status = _kern_mount("/pipe", NULL, "pipefs", 0, NULL, 0); - if (status < B_OK) - panic("error mounting pipefs\n"); - // create directory for the boot volume _kern_create_dir(-1, "/boot", 0755); diff --git a/src/system/libroot/posix/unistd/pipe.c b/src/system/libroot/posix/unistd/pipe.c index f976209cc2..7e665beeea 100644 --- a/src/system/libroot/posix/unistd/pipe.c +++ b/src/system/libroot/posix/unistd/pipe.c @@ -1,34 +1,20 @@ /* - * Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. All rights reserved. * Distributed under the terms of the MIT License. */ - -#include - +#include #include -#include -#include + +#include int pipe(int streams[2]) { - bigtime_t timestamp = system_time(); - char pipeName[64]; - - while (system_time() <= timestamp) // ensure we get an unused timestamp - ; - - sprintf(pipeName, "/pipe/%03lx-%Ld", find_thread(NULL), system_time()); - - streams[0] = open(pipeName, O_CREAT | O_RDONLY, 0777); - if (streams[0] < 0) - return -1; - - streams[1] = open(pipeName, O_WRONLY); - if (streams[1] < 0) { - close(streams[0]); + status_t error = _kern_create_pipe(streams); + if (error != B_OK) { + errno = error; return -1; }