/* * Copyright 2010 Stefan Lankes, Chair for Operating Systems, * RWTH Aachen University * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This file is part of MetalSVM. */ #include #include #include #include #include #include #include /* Implementation of a simple stdin device */ static ssize_t stdin_read(vfs_node_t* node, uint8_t* buffer, size_t size, off_t offset) { kb_buffer.buffer = kmalloc(size * sizeof(char)); kb_buffer.maxsize = size; kb_buffer.size = 0; kb_buffer.tid = per_core(current_task)->id; block_task(per_core(current_task)->id); reschedule(); size = kb_buffer.size; memcpy(buffer, kb_buffer.buffer, size); /*cleaning up */ kb_flush(); //kprintf("Size: %i, offset: %i, buffer: %s", size, buffer, offset); return size; } static ssize_t stdin_write(vfs_node_t* node, uint8_t* buffer, size_t size, off_t offset) { return size; } static int stdin_open(vfs_node_t* node) { return 0; } static int stdin_close(vfs_node_t* node) { return 0; } int stdin_init(vfs_node_t* node, const char* name) { uint32_t i, j; vfs_node_t* new_node; dir_block_t* blockdir; dirent_t* dirent; block_list_t* blist; if (BUILTIN_EXPECT(!node || !name, 0)) return -EINVAL; if (BUILTIN_EXPECT(node->type != FS_DIRECTORY, 0)) return -EINVAL; if (finddir_fs(node, name)) return -EINVAL; new_node = kmalloc(sizeof(vfs_node_t)); if (BUILTIN_EXPECT(!new_node, 0)) return -ENOMEM; memset(new_node, 0x00, sizeof(vfs_node_t)); new_node->type = FS_CHARDEVICE; new_node->open = &stdin_open; new_node->close = &stdin_close; new_node->read = &stdin_read; new_node->write = &stdin_write; spinlock_init(&new_node->lock); blist= &node->block_list; do { for(i=0; idata[i]) { blockdir = (dir_block_t*) blist->data[i]; for(j=0; jentries[j]; if (!dirent->vfs_node) { dirent->vfs_node = new_node; strncpy(dirent->name, name, MAX_FNAME); return 0; } } } } if (!blist->next) { blist->next = (block_list_t*) kmalloc(sizeof(block_list_t)); if (blist->next) memset(blist->next, 0x00, sizeof(block_list_t)); } } while(blist); kfree(new_node, sizeof(vfs_node_t)); return -ENOMEM; }