24.ÀÛ¾÷ Á¦¾î.
ÀÛ¾÷Á¦¾î´Â ´ÜÀÏÇÑ ·Î±×ÀÎ ¼¼¼Ç¿¡¼ »ç¿ëÀÚ°¡ ¿©·¯°³ÀÇ ÇÁ·Î¼¼½º ±×·ìµé(¶Ç´Â ÀÛ¾÷µé) »çÀÌ¿¡¼ Á¦ ¾î¸¦ ¿Å±â´Â °ÍÀ» Çã¿ëÇÏ´Â ÇÁ·ÎÅäÄÝÀ» Àû¿ëÇÑ´Ù. ÀÛ¾÷Á¦¾î ±â´ÉÀº ´ëºÎºÐÀÇ ÇÁ·Î±×·¥¿¡¼ ÀÚµ¿ÀûÀ¸ ·Î Àû´çÇÏ°Ô ¼öÇàµÇ°í, ÀÛ¾÷Á¦¾î¿¡ ´ëÇÑ Æ¯º°ÇÑ ¾î¶² °ÍÀ» ÇÒ Çʿ䰡 ¾ø´Ù. ±×·¡¼ ´ç½ÅÀÌ ½©À̳ª ·Î±×ÀÎ ÇÁ·Î±×·¥À» ¸¸µéÁö ¾Ê´Â´Ù¸é ÀÌ Àå¿¡ ÀÖ´Â °ÍµéÀ» ¹«½ÃÇÒ ¼ö ÀÖ´Ù.
´ç½ÅÀÌ ÀÌ Àå¿¡ ³ª¿ÍÀÖ´Â °ÍµéÀ» ÀÌÇØÇϱâ À§Çؼ´Â ½Ã±×³¯ Çڵ鸵(21Àå [Signal Handling] 271 Æä ÀÌÁö ÂüÁ¶)°ú ÇÁ·Î¼¼½º »ý¼º(23.2Àý [Process Creation Concepts] 325 ÆäÀÌÁö ÂüÁ¶) °ú ¿¬°üµÈ °³³ä ¿¡ Ä£¼÷ÇØÁú Çʿ䰡 ÀÖ´Ù.
24.1 ÀÛ¾÷Á¦¾îÀÇ °³³ä.
´ëÈÇü(interactive) ½©ÀÇ ±âº»ÀûÀÎ ¸ñÀûÀº »ç¿ëÀÚ Å͹̳¯·ÎºÎÅÍ ¸í·É¹®À» ÀÐ°í ±× ¸í·É¹®¿¡ÀÇÇØ Áö Á¤µÈ ÇÁ·Î±×·¥À» ½ÇÇàÇϵµ·Ï ÇÁ·Î¼¼½ºµéÀ» ¸¸µå´Â °ÍÀÌ´Ù. ±×°ÍÀº fork( 23.4Àý [Creadting a Process] 326 ÆäÀÌÁö ÂüÁ¶.)¿Í exec ( 23.5Àý [Executing a File] 327 ÆäÀÌÁö ÂüÁ¶.)ÇÔ¼ö¸¦ »ç¿ëÇØ¼ ÇÒ ¼ö ÀÖ´Ù.
´ÜÀÏÇÑ ¸í·É¹®Àº ´ÜÁö ÇÑ °³ÀÇ ÇÁ·Î¼¼½º¸¦ ½ÇÇà½ÃŰÁö¸¸_Á¾Á¾ ÇÑ °³ÀÇ ¸í·É¹®µµ ¿©·¯°³ÀÇ ÇÁ·Î¼¼½º µéÀ» »ç¿ëÇÑ´Ù. ¸¸ÀÏ ´ç½ÅÀÌ ½© Ä¿¸Çµå¿¡¼ `|'À» »ç¿ëÇÑ´Ù¸é ´ç½ÅÀº ¸í½ÃÀûÀ¸·Î ±×µé ÇÁ·Î¼¼½º¾È¿¡ ¿©·¯°³ÀÇ ÇÁ·Î±×·¥µéÀ» ¿äûÇѰÍÀÌ´Ù. ±×·¯³ª ¸¸ÀÏ ´ç½ÅÀÌ ÇÑ °³ÀÇ ÇÁ·Î±×·¥À» ½ÇÇà½ÃųÁö¶óµµ, ±× °ÍÀÌ ³»ºÎÀûÀ¸·Î´Â ¿©·¯°³ÀÇ ÇÁ·Î¼¼½ºµéÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦µé¾î, `cc -c foo.c'¿Í °°Àº ´ÜÀÏÇÑ ÄÄÆÄÀÏ ¸í·É¹®Àº, ÀüÇüÀûÀ¸·Î ³× °³ÀÇ ÇÁ·Î¼¼½ºµéÀ» »ç¿ëÇÑ´Ù. ¸¸ÀÏ ´ç½ÅÀÌ make¸¦ ½ÇÇàÇÑ´Ù¸é, ±× ÀÛ¾÷Àº ºÐ¸®µÈ ÇÁ·Î¼¼½º ¾È¿¡¼ ´Ù¸¥ ÇÁ·Î±×·¥À» ½ÇÇàÇÏ´Â °ÍÀÌ´Ù.
´ÜÀÏÇÑ ¸í·É¹®¿¡ ¼Ò¼ÓµÇ¾î ÀÖ´Â ÇÁ·Î¼¼½ºµéÀº ÇÁ·Î¼¼½º ±×·ìÀ̳ª ÀÛ¾÷(job)À̶ó°í ºÒ¸°´Ù. ´ç½ÅÀº µ¿½Ã¿¡ ±×µé ¸ðµç ÇÁ·Î¼¼½ºµéÀ» ÀÛµ¿½Ãų ¼ö ÀÖ´Ù. ¿¹¸¦µé¾î, C-c¸¦ ŸÀÌÇÎÇϸé Àü¸é ÇÁ·Î¼¼½º ±× ·ì¿¡ ÀÖ´Â ¸ðµç ÇÁ·Î¼¼½º°¡ Á¾·áµÇµµ·Ï ½Ã±×³¯ SIGINT¸¦ º¸³½´Ù. ¼¼¼ÇÀº ÇÁ·Î¼¼½ºµéÀÇ Á» Å« ±×·ì À̶ó°í ÇÒ ¼ö ÀÖ´Ù. ÀϹÝÀûÀ¸·Î ´ÜÀÏÇÑ ·Î±×Àο¡ ÀÖ´Â ¸ðµç ÇÁ·Î¼¼½ºµéÀº °°Àº ¼¼¼Ç¿¡ ¼ÓÇÑ´Ù.
¸ðµç ÇÁ·Î¼¼½º´Â ÇÁ·Î¼¼½º ±×·ì¿¡ ¼ÓÇÑ´Ù. ¾î¶² ÇÁ·Î¼¼½º°¡ ¸¸µé¾îÁú ¶§, ±×°ÍÀº ºÎ¸ð ÇÁ·Î¼¼½º¿Í °°Àº ÇÁ·Î¼¼½º ±×·ì°ú ¼¼¼ÇÀÇ ¸â¹ö°¡ µÈ´Ù. ´ç½ÅÀº setpid ÇÔ¼ö¸¦ »ç¿ëÇØ¼ ´Ù¸¥ ÇÁ·Î¼¼½º ±×·ìÀ¸·Î ¼Ò¼ÓÀ» ¹Ù²Ü ¼ö Àִµ¥, ±×¶§ ±× ÇÁ·Î¼¼½º ±×·ìÀº °°Àº ¼¼¼Ç¿¡ ¼Ò¼ÓµÈ ÇÁ·Î¼¼½º ±×·ìÀÌ´Ù.
´Ù¸¥ ¼¼¼Ç¿¡ ÇÁ·Î¼¼½º¸¦ ¼Ò¼Ó½ÃŰ´Â À¯ÀÏÇÑ ¹æ¹ýÀº setsid ÇÔ¼ö¸¦ »ç¿ëÇØ¼, »õ·Î¿î ¼¼¼ÇÀ̳ª, ¶Ç´Â ¼¼¼Ç ¸®´õÀÇ Ã³À½ ÇÁ·Î¼¼½º¸¦ ¸¸µå´Â °ÍÀÌ´Ù. »õ·Î¿î ÇÁ·Î¼¼½º ±×·ì¿¡ ¼¼¼Ç¸®´õ¸¦ ¼Ò¼Ó½Ã۸é, ´ç½Å Àº ´Ù½Ã ÇÁ·Î¼¼½º ±×·ìÀÇ ¿ÜºÎ·Î ±×°ÍÀ» ´Ù½Ã ¿Å±æ ¼ö ¾ø´Ù.
º¸Åë, »õ·Î¿î ¼¼¼ÇµéÀº ½Ã½ºÅÛ ·Î±×ÀÎ ÇÁ·Î±×·¥¿¡ ÀÇÇØ ¸¸µé¾îÁö°í ¼¼¼Ç ¸®´õ´Â »ç¿ëÀÚÀÇ ·Î±×ÀÎ ½© À» ½ÇÇà½ÃŰ´Â ÇÁ·Î¼¼½ºÀÌ´Ù. ÀÛ¾÷Á¦¾î¸¦ Áö¿øÇÏ´Â ½©Àº ¾î¶² ½Ã°£¿¡ ¾î¶² ÀÛ¾÷ÀÌ Å͹̳¯À» »ç¿ëÇÒ ¼ö ÀÖµµ·Ï Á¦¾î¸¦ Á¶Á¤Çؾ߸¸ ÇÑ´Ù. ±×·¸Áö¾Ê´Ù¸é ¿©·¯°³ÀÇ ÀÛ¾÷µéÀÌ µ¿½Ã¿¡ Å͹̳ηκÎÅÍ ÀÔ·ÂÀ» ¹Þ¾ÆµéÀÌ·Á ½ÃµµÇÒ°ÍÀ̰í, ¾î¶² ÇÁ·Î¼¼½º°¡ »ç¿ëÀÚ°¡ ŸÀÔÇÑ ÀÔ·ÂÀ» ¹ÞÀ» °ÍÀÎÁö°¡ È¥¶õÇÏ°Ô µÉ ¼ö µµ ÀÖ´Ù. À̰ÍÀ» ¹æÁöÇϱâ À§Çؼ, ½©Àº ÀÌ Àå¿¡ ¼³¸íµÈ ÇÁ·ÎÅäÄÝÀ» »ç¿ëÇØ¼ Å͹̳¯ µå¶óÀ̹ö¿Í Çù ·ÂÇØ¾ß¸¸ ÇÑ´Ù.
½©Àº ÇÑ ¹ø¿¡ ¿ÀÁ÷ ÇÑ ÇÁ·Î¼¼½º ±×·ì¿¡°Ô¸¸ Å͹̳¯À» Á¦¾îÇÏ´Â Á¦ÇѾø´Â ±ÇÇÑÀ» ÁÙ ¼ö ÀÖ´Ù. ÀÌó ·³ Å͹̳¯À» Á¦¾îÇϰí ÀÖ´Â ÇÁ·Î¼¼½º ±×·ìÀ» Àü¸é ÀÛ¾÷(foreground job)À̶ó°í ºÎ¸¥´Ù. Å͹̳¯À» ¾ï ¼¼½º ÇÏÁö ¾Ê°í ½ÇÇàÁßÀÎ, ½©¿¡ ÀÇÇØ 󸮵ǰí ÀÖ´Â ´Ù¸¥ ÇÁ·Î¼¼½º ±×·ìµéÀº ¹è°æÀÛ¾÷(background job)À̶ó°í ºÒ¸°´Ù.
¸¸ÀÏ ¹è°æ ÀÛ¾÷ÀÌ Å͹̳¯À» Á¦¾îÇÏ¿© Å͹̳¯·ÎºÎÅÍ Àаųª ¾²°Å³ª ÇÒ Çʿ䰡 ÀÖ´Ù¸é, ±×°ÍÀº Å͹̳¯ µå¶óÀ̹ö¿¡ ÀÇÇØ ¸ØÃß¾îÁø´Ù. »ç¿ëÀÚ´Â SUSP¹®ÀÚ( 12.4.9Àý [Special Characters] 195 ÆäÀÌÁö ÂüÁ¶) ¸¦ ÀÔ·ÂÇÔÀ¸·Î½á Àü¸é ÀÛ¾÷À» ¸ØÃâ ¼ö ÀÖ°í ÇÁ·Î±×·¥Àº SIGSTOP½Ã±×³¯À» º¸³¿À¸·Î½á ¾î¶² ÀÛ¾÷À» ¸ØÃâ ¼ö ÀÖ´Ù. ÀÛ¾÷µéÀÌ ¸ØÃß¾úÀ» ¶§ ½©Àº ±×µé¿¡ ´ëÇÏ¿© »ç¿ëÀÚ¿¡°Ô ¾Ë¸± Ã¥ÀÓÀÌ ÀÖ°í, ¸ØÃß¾îÁø ÀÛ¾÷¿¡ ´ëÇØ¼ °è¼Ó ÁøÇàÇÒ °ÍÀÎÁö¿¡ ´ëÇÑ ¿©ºÎ¸¦ »ç¿ëÀÚ¿¡°Ô ¼±ÅÃÇϵµ·Ï Çã¿ëÇϱâ À§ÇÑ ¸ÞÄ«´ÏÁò ÀÇ Á¦°ø°ú Àü¸é ÀÛ¾÷°ú ¹è°æ ÀÛ¾÷»çÀÌÀÇ ÀÛ¾÷Àüȯµµ ½©¿¡°Ô Ã¥ÀÓÀÌ ÀÖ´Ù. Á¦¾îÁßÀÎ Å͹̳¯¿¡ ÀÔ/Ãâ ·Â Çϴ°Ϳ¡ ´ëÇÑ ÀÚ¼¼ÇÑ Á¤º¸´Â 24.4Àý [Access to the Terminal] 336 ÆäÀÌÁöÂüÁ¶.
24.2 ÀÛ¾÷Á¦¾î´Â ¼±ÅÃÀûÀÌ´Ù.
¸ðµç ¿î¿µÃ¼Á¦°¡ ÀÛ¾÷Á¦¾î¸¦ Áö¿øÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. GNU ½Ã½ºÅÛÀº ÀÛ¾÷Á¦¾î¸¦ Áö¿øÇÏÁö¸¸, ¸¸ÀÏ ´Ù ¸¥ ½Ã½ºÅÛ¿¡¼ GNU ¶óÀ̺귯¸®¸¦ »ç¿ëÇÑ´Ù°íÇØµµ ±× ½Ã½ºÅÛ¿¡¼ ÀÛ¾÷Á¦¾î¸¦ Áö¿øÇÏÁö ¾ÊÀ» ¼ö µµ ÀÖ´Ù. ´ç½ÅÀº ½Ã½ºÅÛÀÌ ÀÛ¾÷Á¦¾î¸¦ Áö¿øÇÏ´ÂÁö¿¡ ´ëÇÑ ¿©ºÎ¸¦ ½ÃÇèÇϱâ À§Çؼ ÄÄÆÄÀÏÇÒ ¶§ _POSIX_JOB_CONTROL ¸ÅÅ©·Î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. 27.2Àý[System Options] 370 ÆäÀÌÁö ÂüÁ¶.
¸¸ÀÏ ÀÛ¾÷Á¦¾î°¡ Áö¿øµÇÁö ¾ÊÀ¸¸é, ÇÑ ¼¼¼Ç¸¸´Ù ¿ÀÁ÷ ÇÑ °³ÀÇ ÇÁ·Î¼¼½º ±×·ì¸¸ Á¸ÀçÇÏ°í ±× ÇÁ·Î¼¼ ½º ±×·ìÀº Ç×»ó Àü¸é ÀÛ¾÷À¸·Î½á ÇൿÇÑ´Ù. ºÎ°¡ÀûÀÎ ÇÁ·Î¼¼½º ±×·ìÀ» ¸¸µå´Â ÇÔ¼ö¿¡´Â ¿¡·¯ÄÚµå ENOSYS¸¦ »ç¿ëÇØ¼ °£´ÜÈ÷ ½ÇÆÐÇßÀ½À» ¾Ë¸°´Ù.
´Ù¾çÇÑ ÀÛ¾÷Á¦¾î ½Ã±×³¯(21.2.5Àý [Job Control Signals] 277 ÆäÀÌÁö ÂüÁ¶.)µéÀ» ´ëÇ¥Çϰí ÀÖ´Â ¸ÅÅ©·Î µéÀº ÀÛ¾÷Á¦¾î°¡ Áö¿øµÇÁö ¾Ê´Â´Ù°í ÇÒÁö¶óµµ Á¤ÀǵǾî ÀÖ´Ù. ±×·¸Áö¸¸, ÀÛ¾÷Á¦¾î¸¦ Áö¿øÇÏÁö ¾Ê´Â ½Ã½ºÅÛ¿¡¼ ±× ½Ã±×³¯µéÀ» °áÄÚ ¹ß»ýµÇÁö ¾Ê°í, ¿¡·¯¸¦ º¸°íÇϰųª ¾Æ¹«°Íµµ ÇÏÁö¾Ê´Â µîÀÇ ½Ã±×³¯ ¿¡ ´ëÇÑ ÇൿÀ» Á¤Çϰųª ½ÃÇèÇϰųª º¸³»·Á°í ½ÃµµÇÏÁö ¾Ê´Â´Ù.
24.3 ÇÁ·Î¼¼½ºÀÇ Å͹̳¯ Á¦¾îÇϱâ.
ÇÁ·Î¼¼½ºÀÇ ¼Ó¼ºµéÁß Çϳª´Â ±× ÇÁ·Î¼¼½º°¡ Á¦¾îÁßÀÎ Å͹̳¯ÀÌ´Ù. fork¸¦ »ç¿ëÇØ¼ ¸¸µé¾îÁø ÀÚ½Ä ÇÁ·Î¼¼½º´Â ±×µéÀÇ ºÎ¸ð ÇÁ·Î¼¼½º·ÎºÎÅÍ Á¦¾îÁßÀÎ Å͹̳¯À» »ó¼Ó¹Þ´Â´Ù. À̿Ͱ°Àº ¹æ¹ýÀ¸·Î, ÇÑ ¼¼ ¼Ç¾È¿¡ ÀÖ´Â ¸ðµç ÇÁ·Î¼¼½ºµéÀº ¼¼¼Ç ¸®´õ(session leader)·ÎºÎÅÍ Á¦¾îÁßÀÎ Å͹̳¯À» »ó¼Ó¹Þ´Â´Ù. ÅÍ ¹Ì³¯ÀÇ Á¦¾î±ÇÀ» °¡Áø ¼¼¼Ç¸®´õ¸¦ Å͹̳¯ÀÇÁ¦¾îÁßÀÎ ÇÁ·Î¼¼½º(controlling process)¶ó°í ºÒ¸°´Ù.
´ç½ÅÀÌ ·Î±×ÀÎÇÒ ¶§ ½Ã½ºÅÛÀÌ ´ç½ÅÀ» À§Çؼ ±× ÀÏÀ» Çϱ⠶§¹®¿¡, ´ç½ÅÀº ¼¼¼Ç¿¡ Å͹̳¯ Á¦¾î±ÇÀ» ÇÒ´çÇÏ´Â Á¤È®ÇÑ ¸ÞÄ«´ÏÁò¿¡ ´ëÇØ¼´Â °ÆÁ¤ÇÒ Çʿ䰡 ¾ø´Ù. °³º°ÀûÀÎ ÇÁ·Î¼¼½º°¡ »õ·Î¿î ¼¼¼ÇÀÇ ¸® ´õ°¡ µÇ±âÀ§Çؼ setsid¸¦ È£ÃâÇÒ ¶§, ±× ÇÁ·Î¼¼½º´Â Á¦¾îÁßÀÎ Å͹̳¯·ÎºÎÅÍ ´ÜÀýµÈ´Ù.
24.2 Á¦¾îÁßÀÎ Å͹̳¯ ¾ï¼¼½º.
Å͹̳¯À» Á¦¾îÇϰí ÀÖ´Â Àü¸éÀÛ¾÷¾ÈÀÇ ÇÁ·Î¼¼½ºµéÀº Å͹̳¯¿¡ ´ëÇÑ Á¦ÇÑ ¾ø´Â ¾ï¼¼½º ±ÇÇÑÀ» °¡Áø ´Ù; ¹è°æÇÁ·Î¼¼½ºµéÀº ±ÇÇÑÀ» °¡ÁöÁö ¾Ê´Â´Ù. ÀÌ Àý¿¡¼´Â ¹è°æÀÛ¾÷¿¡ ÀÖ´Â ÇÁ·Î¼¼½º°¡ Å͹̳¯À» Á¦ ¾îÇÏ·Á ½ÃµµÇÒ ¶§ ¾î¶² ÀÏÀÌ ¹ß»ýÇÏ´ÂÁö¿¡ ´ëÇØ¼ ÀÚ¼¼È÷ ¼³¸íÇϰí ÀÖ´Ù.
¹è°æÀÛ¾÷¿¡ ÀÖ´Â ÇÁ·Î¼¼½º°¡ Àü¸éÀÛ¾÷ÀÌ Á¦¾îÇϰí ÀÖ´Â Å͹̳ηκÎÅÍ ÀÐÀ¸·Á ½ÃµµÇÒ ¶§, ÇÁ·Î¼¼½º ±×·ìÀº SIGTTIN ½Ã±×³¯À» ¹Þ´Â´Ù. À̰ÍÀº ±×·ì¾È¿¡ ÀÖ´Â ¸ðµç ÇÁ·Î¼¼½ºµéÀÇ µ¿ÀÛÀ» ¸ØÃß°Ô ÇÏ´Â ¿øÀÎÀÌ µÈ´Ù(±× ½Ã±×³¯ÀÌ Ã³¸®µÇÁö ¾Ê°Å³ª ±×µé ½º½º·Î ¸ØÃß°Ô ÇÏÁö ¾Ê´Â´Ù¸é). ±×·¸Áö¸¸ Àб⸦ ½ÃµµÇÑ ÇÁ·Î¼¼½º°¡ ÀÌ ½Ã±×³¯À» ¹«½ÃÇϰųª ºí·ÏÇÑ´Ù¸é, ´ë½Å¿¡ EIO ¿¡·¯¸¦ ¾ò°Ô µÉ °ÍÀÌ´Ù.
À¯»çÇϰÔ, ¹è°æÀÛ¾÷¿¡ ÀÖ´Â ÇÁ·Î¼¼½º°¡ Àü¸éÀÛ¾÷¿¡¼ Á¦¾îÇϰí ÀÖ´Â Å͹̳¯¿¡ Ãâ·ÂÀ» ½ÃµµÇÑ´Ù¸é, ±× °Í¿¡ ´ëÀÀµÈ µðÆúÆ® µ¿ÀÛÀº ÇÁ·Î¼¼½º ±×·ì¿¡°Ô SIGTTOU ½Ã±×³¯À» º¸³»´Â °ÍÀÌ´Ù. ±×·¸Áö¸¸, ±× µ¿ÀÛÀº Áö¿ª ¸ðµå Ç÷¡±×(local modes flags)(12.4.7Àý [Local Modes] 192 ÆäÀÌÁö ÂüÁ¶.)ÀÇ TOSTOP ºñÆ®¿¡ ÀÇÇØ¼ °»½ÅµÈ´Ù. ¸¸ÀÏ ÀÌ ºñÆ®°¡ ¼³Á¤µÇÁö ¾Ê´Â´Ù¸é(À̰ÍÀÌ µðÆúÆ®ÀÌ´Ù.), Àü¸é ÀÛ¾÷¿¡ ÀÇ ÇØ Á¦¾îÁßÀÎ Å͹̳¯¿¡ ¹è°æÀÛ¾÷ÀÌ Ãâ·ÂÀ» ½ÃµµÇÏ´Â °Í¿¡´Â ½Ã±×³¯À» º¸³»Áö ¾Ê°í Ç×»ó Çã°¡µÈ´Ù. ¶ÇÇÑ Ãâ·ÂÀ» ½ÃµµÇÏ´Â ÇÁ·Î¼¼½º¿¡ ÀÇÇØ SIGTTOU ½Ã±×³¯ÀÌ ¹«½ÃµÇ°Å³ª ºí·ÏµÈ´Ù¸é À̶§µµ Ãâ·ÂÀº Çã°¡µÈ´Ù.
ÇÁ·Î±×·¥¿¡¼ ÇÒ ¼ö ÀÖ´Â Å͹̳¯ ¸í·ÉµéÀÇ ´ëºÎºÐÀº ÀÔ·ÂÀ̳ª Ãâ·ÂÀ» À§ÇÑ °ÍÀÌ´Ù. ±âº»ÀûÀÎ ÀԷ°ú Ãâ·Â ÇÔ¼ö¿¡ ´ëÇÑ Á¤º¸´Â 8.2Àý [I/O Primitives] 105 ÆäÀÌÁö ÂüÁ¶.
24.5 °í¾Æ°¡µÈ ÇÁ·Î¼¼½º ±×·ìµé.
Å͹̳¯ Á¦¾îÁßÀÌ´ø ÇÁ·Î¼¼½º°¡ Á¾·áµÇ¸é, ±× Å͹̳¯Àº ÇØÁ¦µÇ°í »õ·Î¿î ¼¼¼Ç¿¡ ÀÇÇØ¼ ´Ù½Ã Á¦¾îµÉ ¼ö ÀÖ´Ù.( ½ÇÁ¦·Î, ´Ù¸¥ »ç¿ëÀÚ°¡ Å͹̳¯ »ó¿¡¼ ·Î±×ÀÎ ÇÒ ¼ö ÀÖ´Ù.) À̰ÍÀº ¸¸ÀÏ ¿¹ÀüÀÇ ¼¼¼Ç¿¡ ÀÖ´Â ¾î¶² ÇÁ·Î¼¼½º°¡ ±× Å͹̳¯À» °è¼Ó »ç¿ëÇÏ·Á°í ½ÃµµÇÑ´Ù¸é ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù.
±×·¯ÇÑ ¹®Á¦µéÀ» ¸·±âÀ§Çؼ, ¼¼¼Ç¸®´õ°¡ Á¾·áµÈ ÈÄ¿¡µµ °è¼Ó ½ÇÇàµÇ°í ÀÖ´Â ÇÁ·Î¼¼½º ±×·ìµéÀº °í ¾Æ°¡µÈ ÇÁ·Î¼¼½º ±×·ìÀ¸·Î½á Ç¥½ÃµÈ´Ù. °í¾Æ ÇÁ·Î¼¼½º ±×·ì(orphand process group) ¾È¿¡ ¼Ò¼ÓµÈ ÇÁ·Î¼¼½ºµéÀº Å͹̳ο¡ Àаųª ¾²±â¸¦ ÇÒ ¼ö ¾ø´Ù. ¸¸ÀÏ ±×·¸°Ô ÇÏ·Á ½ÃµµÇÑ´Ù¸é EIO ¿¡·¯¸¦ ¾ò°Ô µÉ °ÍÀÌ´Ù.
¾î¶² ÇÁ·Î¼¼½º ±×·ìÀÌ °í¾Æ°¡ µÇ¾úÀ» ¶§, ±× ÇÁ·Î¼¼½ºµéÀº SIGHUP ½Ã±×³¯À» ¹Þ´Â´Ù. º¸Åë, À̰ÍÀº ÇÁ·Î¼¼½º¸¦ Á¾·á½ÃŰ´Â ¿øÀÎÀÌ µÈ´Ù. ±×·¸Áö¸¸, ¸¸ÀÏ ÇÁ·Î±×·¥ÀÌ ÀÌ ½Ã±×³¯À» ¹«½ÃÇϰųª ½Ã±×³¯À» À§ÇÑ Çڵ鷯¸¦ ¸¸µé¾ú´Ù¸é(21Àå [Signal Handling] 271 ÆäÀÌÁö ÂüÁ¶.), Å͹̳¯À» Á¦¾îÁßÀÌ´ø ÇÁ·Î¼¼½º °¡ Á¾·áµÇ¾ú´Ù°í ÇÏ´õ¶óµµ ½ÇÇàÁßÀÌ´ø °í¾Æ ÇÁ·Î¼¼½ºµéÀº °è¼Ó ±× ÀÛ¾÷À» ¼öÇàÇÒ ¼ö ÀÖ´Ù; ±×·¸Áö¸¸ ´õ ÀÌ»óÀº Å͹̳¯ÀÇ ¾ï¼¼½º¸¦ ½ÃµµÇÒ ¼ö ¾ø´Ù.
24.6 ÀÛ¾÷Á¦¾î ½© ½ÇÇà½Ã۱â.
ÀÌ ÀýÀº ½©ÀÌ ÀÛ¾÷ Á¦¾î¸¦ ¼öÇàÇϱâ À§Çؼ´Â ¹«¾ùÀ» ÇØ¾ß¸¸ ÇÏ´ÂÁö, ±× °³³äÀÌ Æ÷ÇÔµÈ °£´ÜÇÑ ¿¹Á¦ ÇÁ·Î±×·¥À» ÅëÇØ¼ ¼³¸íÇϰí ÀÖ´Ù.
둁 24.6.1Àý [Data Structures] 337 ÆäÀÌÁö, À̰÷¿¡¼´Â ±× ¿¹Á¦¸¦ ¼Ò°³Çϰí, ÁÖ¿äÇÑ µ¥ÀÌÅÍ ±¸Á¶Ã¼¸¦ ¼Ò°³Çϰí ÀÖ´Ù.
둁 24.6.2Àý [Initializing the Shell] 339 ÆäÀÌÁö, ½©ÀÌ ÀÛ¾÷Á¦¾î¸¦ ÁغñÇϱâ À§Çؼ ¼öÇàÇØ¾ß¸¸ ÇÏ´Â µ¿ À۵鿡 ´ëÇØ¼ ³íÀÇÇϰí ÀÖ´Ù.
둁 24.6.3Àý [Launching Jobs] 340 ÆäÀÌÁö, ¸í·É¹®À» ½ÇÇàÇϱâ À§Çؼ ¾î¶»°Ô ÀÛ¾÷µéÀ» ¸¸µé°ÍÀÌÁö¿¡ ´ëÇÑ Á¤º¸°¡ Æ÷ÇԵǾî ÀÖ´Ù.
둁 24.6.4Àý [Foreground and Background] 343 ÆäÀÌÁö, ¹è°æÀÛ¾÷¿¡ ´ë¸³Çϴ°ÍÀ¸·Î½á Àü¸éÀ¸·Î ÀÛ¾÷À» ÁøÃâ½Ãų ¶§ ½©ÀÌ ¹«¾ùÀ» ´Ù¸£°Ô ÇØ¾ß ¸¸ÇÏ´ÂÁö¸¦ ¼³¸íÇϰí ÀÖ´Ù.
둁 24.6.5Àý [Stoppend and Terminated Jobs] 344 ÆäÀÌÁö, ½©¿¡°Ô ÀÛ¾÷»óȲÀ» º¸°íÇϱ⿡ ´ëÇØ¼ ¼³¸í ÇÑ´Ù.
둁 24.6.6 [Continuing Stopped Jobs] 347 ÆäÀÌÁö, ÀÛ¾÷ÀÌ ¸ØÃß¾îÁ³À» ¶§ ´Ù½Ã °è¼ÓÇϱâ À§Çؼ ¾î¶»°Ô ÇØ¾ßÇÏ´ÂÁö¸¦ ¼³¸íÇÑ´Ù.
둁 24.6.7 [Missing Pieces] 348 ÆäÀÌÁö, ½©ÀÇ ´Ù¸¥ ºÎºÐµé¿¡ ´ëÇØ¼ ¼³¸íÇϰí ÀÖ´Ù.
24.6.1 ½©À» À§ÇÑ µ¥ÀÌÅÍ ±¸Á¶Ã¼µé.
ÀÌ Àå¿¡ Æ÷ÇÔµÈ ¸ðµç ¿¹Á¦ ÇÁ·Î±×·¥µéÀº °£´ÜÇÑ ½© ÇÁ·Î±×·¥ÀÇ ÀϺκÐÀÌ´Ù. ÀÌ ÀýÀº ÀÌ ¿¹Á¦¿¡¼ »ç ¿ëµÇ°í ÀÖ´Â µ¥ÀÌÅÍ ±¸Á¶Ã¼¿Í À¯Æ¿¸®Æ¼ ÇÔ¼öµéÀ» ¼³¸íÇϰí ÀÖ´Ù.
°£´ÜÇÑ ½©Àº ÁÖ·Î µÎ °³ÀÇ µ¥ÀÌÅÍ ±¸Á¶Ã¼¸¦ ´Ù·é´Ù. job ŸÀÔ(type)Àº ÆÄÀÌÇÁ(pipes)·Î ¼·Î ¿¬°áµÈ ¼ºêÇÁ·Î¼¼½ºµéÀÇ ÁýÇÕÀÎ ÀÛ¾÷¿¡ ´ëÇÑ Á¤º¸¸¦ Æ÷ÇÔÇÑ´Ù. process ŸÀÔ(type)Àº ´ÜÀÏÇÑ ¼ºêÇÁ·Î¼¼½º ¿¡ ´ëÇÑ Á¤º¸¸¦ ÀúÀåÇϰí ÀÖ´Ù. ´ÙÀ½Àº ÀûÀýÇÑ µ¥ÀÌÅÍ ±¸Á¶Ã¼ ¼±¾ðµéÀÌ´Ù.
/* process´Â ÇÑ °³ÀÇ ´ÜÀÏÇÑ ÇÁ·Î¼¼½ºÀÌ´Ù. */
typedef struct process
{
struct process *next; /* ÆÄÀÌÇÁ¶óÀο¡ ÀÖ´Â ´ÙÀ½ ÇÁ·Î¼¼½º */
char **argv; /* execÀ» À§ÇÑ */
pid_tpid; /* ÇÁ·Î¼¼½º ID */
char completed; /* ÇÁ·Î¼¼½º°¡ ¼öÇàµÇ¾úÀ¸¸é ÂüÀÌ´Ù. */
char stopped; /* ¸¸ÀÏ ÇÁ·Î¼¼½º°¡ ¸ØÃß¾úÀ¸¸é ÂüÀÌ´Ù. */
int status; /* º¸°íµÈ »óȲµéÀÇ °ª */
} process;
/* job Àº ÇÁ·Î¼¼½ºµéÀÇ ÆÄÀÌÇÁ¶óÀÎÀÌ´Ù. */
typedef struct job
{
struct job *next; /* ´ÙÀ½ Ȱµ¿ÇÒ ÀÛ¾÷ */
char *command; /* ¸Þ½ÃÁö¸¦ À§Çؼ »ç¿ëµÇ´Â, Ä¿¸Çµå ¶óÀÎ */
process *first_process; /* ÀÛ¾÷¾È¿¡ ÀÖ´Â ÇÁ·Î¼¼½ºÀÇ ¸®½ºÆ® */
pid_t pgid; /* ÇÁ·Î¼¼½º ±×·ì ID */
char notified; /* »ç¿ëÀÚ°¡ ¸ØÃá ÀÛ¾÷¿¡ ´ëÇØ¼ ¸»ÇßÀ¸¸é ÂüÀÌ´Ù. */
struct termios tmodes; /* ÀúÀåµÈ Å͹̳¯ ¸ðµåµé */
int stdin, stdout, stderr; /* Ç¥ÁØ ÀÔ/Ãâ·Â ä³Îµé */
} job;
/* Ȱ¼ºÈµÈ ÀÛ¾÷µéÀº ¸®½ºÆ®¾È¿¡ ¿¬°áµÇ¾î ÀÖ°í À̰ÍÀÌ ±× Çìµå(head)ÀÌ´Ù.*/
job *first_job = NULL;
´ÙÀ½Àº ÀÛ¾÷ ¿ÀºêÁ§Æ®µéÀº ¿î¿µÇϱâ À§Çؼ »ç¿ëµÇ´Â À¯Æ¿¸®Æ¼ ÇÔ¼öµé¿¡ ´ëÇÑ °ÍÀÌ´Ù.
/* pgid¸¦ ÅëÇØ¼ Ȱ¼º ÀÛ¾÷À» ã¾Æ¶ó. */
job *
find_job (pid_t pgid)
{
job *j;
for (j = first_job; j; j = j->next)
if (j->pgid == pgid)
return j;
return NULL;
}
/* ¸¸ÀÏ job ¾È¿¡ ÀÖ´Â ¸ðµç ÇÁ·Î¼¼½ºµéÀÌ ¿Ï·áµÇ¾ú°Å³ª ¸ØÃß¾îÀÖ´Ù¸é ÂüÀ» ¸®ÅÏÇÑ´Ù */
int
job_is_stopped (job *j)
{
process *p;
for (p = j->first_process; p; p = p->next)
if (!p->completed && !p->stopped)
return 0;
return 1;
}
/* ¸¸ÀÏ job ¾È¿¡ ÀÖ´Â ¸ðµç ÇÁ·Î¼¼½ºµéÀÌ ¿Ï·áµÇ¾ú´Ù¸é ÂüÀ» ¸®ÅÏ */
int
job_is_completed (job *j)
{
process *p;
for (p = j->first_process; p; p = p->next)
if (!p->completed)
return 0;
return 1;
}
24.6.2 ½© ÃʱâÈÇϱâ
ÀϹÝÀûÀ¸·Î ÀÛ¾÷Á¦¾î¸¦ ¼öÇàÇÏ´Â ½© ÇÁ·Î±×·¥ÀÌ ½ÃÀÛµÉ ¶§, ±× ½©ÀÌ ÀÌ¹Ì ÀÚ½ÅÀÇ ÀÛ¾÷Á¦¾î¸¦ ¼öÇàÇÏ °í ÀÖ´Â ´Ù¸¥ ½©·ÎºÎÅÍ È£ÃâµÇ¾úÀ» °æ¿ì¿¡´Â ÁÖÀǸ¦ ÇØ¾ß¸¸ ÇÑ´Ù. ¼ºê½©(subshell)¿¡¼ ÀÛ¾÷Á¦¾î°¡ °¡´ÉÇÏ°Ô µÇ±âÀü¿¡ ¿ì¼± ºÎ¸ð ½©¿¡ ÀÇÇØ¼ Àü¸é¿¡ ³õ¿©Á®¾ß¸¸ ÇÑ´Ù. ±×°ÍÀº getpgrp·Î Ãʱâ ÇÁ·Î¼¼ ½º ±×·ì ID¸¦ ¾ò°í, ÇöÀç Å͹̳¯À» Á¦¾îÇϰí ÀÖ´Â Àü¸éÀÛ¾÷ÀÇ ÇÁ·Î¼¼½º ±×·ì ID¿Í ±×°ÍÀ» ºñ±³Çؼ ÇÑ´Ù( tcgetpgrpÇÔ¼ö¸¦ »ç¿ëÇØ¼ ÃßÃâµÉ ¼ö ÀÖ´Ù. )
¸¸ÀÏ ±× ¼ºê½©ÀÌ Àü¸é ÀÛ¾÷À¸·Î½á ½ÇÇàµÇ°í ÀÖÁö ¾Ê´Ù¸é, ±×°ÍÀº ±× ÀÚ½ÅÀÇ ÇÁ·Î¼¼½º ±×·ì¿¡ SIGTTIN ½Ã±×³¯À» º¸³¿À¸·Î½á ½º½º·Î ¸ØÃç¾ß¸¸ ÇÑ´Ù. ±×°ÍÀº Àü¸é¿¡ ±× ÀÚ½ÅÀ» Á¦¸Ú´ë·Î ³õÀ»¼ö ¾ø´Ù; »ç¿ëÀÚ°¡ ºÎ¸ð ½©¿¡°Ô À̰ÍÀ» ½Ã۵µ·Ï ±â´Ù·Á¾ß¸¸ ÇÑ´Ù. ¸¸ÀÏ ±× ¼ºê½©ÀÌ °è¼ÓµÈ´Ù¸é, °Ë»ç ¸¦ ¹Ýº¹ÇÏ°í ¸¸ÀÏ ±×°ÍÀÌ ¿©ÀüÈ÷ Àü¸é¿¡ ÀÖÁö ¾Ê´Ù¸é ´Ù½Ã ½º½º·Î ¸ØÃá´Ù.
ÀÏ´Ü ¼ºê½©ÀÌ ºÎ¸ð ½©¿¡ ÀÇÇØ¼ Àü¸é¿¡ ³õÀ̰ԵǸé, ¼ºê½©Àº ÀÚ½ÅÀÇ ÀÛ¾÷ Á¦¾î°¡ °¡´ÉÇÏ°Ô µÈ´Ù. ÀڽżÒÀ¯ÀÇ ÇÁ·Î¼¼½º ±×·ì¾È¿¡ ±× ÀÚ½ÅÀÌ ³õÀ̵µ·Ï setpgid¸¦ È£ÃâÇϰí, ±×´ÙÀ½ Àü¸é¿¡ ÀÌ ÇÁ·Î¼¼½º ±×·ìÀÌ ³õÀ̵µ·Ï tcsetpgrp¸¦ È£ÃâÇÔÀ¸·Î½á ÀÌ·¯ÇÑ ÀÏÀ» ÇÑ´Ù.
½©ÀÌ ÀÛ¾÷Á¦¾î°¡ °¡´ÉÇÏ°Ô µÇ¾úÀ» ¶§, ÀÛ¾÷Á¦¾î¸¦ ¸ØÃßµµ·Ï ÇÏ´Â ¸ðµç ½Ã±×³¯¿¡ ´ëÇØ¼ ¹«½ÃÇϵµ·Ï ±× ÀÚü¿¡¼ ¼³Á¤Çϱ⠶§¹®¿¡ ±× ÀÚü´Â ¿ì¿¬È÷ ¸ØÃß°Ô µÇÁö ¾Ê´Â´Ù. ´ç½ÅÀº ¸ðµç ¸ØÃ㠽ñ׳¯µéÀ» SIG_IGN À¸·Î ¼³Á¤ÇÏ¿© ÀÌ·¯ÇÑ ÀÏÀ» ÇÒ ¼ö ÀÖ´Ù.
ºñ-´ëȽÄÀ¸·Î ½ÇÇàµÇ´Â ¼ºê½©Àº ÀÛ¾÷Á¦¾î°¡ Áö¿øµÇÁöµµ ¾Ê°í Áö¿øµÉ ¼öµµ ¾ø´Ù. ±×°ÍÀº ±×ÀÚü°¡ ½©ÀÎ ÇÁ·Î¼¼½º ±×·ì¾È¿¡ ¸¸µç ¸ðµç ÇÁ·Î¼¼½º°¡ Á¸ÀçÇØ¾ß¸¸ ÇÑ´Ù; À̰ÍÀº ºñ-´ëÈ½Ç ½©°ú ºÎ¸ð ½©¿¡ ÀÇÇØ ´ÜÀÏÇÑ ÀÛ¾÷À¸·Î Ãë±ÞµÇ´Â ÀÚ½Ä ÇÁ·Î¼¼½º¸¦ Çã¿ëÇÑ´Ù. À̰ÍÀº ÀÛ¾÷Á¦¾î¸¦ »ç¿ëÇÏÁö ¾ÊÁö¸¸ ±× °ÍÀ» ÇÏ´Â ½©À» ¸¸µé±â À§Çؼ´Â ±â¾ïÇØ¾ß¸¸ ÇÑ´Ù.
´ÙÀ½Àº ÀÌ·¯ÇÑ ¸ðµç °ÍÀ» ¾î¶»°Ô ÇÏ´ÂÁö º¸¿©ÁÖ´Â ¿¹Á¦ ½©À» À§ÇÑ Ãʱâ ÄÚµåÀÌ´Ù.
/* ½©ÀÇ ¼Ó¼ºÀ» ±â¾ïÇ϶ó. */
#include <sys/types.h>
#include <termios.h>
#include <unistd.h>
pid_t shell_pgid;
struct termios shell_tmodes;
int shell_terminal;
int shell_is_interactive;
/* ÁøÇàÇϱâ Àü¿¡ ½©ÀÌ Àü¸éÀÛ¾÷À¸·Î½á ´ëȽÄÀ¸·Î ½ÇÇàµÇ°í ÀÖ´ÂÁö¸¦ È®ÀÎÇ϶ó. */
void
init_shell ()
{
/* ¸¸ÀÏ ´ëȽÄÀ¸·Î ½ÇÇàµÈ´Ù¸é º¸¾Æ¶ó. */
shell_terminal = STDIN_FILENO;
shell_is_interactive = isatty (shell_terminal);
if (shell_is_interactive)
{
/* Àü¸é¿¡ ³õÀ϶§±îÁö ·çÇÁ¸¦ µ·´Ù. */
while (tcgetpgrp (shell_terminal) != (shell_pgid = getpgrp()))
kill (- shell_pgid, SIGTTIN);
/* ´ëÈ¿Í ÀÛ¾÷-Á¦¾î ½Ã±×³¯µéÀ» ¹«½ÃÇ϶ó. */
signal (SIGINT, SIG_IGN);
signal (SIGQUIT, SIG_IGN);
signal (SIGTSTP, SIG_IGN);
signal (SIGTTIN, SIG_IGN);
signal (SIGTTOU, SIG_IGN);
signal (SIGCHLD, SIG_IGN);
/* ¿ì¸®¼ÒÀ¯ÀÇ ÇÁ·Î¼¼½º ±×·ì¿¡ ¿ì¸®ÀÚ½ÅÀ» ³Ö¾î¶ó. */
shell_pgid = getpid ();
if (setpgid (shell_pgid, shell_pgid) < 0)
{
perror("Couldn't put the shell in its own process group");
exit (1);
}
/* Å͹̳¯ÀÇ Á¦¾î¸¦ Àâ¾Æ¶ó */
tcsetpgrp (shell_terminal, shell_pgid);
/* ½©À» À§ÇÑ µðÆúÆ® Å͹̳¯ ¼Ó¼ºÀ» ÀúÀåÇ϶ó. */
tcgetattr (shell_terminal, &shell_tmodes);
}
}
24.6.3 ÀÛ¾÷µéÀ» °³½ÃÇϱâ.
ÀÏ´Ü ½©ÀÌ Å͹̳¯À» Á¦¾îÇÏ¿©¼ ÀÛ¾÷Á¦¾î¸¦ ¼öÇàÇϴ åÀÓÀ» °®°Ô µÇ¸é, ½©Àº »ç¿ëÀÚ¿¡ÀÇÇØ ÀÔ·ÂµÈ ¸í·É¹®¿¡ ÀÀ´äÇÏ¿© ÀÛ¾÷À» °³½ÃÇÒ ¼ö ÀÖ´Ù. ÇÁ·Î¼¼½º ±×·ì¿¡¼ ÇÁ·Î¼¼½ºµéÀ» ¸¸µé±â À§Çؼ´Â, 23.2 Àý [Process Creation Concepts] 325 ÆäÀÌÁö¿¡ ¼³¸íµÈ fork ¿Í exec¸¦ »ç¿ëÇÑ´Ù. ±×°÷¿¡´Â ¿©·¯°³ÀÇ ÀÚ½Ä ÇÁ·Î¼¼½ºµéÀÌ ÀÌ¹Ì Á¸ÀçÇϰí Àֱ⠶§¹®¿¡, ±× ÀÏÀ» Çϱâ´Â Á» ¸¹ÀÌ º¹ÀâÇÏ°í ´ç½ÅÀº ¿Ã¹Ù¸¥ ¼ø ¼·Î ÇÁ·Î¼¼½º¸¦ ¸¸µéµµ·Ï ÁÖÀǸ¦ ÇØ¾ß¸¸ ÇÑ´Ù. ±×·¸Áö ¾Ê´Ù¸é, °í¾àÇÑ °æÀï»óȲ(race condition)ÀÌ ¹ß»ýµÉ °ÍÀÌ´Ù.
´ç½ÅÀº ÇÁ·Î¼¼½ºµé »çÀÌÀÇ ºÎ¸ð-ÀÚ½Ä °ü°è¸¦ ¾î¶»°Ô ±¸¼ºÇÒ°ÍÀÎÁö¿¡ ´ëÇØ¼ µÎ°¡Áö¸¦ ¼±ÅÃÇÒ ¼ö ÀÖ ´Ù. ÇÁ·Î¼¼½º ±×·ì¾È¿¡ ÀÖ´Â ¸ðµç ÇÁ·Î¼¼½ºµéÀ» ½© ÇÁ·Î¼¼½ºÀÇ ÀÚ½Ä ÇÁ·Î¼¼½º·Î ¸¸µé°Å³ª, ¶Ç´Â ±× ·ì¿¡ ÀÖ´Â ÇÑ °³ÀÇ ÇÁ·Î¼¼½º¸¦ ±× ±×·ì¿¡ ÀÖ´Â ´Ù¸¥ ¸ðµç ÇÁ·Î¼¼½ºµéÀÇ Á¶»óÀÌ µÇµµ·Ï ¸¸µé¼ö ÀÖ´Ù. ÀÌ Àå¿¡ ¼³¸íµÈ ¿¹Á¦ ½© ÇÁ·Î±×·¥Àº ù ¹øÂ°°¡ Á» °£´ÜÇÏ°Ô ¶§¹®¿¡ ù ¹øÂ°¸¦ »ç¿ëÇÑ´Ù.
¸¸µé¾îÁø °¢°¢ÀÇ ÇÁ·Î¼¼½º´Â, setpid¸¦ È£ÃâÇÏ¿© »õ·Î¿î ÇÁ·Î¼¼½º ±×·ì¿¡ ±× ÀÚ½ÅÀ» ³Ö¾î¾ß¸¸ ÇÑ´Ù; 24.7.2Àý [Process Group Functions] 349 ÆäÀÌÁö ÂüÁ¶. »õ·Î¿î ±×·ì¿¡ Àִ ù ¹øÂ° ÇÁ·Î¼¼½º´Â ±× ÇÁ·Î¼¼½º ±×·ìÀÇ ¸®´õ°¡ µÇ°í ±× ÇÁ·Î¼¼½º ID°¡ ±× ±×·ìÀ» À§ÇÑ ÇÁ·Î¼¼½º ±×·ì ID°¡ µÈ´Ù.
½©Àº »õ·Î¿î ÇÁ·Î¼¼½º ±×·ìÀ¸·Î °¢°¢ÀÇ ÀÚ½Ä ÇÁ·Î¼¼½ºµéÀ» ³Ö±â À§Çؼ setpgid¸¦ È£ÃâÇÑ´Ù. ÀÌ°Í Àº ŸÀÌ¹Ö ¹®Á¦°¡ ³»Æ÷µÇ¾î ÀÖ´Ù; °¢°¢ÀÇ ÀÚ½Ä ÇÁ·Î¼¼½º´Â »õ·Î¿î ÇÁ·Î±×·¥ÀÌ ½ÇÇàµÇ±â Àü¿¡ ÇÁ·Î ¼¼½º ±×·ì¿¡ µé¾î°¡¾ß¸¸ Çϰí, ½©Àº ½ÇÇàÀ» °è¼ÓÇϱâ Àü¿¡ ±×·ìÀÌ °¡Áö°í ÀÖ´Â ¸ðµç ÀÚ½Ä ÇÁ·Î¼¼½º ¿¡ ÀÇÁ¸ÇÑ´Ù. ¸¸ÀÏ ÀÚ½Ä ÇÁ·Î¼¼½º¿Í ½©ÀÌ ¸ðµÎ setpgid¸¦ È£ÃâÇÑ´Ù¸é, À̰ÍÀº ÇÁ·Î¼¼½º°¡ ¸ÕÀú ±× ÀÏÀ» ó¸®Çϵµ·Ï ÇØ¼ ¾Æ¹«·± ¹®Á¦°¡ ¹ß»ýµÇÁö ¾ÊÀ» °ÍÀÌ´Ù.
¸¸ÀÏ Àü¸é ÀÛ¾÷À¸·Î ¾î¶² ÀÛ¾÷ÀÌ ÁøÇàµÇ°í ÀÖ´Ù¸é, »õ·Î¿î ÇÁ·Î¼¼½º ±×·ìÀ» tcsetpgrp¸¦ »ç¿ëÇØ¼ ÅÍ ¹Ì³¯À» Á¦¾îÇϰí ÀÖ´Â Àü¸éÀ¸·Î ³ÖÀ» Çʿ䰡 ÀÖ´Ù. ´Ù½Ã, À̰ÍÀº °æÀï »óȲÀ» ÇÇÇϱâ À§Çؼ °¢°¢ÀÇ ÀÚ½Ä ÇÁ·Î¼¼½º »Ó¸¸¾Æ´Ï¶ó, ½©¿¡ ÀÇÇØ¼µµ ¼öÇàµÈ´Ù. °¢ ÀÚ½Ä ÇÁ·Î¼¼½ºÀÇ ´ÙÀ½ ÀÏÀº ½Ã±×³¯µ¿ÀÛÀ» Àç¼³Á¤ÇÏ´Â ÀÏÀÌ´Ù.
ÃʱâÈ Çϴµ¿¾È, ½© ÇÁ·Î¼¼½º´Â ÀÛ¾÷Á¦¾î ½Ã±×³¯µéÀ» ¹«½ÃÇϵµ·Ï ±× ÀÚ½ÅÀ» ¼³Á¤ÇÑ´Ù; 24.6.2Àý [Initializing the Shell] 339 ÆäÀÌÁö ÂüÁ¶. ±× °á°ú·Î, ±×°ÍÀÌ ¸¸µç ¾î¶² ÀÚ½Ä ÇÁ·Î¼¼½ºµµ ¶ÇÇÑ »ó¼ÓÀ¸ ·Î ÀÎÇØ¼ ±×·¯ÇÑ ½Ã±×³¯µéÀ» ¹«½ÃÇÏ°Ô µÈ´Ù. À̰Ϳ¡ ¸¸Á·ÇÏÁö ¸øÇϸé, °¢°¢ÀÇ ÀÚ½Ä ÇÁ·Î¼¼½º´Â ±× °ÍÀÌ ¸¸µé¾îÁø ÈÄ¿¡ SIG-DFLÀ» »ç¿ëÇØ¼ ±× ½Ã±×³¯ÀÇ ¿ø·¡ µ¿ÀÛÀ¸·Î µÇµ¹·Á ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.
½©ÀÌ ÀÌ·¯ÇÑ °ü½ÀÀ» µû¸£±â ¶§¹®¿¡, ÀÀ¿ë ÇÁ·Î±×·¥Àº ±×µéÀÌ ºÎ¸ð ÇÁ·Î¼¼½º·ÎºÎÅÍ ½Ã±×³¯ÀÇ Ã³¸®¿¡ ´ëÇÑ °ÍÀ» Á¤È®È÷ »ó¼Ó¹Þ´Â´Ù°í °¡Á¤ ÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª ¸ðµç ÀÀ¿ëÇÁ·Î±×·¥Àº ¸ØÃ㠽ñ׳¯µéÀÇ Ã³ ¸®¿¡ °£¼·ÇÒ ¼ö ¾ø´Ù. SUSP ¹®ÀÚÀÇ ÀϹÝÀûÀÎ ÇØ¼®ÀÌ ºÒ°¡´ÉÇÏ°Ô ¸¸µç ÀÀ¿ëÇÁ·Î±×·¥Àº »ç¿ëÀÚ°¡ ÀÛ ¾÷À» ¸ØÃß°Ô Çϱâ À§Çؼ ´Ù¸¥ ¸ÞÄ«´ÏÁòÀ» Á¦°øÇÑ´Ù. »ç¿ëÀÚ°¡ ÀÌ ¸ÞÄ«´ÏÁòÀ» È£ÃâÇÒ ¶§, ±× ÇÁ·Î±× ·¥Àº ´ÜÁö ÇÁ·Î¼¼½º ±× ÀÚü°¡ ¾Æ´Ï¶ó, ±× ÇÁ·Î¼¼½ºÀÇ ÇÁ·Î¼¼½º ±×·ì¿¡°Ô SIGTSTP ½Ã±×³¯À» º¸³½ ´Ù. 21.6.2Àý [Signaling Another Process] 295 ÆäÀÌÁö ÂüÁ¶.
¸¶Ä§³», °¢°¢ÀÇ ÀÚ½Ä ÇÁ·Î¼¼½º´Â º¸ÅëÀÇ ¹æ¹ýÀ¸·Î exec¸¦ È£ÃâÇÏ¿©¾ß ÇÑ´Ù. À̰ÍÀº Ç¥ÁØ ÀÔ/Ãâ·Â ä ³ÎµéÀÇ ¸®´ÙÀÌ·º¼ÇÀÌ Ã³¸®µÇ´Â ÁöÁ¡ÀÌ´Ù. 8.8Àý [Duplicating Descriptors] 114 ÆäÀÌÁö¸¦ ÂüÁ¶ÇÏ¿© ÀÌ °ÍÀ» ¾î¶»°Ô ÇÏ´ÂÁö º¸¾Æ¶ó. ´ÙÀ½Àº ÇÁ·Î±×·¥À» °³½ÃÇϱâ À§ÇÑ, ´ëÈ½Ä ½© ÇÁ·Î±×·¥¿¡ ÀÖ´Â ÇÔ¼öÀÌ ´Ù. ±× ÇÔ¼ö´Â ½©¿¡ ÀÇÇØ¼ ÀÚ½Ä ÇÁ·Î¼¼½º°¡ ¸¸µé¾îÁø ÈÄ¿¡ Áï½Ã ÀÚ½Ä ÇÁ·Î¼¼½º¿¡ ÀÇÇØ¼ ½ÇÇàµÇ°í °áÄÚ ¸®ÅÏÇÏÁö ¾Ê´Â´Ù.
void
launch_process (process *p, pid_t pgid, int infile, int outfile, int errfile, int foreground)
{
pid_t pid;
if (shell_is_interactive)
{
/* ÇÁ·Î¼¼½º ±×·ì¿¡ ±× ÇÁ·Î¼¼½º¸¦ ³Ö°í Å͹̳¯À» ÇÁ·Î¼¼½º ±×·ì¿¡°Ô ÁÖ¾î¶ó, Àû´çÇϸé, À̰ÍÀº ½© °ú °³º°ÀûÀÎ ÀÚ½Ä ÇÁ·Î¼¼½º¿¡ ÀÇÇØ¼ ¸ðµÎ ½ÇÇàµÇ±â ¶§¹®¿¡ °æÀï»óȲÀ» Æ÷ÇÔÇϰí ÀÖ´Ù. */
pid = getpid ();
if (pgid == 0) pgid = pid;
setpgid (pid, pgid);
if (foreground)
tcsetpgrp (shell_terminal, pgid);
/* ÀÛ¾÷Á¦¾î ½Ã±×³¯À§ÇÑ Ã³¸®¸¦ µðÆúÆ®·ÎµÇµ¹·Á ¼³Á¤Ç϶ó. */
signal (SIGINT, SIG_DFL);
signal (SIGQUIT, SIG_DFL);
signal (SIGTSTP, SIG_DFL);
signal (SIGTTIN, SIG_DFL);
signal (SIGTTOU, SIG_DFL);
signal (SIGCHLD, SIG_DFL);
}
/* »õ·Î¿î ÇÁ·Î¼¼½º¸¦ À§ÇÑ Ç¥ÁØ ÀÔ/Ãâ·Â ä³ÎµéÀ» ¼³Á¤Ç϶ó. */
if (infile != STDIN_FILENO)
{
dup2 (infile, STDIN_FILENO);
close (infile);
}
if (outfile != STDOUT_FILENO)
{
dup2 (outfile, STDOUT_FILENO);
close (outfile);
}
if (errfile != STDERR_FILENO)
{
dup2 (errfile, STDERR_FILENO);
close (errfile);
}
/* »õ·Î¿î ÇÁ·Î¼¼½º¸¦ ½ÇÇàÇ϶ó. exit¸¦ È®ÀÎÇ϶ó. */
execvp (p->argv[0], p->argv);
perror ("execvp");
exit (1);
}
¸¸ÀÏ ½©ÀÌ ´ëȽÄÀ¸·Î ½ÇÇàµÇÁö ¾ÊÀ¸¸é, ÀÌ ÇÔ¼ö´Â ÇÁ·Î¼¼½º ±×·ìÀ̳ª ½Ã±×³¯·Î ¾Æ¹«Àϵµ ÇÏÁö ¾Ê´Â ´Ù. ÀÛ¾÷Á¦¾î¸¦ ¼öÇàÇÏÁö ¾Ê´Â ½©Àº ±× ÀÚü°¡ ½©ÀÎ ÇÁ·Î¼¼½º ±×·ì¾È¿¡ ¸ðµç ¼ºêÇÁ·Î¼¼½ºµéÀÌ Á¸ ÀçÇØ¾ß¸¸ ÇÑ´Ù.
´ÙÀ½Àº ½ÇÁ¦·Î ¿ÏÀüÇÑ ÀÛ¾÷À» ½ÃÀÛÇÏ´Â ÇÔ¼öÀÌ´Ù. ÀÚ½Ä ÇÁ·Î¼¼½º°¡ ¸¸µé¾îÁø ÈÄ¿¡, ÀÌ ÇÔ¼ö´Â Àü¸é À̳ª ¹è°æÀ¸·Î »õ·ÎÀÌ ¸¸µé¾îÁø ÀÛ¾÷À» ³Ö±âÀ§Çؼ ¾î¶² ´Ù¸¥ ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù; ±×°ÍÀº 24.6.4Àý [Foreground and Background] 343 ÆäÀÌÁö¿¡ ¼³¸íµÇ¾î ÀÖ´Ù.
void
launch_job (job *j, int foreground)
{
process *p;
pid_t pid;
int mypipe[2], infile, outfile;
infile = j->stdin;
for (p = j->first_process; p; p = p->next)
{
/* ¸¸ÀÏ ÇÊ¿äÇϸé pipeµéÀ» ÁغñÇ϶ó. */
if (p->next)
{
if (pipe (mypipe) < 0)
{
perror ("pipe");
exit (1);
}
outfile = mypipe[1];
}
else
outfile = j->stdout;
/* ÀÚ½Ä ÇÁ·Î¼¼½ºµéÀ» ¸¸µé¾î¶ó */
pid = fork ();
if (pid == 0)
/* À̰ÍÀº ÀÚ½Ä ÇÁ·Î¼¼½ºÀÌ´Ù. */
launch_process (p, j->pgid, infile, outfile, j->stderr, foreground);
else if (pid < 0)
{
/* fork °¡ ½ÇÆÐÇß´Ù. */
perror ("fork");
exit (1);
}
else
{
/* À̰ÍÀº ºÎ¸ð ÇÁ·Î¼¼½ºÀÌ´Ù. */
p->pid = pid;
if (shell_is_interactive)
{
if (!j->pgid)
j->pgid = pid;
setpgid (pid, j->pgid);
}
}
/* pipeµéÀ» Á¤¸®Ç϶ó. */
if (infile != j->stdin)
close (infile);
if (outfile != j->stdout)
close (outfile);
infile = mypipe[0];
}
format_job_info (j, "launched");
if (!shell_is_interactive)
wait_for_job (j);
else if (foreground)
put_job_in_foreground (j, 0);
else
put_job_in_background (j, 0);
}
24.6.4 Àü¸é °ú ¹è°æ.
ÀÌÁ¦ Àü¸é(foreground)¿¡ ÀÖ´Â ÀÛ¾÷À» ½ÃÀÛÇÒ ¶§ ½©¿¡ ÀÇÇØ¼ ÇàÇØÁ®¾ß¸¸ ÇÏ´Â µ¿ÀÛÀº ¹«¾ùÀ̸ç, ¹è°æÀÛ¾÷ÀÌ ½ÃÀÛµÉ ¶§ ÇØ¾ß¸¸ µÇ´Â °Í°ú ¹«¾ùÀÌ ¾î¶»°Ô ´Ù¸¥Áö ¾Ë¾Æº¸ÀÚ. Àü¸éÀÛ¾÷ÀÌ ½ÃÀÛµÉ ¶§, ½© Àº ù ¹øÂ°·Î tcsetpgrp¸¦ È£ÃâÇØ¼ ±× Àü¸éÀÛ¾÷¿¡ Å͹̳¯ Á¦¾î±ÇÀ» Áà¾ß¸¸ ÇÑ´Ù. ±×¸®°í³ª¼, ½©Àº ÇÁ·Î¼¼½º ±×·ì¾È¿¡ ÀÖ´Â ÇÁ·Î¼¼½ºµéÀÌ Á¾·áµÇ°Å³ª ¸ØÃâ¶§±îÁö ±â´Ù·Á¾ßÇÑ´Ù. À̰Ϳ¡ ´ëÇÑ »ó¼¼ÇÑ ³»¿ëÀº 24.6.5Àý [Stopped and Terminated Jobs] 344 ÆäÀÌÁö¸¦ ÂüÁ¶Ç϶ó.
±×·ì¾È¿¡ ÀÖ´Â ¸ðµç ÇÁ·Î¼¼½ºµéÀÌ ¼öÇàµÆ°Å³ª ¸ØÃß¾úÀ» ¶§, ½©Àº ´Ù½Ã tcsetpgrp¸¦ È£ÃâÇØ¼ ÀڽŠÀÇ ÇÁ·Î¼¼½º ±×·ìÀ» À§Çؼ Å͹̳¯ Á¦¾î±ÇÀ» µÇã´Â´Ù. ¹è°æÀÛ¾÷À¸·ÎºÎÅÍÀÇ ÀÔ/Ãâ·ÂÀ̳ª »ç¿ëÀÚ¿¡ ÀÇÇØ ÀÔ·ÂµÈ SUSP ¹®ÀÚ°¡ ¿øÀÎÀÌ µÈ ¸ØÃ㠽ñ׳¯ÀÌ ÇÁ·Î¼¼½º ±×·ì¿¡°Ô º¸³»¾îÁö¸é, º¸Åë, ÀÛ¾÷¾È¿¡ ÀÖ´Â ¸ðµç ÇÁ·Î¼¼½ºµéÀÌ ÇÔ²² ¸ØÃá´Ù.
Àü¸éÀÛ¾÷ÀÌ Å͹̳¯À» ÀÌ»óÇÑ »óȲÀ¸·Î ¸¸µé¾úÀ»Áöµµ ¸ð¸£¹Ç·Î, ½©Àº °è¼ÓÇϱâÀü¿¡ ÀÚ½ÅÀÌ ÀúÀåÇØ³õ ¾Ò´ø Å͹̳¯ ¸ðµåµéÀ» ¹ÝȯÇÏ¿©¾ßÇÑ´Ù. ÀÛ¾÷ÀÌ ¿ÏÀüÈ÷ ¸ØÃá°æ¿ì¿¡, ½©Àº ÀÏ´Ü ÇöÀç Å͹̳¯ ¸ðµåµéÀ» ÀúÀåÇϰí, ±×·¡¼ ¸¸ÀÏ ±× ÀÛ¾÷ÀÌ ³ªÁß¿¡ ´Ù½Ã °è¼ÓµÈ´Ù¸é ±×µéÀ» ¹ÝȯÇÒ ¼ö ÀÖ´Ù. Å͹̳¯ ¸ðµåµéÀ» ´Ù·ç´Â ÇÔ¼öµéÀº tcgetattr °ú tcsetattrÀÌ ÀÖ´Ù; ±×µéÀº 12.4Àý [Terminal Modes] 186 ÆäÀÌÁö¸¦ ÂüÁ¶ Ç϶ó. ´ÙÀ½Àº À§¿¡ ¼³¸íµÈ ÀϵéÀ» ÇÏ´Â ¿¹Á¦ ½©À» ÇÔ¼öÀÌ´Ù.
/* ÀÛ¾÷ j¸¦ Àü¸é¿¡ ³õ´Â´Ù. ¸¸ÀÏ cont°¡ 0ÀÌ ¾Æ´Ï¸é, ÀúÀåµÈ Å͹̳¯ ¸ðµåµéÀ» ¹ÝȯÇÏ°í ¿ì¸®°¡ ºí ·ÏÇϱâ Àü¿¡ ±×°ÍÀÌ °è¼ÓµÇµµ·Ï SIGCONT ½Ã±×³¯À» ÇÁ·Î¼¼½º ±×·ì¿¡°Ô º¸³½´Ù. */
void
put_job_in_foreground (job *j, int cont)
{
/* Àü¸éÀ¸·Î ÀÛ¾÷À» ³õ´Â´Ù. */
tcsetpgrp (shell_terminal, j->pgid);
/* ¸¸ÀÏ ÇÊ¿äÇÏ´Ù¸é ÀÛ¾÷À» °è¼ÓÇϵµ·Ï ½Ã±×³¯À» º¸³½´Ù. */
if (cont)
{
tcsetattr (shell_terminal, TCSADRAIN, &j->tmodes);
if (kill (- j->pgid, SIGCONT) < 0)
perror ("kill (SIGCONT)");
}
/* º¸°íÇϵµ·Ï ±â´Ù¸°´Ù. */
wait_for_job (j);
/* Àü¸é¿¡ ½©À» ´Ù½Ã ³õ¾Æ¶ó. */
tcsetpgrp (shell_terminal, shell_pgid);
/* ½©ÀÇ Å͹̳¯ ¸ðµåµéÀ» ¹ÝȯÇÑ´Ù. */
tcgetattr (shell_terminal, &j->tmodes);
tcsetattr (shell_terminal, TCSADRAIN, &shell_tmodes);
}
¸¸ÀÏ ÇÁ·Î¼¼½º ±×·ìÀÌ ¹è°æÀÛ¾÷À¸·Î½á ½ÃÀ۵ȴٸé, ½©Àº Àü¸é¿¡ ÀÚ½ÅÀ» ³õ°í Å͹̳¯·ÎºÎÅÍ ¸í·É¹® Àб⸦ °è¼ÓÇÑ´Ù. ¿¹Á¦ ½©¿¡¼´Â, ¹è°æ¿¡ ÀÛ¾÷À» ³õ¾Æ¾ß µÉ Çʿ䰡 ±×´ÙÁö ¾ø´Ù. ´ÙÀ½Àº ±×°ÍÀ» »ç ¿ëÇÏ´Â ÇÔ¼öÀÌ´Ù.
/* ¹è°æ¿¡ ÀÛ¾÷À» ³õ´Â´Ù. ¸¸ÀÏ cont Àμö°¡ ÂüÀ̸é, ±×°ÍÀÌ °è¼ÓµÇµµ·Ï SIGCONT ½Ã±×³¯À» ÇÁ·Î ¼¼½º ±×·ì¿¡°Ô º¸³½´Ù. */
void
put_job_in_background (job *j, int cont)
{
/* ¸¸ÀÏ ÇÊ¿äÇϸé, ÀÛ¾÷À» °è¼ÓÇϵµ·Ï ½Ã±×³¯À» º¸³½´Ù. */
if (cont)
if (kill (-j->pgid, SIGCONT) < 0)
perror ("kill (SIGCONT)");
}
24.6.5 ¸ØÃß°í Á¾·áµÈ ÀÛ¾÷µé.
Àü¸é ÇÁ·Î¼¼½º°¡ ½ÃÀÛµÉ ¶§, ½©Àº ÀÛ¾÷¿¡ ÀÖ´Â ¸ðµç ÇÁ·Î¼¼½ºµéÀÌ ¸ØÃ߰ųª Á¾·áµÉ¶§±îÁö ºí·ÏÇØ¾ß ¸¸ ÇÑ´Ù. ±×°ÍÀº waitpid ÇÔ¼ö¸¦ È£ÃâÇÔÀ¸·Î½á ÀÌ·ç¾îÁø´Ù; 23.6Àý [Process Completion] 329 ÆäÀÌ Áö ÂüÁ¶. ÇÁ·Î¼¼½º°¡ Á¾·áµÈ°Í»Ó¸¸ ¾Æ´Ï¶ó ¸ØÃã ¶ÇÇÑ º¸°íÇϵµ·Ï WUNTRACED ¿É¼ÇÀ» »ç¿ëÇ϶ó. ½©Àº ¹è°æÀÛ¾÷ÀÌ ¸ØÃß¾ú°Å³ª Á¾·áµÈ ÀÛ¾÷µéÀ» »ç¿ëÀÚ¿¡°Ô º¸°íÇϵµ·Ï ¹è°æÀÛ¾÷µéÀÇ »óȲÀ» Ã¼Å©ÇØ ¾ß¸¸ ÇÑ´Ù; À̰ÍÀº WNOHANG ¿É¼ÇÀ» »ç¿ëÇØ¼ waitpid ÇÔ¼ö¸¦ È£ÃâÇÔÀ¸·Î½áÇÒ ¼ö ÀÖ´Ù. ÀÛ¾÷ÀÌ ¸ØÃß¾ú°Å³ª Á¾·áµÇ¾úÀ½À» üũÇϴ°Ͱú °°Àº Äڵ幮À» ³Ö´Â ÁÁÀº À§Ä¡´Â »õ·Î¿î ¸í·É¹®À» ÀÐÀ¸·Á (prompting) Çϱâ ÀüÀÌ´Ù.
½©Àº SIGCHLD ½Ã±×³¯À» ó¸®ÇÏ´Â Çڵ鷯¸¦ ¸¸µêÀ¸·Î½á ÀÚ½Ä ÇÁ·Î¼¼½º¸¦ À§ÇÑ À¯¿ëÇÑ »óȲÁ¤º¸¸¦ ºñµ¿±âÀûÀ¸·Î ÅëÁö¹ÞÀ» ¼ö ÀÖ´Ù. 21Àå [Signal Handling] 271 ÆäÀÌÁö ÂüÁ¶.
¿¹Á¦ ½© ÇÁ·Î±×·¥ÀÇ °æ¿ì¿¡´Â, SIGCHLD ½Ã±×³¯Àº º¸Åë ¹«½ÃµÈ´Ù. ½©ÀÌ Á¶ÀÛÇϰí ÀÖ´Â Àü¿ª µ¥ÀÌ ÅÍ ±¸Á¶Ã¼¸¦ ÀçÁøÀÔÇÏ´Â ¹®Á¦¸¦ ÇÇÇϱâ À§ÇÔÀÌ´Ù. ±×·¯³ª ½©ÀÌ ±×µé µ¥ÀÌÅÍ ±¸Á¶Ã¼¸¦ »ç¿ëÇÏÁö ¾Ê ´Â ¾î¶² ½Ã°£µ¿¾È¿¡´Â _¿¹¸¦µé¾î, Å͹̳¯¿¡¼ ÀÔ·ÂÀ» ±â´Ù¸®´Â ¶§¿Í °°Àº_SIGCHLD ½Ã±×³¯À» ó¸® ÇÏ´Â Çڵ鷯´Â °¡´ÉÇÏ´Ù. µ¿±âÀûÀ¸·Î »óȲµéÀ» üũÇϴµ¥ »ç¿ëµÇ´Â °°Àº ÇÔ¼ö´Â (ÀÌ °æ¿ì, do_job_notification) ÀÌ Çڵ鷯·ÎºÎÅÍ È£ÃâµÉ ¼ö ÀÖ´Ù.
´ÙÀ½Àº ÀÛ¾÷ÀÇ »óȲµéÀ» üũÇÏ°í »ç¿ëÀÚ¿¡°Ô Á¤º¸¸¦ º¸°íÇÏ´Â °ÍÀ» Ãë±ÞÇÏ´Â ¿¹Á¦ ½© ÇÁ·Î±×·¥ÀÇ ÀϺκÐÀÌ´Ù.
/* waitpid¿¡ ÀÇÇØ ¸®ÅÏµÈ ÇÁ·Î¼¼½º pidÀÇ »óȲÀ» ÀúÀåÇ϶ó. ¸ðµÎ Àß µÆÀ¸¸é 0À» ¸®ÅÏÇϰí, ¾Æ´Ï¸é 0ÀÌ ¾Æ´Ñ°ªÀ» ¸®ÅÏÇ϶ó. */
int
mark_process_status (pid_t pid, int status)
{
job *j;
process *p;
if (pid > 0)
{
/* ÇÁ·Î¼¼½º¸¦ À§Çؼ ±â·ÏÀ» °»½ÅÇ϶ó. */
for (j = first_job; j; j = j->next)
for (p = j->first_process; p; p = p->next)
if (p->pid == pid)
{
p->status = status;
if (WIFSTOPPED (status))
p->stopped = 1;
else
{
p->completed = 1;
if (WIFSIGNALED (status))
fprintf(stderr, "%d: Terminated by signal
%d.\n", (int)pid, WTERMSIG(p->status));
}
return 0;
}
fprintf (stderr, "No child process %d.\n", pid);
return -1;
}
else if (pid == 0 || errno == ECHILD)
/* º¸°íÇϱâÀ§ÇØ ÁغñµÈ ÇÁ·Î¼¼½º°¡ ¾ø´Ù. */
return -1;
else {
/* Other weird errors. */
perror ("waitpid");
return -1;
}
}
/* ºí·ÏÇÏÁöÁö ¾Ê°í, À¯¿ëÇÑ »óȲÁ¤º¸¸¦ °¡Áø ÇÁ·Î¼¼½ºµéÀ» üũÇ϶ó. */
void
update_status (void)
{
int status;
pid_t pid;
do
pid = waitpid(WAIT_ANY, &status, WUNTRACED|WNOHANG);
while (!mark_process_status (pid, status));
}
/* ÁÖ¾îÁø ÀÛ¾÷¾È¿¡ ÀÖ´Â ¸ðµç ÇÁ·Î¼¼½ºµéÀÌ º¸°íµÇ¾úÀ»¶§±îÁö ºí·ÏÇÏ¿©, À¯¿ëÇÑ »óȲÁ¤º¸¸¦ °¡Áø ÇÁ·Î¼¼½ºµéÀ» üũÇ϶ó. */
void
wait_for_job (job *j)
{
int status;
pid_t pid;
do
pid = waitpid (WAIT_ANY, &status, WUNTRACED);
while (!mark_process_status (pid, status)
&& !job_is_stopped (j)
&& !job_is_completed (j));
}
/* »ç¿ëÀÚ¿¡°Ô º¸À̱âÀ§ÇÑ ÀÛ¾÷»óȲ¿¡ ´ëÇÑ Á¤º¸¸¦ Çü½ÄÈÇ϶ó. */
void
format_job_info (job *j, const char *status)
{
fprintf(stderr, "%ld (%s): %s\n", (long)j->pgid, status, j->command);}
/* ¸ØÃß¾ú°Å³ª Á¾·áµÈ ÀÛ¾÷µé¿¡ ´ëÇØ¼ »ç¿ëÀÚ¿¡°Ô º¸°íÇ϶ó. Ȱ¼ºÈµÈ ÀÛ¾÷ ¸®½ºÆ®·ÎºÎÅÍ Á¾·áµÈ ÀÛ¾÷µéÀ» Áö¿ö¶ó. */
void
do_job_notification (void)
{
job *j, *jlast, *jnext;
process *p;
/* ÀÚ½Ä ÇÁ·Î¼¼½º¸¦ À§ÇÑ »óȲÁ¤º¸µéÀ» °»½ÅÇ϶ó. */
update_status ();
jlast = NULL;
for (j = first_job; j; j = jnext)
{
jnext = j->next;
/* ¸¸ÀÏ ¸ðµç ÇÁ·Î¼¼½ºµéÀÌ ¿Ï¼öµÇ¾ú´Ù¸é, ÀÛ¾÷µéÀÌ ¿Ï¼öµÇ¾úÀ½À» »ç¿ëÀÚ¿¡°Ô ¾Ë¸®°í Ȱ¼º ÀÛ¾÷ ¸® ½ºÆ®¿¡¼ ±×°ÍÀ» Áö¿ö¶ó. */
if (job_is_completed (j)) {
format_job_info (j, "completed");
if (jlast)
jlast->next = jnext;
else
first_job = jnext;
free_job (j);
}
/* ´õ ÀÌ»ó ÁøÇàÇÒ ¼ö ¾øÀ½À» Ç¥½ÃÇÏ¿©, ¸ØÃß¾îÁø ÀÛ¾÷¿¡ ´ëÇÏ¿© »ç¿ëÀÚ¿¡°Ô ÅëÁöÇ϶ó. */
else if (job_is_stopped (j) && !j->notified) {
format_job_info (j, "stopped");
j->notified = 1;
jlast = j;
}
/* ¿©ÀüÈ÷ ½ÇÇàµÇ°í ÀÖ´Â ÀÛ¾÷µé¿¡ ´ëÇØ¼´Â ¾Æ¹«°Íµµ ¸»ÇÏÁö ¸»¾Æ¶ó. */
else
jlast = j;
}
}
24.6.6 ¸ØÃß¾îÀÖ´Â ÀÛ¾÷µéÀ»°è¼Ó ½ÇÇà½Ã۱â.
½©Àº ÇÁ·Î¼¼½º ±×·ì¿¡°Ô SIGCONT ½Ã±×³¯À» º¸³¿À¸·Î½á ¸ØÃß¾îÁø ÀÛ¾÷À» °è¼ÓÇÏ°Ô ÇÒ ¼ö ÀÖ´Ù. ¸¸ÀÏ ÀÛ¾÷ÀÌ Àü¸é¿¡¼ °è¼Ó ½ÇÇàµÇ¾î¾ßÇϸé, ½©Àº ÀÏ´Ü tcsetpgrp ¸¦ È£ÃâÇØ¼ Å͹̳¯ Á¦¾î±ÇÀ» ±× ÀÛ¾÷¿¡°Ô ºÎ¿©Çϰí, ÀúÀåµÈ Å͹̳¯ ¼³Á¤À» ¹ÝȯÇÑ´Ù. Àü¸é¿¡¼ ÀÛ¾÷ÀÌ Àç°³µÈ ÈÄ¿¡, ½©Àº ±× ÀÛ¾÷ÀÌ ¸¶Ä¡ Àü¸é¿¡¼ ½ÃÀ۵ȰÍó·³, ±× ÀÛ¾÷ÀÌ ¸ØÃ߰ųª Á¾·áµÇ±â¸¦ ±â´Ù¸°´Ù.
¿¹Á¦ ½© ÇÁ·Î±×·¥¿¡¼ »õ·ÎÀÌ ¸¸µé¾îÁø ÀÛ¾÷°ú Àç°³µÈ ÀÛ¾÷µé¿¡ ´ëÇÑ Ã³¸®´Â put_job_in_foreground ¿Í put_job_in_background ÇѽÖÀÇ ÇÔ¼ö·Î ÀÌ·ç¾îÁø´Ù. ±×µé ÇÔ¼ö¿¡ ´ëÇÑ Á¤ ÀÇ´Â 24.6.4Àý [Foreground and Background] 343 ÆäÀÌÁö¿¡ ³ª¿ÍÀÖ´Ù. ¸ØÃß¾ú´ø ÀÛ¾÷À» Àç°³ÇÒ ¶§, cont Àμö¿¡ ÁÖ¾îÁø 0ÀÌ ¾Æ´Ñ°ªÀº SIGCONT ½Ã±×³¯À» º¸³»°í Àû´çÇÑ Å͹̳Π¸ðµå¸¦ ¹ÝȯÇÔÀ» È®½Ç ÇÏ°Ô ÇÑ´Ù.
´ÙÀ½Àº Àç°³µÇ¾î ½ÇÇàµÇ°í ÀÖ´Â ÀÛ¾÷¿¡ ´ëÇØ¼ ½©ÀÌ ³»ºÎÀûÀ¸·Î º¸À¯Çϰí ÀÖ´ø Á¤º¸¸¦ °»½ÅÇÏ´Â ÇÔ¼öÀÌ´Ù.
/* ¸ØÃß¾îÀÖ´ø ÀÛ¾÷ J¸¦ ´Ù½Ã ½ÇÇàµÇ°í ÀÖ´Â ÀÛ¾÷À¸·Î½á Ç¥½ÃÇ϶ó. */
void
mark_job_as_running (job *j)
{
Process *p;
for (p = j->first_process; p; p = p->next)
p->stopped = 0;
j->notified = 0;
}
/* ÀÛ¾÷ J¸¦ °è¼ÓÇ϶ó. */
void
continue_job (job *j, int foreground)
{
mark_job_as_running (j);
if (foreground)
put_job_in_foreground (j, 1);
else
put_job_in_background (j, 1);
}
24.6.7 ÀÌ Àå¿¡¼ ¼³¸íµÇÁö ¾ÊÀº ºÎºÐµé.
ÀÌÀå¿¡ Æ÷ÇÔµÈ ¿¹Á¦ ½©À» À§ÇÑ ¿©ºÐÀÇ ÄÚµå´Â Àüü ½© ÇÁ·Î±×·¥À» À§ÇÑ ÀϺκÐÀÌ´Ù. ÇÏÁö¸¸, ¾î¶»°Ô ÀÛ¾÷°ú ÇÁ·Î±×·¥ µ¥ÀÌÅÍ ±¸Á¶Ã¼µéÀÌ ÇÒ´çµÇ°í ÃʱâȵǴÂÁö¿¡ ´ëÇØ¼´Â ÀüÇô ¾ê±âÇÏÁö ¾Ê¾Ò´Ù. ´ëºÎ ºÐÀÇ ½ÇÁ¦ ½©Àº ¸í·É¹®; º¯¼öµé; ¾à¾î, ´ëÀÔ, ±×¸®°í ÆÄÀÏÀ̸§ÀÇ ÆÐÅÏ ¸ÅεîÀ» À§ÇÑ °ÍÀ» Á¦°øÇÏ´Â, º¹ÀâÇÑ »ç¿ëÀÚ ÀÎÅÍÆäÀ̽º·Î µÇ¾îÀÖ´Ù. À̰÷¿¡ ¼³¸íµÈ ÀÌ ¸ðµç °ÍÀº º¹ÀâÇÔ°ú´Â °Å¸®°¡ ¸Ö´Ù! ´ë½Å ¿¡, ¿ì¸®´Â ¾î¶»°Ô ÄÚ¾Æ ÇÁ·Î¼¼½º¸¦ »ý¼ºÀ» ÇÏ´ÂÁö¸¦ º¸¿©ÁÖ°í ±×¿Í °°Àº ½©¿¡¼ ¾î¶² ÀÛ¾÷Á¦¾î ÇÔ ¼öµéÀÌ È£ÃâµÉ ¼ö ÀÖ´ÂÁö¿¡ ´ëÇØ¼ °ü½ÉÀ» µÎ¾ú´Ù. ´ÙÀ½Àº ¿ì¸®°¡ Ç¥ÇöÇß´ø ÁÖ¿ä ¿£Æ®¸® Æ÷ÀÎÆ®¸¦ ¿ä¾àÇÑ Å×À̺íÀÌ´Ù.
void init_shell (void)
½©ÀÇ ³»ºÎ »óȲÀ» ÃʱâÈÇÑ´Ù. 24.6.2Àý [Initializing the Shell] 339 ÆäÀÌÁö ÂüÁ¶.
void init_sh
void launch_job (job *j, int foreground)
Àü¸é ¶Ç´Â ¹è°æ¿¡¼ ÀÛ¾÷ j¸¦ ½ÃÀÛÇÑ´Ù. 24.6.3Àý [Launching Jobs] 340 ÆäÀÌÁö ÂüÁ¶.
void do_job_notification (void)
Á¾·áµÇ°Å³ª ¸ØÃß¾îÁø ¾î¶² ÀÛ¾÷µéÀÌ ÀÖ´ÂÁö üũÇÏ°í º¸°íÇÑ´Ù. SIGCHLD ½Ã±×³¯À» À§ÇÑ Çڵ鷯 ¾È ¿¡¼ ¶Ç´Â µ¿±âÀûÀ¸·Î È£ÃâµÉ ¼ö ÀÖ´Ù. 24.6.5Àý [Stopped and Terminated Jobs] 344 ÆäÀÌÁö ÂüÁ¶.
void continue_job (job *j, int foreground)
ÀÛ¾÷ j¸¦ Àç°³ÇÑ´Ù. 24.6.6Àý [Continuing Stopped Jobs] 347ÆäÀÌÁö ÂüÁ¶.
¹°·Ð, ½ÇÁ¦ ½©Àº ÀÛ¾÷À» ó¸®Çϱâ À§Çؼ ´Ù¸¥ ÇÔ¼öµéÀ» Á¦°ø¹Þ±â ¿øÇÒÁö ¸ð¸¥´Ù. ¿¹¸¦µé¾î, Ȱ¼º ÈµÈ ¸ðµç ÀÛ¾÷µéÀÇ ¸®½ºÆ®¸¦ º¸¿©Áְųª, ÀÛ¾÷¿¡°Ô ½Ã±×³¯(SIGKILL °ú °°Àº)À» º¸³»´Â ¸í·É¹®Àº À¯¿ëÇÒ °ÍÀÌ´Ù.
24.7 ÀÛ¾÷Á¦¾î¸¦ À§ÇÑ ÇÔ¼öµé.
ÀÌ ÀýÀº ÀÛ¾÷Á¦¾î¿Í ¿¬°üµÈ ÇÔ¼öµéÀ» ÀÚ¼¼ÇÏ°Ô ¼³¸íÇϰí ÀÖ´Ù.
24.7.1 Á¦¾îÁßÀÎ Å͹̳¯ È®ÀÎÇϱâ.
´ç½ÅÀº Á¦¾îÁßÀÎ Å͹̳¯À» °³¹æÇϱâ À§Çؼ »ç¿ëÇÒ ¼ö ÀÖ´Â ÆÄÀÏÀ̸§À» ¾ò±â À§Çؼ ctermid ÇÔ¼ö ¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. GNU ¶óÀ̺귯¸®¿¡¼´Â, Ç×»ó °°Àº ¹®ÀÚ¿ÀÌ ¸®ÅϵȴÙ: "/dev/tty". ±×°ÍÀº Çö Àç ÇÁ·Î¼¼½ºÀÇ Á¦¾î ÁßÀÎ Å͹̳¯(¸¸ÀÏ ±×°ÍÀÌ ÇÑ °³¶ó¸é)À» ÂüÁ¶ÇϱâÀ§ÇÑ "ÀÌ»óÇÑ" Ưº°ÆÄÀÏ À̸§ÀÌ ´Ù. ctermid ÇÔ¼ö´Â Çì´õÆÄÀÏ `stdio.h'¿¡ ¼±¾ðµÇ¾î ÀÖ´Ù.
ÇÔ¼ö : char * ctermid (char *string)
ctermid ÇÔ¼ö´Â ÇöÀç ÇÁ·Î¼¼½º¸¦ À§Çؼ Á¦¾îÁßÀÎ Å͹̳¯ÀÇ ÆÄÀÏÀ̸§ÀÌ Æ÷ÇÔµÈ ¹®ÀÚ¿À» ¸®ÅÏÇÑ´Ù. ¸¸ÀÏ ¹®ÀÚ¿ÀÌ ³Î Æ÷ÀÎÅͰ¡ ¾Æ´Ï¶ó¸é, ±×°ÍÀº Àû¾îµµ L_ctermid ¹®ÀÚµéÀ» ÀúÀåÇϰí ÀÖ´Â ¹è¿ÀÌ µÉ °ÍÀÌ´Ù. ¹®ÀÚ¿À» ÀÌ ¹è¿¾È¿¡ ¸®ÅϵȴÙ. ±×·¸Áö ¾Ê´Ù¸é, Á¤Àû Áö¿ª¾È¿¡ ¸®ÅÏµÈ ¹®ÀÚ¿¿¡ ´ëÇÑ Æ÷ÀÎ ÅÍ´Â ÀÌ ÇÔ¼ö°¡ ¿¬¼ÓÀûÀ¸·Î È£ÃâµÇ¾î µ¡¾º¿öÁú °ÍÀÌ´Ù.
¸¸ÀÏ ¾î¶°ÇÑ ÀÌÀ¯·Î ÆÄÀÏÀ̸§ÀÌ °áÁ¤µÉ ¼ö ¾ø´Ù¸é ºó ¹®ÀÚ¿(empty string)À» ¸®ÅÏÇÑ´Ù. ½ÉÁö¾î ÆÄ ÀÏÀ̸§ÀÌ ¸®ÅϵÆÀ»Áö¶óµµ, ±× ÆÄÀÏ¿¡ ´ëÇÑ ¾ï¼¼½º´Â º¸ÁõµÇÁö ¾Ê´Â´Ù.
¸ÅÅ©·Î : int L_ctermid
ÀÌ ¸ÅÅ©·Î´Â ctermid¿¡ ÀÇÇØ ¸®ÅÏµÈ ÆÄÀÏÀ̸§À» ÀúÀåÇϱ⿡ ÃæºÐÈ÷ Å« ¹®ÀÚ¿ÀÇ Å©±â¸¦ ³ªÅ¸³»´Â Á¤ ¼ö »ó¼ö Ç¥Çö½ÄÀÌ´Ù.
¶ÇÇÑ 12.1Àý [Is It a Terminal] 185 ÆäÀÌÁö¿¡ ÀÖ´Â isatty ¿Í ttyname ÇÔ¼ö¸¦ ÂüÁ¶Ç϶ó.
24.7.2 ÇÁ·Î¼¼½º ±×·ì ÇÔ¼öµé.
´ÙÀ½Àº ÇÁ·Î¼¼½º ±×·ìÀ» ´Ù·ç±â À§ÇÑ ÇÔ¼ö¸¦ ¼³¸íÇϰí ÀÖ´Ù. ´ç½ÅÀÇ ÇÁ·Î±×·¥¿¡¼ ±×µé ÇÔ¼öµéÀ» »ç¿ëÇϱâ À§Çؼ´Â Çì´õÆÄÀÏ `sys/types.h' ¿Í `unistd.h'¸¦ Æ÷ÇÔÇØ¾ß¸¸ ÇÑ´Ù.
ÇÔ¼ö : pid_t setsid (void)
setsid ÇÔ¼ö´Â »õ·Î¿î ¼¼¼ÇÀ» ¸¸µç´Ù. È£ÃâÇÑ ÇÁ·Î¼¼½º´Â ¼¼¼Ç¸®´õ°¡ µÇ°í, ±× ÇÁ·Î¼¼½ºÀÇ ÇÁ·Î¼¼½º ID¿Í °°Àº ID¸¦ °¡Áø »õ·Î¿î ÇÁ·Î¼¼½º ±×·ìÀÌ ¸¸µé¾îÁö°í ÇÁ·Î¼¼½º°¡ ±× ¾È¿¡ ¼Ò¼ÓµÈ´Ù. »õ·Î¿î ÇÁ ·Î¼¼½º ±×·ì¿¡ ´Ù¸¥ ÇÁ·Î¼¼½ºµéÀÌ ¾ø°í »õ·Î¿î ¼¼¼Ç¾È¿¡ ´Ù¸¥ ÇÁ·Î¼¼½º ±×·ìÀÌ ¾øÀÌ ÃʱâȵȴÙ. ÀÌ ÇÔ¼ö´Â ¶ÇÇÑ È£ÃâÇÑ ÇÁ·Î¼¼½º°¡ Á¦¾îÁßÀÎ Å͹̳¯À» °®Áö ¾Êµµ·Ï ¸¸µç´Ù. setsid ÇÔ¼ö´Â ¸¸ÀÏ ¼º°øÇÏ ¸é È£ÃâÇÑ ÇÁ·Î¼¼½ºÀÇ »õ·Î¿î ÇÁ·Î¼¼½º ±×·ì ID¸¦ ¸®ÅÏÇÏ°í ½ÇÆÐÇϸé -1ÀÇ °ªÀ» ¸®ÅÏÇÑ´Ù. ´ÙÀ½Àº ÀÌ ÇÔ¼ö¸¦ À§ÇØ Á¤ÀÇµÈ ¿¡·¯»óȲÀÌ´Ù.
EPERM
È£ÃâÇÑ ÇÁ·Î¼¼½º°¡ ÀÌ¹Ì ÇÁ·Î¼¼½º ±×·ìÀÇ ¸®´õÀ̰ųª, °°Àº ÇÁ·Î¼¼½º ±×·ì ID¸¦ °¡Áø ´Ù¸¥ ÇÁ·Î¼¼½º ±×·ìÀÌ ÀÖ´Ù.
getpgrp ÇÔ¼ö´Â µÎ °³ÀÇ Á¤ÀǸ¦ °¡Áø´Ù; ÇÑ °³´Â BSD À¯´Ð½º¿¡¼ ¿Ô°í, ÇÑ °³´Â POSIX.1 Ç¥ÁØÀ¸ ·ÎºÎÅÍ ¿Â °ÍÀÌ´Ù. ´ç½ÅÀÌ ¼±ÅÃÇÑ Å×½ºÆ® ¸ÅÅ©·Î(1.3.4Àý [Feature Test Macros] 6 ÆäÀÌÁö ÂüÁ¶.)¿¡ µû¶ó¼ ´ç½ÅÀÌ ¾î¶² Á¤ÀǸ¦ ¼±ÅÃÇß´ÂÁö°¡ °áÁ¤µÈ´Ù. Áï, ´ç½ÅÀÌ _BSD_SOURCE¸¦ Á¤ÀÇÇϸé BSD °ÍÀÌ ¼±Åõǰí; ±×·¸Áö¾Ê°í, _POSIX_SOURCE ¶Ç´Â _GNU_SOURCE¸¦ Á¤ÀÇÇÑ´Ù¸é POSIXÀÇ °ÍÀÌ ¼±ÅÃµÈ °ÍÀÌ´Ù. ¿À·¡µÈ BSD ½Ã½ºÅÛ¿¡¼ ¸¸µé¾îÁø ÇÁ·Î±×·¥µéÀº _BSD_SOURCE ÇÏ¿¡¼ Ưº°È÷ Á¤ ÀÇµÈ getgrp¸¦ »ç¿ëÇϵµ·Ï `unistd.h'¸¦ ÀÎŬ·çµå ÇÒ ¼ö¾ø´Ù. ´ç½ÅÀº BSDÁ¤ÀǸ¦ ȹµæ Çϱâ À§Çؼ -lbsd-compact ·Î ±×¿Í °°Àº ÇÁ·Î±×·¥µéÀ» ¸µÅ©Çؾ߸¸ ÇÑ´Ù.
POSIX.1 ÇÔ¼ö : pid_t getpgrp (void)
getpgrpÀÇ POSIX.1 Á¤ÀǴ ȣÃâÇÑ ÇÁ·Î¼¼½ºÀÇ ÇÁ·Î¼¼½º ±×·ì ID¸¦ ¸®ÅÏÇÑ´Ù.
BSD ÇÔ¼ö : pid_t getpgrp (pid_t pid)
getpgrp ÀÇ BSD Á¤ÀÇ´Â ÇÁ·Î¼¼½º pidÀÇ ÇÁ·Î¼¼½º ±×·ì ID¸¦ ¸®ÅÏÇÑ´Ù. ´ç½ÅÀÌ È£ÃâÇÑ ÇÁ·Î¼¼½º¿¡ ´ëÇÑ Á¤º¸¸¦ ¾ò±âÀ§Çؼ´Â pidÀμö¸¦ À§Çؼ 0ÀÇ °ªÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.
ÇÔ¼ö : int setpgid (pid_t pid, pid_t pgid)
setpgid ÇÔ¼ö´Â ÇÁ·Î¼¼½º ±×·ì pgid¿¡ ÇÁ·Î¼¼½º pid¸¦ ¼Ò¼Ó½ÃŲ´Ù. Ưº°ÇÑ °æ¿ì·Î, pid ¶Ç´Â pgid´Â È£ÃâÇÑ ÇÁ·Î¼¼½ºÀÇ ÇÁ·Î¼¼½º ±×·ìÀ» ÁöÀûÇϱâ À§Çؼ 0À¸·Î µÉ ¼ö ÀÖ´Ù. ÀÌ ÇÔ¼ö´Â ÀÛ¾÷Á¦¾î¸¦ Áö ¿øÇÏÁö ¾Ê´Â ½Ã½ºÅÛ¿¡¼´Â ½ÇÆÐÇÑ´Ù. 24.2Àý [Job Control is Optional] 336 ÆäÀÌÁö ÂüÁ¶ÇÏ¿© »ó¼¼ÇÑ Á¤º¸¸¦ ¾ò¾î¶ó. ¸¸ÀÏ ¸í·ÉÀÌ ¼º°øÇϸé, setpgid´Â 0À» ¸®ÅÏÇÑ´Ù. ±×·¸Áö ¾Ê´Ù¸é -1À» ¸®ÅÏÇÑ´Ù. ´ÙÀ½ ÀÇ errno´Â ÀÌ ÇÔ¼ö¸¦ À§ÇØ Á¤ÀÇµÈ ¿¡·¯»óȲÀÌ´Ù.
EACCES
pid¶ó´Â À̸§À» °¡Áø ÀÚ½Ä ÇÁ·Î¼¼½º°¡ ¸¸µé¾îÁø ÈÄ¿¡ exec ÇÔ¼ö¸¦ ÅëÇØ¼ ½ÇÇàµÇ¾ú´Ù.
EINVAL
pgidÀÇ °ªÀÌ À¯¿ëÇÏÁö ¾Ê´Ù.
ENOSYS
½Ã½ºÅÛÀÌ ÀÛ¾÷Á¦¾î¸¦ Áö¿øÇÏÁö ¾Ê´Â´Ù.
EPERM
pid Àμö¿¡ ÀÇÇØ ÁöÀûµÈ ÇÁ·Î¼¼½º°¡ ¼¼¼Ç¸®´õÀ̰ųª, È£ÃâÇÑ ÇÁ·Î¼¼½º¿Í °°Àº ¼¼¼Ç¿¡ ¾ø°Å³ª, pgid ÀμöÀÇ °ªÀÌ È£ÃâÇÑ ÇÁ·Î¼¼½º¿Í °°Àº ¼¼¼Ç¾È¿¡ ÀÖ´Â ÇÁ·Î¼¼½º ±×·ì ID¿Í ¸ÅÄ¡µÇ´Â °ÍÀÌ ¾ø´Ù.
ESRCH
pid Àμö¿¡ ÀÇÇØ ÁöÀûµÈ ÇÁ·Î¼¼½º°¡ È£ÃâÇÑ ÇÁ·Î¼¼½º°¡ ¾Æ´Ï°Å³ª È£ÃâÇÑ ÇÁ·Î¼¼½ºÀÇ ÀÚ½Ä ÇÁ·Î¼¼½º °¡ ¾Æ´Ï´Ù.
ÇÔ¼ö : int setpgrp(pid_t pid, pid_t pgid)
À̰ÍÀº setpgid¸¦ À§ÇÑ BSD¿ëÀÌ´Ù. µÎ ÇÔ¼ö´Â °°Àº ÀÏÀ» ÇÑ´Ù.
24.7.3 Á¦¾î±ÇÀ» °¡Áø Å͹̳¯À» ¾ï¼¼½ºÇϱâ À§ÇÑ ÇÔ¼öµé.
´ÙÀ½Àº Å͹̳¯ÀÇ Àü¸é ÇÁ·Î¼¼½º ±×·ìÀ» ¾Ë¾Æ³»°Å³ª ¼³Á¤Çϱâ À§ÇÑ ÇÔ¼öµéÀÌ´Ù. ´ç½ÅÀº ±×µé ÇÔ¼ö µéÀ» ´ç½ÅÀÇ ¾îÇø®ÄÉÀ̼ǿ¡¼ »ç¿ëÇϱâ À§Çؼ´Â Çì´õÆÄÀÏ `sys/types.h' ¿Í `unistd.h'¸¦ ÀÎŬ·çµå ÇØ¾ß¸¸ ÇÑ´Ù. ±×µéÇÔ¼öµéÀÌ Å͹̳¯ µð¹ÙÀ̽º¸¦ Á¤Çϵµ·Ï ÆÄÀÏ ±â¼úÀÚ Àμö¸¦ Á¤ÇÑ´Ù°í ÇÏ´õ¶óµµ, Àü ¸éÀÛ¾÷Àº Å͹̳¯ ÆÄÀÏ ±×ÀÚü¿Í ¿¬°üµÇ¾î ÀÖ°í Æ¯º°È÷ °³¹æµÈ ÆÄÀÏ ±â¼úÀÚ°¡ ¾Æ´Ï´Ù.
ÇÔ¼ö : pid_t tcgetpgrp(int filedes)
ÀÌ ÇÔ¼ö´Â ±â¼úÀÚ filedes·Î °³¹æÇÑ Å͹̳¯°ú ¿¬°üµÈ Àü¸é ÇÁ·Î¼¼½º ±×·ìÀÇ ÇÁ·Î¼¼½º ±×·ì ID¸¦ ¸®ÅÏ ÇÑ´Ù. ¸¸ÀÏ ¾Æ¹«·± Àü¸é ÇÁ·Î¼¼½º ±×·ìÀÌ ¾ø´Ù¸é, ÇöÁ¸ÇÏ´Â ÇÁ·Î¼¼½º ±×·ìÀÇ ÇÁ·Î¼¼½º ±×·ì ID¿Í ¸ÅÄ¡ µÇÁö ¾Ê´Â, 1º¸´Ù Å« ¼ö¸¦ ¸®ÅÏÇÑ´Ù. ±×·¯ÇÑ °æ¿ì´Â Àü¸éÀÛ¾÷À¸·Î½á ¼öÇàµÇ°í ÀÖ´ø ÀÛ¾÷¾È¿¡ ÀÖ´Â ¸ðµç ÇÁ·Î¼¼½ºµéÀÌ Á¾·áµÇ°í Àü¸éÀ¸·Î ¿Å°ÜÁú ÀÛ¾÷µéÀÌ ¾øÀ» ¶§ ¹ß»ýÇÒ ¼ö ÀÖ´Ù ¿¡·¯ÀÇ °æ¿ì ¿¡ -1ÀÇ °ªÀÌ ¸®ÅϵȴÙ. ´ÙÀ½ÀÇ errno´Â ÀÌ ÇÔ¼ö¸¦ À§ÇØ Á¤ÀÇµÈ ¿¡·¯»óȲÀÌ´Ù.
EBADF
filedes Àμö°¡ À¯¿ëÇÑ ÆÄÀÏ ±â¼úÀÚ°¡ ¾Æ´Ï´Ù.
ENOSYS
½Ã½ºÅÛÀÌ ÀÛ¾÷Á¦¾î¸¦ Áö¿øÇÏÁö ¾Ê´Â´Ù.
ENOTTY
filedes Àμö¿Í ¿¬°üµÈ Å͹̳¯ ÆÄÀÏÀÌ È£ÃâÇÑ ÇÁ·Î¼¼½º°¡ Á¦¾îÁßÀÎ Å͹̳¯ÀÌ ¾Æ´Ï´Ù.
ÇÔ¼ö : tcsetpgrp(int filedes, pid_t pgid)
ÀÌ ÇÔ¼ö´Â Å͹̳¯ÀÇ Àü¸é ÇÁ·Î¼¼½º ±×·ì ID¸¦ ¼³Á¤Çϴµ¥ »ç¿ëµÈ´Ù. Àμö filedes´Â Å͹̳¯À» ÁöÁ¤ÇÏ ´Â ±â¼úÀÚÀÌ´Ù; pgid Àμö´Â ÇÁ·Î¼¼½º ±×·ìÀ» ÁöÁ¤ÇÑ´Ù. È£ÃâÇÑ ÇÁ·Î¼¼½º´Â pgid¿Í °°Àº ¼¼¼ÇÀÇ ¸â ¹ö°¡ µÇ¾î¾ß¸¸ ÇÏ°í °°Àº Å͹̳¯À» Á¦¾îÇϰí ÀÖ¾î¾ß¸¸ ÇÑ´Ù.
Å͹̳¯ ¾ï¼¼½º¸¦ ¸ñÀûÀ¸·Î ÇÏ¿©, ÀÌ ÇÔ¼ö´Â Ãâ·ÂÀ¸·Î Ãë±ÞµÈ´Ù. ¸¸ÀÏ ¹è°æ ÇÁ·Î¼¼½º·ÎºÎÅÍ ÀÌ ÇÔ¼ö °¡ È£ÃâµÈ´Ù¸é, º¸Åë ±× ÇÁ·Î¼¼½º ±×·ì¾È¿¡ ÀÖ´Â ¸ðµç ÇÁ·Î¼¼½ºµé¿¡°Ô SIGTTOU ½Ã±×³¯ÀÌ º¸³»¾î Áø´Ù. ¸¸ÀÏ È£ÃâÇÑ ÇÁ·Î¼¼½º ÀÚü°¡ SIGTTOU ½Ã±×³¯À» ¹«½ÃÇÏ´Â ¿¹¿ÜÀÇ °æ¿ì¶ó¸é, ±× ¸í·ÉÀº ¼ö ÇàµÇ°í ¾Æ¹«·± ½Ã±×³¯µµ º¸³»¾îÁöÁö ¾Ê´Â´Ù.
¸¸ÀÏ ¼º°øÇϸé, tcsetpgrp ´Â 0À» ¸®ÅÏÇÑ´Ù. ¿¡·¯°¡ ¹ß»ýÇÑ °æ¿ì¿¡´Â -1À» ¸®ÅÏÇÑ´Ù. ´ÙÀ½ÀÇ errno´Â ÀÌ ÇÔ¼ö¸¦ À§ÇØ Á¤ÀÇµÈ ¿¡·¯»óȲÀÌ´Ù.
EBADF
filedes Àμö°¡ À¯¿ëÇÑ ÆÄÀÏ ±â¼úÀÚ°¡ ¾Æ´Ï´Ù.
EINVAL
pgid Àμö°¡ À¯¿ëÇÏÁö ¾Ê´Ù.
ENOSYS
½Ã½ºÅÛÀÌ ÀÛ¾÷Á¦¾î¸¦ Áö¿øÇÏÁö ¾Ê´Â´Ù.
ENOTTY
filedes´Â È£ÃâÇÑ ÇÁ·Î¼¼½º°¡ Á¦¾îÇϰí ÀÖ´Â Å͹̳¯ÀÌ ¾Æ´Ï´Ù.
EPERM
pgid ´Â È£ÃâÇÑ ÇÁ·Î¼¼½º¿Í °°Àº ¼¼¼Ç¿¡ ÀÖ´Â ÇÁ·Î¼¼½º ±×·ìÀÌ ¾Æ´Ï´Ù.