เป็นไปได้ไหมที่จะได้ชื่อไฟล์ของ file descriptor (Linux) ใน C?
เป็นไปได้ไหมที่จะได้ชื่อไฟล์ของ file descriptor (Linux) ใน C?
คำตอบ:
คุณสามารถใช้readlink
ใน/proc/self/fd/NNN
ที่ NNN คืออธิบายไฟล์ สิ่งนี้จะทำให้คุณได้ชื่อไฟล์เหมือนตอนที่เปิดอย่างไรก็ตามหากไฟล์ถูกย้ายหรือลบตั้งแต่นั้นมาไฟล์นั้นอาจไม่ถูกต้องอีกต่อไป (แม้ว่า Linux จะสามารถติดตามการเปลี่ยนชื่อได้ในบางกรณี) เพื่อตรวจสอบstat
ชื่อไฟล์ที่กำหนดและfstat
fd คุณมีและให้แน่ใจว่าst_dev
และst_ino
จะเหมือนกัน
แน่นอนไม่ใช่ตัวอธิบายไฟล์ทั้งหมดที่อ้างถึงไฟล์และสำหรับสิ่งที่คุณจะเห็นสตริงข้อความแปลก ๆ เช่นpipe:[1538488]
. เนื่องจากชื่อไฟล์จริงทั้งหมดจะเป็นพา ธ สัมบูรณ์คุณจึงสามารถระบุได้ว่าชื่อไฟล์ใดที่ง่ายพอ นอกจากนี้ตามที่คนอื่น ๆ ตั้งข้อสังเกตไว้ไฟล์สามารถมีฮาร์ดลิงก์หลายตัวชี้ไปที่พวกเขาซึ่งจะรายงานเฉพาะที่เปิดด้วยเท่านั้น หากคุณต้องการค้นหาชื่อทั้งหมดของไฟล์ที่กำหนดคุณจะต้องสำรวจระบบไฟล์ทั้งหมด
fd
จะเป็นการอ้างอิงเช่นนั้น) จะไม่สามารถใช้หมายเลขไอโหนดซ้ำได้ ซอฟต์แวร์ใด ๆ ที่ใช้หมายเลขไอโหนดหลังจากปิดไฟล์หรือก่อนที่จะเปิดขึ้นมาจะต้องเป็นไปตามเงื่อนไขการแข่งขัน
setuid()
เล่นกลอาจเป็น/proc/self/fd
ไปได้ที่กระบวนการของคุณจะไม่สามารถเข้าถึงได้ ดู: permalink.gmane.org/gmane.linux.kernel/1302546
ฉันมีปัญหานี้ใน Mac OS X เราไม่มี/proc
ระบบไฟล์เสมือนดังนั้นโซลูชันที่ยอมรับจึงไม่สามารถใช้งานได้
เรามีF_GETPATH
คำสั่งสำหรับfcntl
:
F_GETPATH Get the path of the file descriptor Fildes. The argu-
ment must be a buffer of size MAXPATHLEN or greater.
ดังนั้นในการรับไฟล์ที่เชื่อมโยงกับตัวอธิบายไฟล์คุณสามารถใช้ข้อมูลโค้ดนี้:
#include <sys/syslimits.h>
#include <fcntl.h>
char filePath[PATH_MAX];
if (fcntl(fd, F_GETPATH, filePath) != -1)
{
// do something with the file path
}
เนื่องจากฉันจำไม่ได้ว่าMAXPATHLEN
มีการกำหนดไว้ที่ไหนฉันคิดว่าPATH_MAX
จาก syslimits น่าจะดี
getsockname
.
ใน Windows ด้วยGetFileInformationByHandleExผ่านFileNameInfoคุณสามารถดึงชื่อไฟล์ได้
ดังที่ไทเลอร์ชี้ให้เห็นว่าไม่มีวิธีใดที่จะทำสิ่งที่คุณต้องการได้ "โดยตรงและเชื่อถือได้" เนื่องจาก FD ที่ระบุอาจตรงกับชื่อไฟล์ 0 (ในหลายกรณี) หรือ> 1 ("ฮาร์ดลิงก์" หลายรายการเป็นวิธีการอธิบายสถานการณ์หลังโดยทั่วไป ). หากคุณยังต้องการฟังก์ชั่นที่มีข้อ จำกัด ทั้งหมด (เกี่ยวกับความเร็วและความเป็นไปได้ที่จะได้ผลลัพธ์ 0, 2, ... แทนที่จะเป็น 1) นี่คือวิธีที่คุณสามารถทำได้: อันดับแรกfstat FD - สิ่งนี้จะบอกคุณ ผลstruct stat
ที่ได้คืออุปกรณ์ที่มีไฟล์อยู่จำนวนฮาร์ดลิงก์ที่มีไม่ว่าจะเป็นไฟล์พิเศษ ฯลฯ สิ่งนี้อาจตอบคำถามของคุณได้อยู่แล้วเช่นถ้า 0 ฮาร์ดลิงก์คุณจะรู้ว่าไม่มีชื่อไฟล์ที่เกี่ยวข้อง บนดิสก์
หากสถิติทำให้คุณมีความหวังคุณจะต้อง "เดินตามต้นไม้" ของไดเรกทอรีบนอุปกรณ์ที่เกี่ยวข้องจนกว่าคุณจะพบฮาร์ดลิงก์ทั้งหมด (หรือแค่อันแรกหากคุณไม่ต้องการมากกว่าหนึ่งอันและอันใดอันหนึ่งจะทำ ). เพื่อจุดประสงค์นั้นคุณใช้readdir (และแน่นอน opendir & c) เปิดไดเร็กทอรีย่อยแบบวนซ้ำจนกว่าคุณจะพบว่าstruct dirent
ได้รับหมายเลขไอโหนดเดียวกันกับที่คุณมีในต้นฉบับstruct stat
(ในเวลานั้นหากคุณต้องการเส้นทางทั้งหมดแทนที่จะเป็นเพียงชื่อ คุณจะต้องเดินห่วงโซ่ของไดเรกทอรีย้อนกลับเพื่อสร้างใหม่)
หากวิธีการทั่วไปนี้เป็นที่ยอมรับได้ แต่คุณต้องการรหัส C ที่ละเอียดกว่านี้โปรดแจ้งให้เราทราบมันจะไม่ยากที่จะเขียน (แม้ว่าฉันจะไม่เขียนมันถ้ามันไร้ประโยชน์กล่าวคือคุณไม่สามารถทนต่อประสิทธิภาพที่ช้าอย่างหลีกเลี่ยงไม่ได้หรือ ความเป็นไปได้ในการรับ! = 1 ผลลัพธ์สำหรับวัตถุประสงค์ในการสมัครของคุณ ;-)
ก่อนที่จะเขียนสิ่งนี้ออกไปอย่างเป็นไปไม่ได้ฉันขอแนะนำให้คุณดูซอร์สโค้ดของคำสั่งlsof
อาจมีข้อ จำกัด แต่ดูเหมือนว่า lsof จะสามารถกำหนด file descriptor และชื่อไฟล์ได้ ข้อมูลนี้มีอยู่ในระบบไฟล์ / proc ดังนั้นจึงควรได้รับจากโปรแกรมของคุณ
คุณสามารถใช้ fstat () เพื่อรับไอโหนดของไฟล์โดย struct stat จากนั้นใช้ readdir () คุณสามารถเปรียบเทียบไอโหนดที่คุณพบกับสิ่งที่มีอยู่ (โครงสร้างไดเรนต์) ในไดเร็กทอรี (สมมติว่าคุณรู้จักไดเร็กทอรีมิฉะนั้นคุณจะต้องค้นหาระบบไฟล์ทั้งหมด) และค้นหาชื่อไฟล์ที่เกี่ยวข้อง น่ารังเกียจ?
เป็นไปไม่ได้ ตัวอธิบายไฟล์อาจมีหลายชื่อในระบบไฟล์หรืออาจไม่มีชื่อเลย
แก้ไข: สมมติว่าคุณกำลังพูดถึงระบบ POSIX แบบเก่าโดยไม่มี API เฉพาะระบบปฏิบัติการใด ๆ เนื่องจากคุณไม่ได้ระบุระบบปฏิบัติการ