feat: extend vfs with vfsPipe and vfsPipeCreateHandle
This commit is contained in:
1 parent
560d0c6aca
commit
3124635682
1 file changed
+187
@@ -903,6 +903,175 @@ int vfsClose(int fd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vfsPipe(int* readFd, int* writeFd)
|
||||||
|
{
|
||||||
|
int rfd = allocFd();
|
||||||
|
if (rfd < 0)
|
||||||
|
return -1;
|
||||||
|
currentThread()->fds[rfd].kind = fdPipeRead;
|
||||||
|
|
||||||
|
int wfd = allocFd();
|
||||||
|
if (wfd < 0) {
|
||||||
|
currentThread()->fds[rfd].kind = fdFree;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
currentThread()->fds[wfd].kind = fdPipeWrite;
|
||||||
|
|
||||||
|
int handle = pipeCreate();
|
||||||
|
if (handle < 0) {
|
||||||
|
currentThread()->fds[rfd].kind = fdFree;
|
||||||
|
currentThread()->fds[wfd].kind = fdFree;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentThread()->fds[rfd].pipeHandle = handle;
|
||||||
|
currentThread()->fds[wfd].pipeHandle = handle;
|
||||||
|
*readFd = rfd;
|
||||||
|
*writeFd = wfd;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vfsPipeCreateHandle(void)
|
||||||
|
{
|
||||||
|
return pipeCreateDetached();
|
||||||
|
}
|
||||||
|
|
||||||
|
int vfsPipeAttach(int handle, bool wantWrite)
|
||||||
|
{
|
||||||
|
if (!pipeValid(handle))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int fd = allocFd();
|
||||||
|
if (fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
FileDescriptor* d = ¤tThread()->fds[fd];
|
||||||
|
d->node = nullptr;
|
||||||
|
d->offset = 0;
|
||||||
|
d->kind = wantWrite ? fdPipeWrite : fdPipeRead;
|
||||||
|
d->flags = fdFlagBlocking;
|
||||||
|
d->pipeHandle = handle;
|
||||||
|
|
||||||
|
if (wantWrite)
|
||||||
|
pipeAddWriter(handle);
|
||||||
|
else
|
||||||
|
pipeAddReader(handle);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vfsPipeAttachInto(FileDescriptor* targetFds, int fd, int handle, bool wantWrite)
|
||||||
|
{
|
||||||
|
if (!pipeValid(handle))
|
||||||
|
return;
|
||||||
|
|
||||||
|
FileDescriptor* d = &targetFds[fd];
|
||||||
|
d->node = nullptr;
|
||||||
|
d->offset = 0;
|
||||||
|
d->kind = wantWrite ? fdPipeWrite : fdPipeRead;
|
||||||
|
d->flags = fdFlagBlocking;
|
||||||
|
d->pipeHandle = handle;
|
||||||
|
|
||||||
|
if (wantWrite)
|
||||||
|
pipeAddWriter(handle);
|
||||||
|
else
|
||||||
|
pipeAddReader(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
int vfsPidfdOpen(uint32 targetId)
|
||||||
|
{
|
||||||
|
int handle = pidfdOpen(targetId);
|
||||||
|
if (handle < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int fd = allocFd();
|
||||||
|
if (fd < 0) {
|
||||||
|
pidfdClose(handle);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDescriptor* d = ¤tThread()->fds[fd];
|
||||||
|
d->node = nullptr;
|
||||||
|
d->offset = 0;
|
||||||
|
d->kind = fdPidfd;
|
||||||
|
d->flags = 0;
|
||||||
|
d->pipeHandle = handle;
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 vfsPidfdTarget(int fd)
|
||||||
|
{
|
||||||
|
FileDescriptor* d = fdAt(fd);
|
||||||
|
if (!d || d->kind != fdPidfd)
|
||||||
|
return threadInvalidId;
|
||||||
|
return pidfdTarget(d->pipeHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
const void* vfsBlockingChannel(int fd, bool forWrite)
|
||||||
|
{
|
||||||
|
FileDescriptor* d = fdAt(fd);
|
||||||
|
if (!d || !(d->flags & fdFlagBlocking))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (d->kind == fdPipeRead || d->kind == fdPipeWrite) {
|
||||||
|
if (forWrite) {
|
||||||
|
if (d->kind != fdPipeWrite || pipeWriteBroken(d->pipeHandle))
|
||||||
|
return nullptr;
|
||||||
|
} else if (d->kind != fdPipeRead) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return pipeChannel(d->pipeHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d->kind == fdConsole) {
|
||||||
|
/* Console writes (kputchar) are never buffered and never block. */
|
||||||
|
if (forWrite)
|
||||||
|
return nullptr;
|
||||||
|
return keyboardReaderChannel(d->pipeHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfsPollReady(int fd, int16 events, int16* outRevents)
|
||||||
|
{
|
||||||
|
int16 revents = 0;
|
||||||
|
FileDescriptor* d = fdAt(fd);
|
||||||
|
if (!d) {
|
||||||
|
*outRevents = pollNval;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (d->kind) {
|
||||||
|
case fdPipeRead:
|
||||||
|
if ((events & pollIn) && pipeHasData(d->pipeHandle))
|
||||||
|
revents |= pollIn;
|
||||||
|
break;
|
||||||
|
case fdPipeWrite:
|
||||||
|
if (pipeWriteBroken(d->pipeHandle))
|
||||||
|
revents |= pollErr;
|
||||||
|
else if ((events & pollOut) && pipeHasSpace(d->pipeHandle))
|
||||||
|
revents |= pollOut;
|
||||||
|
break;
|
||||||
|
case fdConsole:
|
||||||
|
if ((events & pollIn) && keyboardReaderHasData(d->pipeHandle))
|
||||||
|
revents |= pollIn;
|
||||||
|
/* Console writes (kputchar) are never buffered and never block --
|
||||||
|
see vfsBlockingChannel above. */
|
||||||
|
if (events & pollOut)
|
||||||
|
revents |= pollOut;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* fdFile, fdBlockDev, fdSfs: every read/write on these runs to
|
||||||
|
completion synchronously (see vfsRead/vfsWrite below), exactly
|
||||||
|
like a real local filesystem always reports poll-ready. */
|
||||||
|
revents |= (int16)(events & (pollIn | pollOut));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*outRevents = revents;
|
||||||
|
return revents != 0;
|
||||||
|
}
|
||||||
|
|
||||||
int64 vfsWrite(int fd, const void* buffer, uint64 length)
|
int64 vfsWrite(int fd, const void* buffer, uint64 length)
|
||||||
{
|
{
|
||||||
FileDescriptor* d = fdAt(fd);
|
FileDescriptor* d = fdAt(fd);
|
||||||
@@ -916,6 +1085,15 @@ int64 vfsWrite(int fd, const void* buffer, uint64 length)
|
|||||||
return (int64)length;
|
return (int64)length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (d->kind == fdPipeWrite)
|
||||||
|
return pipeWrite(d->pipeHandle, buffer, length);
|
||||||
|
if (d->kind == fdPipeRead)
|
||||||
|
return -1;
|
||||||
|
if (d->kind == fdBlockDev)
|
||||||
|
return blockDevWrite(d, buffer, length);
|
||||||
|
if (d->kind == fdSfs)
|
||||||
|
return sfsFdWrite(d, buffer, length);
|
||||||
|
|
||||||
VfsNode* node = d->node;
|
VfsNode* node = d->node;
|
||||||
if (node->type != fsTypeFile || !node->writable)
|
if (node->type != fsTypeFile || !node->writable)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -934,6 +1112,15 @@ int64 vfsRead(int fd, void* buffer, uint64 length)
|
|||||||
if (!d)
|
if (!d)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (d->kind == fdPipeRead)
|
||||||
|
return pipeRead(d->pipeHandle, buffer, length);
|
||||||
|
if (d->kind == fdPipeWrite)
|
||||||
|
return -1;
|
||||||
|
if (d->kind == fdBlockDev)
|
||||||
|
return blockDevRead(d, buffer, length);
|
||||||
|
if (d->kind == fdSfs)
|
||||||
|
return sfsFdRead(d, buffer, length);
|
||||||
|
|
||||||
if (d->kind == fdConsole) {
|
if (d->kind == fdConsole) {
|
||||||
char* text = (char*)buffer;
|
char* text = (char*)buffer;
|
||||||
uint64 count = 0;
|
uint64 count = 0;
|
||||||
|
|||||||
Reference in new issue
Block a user