Changeset 23 for trunk/kernel/syscalls/sys_read.c
- Timestamp:
- Jun 18, 2017, 10:06:41 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_read.c
r1 r23 1 1 /* 2 * kern/sys_read.c - read bytes from an openedfile2 * sys_read.c - read bytes from a file 3 3 * 4 * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless 5 * Copyright (c) 2011,2012 UPMC Sorbonne Universites 4 * Author Alain Greiner (2016,2017) 6 5 * 7 * This file is part of ALMOS-kernel.6 * Copyright (c) UPMC Sorbonne Universites 8 7 * 9 * ALMOS-kernel is free software; you can redistribute it and/or modify it 8 * This file is part of ALMOS-MKH. 9 * 10 * ALMOS-MKH is free software; you can redistribute it and/or modify it 10 11 * under the terms of the GNU General Public License as published by 11 12 * the Free Software Foundation; version 2.0 of the License. 12 13 * 13 * ALMOS- kernelis distributed in the hope that it will be useful, but14 * ALMOS-MKH is distributed in the hope that it will be useful, but 14 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU … … 17 18 * 18 19 * You should have received a copy of the GNU General Public License 19 * along with ALMOS- kernel; if not, write to the Free Software Foundation,20 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 20 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 22 */ 22 23 24 #include <kernel_config.h> 25 #include <hal_types.h> 26 #include <hal_uspace.h> 27 #include <hal_special.h> 23 28 #include <errno.h> 29 #include <vfs.h> 30 #include <vmm.h> 24 31 #include <thread.h> 25 #include <vfs.h> 26 #include <sys-vfs.h> 27 #include <task.h> 32 #include <printk.h> 33 #include <process.h> 28 34 29 int sys_read (uint_t fd, void *buf, size_t count) 35 /* TODO: user page(s) need to be locked [AG] */ 36 37 ///////////////////////////////// 38 int sys_read( uint32_t file_id, 39 void * buf, 40 uint32_t count ) 30 41 { 31 struct ku_obj kub; 32 ssize_t err; 33 struct thread_s *this; 34 struct task_s *task; 35 struct vfs_file_s *file; 42 error_t error; 43 paddr_t paddr; 44 char kbuf[CONFIG_VFS_KBUF_SIZE]; 36 45 37 file = NULL; 38 this = current_thread; 39 task = current_task; 46 xptr_t file_xp; // remote file extended pointer 47 uint32_t nbytes; // number of bytes in one iteration 40 48 41 if((fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task, fd, &file))) 49 thread_t * this = CURRENT_THREAD; 50 process_t * process = this->process; 51 52 // check file_id argument 53 if( file_id >= CONFIG_PROCESS_FILE_MAX_NR ) 42 54 { 43 this->info.errno = EBADFD; 55 printk("\n[ERROR] in %s : illegal file descriptor index = %d\n", 56 __FUNCTION__ , file_id ); 57 this->errno = EBADFD; 44 58 return -1; 45 59 } 46 60 47 KU_SLICE_BUFF(kub, buf, count); 48 if((err = vfs_read(file, &kub)) < 0) 61 // check user buffer in user space 62 error = vmm_v2p_translate( false , buf , &paddr ); 63 64 if ( error ) 65 { 66 printk("\n[ERROR] in %s : user buffer unmapped = %x\n", 67 __FUNCTION__ , (intptr_t)buf ); 68 this->errno = EINVAL; 69 return -1; 70 } 71 72 // get extended pointer on remote file descriptor 73 file_xp = process_fd_get_xptr( process , file_id ); 74 75 if( file_xp == XPTR_NULL ) 76 { 77 printk("\n[ERROR] in %s : undefined file descriptor index = %d\n", 78 __FUNCTION__ , file_id ); 79 this->errno = EBADFD; 80 return -1; 81 } 82 83 // get file descriptor cluster and local pointer 84 vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp ); 85 cxy_t file_cxy = GET_CXY( file_xp ); 86 87 // check file readable 88 uint32_t attr = hal_remote_lw( XPTR( file_cxy , &file_ptr->attr ) ); 89 if( (attr & FD_ATTR_READ_ENABLE) == 0 ) 49 90 { 50 this->info.errno = -err; 51 printk(INFO, "INFO: sys_read: Error %d\n", this->info.errno); 91 printk("\n[ERROR] in %s : file %d not readable\n", 92 __FUNCTION__ , file_id ); 93 this->errno = EBADFD; 52 94 return -1; 53 95 } 54 96 55 return err; 56 } 97 // transfer at most CONFIG_VFS_KBUF_SIZE bytes per iteration 98 while( count ) 99 { 100 if( count <= CONFIG_VFS_KBUF_SIZE ) 101 { 102 nbytes = count; 103 count = 0; 104 } 105 else 106 { 107 nbytes = CONFIG_VFS_KBUF_SIZE; 108 count = count - CONFIG_VFS_KBUF_SIZE; 109 } 110 111 // transfer nbytes to kernel buffer 112 error = vfs_move( true, // read => (to_buffer = true) 113 file_xp , 114 kbuf , 115 nbytes ); 116 117 if( error ) 118 { 119 printk("\n[ERROR] in %s cannot read data from file %d\n", 120 __FUNCTION__ , file_id ); 121 this->errno = error; 122 return -1; 123 } 124 125 // copy kernel buffer to user space 126 hal_copy_to_uspace( buf , kbuf , nbytes ); 127 } 128 129 hal_wbflush(); 130 131 return 0; 132 133 } // end sys_read()
Note: See TracChangeset
for help on using the changeset viewer.