PATH_MAX กำหนดไว้ที่ไหนใน Linux?


113

ไฟล์ส่วนหัวใดที่ฉันควรเรียกใช้#includeเพื่อให้สามารถใช้ PATH_MAX เป็น int สำหรับปรับขนาดสตริงได้

ฉันต้องการที่จะประกาศ:

char *current_path[PATH_MAX];

แต่เมื่อฉันทำเช่นนั้นคอมไพเลอร์ของฉัน (Clang / LLVM บน Linux) ออกข้อผิดพลาดต่อไปนี้:

recursive_find6.c:29:20: error: use of undeclared identifier 'PATH_MAX'
char *current_path[PATH_MAX];
                   ^

ฉันลองค้นหาโดย Google แล้ว แต่ก็ยังไม่มีโชค

#include <limits.h> ไม่แก้ไขปัญหา / ข้อผิดพลาด

ฉันแก้ไขด้วยหรือไม่ว่าค่าของ PATH_MAX เป็น int


3
โปรดดูคำถามนี้: stackoverflow.com/questions/833291/…
Josh Brown

18
คุณอาจต้องการchar current_path[PATH_MAX];แทนที่จะเป็นchar *current_path[PATH_MAX];- คุณต้องการสตริงแทนที่จะเป็นอาร์เรย์ของพอยน์เตอร์
John Carter

หรืออันนี้stackoverflow.com/questions/4267390/…
qdii

คำตอบ:


135

มันอยู่ในlinux/limits.h.
#define PATH_MAX 4096 /* # chars in a path name including nul */

#include <linux/limits.h>

char current_path[PATH_MAX];

PATH_MAXมีข้อบกพร่องบางประการตามที่กล่าวไว้ในบล็อกนี้ (ขอบคุณ paulsm4)


23
นี่คือลิงค์ที่ดีเกี่ยวกับ PATH_MAX ... และทำไมมันถึงไม่เป็นเช่นนั้น : insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
paulsm4

เดี๋ยวก่อน ... นี่หมายความว่า PATH_MAX เป็นเฉพาะ linux ไม่ใช่ส่วนหนึ่งของมาตรฐานใด ๆ ใช่หรือไม่
Edward Falk

6
คุณควรใช้ <LIMIT.h>; <linux / LIMIT.h> มีลักษณะไม่พกพาอย่างชัดเจน
Edward Falk

4
ระวัง: PATH_MAX แตกต่างจาก NAME_MAX (และส่วนหนึ่งของบทความ x-ref'd จะทำให้ทั้งสองสับสนอย่างน้อยก็ในบางส่วน) หมายเหตุ: POSIX <limits.h>ระบุว่า: คำจำกัดความของค่าคงที่สัญลักษณ์หนึ่งในรายการต่อไปนี้จะถูกละเว้นจาก<limits.h>ส่วนหัว […] โดยที่ค่าที่สอดคล้องกันจะเท่ากับหรือมากกว่าค่าต่ำสุดที่ระบุไว้ แต่โดยที่ค่าอาจแตกต่างกันไปขึ้นอยู่กับไฟล์ ที่จะนำไปใช้ ค่าจริงที่รองรับสำหรับชื่อพา ธ เฉพาะจะถูกจัดเตรียมโดยฟังก์ชัน pathconf ()
Jonathan Leffler

1
ชื่อพา ธ นั้นชั่วร้ายมากไม่ปลอดภัยและ path_max เป็นเรื่องโกหกและไม่ใช่ค่าคงที่ (อาจแตกต่างกันในฟังก์ชัน OS ที่แตกต่างกัน) เป็นคุณสมบัติที่แย่มากและควรเปลี่ยนให้เร็วที่สุด
Lothar

13

โปรดทราบว่ายังไม่ชัดเจนว่าPATH_MAXกำหนดความยาวสูงสุดโดยมีหรือไม่มี nul ไบต์ต่อท้าย อาจเป็นอย่างใดอย่างหนึ่งในระบบปฏิบัติการอื่น หากคุณไม่สามารถหรือไม่ต้องการตรวจสอบว่าเป็นกรณีใดระหว่างการรวบรวมการบังคับใช้ขีด จำกัด เทียมของPATH_MAX - 1ไฟล์. ปลอดภัยดีกว่าเสียใจ (เห็นได้ชัดว่าคุณยังต้องจองPATH_MAXหน่วยความจำอย่างน้อยไบต์เพื่อบัฟเฟอร์สตริง)


4
> {PATH_MAX}จำนวนไบต์สูงสุดในชื่อพา ธ รวมถึงอักขระ null ที่สิ้นสุด จาก POSIX '01.
muh กรรม

8
โปรดทราบว่า POSIX 2008 แก้ไขความสับสน - <limits.h>(Rationale): {PATH_MAX} IEEE PASC Interpretation 1003.1 # 15 กล่าวถึงความไม่สอดคล้องกันในมาตรฐานด้วยคำจำกัดความของชื่อพา ธ และคำอธิบายของ {PATH_MAX} ทำให้นักพัฒนาแอปพลิเคชันสามารถจัดสรร {PATH_MAX} หรือ {PATH_MAX} +1 ไบต์ ความไม่สอดคล้องถูกลบออกโดยการแก้ไขนิยาม {PATH_MAX} เพื่อรวมอักขระ null ด้วยการเปลี่ยนแปลงนี้แอปพลิเคชันที่จัดสรร {PATH_MAX} ไบต์ไว้ก่อนหน้านี้จะยังคงประสบความสำเร็จ
Jonathan Leffler

1
โปรดทราบว่าคุณไม่ควรใช้PATH_MAX - 1แต่PATH_MAX + 1. คุณไม่จำเป็นต้องทำอีกต่อไป แต่คุณต้องการเพิ่มหนึ่งไบต์สำหรับไฟล์'\0'.
Alexis Wilke

1
PATH_MAX คือสาเหตุที่คนคิดว่า windows มันห่วยในขณะที่จริงๆแล้วมันเป็นโปรแกรมเมอร์เท่านั้นที่ใช้ PATH_MAX ห่วย PATH_MAX มีขนาดอย่างน้อย 32k บน windows และคุณแทบไม่ต้องการให้ PATH_MAX เป็น 32k เลย
Lothar

7

วิธีทำแบบพกพาคือ:

#define _POSIX_C_SOURCE 1
#include <limits.h>

ข้อมูลจำเพาะ: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html


และถึงอย่างนั้นก็ยังไม่เพียงพอ PATH_MAXไม่จำเป็นต้องกำหนด: "คำจำกัดความของค่าคงที่เชิงสัญลักษณ์อย่างใดอย่างหนึ่งในรายการต่อไปนี้จะถูกละเว้นจาก<limits.h>ส่วนหัวของการใช้งานเฉพาะที่ค่าที่สอดคล้องกันเท่ากับหรือมากกว่าค่าต่ำสุดที่ระบุไว้ แต่โดยที่ค่าอาจแตกต่างกันไปขึ้นอยู่กับ บนไฟล์ที่นำไปใช้ค่าจริงที่รองรับสำหรับชื่อพา ธ ที่ระบุจะถูกจัดเตรียมโดยpathconf()ฟังก์ชัน " ได้รับการสนับสนุนระบบไฟล์ลินุกซ์ค่าที่แตกต่างก็อาจละเมิดมาตรฐาน POSIX PATH_MAXสำหรับลินุกซ์ที่จะกำหนด
Andrew Henle

1

เมื่อเขียนโปรแกรม C อย่างง่ายฉันก็พบกับความท้าทายเดียวกัน บนระบบ Linux ของคุณไดเร็กทอรี / usr / include มีไฟล์ส่วนหัวจำนวนมากที่นี่เฉพาะสำหรับ Linux OS

find . -name "*.h" | xargs grep PATH_MAX 

คุณควรเห็นส่วนหัวหลายส่วนที่กำหนด PATH_MAX น่าเสียดายที่ค่านี้ถูกกำหนดไว้แตกต่างกันในส่วนหัวที่ต่างกัน นี่คือรายชื่อจาก Ubuntu ของฉัน (ฉันยังลบ Hit positive ที่ผิดพลาดออกจากโปรแกรม grep ด้วยตนเอง)

./x86_64-linux-gnu/bits/posix1_lim.h:#define _POSIX_PATH_MAX      256
./X11/InitialI.h:#ifndef PATH_MAX
./X11/InitialI.h:#define PATH_MAX 512
./X11/InitialI.h:#ifndef PATH_MAX
./X11/InitialI.h:#define PATH_MAX MAXPATHLEN
./X11/InitialI.h:#define PATH_MAX 1024
./X11/Xos.h:#  define PATH_MAX 4096
./X11/Xwindows.h:#if defined(WIN32) && (!defined(PATH_MAX) || PATH_MAX < 1024)
./X11/Xwindows.h:# undef PATH_MAX
./X11/Xwindows.h:# define PATH_MAX 1024
./X11/Xosdefs.h:#  ifndef PATH_MAX
./X11/Xosdefs.h:#   define PATH_MAX 4096
./X11/Xosdefs.h:#  ifndef PATH_MAX
./X11/Xosdefs.h:#   define PATH_MAX 1024
./X11/extensions/XKBsrv.h:#define   PATH_MAX MAXPATHLEN
./X11/extensions/XKBsrv.h:#define   PATH_MAX 1024
./python2.7/osdefs.h:#ifndef PATH_MAX
./python2.7/osdefs.h:#define PATH_MAX MAXPATHLEN
./python2.7/osdefs.h:#if defined(PATH_MAX) && PATH_MAX > 1024
./python2.7/osdefs.h:#define MAXPATHLEN PATH_MAX
./linux/limits.h:#define PATH_MAX        4096   /* # chars in a path name including nul */
./linux/btrfs.h:#define BTRFS_INO_LOOKUP_PATH_MAX 4080
./linux/un.h:#define UNIX_PATH_MAX  108

ส่วนหัว /linux/limits.h มีจำนวนมากที่สุดและควรเป็นส่วนหัวที่แท้จริงที่สุด กลยุทธ์ทางเลือกคือการกำหนดชื่อของคุณเองโดยใช้ชื่ออื่น PATHLEN (4080 นั้นยาวพอสำหรับสถานการณ์จริงส่วนใหญ่) ประเด็นหลักของฉันคือการเรียนรู้ที่จะใช้การค้นหาเพื่อค้นหาคำตอบสำหรับคำถามของคุณ


0

PATH_MAX เป็นขีด จำกัด ของระบบ มีสามประเภทเกี่ยวกับขีด จำกัด ของระบบที่มีอยู่ในสภาพแวดล้อม POSIX หนึ่งในประเภทเหล่านี้คือชื่อเส้นทางค่าตัวแปร ขีด จำกัด ของระบบซึ่งขึ้นอยู่กับระบบไฟล์จะอยู่ในประเภทนี้ PATHMAX ยังเป็นค่าตัวแปรชื่อพา ธ (ดังนั้นค่านี้สามารถเปลี่ยนจากระบบไฟล์เป็นระบบไฟล์) ดังนั้นขีด จำกัด PATHNAME สามารถรับได้ด้วยฟังก์ชันpathconf () / fpathconf () POSIX วิธีนี้เป็นวิธีพกพาในการ จำกัด PATHNAME ของระบบไฟล์ spesific ตัวอย่างโค้ดดังต่อไปนี้:

long
get_pathmax(void)
{
  long pathmax = -1;

  errno = 0;
  pathmax = pathconf("/", _PC_PATH_MAX);
  if (-1 == pathmax)
  {
    if (0 == errno)
    {
#define PATHMAX_INFINITE_GUESS 4096
      pathmax = PATHMAX_INFINITE_GUESS;
    }
    else
    {
      fprintf (stderr, "pathconf() FAILED, %d, %s\n", errno, strerror(errno));
    }
  }

  return pathmax;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.