Changeset 23 for trunk/kernel/syscalls/sys_write.c
- Timestamp:
- Jun 18, 2017, 10:06:41 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_write.c
r1 r23 1 1 /* 2 * kern/sys_write.c - write bytes to a file2 * sys_write.c - write bytes to 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> 24 #include <thread.h>25 29 #include <vfs.h> 26 30 #include <thread.h> 27 #include < sys-vfs.h>28 #include < task.h>31 #include <printk.h> 32 #include <process.h> 29 33 30 int sys_write (uint_t fd, void *buf, size_t count) 34 /* TODO: user page(s) need to be locked [AG] */ 35 36 ////////////////////////////////// 37 int sys_write( uint32_t file_id, 38 void * buf, 39 uint32_t count ) 31 40 { 32 ssize_t err = 0;33 struct thread_s *this;34 struct task_s *task;35 struct vfs_file_s *file;36 struct ku_obj kub; 41 error_t error; 42 paddr_t paddr; 43 char kbuf[CONFIG_VFS_KBUF_SIZE]; 44 xptr_t file_xp; // remote file extended pointer 45 uint32_t nbytes; // number of bytes in one iteration 37 46 38 file = NULL; 39 this = current_thread; 40 task = current_task; 47 thread_t * this = CURRENT_THREAD; 48 process_t * process = this->process; 41 49 42 if((fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task, fd, &file))) 50 // check file_id argument 51 if( file_id >= CONFIG_PROCESS_FILE_MAX_NR ) 43 52 { 44 this->info.errno = EBADFD; 53 printk("\n[ERROR] in %s : illegal file descriptor index\n", __FUNCTION__ ); 54 this->errno = EBADFD; 45 55 return -1; 46 56 } 47 57 48 KU_SLICE_BUFF(kub, buf, count); 49 if((err = vfs_write(file, &kub)) < 0) 58 // check user buffer in user space 59 error = vmm_v2p_translate( false , buf , &paddr ); 60 61 if ( error ) 62 { 63 printk("\n[ERROR] in %s : user buffer unmapped = %x\n", 64 __FUNCTION__ , (intptr_t)buf ); 65 this->errno = EINVAL; 66 return -1; 67 } 68 69 // get extended pointer on remote file descriptor 70 file_xp = process_fd_get_xptr( process , file_id ); 71 72 if( file_xp == XPTR_NULL ) 73 { 74 printk("\n[ERROR] in %s : undefined file descriptor index = %d\n", 75 __FUNCTION__ , file_id ); 76 this->errno = EBADFD; 77 return -1; 78 } 79 80 // get file descriptor cluster and local pointer 81 vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp ); 82 cxy_t file_cxy = GET_CXY( file_xp ); 83 84 // check file writable 85 uint32_t attr = hal_remote_lw( XPTR( file_cxy , &file_ptr->attr ) ); 86 if( (attr & FD_ATTR_WRITE_ENABLE) == 0 ) 50 87 { 51 this->info.errno = (err < 0) ? -err : err; 88 printk("\n[ERROR] in %s : file %d not writable\n", 89 __FUNCTION__ , file_id ); 90 this->errno = EBADFD; 52 91 return -1; 53 92 } 54 93 55 return err; 56 } 94 // transfer at most CONFIG_VFS_KBUF_SIZE bytes per iteration 95 while( count ) 96 { 97 if( count <= CONFIG_VFS_KBUF_SIZE ) 98 { 99 nbytes = count; 100 count = 0; 101 } 102 else 103 { 104 nbytes = CONFIG_VFS_KBUF_SIZE; 105 count = count - CONFIG_VFS_KBUF_SIZE; 106 } 107 108 // copy user buffer to kernel buffer 109 hal_copy_to_uspace( buf , kbuf , nbytes ); 110 111 // transfer nbytes from kernel buffer 112 error = vfs_move( false, // write => (to_buffer = false) 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 126 hal_wbflush(); 127 128 return 0; 129 130 } // end sys_write()
Note: See TracChangeset
for help on using the changeset viewer.