新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > linux內(nèi)核中的文件描述符(五)--fd的分配--locate_fd

        linux內(nèi)核中的文件描述符(五)--fd的分配--locate_fd

        作者: 時間:2016-11-22 來源:網(wǎng)絡(luò) 收藏
        Kernel version:2.6.14

        CPU architecture:ARM920T

        本文引用地址:http://www.104case.com/article/201611/320001.htm

        Author:ce123(http://blog.csdn.net/ce123)

        繼續(xù)上一篇博客的內(nèi)容,分析另一個文件描述符fd的分配函數(shù)locate_fd。dup系統(tǒng)調(diào)用用于復(fù)制一個文件描述符對應(yīng)的文件,返回值是個文件描述符。在前面的文章中,我們已經(jīng)分析過了dup的源碼(http://blog.csdn.net/ce123/article/details/8444482),在這里我們深入分析locate_fd函數(shù),其定義如下:

        [plain]view plaincopy
        print?
        1. staticintlocate_fd(structfiles_struct*files,
        2. structfile*file,unsignedintorig_start)//從orig_start位開始分配fd
        3. {
        4. unsignedintnewfd;
        5. unsignedintstart;
        6. interror;
        7. structfdtable*fdt;
        8. error=-EINVAL;
        9. if(orig_start>=current->signal->rlim[RLIMIT_NOFILE].rlim_cur)//檢查orig_start是大于進(jìn)程最大可以打開文件的數(shù)量
        10. gotoout;
        11. repeat:
        12. fdt=files_fdtable(files);//文件描述符位圖
        13. /*
        14. *Someonemighthaveclosedfdsintherange
        15. *orig_start..fdt->next_fd
        16. */
        17. start=orig_start;
        18. if(startnext_fd)
        19. start=fdt->next_fd;//如果orig_start小于next_fd,那就從next_fd開始分配
        20. newfd=start;
        21. if(startmax_fdset){//max_fdset是描述符問題的位數(shù),下面會具體講解
        22. newfd=find_next_zero_bit(fdt->open_fds->fds_bits,
        23. fdt->max_fdset,start);//分配fd
        24. }
        25. error=-EMFILE;
        26. if(newfd>=current->signal->rlim[RLIMIT_NOFILE].rlim_cur)//進(jìn)行判斷,分配的fd不能大于進(jìn)程最大可以打開的文件數(shù)量
        27. gotoout;
        28. error=expand_files(files,newfd);//文件描述符表的擴(kuò)展,這個我們留在下一篇文章中詳細(xì)講解
        29. if(error<0)
        30. gotoout;
        31. /*
        32. *Ifweneededtoexpandthefsarraywe
        33. *mighthaveblocked-tryagain.
        34. */
        35. if(error)
        36. gotorepeat;
        37. /*
        38. *Wereacquiredfiles_lock,sowearesafeaslongas
        39. *wereacquirethefdtablepointeranduseitwhileholding
        40. *thelock,noonecanfreeitduringthattime.
        41. */
        42. fdt=files_fdtable(files);
        43. if(start<=fdt->next_fd)
        44. fdt->next_fd=newfd+1;//更新next_fd值
        45. error=newfd;
        46. out:
        47. returnerror;
        48. }
        max_fdset值的分析和rlim_cur差不多,最初的值時從父進(jìn)程繼承過來的。

        [plain]view plaincopy
        print?
        1. linux/arch/arm/kernel/init_task.c
        2. structtask_structinit_task=INIT_TASK(init_task);
        3. #defineINIT_TASK(tsk)
        4. {
        5. ...
        6. .files=&init_files,
        7. ...
        8. }
        init_files的定義如下:

        [plain]view plaincopy
        print?
        1. staticstructfiles_structinit_files=INIT_FILES;
        2. linux/init_task.h
        3. #defineINIT_FDTABLE
        4. {
        5. .max_fds=NR_OPEN_DEFAULT,
        6. .max_fdset=__FD_SETSIZE,
        7. .next_fd=0,
        8. .fd=&init_files.fd_array[0],
        9. .close_on_exec=&init_files.close_on_exec_init,
        10. .open_fds=&init_files.open_fds_init,
        11. .rcu=RCU_HEAD_INIT,
        12. .free_files=NULL,
        13. .next=NULL,
        14. }
        15. #defineNR_OPEN_DEFAULTBITS_PER_LONG
        16. #define__FD_SETSIZE1024
        17. #defineINIT_FILES
        18. {
        19. .count=ATOMIC_INIT(1),
        20. .file_lock=SPIN_LOCK_UNLOCKED,
        21. .fdt=&init_files.fdtab,
        22. .fdtab=INIT_FDTABLE,
        23. .close_on_exec_init={{0,}},
        24. .open_fds_init={{0,}},
        25. .fd_array={NULL,}
        26. }
        BITS_PER_LONG是long型數(shù)據(jù)的字節(jié)數(shù),即4*8=3,也就是說max_fds = 32。max_fdset為1024。max_fdset是進(jìn)程打開文件描述符位圖open_fds的大小。open_fds是fd_set的指針。

        [plain]view plaincopy
        print?
        1. typedef__kernel_fd_setfd_set;
        2. #undef__NFDBITS
        3. #define__NFDBITS(8*sizeof(unsignedlong))
        4. #undef__FD_SETSIZE
        5. #define__FD_SETSIZE1024
        6. #undef__FDSET_LONGS
        7. #define__FDSET_LONGS(__FD_SETSIZE/__NFDBITS)
        8. #undef__FDELT
        9. #define__FDELT(d)((d)/__NFDBITS)
        10. #undef__FDMASK
        11. #define__FDMASK(d)(1UL<<((d)%__NFDBITS))
        12. typedefstruct{
        13. unsignedlongfds_bits[__FDSET_LONGS];
        14. }__kernel_fd_set;
        fds_bits是一個long型數(shù)組,共有32個元素,共有1024bit。


        評論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 黔江区| 天水市| 邻水| 缙云县| 黔江区| 定远县| 夏邑县| 肃北| 梁平县| 土默特右旗| 浦东新区| 廊坊市| 乳山市| 安塞县| 垦利县| 凤山县| 特克斯县| 岢岚县| 普宁市| 乌苏市| 鹤峰县| 澄迈县| 大埔县| 伊宁市| 陵水| 神木县| 色达县| 固始县| 平阴县| 兴国县| 乌兰浩特市| 苍山县| 中超| 田林县| 任丘市| 贞丰县| 南汇区| 蓝山县| 静乐县| 横峰县| 仲巴县|