??????Linux???????????????????漰????????????????get_unused_fd??locate_fd?????????????get_unused_fd?????????????????н???locate_fd?????????get_unused_fd?????(fs/open.c)??


int get_unused_fd(void)
{
 struct files_struct * files = current->files;//???????????????б?files
 int fd?? error;
 struct fdtable *fdt;

   error = -EMFILE;
 spin_lock(&files->file_lock);

repeat:
 fdt = files_fdtable(files);//????????????λ???
  fd = find_next_zero_bit(fdt->open_fds->fds_bits??
    fdt->max_fdset??
    fdt->next_fd);
//find_next_zero_bit???????????????λ?fds_bits?д?next_fdλ????????????(????next_fd)?0??λ????????????????????
 /*
  * N.B. For clone tasks sharing a files structure?? this test
  * will limit the total number of files that can be opened.
  */
 if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)//????????????????????????????
  goto out;

 /* Do we need to expand the fd array or fd set?  */
 error = expand_files(files?? fd);//??????????fd?????????????????ú??????????<0???????????>0?????????ν???fd?????
 if (error < 0)
  goto out;

 if (error) {
  /*
    * If we needed to expand the fs array we
   * might have blocked - try again.
   */
  error = -EMFILE;
  goto repeat;//??????????????????????????ο???fd?????
 }

 FD_SET(fd?? fdt->open_fds);//??open_fds??λ?????λ
 FD_CLR(fd?? fdt->close_on_exec);
 fdt->next_fd = fd + 1;//next_fd??1
#if 1
 /* Sanity check */
 if (fdt->fd[fd] != NULL) {
  printk(KERN_WARNING "get_unused_fd: slot %d not NULL! "?? fd);
  fdt->fd[fd] = NULL;
 }
#endif
 error = fd;

out:
 spin_unlock(&files->file_lock);
 return error;
}
 


????current->signal->rlim[RLIMIT_NOFILE].rlim_cur?????????????????????????????????????RLIMIT_NOFILE????????????£?


# define RLIMIT_NOFILE  7 /* max number of open files */


??????signal???У?rlim??struct rlimit????????飬


struct signal_struct {
 ...
 struct rlimit rlim[RLIM_NLIMITS];
 ...
};


????struct rlimit????????


struct rlimit {
 unsigned long rlim_cur;//????
 unsigned long rlim_max;//???