Welcome to The Fiwix Project
A UNIX-like kernel for the i386 architecture
1 /* 2 * fiwix/kernel/syscalls/mknod.c 3 * 4 * Copyright 2018, Jordi Sanfeliu. All rights reserved. 5 * Distributed under the terms of the Fiwix License. 6 */ 7 8 #include <fiwix/types.h> 9 #include <fiwix/fs.h> 10 #include <fiwix/stat.h> 11 #include <fiwix/errno.h> 12 #include <fiwix/string.h> 13 14 #ifdef __DEBUG__ 15 #include <fiwix/stdio.h> 16 #include <fiwix/process.h> 17 #endif /*__DEBUG__ */ 18 19 int sys_mknod(const char *pathname, __mode_t mode, __dev_t dev) 20 { 21 struct inode *i, *dir; 22 char *tmp_name, *basename; 23 int errno; 24 25 #ifdef __DEBUG__ 26 printk("(pid %d) sys_mknod('%s', %d, %x)\n", current->pid, pathname, mode, dev); 27 #endif /*__DEBUG__ */ 28 29 if(!S_ISCHR(mode) && !S_ISBLK(mode) && !S_ISFIFO(mode)) { 30 return -EINVAL; 31 } 32 if(!S_ISFIFO(mode) && !IS_SUPERUSER) { 33 return -EPERM; 34 } 35 36 if((errno = malloc_name(pathname, &tmp_name)) < 0) { 37 return errno; 38 } 39 basename = get_basename(tmp_name); 40 if((errno = namei(tmp_name, &i, &dir, !FOLLOW_LINKS))) { 41 if(!dir) { 42 free_name(tmp_name); 43 return errno; 44 } 45 } 46 if(!errno) { 47 iput(i); 48 iput(dir); 49 free_name(tmp_name); 50 return -EEXIST; 51 } 52 if(IS_RDONLY_FS(dir)) { 53 iput(dir); 54 free_name(tmp_name); 55 return -EROFS; 56 } 57 if(check_permission(TO_EXEC | TO_WRITE, dir) < 0) { 58 iput(dir); 59 free_name(tmp_name); 60 return -EACCES; 61 } 62 63 if(dir->fsop && dir->fsop->mknod) { 64 errno = dir->fsop->mknod(dir, basename, mode, dev); 65 } else { 66 errno = -EPERM; 67 } 68 iput(dir); 69 free_name(tmp_name); 70 return errno; 71 }