/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */ /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */ /* Copyright (C) 2014 OSCAR lab, Stony Brook University This file is part of Graphene Library OS. Graphene Library OS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Graphene Library OS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* * fs.c * * This file contains codes for implementation of 'pipe' filesystem. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int pipe_read (struct shim_handle * hdl, void * buf, size_t count) { int rv = 0; if (!count) goto out; rv = DkStreamRead(hdl->pal_handle, 0, count, buf, NULL, 0) ? : -PAL_ERRNO; out: return rv; } static int pipe_write (struct shim_handle * hdl, const void * buf, size_t count) { if (!count) return 0; int bytes = DkStreamWrite(hdl->pal_handle, 0, count, (void *) buf, NULL); if (!bytes) return -PAL_ERRNO; return bytes; } static int pipe_hstat (struct shim_handle * hdl, struct stat * stat) { if (!stat) return 0; struct shim_thread * thread = get_cur_thread(); stat->st_dev = (dev_t) 0; /* ID of device containing file */ stat->st_ino = (ino_t) 0; /* inode number */ stat->st_nlink = (nlink_t) 0; /* number of hard links */ stat->st_uid = (uid_t) thread->uid; /* user ID of owner */ stat->st_gid = (gid_t) thread->gid; /* group ID of owner */ stat->st_rdev = (dev_t) 0; /* device ID (if special file) */ stat->st_size = (off_t) 0; /* total size, in bytes */ stat->st_blksize = 0; /* blocksize for file system I/O */ stat->st_blocks = 0; /* number of 512B blocks allocated */ stat->st_atime = (time_t) 0; /* access time */ stat->st_mtime = (time_t) 0; /* last modification */ stat->st_ctime = (time_t) 0; /* last status change */ stat->st_mode = S_IRUSR|S_IWUSR|S_IFIFO; return 0; } static int pipe_checkout (struct shim_handle * hdl) { hdl->fs = NULL; return 0; } static int pipe_poll (struct shim_handle * hdl, int poll_type) { int ret = 0; lock(hdl->lock); if (!hdl->pal_handle) { ret = -EBADF; goto out; } PAL_STREAM_ATTR attr; if (!DkStreamAttributesQuerybyHandle(hdl->pal_handle, &attr)) { ret = -PAL_ERRNO; goto out; } if (poll_type == FS_POLL_SZ) { ret = attr.pending_size; goto out; } ret = 0; if (attr.disconnected) ret |= FS_POLL_ER; if ((poll_type & FS_POLL_RD) && attr.readable) ret |= FS_POLL_RD; if ((poll_type & FS_POLL_WR) && attr.writeable) ret |= FS_POLL_WR; out: unlock(hdl->lock); return ret; } static int pipe_setflags (struct shim_handle * hdl, int flags) { if (!hdl->pal_handle) return 0; PAL_STREAM_ATTR attr; if (!DkStreamAttributesQuerybyHandle(hdl->pal_handle, &attr)) return -PAL_ERRNO; if (attr.nonblocking) { if (flags & O_NONBLOCK) return 0; attr.nonblocking = PAL_FALSE; } else { if (!(flags & O_NONBLOCK)) return 0; attr.nonblocking = PAL_TRUE; } if (!DkStreamAttributesSetbyHandle(hdl->pal_handle, &attr)) return -PAL_ERRNO; return 0; } struct shim_fs_ops pipe_fs_ops = { .read = &pipe_read, .write = &pipe_write, .hstat = &pipe_hstat, .checkout = &pipe_checkout, .poll = &pipe_poll, .setflags = &pipe_setflags, }; struct shim_mount pipe_builtin_fs = { .type = "pipe", .fs_ops = &pipe_fs_ops, };