Fork me on GitHub

root/kernel/syscalls/rename.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sys_rename

   1 /*
   2  * fiwix/kernel/syscalls/rename.c
   3  *
   4  * Copyright 2018-2022, Jordi Sanfeliu. All rights reserved.
   5  * Distributed under the terms of the Fiwix License.
   6  */
   7 
   8 #include <fiwix/fs.h>
   9 #include <fiwix/stat.h>
  10 #include <fiwix/errno.h>
  11 #include <fiwix/string.h>
  12 
  13 #ifdef __DEBUG__
  14 #include <fiwix/stdio.h>
  15 #include <fiwix/process.h>
  16 #endif /*__DEBUG__ */
  17 
  18 int sys_rename(const char *oldpath, const char *newpath)
  19 {
  20         struct inode *i, *dir, *i_new, *dir_new;
  21         char *tmp_oldpath, *tmp_newpath;
  22         char *oldbasename, *newbasename;
  23         int errno;
  24 
  25 #ifdef __DEBUG__
  26         printk("(pid %d) sys_rename('%s', '%s')\n", current->pid, oldpath, newpath);
  27 #endif /*__DEBUG__ */
  28 
  29         if((errno = malloc_name(oldpath, &tmp_oldpath)) < 0) {
  30                 return errno;
  31         }
  32         if((errno = namei(tmp_oldpath, &i, &dir, !FOLLOW_LINKS))) {
  33                 if(dir) {
  34                         iput(dir);
  35                 }
  36                 free_name(tmp_oldpath);
  37                 return errno;
  38         }
  39         if(IS_RDONLY_FS(i)) {
  40                 iput(i);
  41                 iput(dir);
  42                 free_name(tmp_oldpath);
  43                 return -EROFS;
  44         }
  45 
  46         if((errno = malloc_name(newpath, &tmp_newpath)) < 0) {
  47                 iput(i);
  48                 iput(dir);
  49                 free_name(tmp_oldpath);
  50                 return errno;
  51         }
  52         newbasename = remove_trailing_slash(tmp_newpath);
  53         if((errno = namei(newbasename, &i_new, &dir_new, !FOLLOW_LINKS))) {
  54                 if(!dir_new) {
  55                         iput(i);
  56                         iput(dir);
  57                         free_name(tmp_oldpath);
  58                         free_name(tmp_newpath);
  59                         return errno;
  60                 }
  61         }
  62         if(dir->dev != dir_new->dev) {
  63                 errno = -EXDEV;
  64                 goto end;
  65         }
  66         newbasename = get_basename(newbasename);
  67         if((newbasename[0] == '.' && newbasename[1] == '\0') || (newbasename[0] == '.' && newbasename[1] == '.' && newbasename[2] == '\0')) {
  68                 errno = -EINVAL;
  69                 goto end;
  70         }
  71 
  72         oldbasename = get_basename(tmp_oldpath);
  73         oldbasename = remove_trailing_slash(oldbasename);
  74         if((oldbasename[0] == '.' && oldbasename[1] == '\0') || (oldbasename[0] == '.' && oldbasename[1] == '.' && oldbasename[2] == '\0')) {
  75                 errno = -EINVAL;
  76                 goto end;
  77         }
  78 
  79         if(i_new) {
  80                 if(S_ISREG(i->i_mode)) {
  81                         if(S_ISDIR(i_new->i_mode)) {
  82                                 errno = -EISDIR;
  83                                 goto end;
  84                         }
  85                 }
  86                 if(S_ISDIR(i->i_mode)) {
  87                         if(!S_ISDIR(i_new->i_mode)) {
  88                                 errno = -ENOTDIR;
  89                                 goto end;
  90                         }
  91                 }
  92                 if(i->inode == i_new->inode) {
  93                         errno = 0;
  94                         goto end;
  95                 }
  96         }
  97 
  98         if(check_permission(TO_EXEC | TO_WRITE, dir_new) < 0) {
  99                 errno = -EACCES;
 100                 goto end;
 101         }
 102 
 103         if(dir_new->fsop && dir_new->fsop->rename) {
 104                 errno = dir_new->fsop->rename(i, dir, i_new, dir_new, oldbasename, newbasename);
 105         } else {
 106                 errno = -EPERM;
 107         }
 108 
 109 end:
 110         iput(i);
 111         iput(dir);
 112         iput(i_new);
 113         iput(dir_new);
 114         free_name(tmp_oldpath);
 115         free_name(tmp_newpath);
 116         return errno;
 117 }

/* [previous][next][first][last][top][bottom][index][help] */