作者 主題: 想用 stat() 判斷掛載資料夾  (閱讀 9063 次)

0 會員 與 1 訪客 正在閱讀本文。

id4fox

  • 憂鬱的高中生
  • ***
  • 文章數: 103
  • 40 oz 挑戰成功!
    • 檢視個人資料
想用 stat() 判斷掛載資料夾
« 於: 2010-03-11 18:07 »
我對一個掛載了 Windows 共享資料夾的資料夾使用 stat() 函數,
但是都回傳失敗
errno = 75 "Value too large for defined data type"

請問是不是我哪做錯了? 還是有其他解決的方法呢?

目標: 我想判斷掛載資料夾下的路徑為檔案還是資料夾
        [ps : 最好用 stat(), 才能使用 ftw()]

環境: kernel : 2.6.31.5-127.fc12.i686.PAE
        gcc     : v 4.4.2

if(stat(argv[1],&buf)){
    perror("stat");
}

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
回覆: 想用 stat() 判斷掛載資料夾
« 回覆 #1 於: 2010-03-12 13:48 »
stat結構下的st_mode的S_IFDIR旗標可判斷是否為目錄(其他旗標的函義請參考 Linux C 參考手冊 旗標出版社 徐千洋著)
巨集的話則S_ISREG(st_mode)判斷是否為一般檔案,S_ISDIR(st_mode)則判斷是否為目錄

參考參考吧^_^
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

elleryq

  • 區域板主
  • 鑽研的研究生
  • *****
  • 文章數: 908
  • 性別: 男
    • 檢視個人資料
    • Thinking more...
回覆: 想用 stat() 判斷掛載資料夾
« 回覆 #2 於: 2010-03-12 14:27 »
stat 執行失敗了,應該也沒辦法用 S_ISREG 或 S_ISDIR 來判斷了
試著加上 -D FILE_OFFSET_BITS=64 試試看?
Plan your work, then work your plan.
我的首頁:http://blog.elleryq.idv.tw
351899by http://counter.li.org

elleryq

  • 區域板主
  • 鑽研的研究生
  • *****
  • 文章數: 908
  • 性別: 男
    • 檢視個人資料
    • Thinking more...
回覆: 想用 stat() 判斷掛載資料夾
« 回覆 #3 於: 2010-03-12 14:41 »
改用 stat64

但老實說,我不是很了解其原理。
Plan your work, then work your plan.
我的首頁:http://blog.elleryq.idv.tw
351899by http://counter.li.org

id4fox

  • 憂鬱的高中生
  • ***
  • 文章數: 103
  • 40 oz 挑戰成功!
    • 檢視個人資料
回覆: 想用 stat() 判斷掛載資料夾
« 回覆 #4 於: 2010-03-12 15:28 »
改用 stat64

但老實說,我不是很了解其原理。
It's WORK !!!
喔喔! 太感謝拉!!! 原來還有個 stat64() 函數
好像即使編譯不加入 -D FILE_OFFSET_BITS=64 也 OK 喔!

至於差異上, "個人猜測"
會不會是因為掛載的關係, 個別檔案屬性資料的儲存內容較一般Linux檔案來的多
所以超出了 stat() 所預設的範圍, (注意! 個人猜測)

總之, 解決了真是太好了, 下次其他函數出 errno = 75 也來加個64看看 哈
謝謝各位的幫忙!

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
回覆: 想用 stat() 判斷掛載資料夾
« 回覆 #5 於: 2010-03-12 16:37 »
會不會是kernel : 2.6.31.5-127.fc12.i686.PAE的關係呢?

http://phorum.study-area.org/index.php/topic,51286.msg261980.html#msg261980
這篇文章就是我當初在寫檔案權限相關的函數時從stat()領悟出來的一種寫法

所以如果是i386可能st_mode比對的旗標只有32個位元,而i686比對的旗標則有64個位元
不過,我這也只是猜測而已還沒確切證據來驗證^_^


程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

id4fox

  • 憂鬱的高中生
  • ***
  • 文章數: 103
  • 40 oz 挑戰成功!
    • 檢視個人資料
回覆: 想用 stat() 判斷掛載資料夾
« 回覆 #6 於: 2010-03-12 18:25 »
會不會是kernel : 2.6.31.5-127.fc12.i686.PAE的關係呢?

http://phorum.study-area.org/index.php/topic,51286.msg261980.html#msg261980
這篇文章就是我當初在寫檔案權限相關的函數時從stat()領悟出來的一種寫法

所以如果是i386可能st_mode比對的旗標只有32個位元,而i686比對的旗標則有64個位元
不過,我這也只是猜測而已還沒確切證據來驗證^_^
恩...個人的認知 i686 指的是 pentun II 以後等級的 CPU, 大概跟 32 bit, 64 bit 不很相關
stat( ) 函數是可以指定 Linux 其他一般檔案路徑的, 所以也不是非 stat64( ) 不可,
所以我推測可能不是這個原因喔(當然, 也是推測 盼高手指點)

P.S : 提供Link內的判斷方式真有意思, 研究研究 , 謝謝拉! :D

rainday

  • 鑽研的研究生
  • *****
  • 文章數: 738
  • 性別: 男
  • enhancing and optimizing
    • 檢視個人資料
回覆: 想用 stat() 判斷掛載資料夾
« 回覆 #7 於: 2010-03-13 01:15 »
這邊有說明到這部份

--- man stat ---
EOVERFLOW
              (stat()) path refers to a file whose size cannot be represented in the type off_t.  This  can occur when an  application  compiled  on  a  32-bit  platform  without  -D_FILE_OFFSET_BITS=64 calls stat() on a file whose size exceeds (2<<31)-1 bits.


--- info stat ---

-- Function: int stat (const char *FILENAME, struct stat *BUF)
     The `stat' function returns information about the attributes of the
     file named by FILENAME in the structure pointed to by BUF.

     If FILENAME is the name of a symbolic link, the attributes you get
     describe the file that the link points to.  If the link points to a
     nonexistent file name, then `stat' fails reporting a nonexistent
     file.

     The return value is `0' if the operation is successful, or `-1' on
     failure.  In addition to the usual file name errors (*note File
     Name Errors::, the following `errno' error conditions are defined
     for this function:

    `ENOENT'
          The file named by FILENAME doesn't exist.

     When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
     function is in fact `stat64' since the LFS interface transparently
     replaces the normal implementation.

-- Function: int stat64 (const char *FILENAME, struct stat64 *BUF)
     This function is similar to `stat' but it is also able to work on
     files larger then 2^31 bytes on 32-bit systems.  To be able to do
     this the result is stored in a variable of type `struct stat64' to
     which BUF must point.

     When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
     function is available under the name `stat' and so transparently
     replaces the interface for small files on 32-bit machines.
<0  =_=  Don't learn to hack , hack to learn.

kenduest

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3675
    • 檢視個人資料
    • http://kenduest.sayya.org
回覆: 想用 stat() 判斷掛載資料夾
« 回覆 #8 於: 2010-03-13 01:30 »

我感覺你們離題了。

首先不應該使用 state64 這類函數,因為你程式碼並得不是很有彈性,porting 也會有問題。

stat() 是標準 unix 函數,系統為了要處理 > 2GB 等這類檔案的位置偏移部份產生了 64bit 的介面。不過正確方式應該於 gcc 編譯使用時候傳入 -D FILE_OFFSET_BITS=64 與 -D_LARGEFILE_SOURCE 這類參數,這樣透過 include header 檔案內的 #define 處理自動會替換使用到 64bit 介面的 stat64() 函數,並且調整相關變數的長度類型。透過這樣方式,程式碼才可攜編譯使用。

題外話,以 freebsd 目前我用的版本來看,系統並無 stat64() 函數... 測試過也不用這個參數。
I am kenduest - 小州

my website: http://kenduest.sayya.org/

rainday

  • 鑽研的研究生
  • *****
  • 文章數: 738
  • 性別: 男
  • enhancing and optimizing
    • 檢視個人資料
回覆: 想用 stat() 判斷掛載資料夾
« 回覆 #9 於: 2010-03-13 01:34 »
稍微問一下
會是因為win的32bit os  or 64 bit os而有所差異嗎?
沒研究過win的檔案結構,這方面不是很清楚
<0  =_=  Don't learn to hack , hack to learn.

elleryq

  • 區域板主
  • 鑽研的研究生
  • *****
  • 文章數: 908
  • 性別: 男
    • 檢視個人資料
    • Thinking more...
回覆: 想用 stat() 判斷掛載資料夾
« 回覆 #10 於: 2010-03-15 09:07 »
引用
稍微問一下
會是因為win的32bit os  or 64 bit os而有所差異嗎?
沒研究過win的檔案結構,這方面不是很清楚

跟底層 filesystem 比較有關係.
因為我是在 32bit Windows XP 跟 32bit Linux 上試的。
Plan your work, then work your plan.
我的首頁:http://blog.elleryq.idv.tw
351899by http://counter.li.org

id4fox

  • 憂鬱的高中生
  • ***
  • 文章數: 103
  • 40 oz 挑戰成功!
    • 檢視個人資料
回覆: 想用 stat() 判斷掛載資料夾
« 回覆 #11 於: 2010-03-15 09:37 »
我感覺你們離題了。

首先不應該使用 state64 這類函數,因為你程式碼並得不是很有彈性,porting 也會有問題。

stat() 是標準 unix 函數,系統為了要處理 > 2GB 等這類檔案的位置偏移部份產生了 64bit 的介面。不過正確方式應該於 gcc 編譯使用時候傳入 -D FILE_OFFSET_BITS=64 與 -D_LARGEFILE_SOURCE 這類參數,這樣透過 include header 檔案內的 #define 處理自動會替換使用到 64bit 介面的 stat64() 函數,並且調整相關變數的長度類型。透過這樣方式,程式碼才可攜編譯使用。

題外話,以 freebsd 目前我用的版本來看,系統並無 stat64() 函數... 測試過也不用這個參數。
謝謝 kenduest 的說明!
但是我用 stat( ) 加入 -D FILE_OFFSET_BITS=64 與 -D_LARGEFILE_SOURCE
進行編譯還是沒有任何幫助~似乎是沒有轉換的樣子

以 " objdump -x (執行檔路徑) " 摘錄其中 ELF 的 stat symbol 的結果 :
(不知道這樣看是不是正確的做法)

1. stat + 一般編譯
00000000       F *UND*  00000000              __xstat@@GLIBC_2.0
0804dad0 g     F .text  00000032              .hidden __stat
0804dad0  w    F .text  00000032              .hidden stat

2. stat + -D FILE_OFFSET_BITS=64 與 -D_LARGEFILE_SOURCE
00000000       F *UND*  00000000              __xstat@@GLIBC_2.0
0804dad0 g     F .text  00000032              .hidden __stat
0804dad0  w    F .text  00000032              .hidden stat

3. stat64 + 一般編譯
00000000       F *UND*  00000000              __xstat@@GLIBC_2.0
00000000       F *UND*  00000000              __xstat64@@GLIBC_2.2
0804db10 g     F .text  00000032              .hidden __stat
0804db10  w    F .text  00000032              .hidden stat
0804db50 g     F .text  00000032              .hidden stat64

kenduest

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3675
    • 檢視個人資料
    • http://kenduest.sayya.org
回覆: 想用 stat() 判斷掛載資料夾
« 回覆 #12 於: 2010-03-15 11:42 »
不好意思,編譯參數漏了一個字元。

代碼: [選擇]
gcc -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
原本文章內少個底線字元...




I am kenduest - 小州

my website: http://kenduest.sayya.org/

id4fox

  • 憂鬱的高中生
  • ***
  • 文章數: 103
  • 40 oz 挑戰成功!
    • 檢視個人資料
回覆: 想用 stat() 判斷掛載資料
« 回覆 #13 於: 2010-03-15 13:40 »
不好意思,編譯參數漏了一個字元。

代碼: [選擇]
gcc -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
原本文章內少個底線字元...

喔喔喔! 用 objdump 看到很多函數都給他加了個 '64' 呢!
運作上的確是沒問題了!
學到了很正規的解決方法勒! 謝謝 kenduest
(謝謝 rainday, 我真該先認真看你的文件的)
« 上次編輯: 2010-03-15 18:55 由 id4fox »

elleryq

  • 區域板主
  • 鑽研的研究生
  • *****
  • 文章數: 908
  • 性別: 男
    • 檢視個人資料
    • Thinking more...
回覆: 想用 stat() 判斷掛載資料夾
« 回覆 #14 於: 2010-03-16 14:10 »
不好意思,編譯參數漏了一個字元。

代碼: [選擇]
gcc -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
原本文章內少個底線字元...






我試的時候也是漏了底線。
Plan your work, then work your plan.
我的首頁:http://blog.elleryq.idv.tw
351899by http://counter.li.org