putenv () / setenv () ทำงานอย่างไรโดยไม่ต้องเลื่อนสแต็กผู้ใช้ทั้งหมด

Aug 20 2020

ฉันได้อ่านโพสต์ต่างๆที่นี่และยังสับสนเกี่ยวกับวิธีการsetenv()ทำงาน:

  • ลินุกซ์ที่จัดเก็บตัวแปรสภาพแวดล้อม
  • ที่คือสภาพแวดล้อมสตริงที่เก็บจริง
  • วิธีทำ -i-program-my-own-setenv

ความเข้าใจของฉันคือตัวแปรสภาพแวดล้อมถูกเก็บไว้เป็นกลุ่มของสตริง "foo = bar \ 0" อย่างต่อเนื่องที่ด้านล่างของสแต็กผู้ใช้จากนั้นจะมีอาร์เรย์envp[]ของพอยน์เตอร์ที่ชี้ไปที่สตริงเหล่านี้และใกล้กับด้านล่างของ กองผู้ใช้ สแต็กผู้ใช้เติบโตขึ้นด้านบนของไบต์เหล่านี้ซึ่งหมายความว่าการเพิ่มสิ่งต่างๆให้กับพื้นที่สตริงหรืออาร์เรย์ตัวชี้นั้นไม่สำคัญ ดังนั้นจะsetenv()ทำงานอย่างไรหากตั้งค่าตัวแปรใหม่ (ต้องเพิ่มองค์ประกอบenvp[]) หรือมีการเปลี่ยนแปลงตัวแปร แต่สตริงค่าใหม่ยาวกว่าตัวเก่า (ทำให้การปรับเปลี่ยนแบบแทนที่เป็นไปไม่ได้) โดยไม่ต้องเปลี่ยน (เกือบ) สแต็คผู้ใช้ทั้งหมดเพื่อให้มีที่ว่างสำหรับผู้มาใหม่?

คำถามที่ค่อนข้างเกี่ยวข้องคือbashเก็บรายการภายในของตัวแปรที่ตั้งไว้ในเครื่องและเมื่อผู้ใช้exportตัวแปรที่ตั้งค่าในเครื่องbashเพียงแค่ลบมันออกจากรายการที่จัดการในเครื่องนี้และเพิ่มลงในด้านล่างของพื้นที่สตริงสแต็กที่กล่าวถึงข้างต้นและแทรกตัวชี้ไปที่ อาร์เรย์ตัวชี้envp[]เพื่อให้ลูกของมันประมวลผลโดยอัตโนมัติรับตัวแปรที่ส่งออก?

คำตอบ

KurtisRader Aug 20 2020 at 12:35

ความเข้าใจของฉันคือตัวแปรสภาพแวดล้อมถูกจัดเก็บเป็น ...

ความเข้าใจของคุณถูกต้องเพียงบางส่วน :ยิ้ม:

... โดยไม่ต้องเปลี่ยน (เกือบ) กองซ้อนผู้ใช้ทั้งหมดเพื่อให้มีที่ว่างสำหรับผู้มาใหม่?

นั่นคงเป็นไปไม่ได้ ไม่ว่าภาษาที่เขียนโปรแกรมจะเป็นภาษา C หรือระบบปฏิบัติการคือ UNIX ตัวอย่างเช่นเนื่องจากพอยน์เตอร์บนสแต็กสามารถอ้างถึงตำแหน่งอื่นบนสแตกได้

สิ่งแรกที่ควรทราบก็คือตำแหน่งที่เก็บ env vars ในกระบวนการใหม่นั้นขึ้นอยู่กับสถาปัตยกรรม การใช้งาน UNIX ส่วนใหญ่บนสถาปัตยกรรม CPU ส่วนใหญ่จะจัดเก็บไว้ในสแตกตามที่คุณอธิบายไว้ แต่ไม่มีสิ่งใดในข้อกำหนด C ที่กำหนดวิธีการแก้ปัญหานั้น นอกจากนี้หากคุณปรับเปลี่ยนสภาพแวดล้อมการนำไปใช้งานมีอิสระที่จะคัดลอกบล็อกของสภาพแวดล้อมที่มีอยู่ไปยังตำแหน่งใหม่ในหน่วยความจำ การใช้งาน C มีอิสระที่จะย้ายบล็อกของ env vars และอัปเดต magic __environvar

คำถามที่ค่อนข้างเกี่ยวข้องคือ bash เก็บรายชื่อตัวแปรที่ตั้งไว้ภายในไว้หรือไม่ ....

ไม่ใช่ในลักษณะที่คุณอธิบาย จะเก็บ "รายการภายใน" ของตัวแปรที่ตั้งไว้ในเครื่อง แต่ไม่ได้ใช้ลักษณะที่คุณแนะนำ

ฉันสงสัยว่าอะไรทำให้คุณเปิดประเด็นนี้