[{"data":1,"prerenderedAt":233},["ShallowReactive",2],{"blog:\u002Fblog\u002F2020\u002F08\u002F31\u002Fapue-exercise-9_2\u002F":3},{"id":4,"title":5,"body":6,"categories":217,"comments":57,"date":219,"description":220,"draft":221,"extension":222,"legacySlug":223,"meta":224,"navigation":57,"path":225,"seo":226,"stem":227,"tags":228,"updated":231,"__hash__":232},"blog\u002Fblog\u002F2020\u002F08\u002F31\u002Fapue-exercise-9_2.md","apue习题9.2",{"type":7,"value":8,"toc":215},"minimark",[9,13,19,22,211],[10,11,12],"p",{},"UNIX环境高级编程第九章有如下一道习题",[14,15,16],"blockquote",{},[10,17,18],{},"9.2 编写一段程序调用fork并使子进程建立一个新的会话。验证子进程变成了进程组组长且不再有控制终端。",[10,20,21],{},"下边给出博主的解答，仅供参考。",[23,24,29],"pre",{"className":25,"code":26,"language":27,"meta":28,"style":28},"language-c shiki shiki-themes github-light github-dark","#include \u003Cstdio.h>\n#include \u003Cunistd.h>\n#include \u003Cstdlib.h>\n\nvoid\nmain()\n{\n    pid_t   pid, sid, gid;\n    if((pid = fork()) \u003C 0) {\n        perror(\"fork error\");\n    } else if (pid > 0) { \u002F*parent*\u002F\n        if((open(\"\u002Fdev\u002Ftty\", 0)) == -1) {\n            perror(\"没有控制终端，open \u002Fdev\u002Ftty 失败\");\n        } else {\n            printf(\"父进程有控制终端，open \u002Fdev\u002Ftty 成功\\n\");\n        }\n        exit(0);\n    } else { \u002F*child*\u002F\n        if((sid = setsid()) == (pid_t) -1) {\n            perror(\"setsid error\");\n        }\n        if((gid = getpgrp()) == getpid()) {\n            printf(\"子进程成为进程组组长\\n\");\n        }\n        \u002F\u002F如果当前进程有控制终端(Controlling Terminal)的话，那么\u002Fdev\u002Ftty就是当前进程的控制终端的设备特殊文件\n        if((open(\"\u002Fdev\u002Ftty\", 0)) == -1) {\n            perror(\"子进程没有控制终端，open \u002Fdev\u002Ftty 失败\");\n        }\n    }\n}\n","c","",[30,31,32,40,46,52,59,65,71,77,83,89,95,101,107,113,119,125,131,137,143,149,155,160,166,172,177,183,188,194,199,205],"code",{"__ignoreMap":28},[33,34,37],"span",{"class":35,"line":36},"line",1,[33,38,39],{},"#include \u003Cstdio.h>\n",[33,41,43],{"class":35,"line":42},2,[33,44,45],{},"#include \u003Cunistd.h>\n",[33,47,49],{"class":35,"line":48},3,[33,50,51],{},"#include \u003Cstdlib.h>\n",[33,53,55],{"class":35,"line":54},4,[33,56,58],{"emptyLinePlaceholder":57},true,"\n",[33,60,62],{"class":35,"line":61},5,[33,63,64],{},"void\n",[33,66,68],{"class":35,"line":67},6,[33,69,70],{},"main()\n",[33,72,74],{"class":35,"line":73},7,[33,75,76],{},"{\n",[33,78,80],{"class":35,"line":79},8,[33,81,82],{},"    pid_t   pid, sid, gid;\n",[33,84,86],{"class":35,"line":85},9,[33,87,88],{},"    if((pid = fork()) \u003C 0) {\n",[33,90,92],{"class":35,"line":91},10,[33,93,94],{},"        perror(\"fork error\");\n",[33,96,98],{"class":35,"line":97},11,[33,99,100],{},"    } else if (pid > 0) { \u002F*parent*\u002F\n",[33,102,104],{"class":35,"line":103},12,[33,105,106],{},"        if((open(\"\u002Fdev\u002Ftty\", 0)) == -1) {\n",[33,108,110],{"class":35,"line":109},13,[33,111,112],{},"            perror(\"没有控制终端，open \u002Fdev\u002Ftty 失败\");\n",[33,114,116],{"class":35,"line":115},14,[33,117,118],{},"        } else {\n",[33,120,122],{"class":35,"line":121},15,[33,123,124],{},"            printf(\"父进程有控制终端，open \u002Fdev\u002Ftty 成功\\n\");\n",[33,126,128],{"class":35,"line":127},16,[33,129,130],{},"        }\n",[33,132,134],{"class":35,"line":133},17,[33,135,136],{},"        exit(0);\n",[33,138,140],{"class":35,"line":139},18,[33,141,142],{},"    } else { \u002F*child*\u002F\n",[33,144,146],{"class":35,"line":145},19,[33,147,148],{},"        if((sid = setsid()) == (pid_t) -1) {\n",[33,150,152],{"class":35,"line":151},20,[33,153,154],{},"            perror(\"setsid error\");\n",[33,156,158],{"class":35,"line":157},21,[33,159,130],{},[33,161,163],{"class":35,"line":162},22,[33,164,165],{},"        if((gid = getpgrp()) == getpid()) {\n",[33,167,169],{"class":35,"line":168},23,[33,170,171],{},"            printf(\"子进程成为进程组组长\\n\");\n",[33,173,175],{"class":35,"line":174},24,[33,176,130],{},[33,178,180],{"class":35,"line":179},25,[33,181,182],{},"        \u002F\u002F如果当前进程有控制终端(Controlling Terminal)的话，那么\u002Fdev\u002Ftty就是当前进程的控制终端的设备特殊文件\n",[33,184,186],{"class":35,"line":185},26,[33,187,106],{},[33,189,191],{"class":35,"line":190},27,[33,192,193],{},"            perror(\"子进程没有控制终端，open \u002Fdev\u002Ftty 失败\");\n",[33,195,197],{"class":35,"line":196},28,[33,198,130],{},[33,200,202],{"class":35,"line":201},29,[33,203,204],{},"    }\n",[33,206,208],{"class":35,"line":207},30,[33,209,210],{},"}\n",[212,213,214],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":28,"searchDepth":42,"depth":42,"links":216},[],[218],"unix","2020-08-31","UNIX环境高级编程第九章有如下一道习题 9.2 编写一段程序调用fork并使子进程建立一个新的会话。验证子进程变成了进程组组长且不再有控制终端。 下边给出博主的解答，仅供参考。",false,"md","apue-exercise-9_2",{},"\u002Fblog\u002F2020\u002F08\u002F31\u002Fapue-exercise-9_2",{"title":5,"description":220},"blog\u002F2020\u002F08\u002F31\u002Fapue-exercise-9_2",[229,230],"apue","unix编程",null,"NNYcE659opxNQqviJV7yJoBoP-7iYS-w2nK6vMncwew",1783807996125]