/* * Copyright 2011 Marian Ohligs, 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 #if defined(CONFIG_LWIP) && LWIP_SOCKET #include #include #include #include #include #include #include #include #include #include #include #endif /* Implementation of a simple netio device */ static ssize_t socket_read(fildes_t* file, uint8_t* buffer, size_t size) { int ret = 0; #if defined(CONFIG_LWIP) && LWIP_SOCKET ret = lwip_read((int)file->offset, buffer, size); if (ret < 0) ret = -errno; #endif return ret; } static ssize_t socket_write(fildes_t* file, uint8_t* buffer, size_t size) { int ret = 0; #if defined(CONFIG_LWIP) && LWIP_SOCKET if (BUILTIN_EXPECT(!size, 0)) return 0; #if LWIP_TCPIP_CORE_LOCKING ret = lwip_write(file->offset, buffer, size); #else // create a copy and forward this copy to the TCP/IP stack uint8_t* tmp = kmalloc(size); if (BUILTIN_EXPECT(!tmp, 0)) return -ENOMEM; memcpy(tmp, buffer, size); ret = lwip_write(file->offset, tmp, size); kfree(tmp); #endif if (ret < 0) ret = -errno; #endif return ret; } static int socket_open(fildes_t* file, const char* name) { return 0; } static int socket_close(fildes_t* file) { int ret = 0; #if defined(CONFIG_LWIP) && LWIP_SOCKET ret = lwip_close(file->offset); if (ret < 0) ret = -errno; #endif return ret; } int socket_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_SOCKET; new_node->open = &socket_open; new_node->close = &socket_close; new_node->read = &socket_read; new_node->write = &socket_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); return -ENOMEM; }