Welcome to The Fiwix Project
A UNIX-like kernel for the i386 architecture
1 /* 2 * fiwix/kernel/syscalls/fcntl.c 3 * 4 * Copyright 2018, Jordi Sanfeliu. All rights reserved. 5 * Distributed under the terms of the Fiwix License. 6 */ 7 8 #include <fiwix/syscalls.h> 9 #include <fiwix/fcntl.h> 10 #include <fiwix/locks.h> 11 #include <fiwix/errno.h> 12 13 #ifdef __DEBUG__ 14 #include <fiwix/stdio.h> 15 #include <fiwix/process.h> 16 #endif /*__DEBUG__ */ 17 18 int sys_fcntl(int ufd, int cmd, unsigned long int arg) 19 { 20 int new_ufd, errno; 21 22 #ifdef __DEBUG__ 23 printk("(pid %d) sys_fcntl(%d, %d, 0x%08x)\n", current->pid, ufd, cmd, arg); 24 #endif /*__DEBUG__ */ 25 26 CHECK_UFD(ufd); 27 switch(cmd) { 28 case F_DUPFD: 29 CHECK_UFD(ufd); 30 if(arg >= OPEN_MAX) { 31 return -EINVAL; 32 } 33 if((new_ufd = get_new_user_fd(arg)) < 0) { 34 return new_ufd; 35 } 36 current->fd[new_ufd] = current->fd[ufd]; 37 fd_table[current->fd[new_ufd]].count++; 38 #ifdef __DEBUG__ 39 printk("\t--> returning %d\n", new_ufd); 40 #endif /*__DEBUG__ */ 41 return new_ufd; 42 case F_GETFD: 43 return (current->fd_flags[ufd] & FD_CLOEXEC); 44 case F_SETFD: 45 current->fd_flags[ufd] = (arg & FD_CLOEXEC); 46 break; 47 case F_GETFL: 48 return fd_table[current->fd[ufd]].flags; 49 case F_SETFL: 50 fd_table[current->fd[ufd]].flags &= ~(O_APPEND | O_NONBLOCK); 51 fd_table[current->fd[ufd]].flags |= arg & (O_APPEND | O_NONBLOCK); 52 break; 53 case F_GETLK: 54 case F_SETLK: 55 case F_SETLKW: 56 if((errno = check_user_area(VERIFY_READ, (void *)arg, sizeof(struct flock)))) { 57 return errno; 58 } 59 return posix_lock(ufd, cmd, (struct flock *)arg); 60 default: 61 return -EINVAL; 62 } 63 return 0; 64 }