Showing posts with label execv. Show all posts
Showing posts with label execv. Show all posts

Tuesday, July 3, 2012

UNIX Programming

ไปขึ้นสวรรค์น่ะพี่น่ะ
ใน ตอนที่ผ่านมา ได้กล่าวถึงการ overlay ทับหน่วยความจำ ของ process เดิมด้วย process ใหม่ ที่สร้างขึ้น ด้วยคำสั่ง execl แล้วบอกว่า เป็นการทำงานทางเดียว ไปแล้วไปลับ ไม่มีกลับมาอีก ทำนองนี้

ก็ดูว่า พอมีข้อยกเว้น อยู่บ้าง เรื่องก็คงคล้ายๆกับ ในชีวิตจริง ที่ว่า เราเกลียดขี้หน้าใครบางคนเสียเต็มประดา ครั้นจะไล่ไปให้ห่างๆ ก็เกรงใจคนฝากงาน ครั้นจะบอกให้ไปลงนรกเสีย ก็ดูว่าให้สงสาร ใจไม่แข็งพอ เพราะมันไม่รู้เรื่อง จนในที่สุดมาลงเอยที่ว่า

เออก็ นี่พ่อ พ่อไปขึ้นสวรรค์เสียเถอะน่ะพ่อน่ะ

อะไรประมาณนี้ พร้อมกับมอบหมายงานบางอย่างให้ไปทำบนสวรรค์ ว่ายังงั้น จะชั้นไหนก็ช่างเหอะน่า

ในเรื่องของ process ก็คงคล้ายๆกัน กล่าวคือ เมื่อเราสั่งให้วิ่ง process ใหม่ด้วยคำสั่ง execl แล้ว เกิดมีข้อผิดพลาดขึ้น เรื่องกลับไม่ได้จบ ณ ตรงนั้น มันย้อนกลับมาหาตัวผู้สั่งการเอง มามีเรื่องกันตรงนี้ ดั่งตัวโปรแกรมสั้นๆ ข้างล่างนี้

/*
 * exec-return.c
 */

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    execl("/usr/local/bin/heaven", "heaven", NULL);
    fprintf(stderr,"Some one stole 'heaven', heaven closed.\n");
}


ข้อผิดพลาด มันเกิดขึ้น เพราะหาสวรรค์ไม่เจอ อันเนื่องมาจาก เราไปกำหนด ตำแหน่งแห่งหน ของสวรรค์ไว้ผิดที่ ผิดทางนั่นเอง  ซึ่งจะยังผลให้ process ใหม่ที่วิ่งอยู่นี้ ไม่สามารถทำงานได้ จึ่งต้องกลับมายังผู้สั่งการ แล้วเจอคำสั่งให้พิมพ์ข้อความ "Some one stole 'heaven', heaven closed.\n" ออกทาง standard error แล้วจึงปิด case จบงานกัน ที่ main นั่นเอง

ลองคอมไพล์โปรแกรมข้างบนนั้นดูซิ น่ะ

% cc -o myjob exec-return.c

แล้วลองเรียกดูด้วยคำสั่งนี้

% ./myjob

อันนี้ ก็เป็น หนึ่ง ในข้อยกเว้น ที่เกิดขึ้น ข้อยกเว้นที่ว่า เมื่อสั่ง exec แล้ว มันจะทำงานไป และจบงานตรงนั้น ไม่มีกลับมายังตัวผู้สั่งอีก

นี้ ขอคั่นรายการ ก่อนจะนำเสนอเรื่องราวของ process ในตอน process control ซึ่งจะว่าไป น่าจะเป็นการ create เสียมากกว่า แต่ก็อย่างว่า วิชาการเรื่องนี้ คนไทย ไม่ได้สร้าง/ผลิตขึ้น เขาว่ามายังไง ก็ต้องว่าไปยังงั้น อย่างมากก็แค่ท้วงติงไป ซึ่งอาจจะได้ผล ไม่ได้ผล ก็แล้วแต่ว่า เจ้าของนั้น จะรับฟังหรือไม่ (หรืออีกที ก็ เจ้าของนั้น จะยังมีชีวิตอยู่หรือเปล่า)

ลป.  ลืมไปว่า ใน FreeBSD นั้นไม่มีแฟ้ม /usr/local/bin/heaven ครับ หาก UNIX รสชาติที่ท่านใช้นั้นมี heaven ดูให้ดีดีก็แล้วกัน ยังไงเสียก็ อ่าน man heanven, คู่มือสวรรค์, ให้ละเอียดน่ะครับ

Tuesday, June 26, 2012

UNIX Programming


“Process”
ได้เคยเขียนเรื่องของ process ไว้บ้างแล้ว ใน blog นี้, fork, แต่ขอเริ่มใหม่อีกครั้ง ให้อยู่ในหัวข้อของ UNIX Programming ไปเลยด้วยกันนี้

หลักการทำงานของ UNIX เท่าที่คลุกคลีมาคือ หากมีของอยู่แล้ว ก็ใช้ของนั้นมาทำงานให้ ไม่ต้องสร้างของนั้นขึ้นมาใหม่อีก และเพราะเหตุนี้ ใน FreeBSD จึงเต็มไปด้วย tools เพื่อใช้งาน เพื่อให้แต่ละงาน ช่วยงานอื่นให้สำเร็จลุล่วงไปได้

โดยหลักอันนี้เอง ทำให้เรา เรียกโปรแกรมอื่น มาทำงานให้เราขณะที่เราก็กำลังวิ่ง process ของเราอยู่ ซึ่งก็คือสิ่งที่ได้เขียนไป และ ให้ลิงค์ไว้ข้างบนนั้น นั่นเอง

(๓.๑) “system” ฟังก์ชั่น
เราใช้บริการของฟังก์ชั่นใน system library ชื่อ system เรียกโปรแกรมระบบ ในตัวอย่างนี้คือโปรแกรมชื่อ date มาช่วยงานได้ ดังนี้

#include <stdlib.h>

main()
{
    system("date");
}

ซึ่งในชีวิตจริง คงไม่ใช่โปรแกรม date นี้หรอก เป็นแต่เพียงยกตัวอย่างมาให้เห็นว่า การเรียกใช้บริการของฟังก์ชั่นใน system library นั้นกระทำกันผ่านช่องทางไหน  อนึ่ง ท่านสามารถ เขียน คำสั่งที่จะส่งผ่านให้ฟังก์ชั่น system ผ่านทางฟังก์ชั่น sprintf ได้

แต่ถึงอย่างนั้น วิธีการนี้ก็ยังคงมีข้อจำกัดอยู่ ตรงที่ว่า buffer output นั้นเราต้อง flush เอาเอง

(๓.๒) “Process Creation – execl & execv”
จะเห็นว่า แม้ฟังก์ชั่น system จะอนุญาตให้เรา เรียกโปรแกรม จากระบบปฏิบัติการ มาทำงานให้เราได้  แต่บางครั้ง ยังรู้สึกอยู่ว่า เราน่าจะทำอะไร มากกว่านั้นได้ กับ process ที่จะวิ่งงานให้นี้

วิธีที่ง่ายที่สุด สำหรับงานนี้คือ สั่งให้โปรแกรมใหม่นั้น ทำงานไปเลย โดยไม่ต้องหวลกลับมายัง โปรแกรมหลัก ของเราอีก   โดยการใช้ execl ดังนี้

/*
 * execl routine
 */

#include <unistd.h>

int main(int argc, char *argv[])
{
    execl("/bin/date", "date", NULL);
}

execl จะทับหน่วยความจำของโปรแกรมเดิมหมดสิ้น ดังนั้น จึงไม่สามารถ ที่จะกลับมาหา สถานะเดิม ได้อีกแล้ว เมื่อ execl ได้ทำงานเสร็จสิ้นแล้ว จึงมีแต่ ทำงานแล้วตายไปเลย อยู่ที่ว่า
  • สุคติ ทำงานสำเร็จ exit status 0 หรือ 
  • ทุคติ ทำงานไม่สำเร็จ มีปัญหา exit status ไม่เป็น 0

อีกหนึ่ง routine ที่คล้ายๆกับ execl คือ execv ที่อนุญาตให้ท่าน สร้างองค์ประกอบต่างๆ ของคำสั่งที่จะเรียกใช้งานได้ โดยมีวิธีการเรียกใช้งาน ดังนี้

int execv(const char *pathname, const char *argv[]);

ทั้ง ๒ routine นี้ เมื่อจะเรียกใช้งาน ต้องรวมแฟ้ม unistd.h เอาไว้ด้วย   ขอให้ท่านอ่าน execl(3) ด้วย และสำหรับรายละเอียดอื่นๆ จากเอกสารอ้างอิง หมายเลข ๓ บทที่ ๘  หัวข้อ process control


View My Stats