???????汾??2.6.14

????dup???????????????sys_dup????????????fs/fcntl.c?С?sys_dup()??????????????????????????????????????????????????linux????????????????/????????sys_dup()???????????????“????”??????????????????????????????????????????????????????????????

????1??sys_dup??????


asmlinkage long sys_dup(unsigned int fildes)//sys_dup?????????????fildes?????????????fd
{
 int ret = -EBADF;
 struct file * file = fget(fildes);//???????????????????????


 if (file)
  ret = dupfd(file?? 0);//????????μ??????????fd??????fd??file???????
 return ret;
}
 


????1.1 fget(fildes)


struct file fastcall *fget(unsigned int fd)
{
 struct file *file;
 struct files_struct *files = current->files;//????????????????


 rcu_read_lock();
 file = fcheck_files(files?? fd);//????fd????????files??????????file??????
 if (file) {
  if (!rcuref_inc_lf(&file->f_count)) {  //????????
   /* File object ref couldn't be taken */
   rcu_read_unlock();
   return NULL;
  }
 }
 rcu_read_unlock();


 return file;
}
static inline struct file * fcheck_files(struct files_struct *files?? unsigned int fd)
{
 struct file * file = NULL;
 struct fdtable *fdt = files_fdtable(files);


 if (fd < fdt->max_fds)
  file = rcu_dereference(fdt->fd[fd]);
 return file;
}
 


????1.2 dupfd(file?? 0)


static int dupfd(struct file *file?? unsigned int start)
{
 struct files_struct * files = current->files;
 struct fdtable *fdt;
 int fd;


 spin_lock(&files->file_lock);
 fd = locate_fd(files?? file?? start);//?????????????
 if (fd >= 0) {
  /* locate_fd() may have expanded fdtable?? load the ptr */
  fdt = files_fdtable(files);//??????????????
  FD_SET(fd?? fdt->open_fds);//???????????
  FD_CLR(fd?? fdt->close_on_exec);
  spin_unlock(&files->file_lock);
  fd_install(fd?? file);//????fd??file?????????????fd???????file
 } else {
  spin_unlock(&files->file_lock);
  fput(file);
 }


 return fd;
}