亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 19.htm

?? UNIX環境下C編程的詳細詳細介紹
?? HTM
?? 第 1 頁 / 共 4 頁
字號:
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
<title>C:\WINDOWS\Desktop\UnixProg\7.htm</title>
</head>

<body>
<font SIZE="2">

<h1 align="center">第十九章 偽終端 </h1>

<p>19.1 引言 </p>

<p>在第九章中我們介紹了進行終端登錄時,需要通過一個終端設備自動提供終端</p>

<p>的語 </p>

<p>義。在終端和運行程序之間有一個終端行規程(圖11.2),通過這個規程我</p>

<p>們能夠 </p>

<p>在終端上設置特殊字符(退格、行刪除、中斷等)。但是,當一個登錄請求到</p>

<p>達網 </p>

<p>絡連接時,終端行規程并不是自動被加載到網絡連接和登錄程序shell之間</p>

<p>的。圖 </p>

<p>9.5顯示了有一個偽終端設備驅動程序被用來提供終端語義。 </p>

<p>除了用于網絡登錄,偽終端還被用在其他方面,我們將在本章中進行介紹。我</p>

<p>們 </p>

<p>將首先提供在SVR4和4.3+BSD系統下用于創建偽終端的函數,然后使用這些</p>

<p>函數編 </p>

<p>寫一個程序用來調用pty。我們將看到這個程序的不同使用:在輸入字符和終</p>

<p>端顯 </p>

<p>示之間進行轉換(BSD的碼轉換程序)和運行協同進程來避免我們在程序</p>

<p>14.10中遇 </p>

<p>到的緩沖區問題。 </p>

<p>19.2 概述 </p>

<p>偽終端這個名詞暗示了與一個應用程序相比,它更加象一個終端。但事實上,</p>

<p>偽終 </p>

<p>端并不是一個真正的終端。圖19.1顯示了使用偽終端的進程的典型結構。其</p>

<p>中關鍵 </p>

<p>點如下: </p>

<p>圖19.1 使用偽終端的典型進程結構 </p>

<p>1 通常一個進程打開偽終端主設備然后調用fork。子進程建立了一個新的會</p>

<p>話,打 </p>

<p>開一個相應的偽終端從設備,將它復制成標準輸入、標準輸出和標準出錯,然</p>

<p>后調 </p>

<p>用exec。偽終端從設備成為子進程的控制終端。 </p>

<p>2 
對于偽終端從設備之上的用戶進程來說,其標準輸入、標準輸出和標準出</p>

<p>錯都能 </p>

<p>當作終端設備使用。用戶進程能夠調用11章中講到的所有輸入/輸出函數。但</p>

<p>是因 </p>

<p>為在偽終端從設備之下并沒有真正的設備,無意義的函數調用(改變波特率、</p>

<p>發送 </p>

<p>中斷符、設置奇偶校驗等)將被忽略。 </p>

<p>3 
任何寫到偽終端主設備的輸入都會作為在從設備端的輸入,反之亦然。事</p>

<p>實上所 </p>

<p>有從設備端的輸入都來自于主設備上的用戶進程。這看起來就象一個流管道</p>

<p>(圖1 </p>

<p>5.3),但從設備上的終端行規程使我們擁有普通管道之外的其他處理能力。</p>

<p>圖19.1顯示了BSD系統中的偽終端結構。在19.3.2中我們將看到如何打開這</p>

<p>些設備 </p>

<p>。 </p>

<p>在SVR4系統中偽終端是使用流系統來創建的(12.4節)。圖19.2詳細描述了</p>

<p>SVR4系 </p>

<p>統中各個偽終端模塊之間的關系。在虛線框中的兩個流模塊是可選的。請注意</p>

<p>在從 </p>

<p>設備上的三個流模塊同12.10網絡登錄程序的輸出是一樣的。在19.3.1小節</p>

<p>中將介 </p>

<p>紹如何組織這些流模塊。 </p>

<p>從現在開始將簡化以上圖示,首先我們不再畫出圖19.1的&quot;讀、寫功能&quot;或圖</p>

<p>19.2 </p>

<p>的流首。我們還使用縮寫&quot;pty&quot;表示偽終端,并將圖19.2中所有偽終端從設</p>

<p>備之上 </p>

<p>的流模塊集合表示為&quot;終端行規程&quot;模塊。 </p>

<p>圖19.2 在SVR4下的偽終端組織結構 </p>

<p>現在來看一下偽終端的幾種典型用法。 </p>

<p>網絡登錄服務器 </p>

<p>偽終端用于構造網絡登錄服務器。典型的例子是telnetd和rlogind服務器。</p>

<p>在St </p>

<p>evens[1990]的第15章中詳細討論了提供rlogin服務的步驟。一旦登錄</p>

<p>shell運行在 </p>

<p>遠端主機上,我們得到如圖19.3的結構。同樣的結構也用于telnetd服務</p>

<p>器。 </p>

<p>在rlogind服務器和登錄shell之間有兩個exec調用,這是因為login程序通</p>

<p>常是在 </p>

<p>兩個exec之間檢驗用戶是否合法的。 </p>

<p>圖19.3 rlogind服務器的進程組織結構 </p>

<p>本圖的一個關鍵點是驅動偽終端主設備的進程通常同時在讀寫另一個輸入/輸</p>

<p>出流 </p>

<p>。在本例中另一個輸入/輸出流是TCP/IP。這表示該進程必然使用了某種形式</p>

<p>的如 </p>

<p>select或poll那樣的輸入/輸出多路轉接(節12.5),或被分成兩個進程。</p>

<p>請回憶 </p>

<p>我們在18.7節討論過的一個進程和兩個進程的的比較。 </p>

<p>script程序 </p>

<p>script程序是隨SVR4和4.3+BSD提供的,該程序將終端會話期間所有的輸入</p>

<p>和輸出 </p>

<p>信息在一個文件中做一個拷貝。它通過將自己置于終端和登錄shell的一個新</p>

<p>的調 </p>

<p>用之間來完成這個工作。圖19.4詳細描述了script程序相關的交互。這里我</p>

<p>們特別 </p>

<p>指出script程序通常是從登錄shell啟動的,該shell然后等待程序的結束。</p>

<p>當script程序在運行的時候,在偽終端從設備之上終端行規程的所有輸出都</p>

<p>被復制 </p>

<p>到一個script文件中(通常叫做typescript)。因為我們的擊鍵通常被行規</p>

<p>程的模 </p>

<p>塊回顯,該script文件也包括了輸入的內容。但是,因為口令字不被回顯,</p>

<p>該scr </p>

<p>ipt文件不會包含口令字。 </p>

<p>圖19.4 script程序 </p>

<p>本書中所有運行程序并顯示其輸出的實例都是由script程序實現的,這樣避</p>

<p>免了手 </p>

<p>動拷貝程序輸出可能帶來的錯誤。 </p>

<p>在19.5節開發一個通用的pty程序后,我們將看到一個巧妙的shell程序能夠</p>

<p>將它轉 </p>

<p>化成一個script程序。 </p>

<p>expect程序 </p>

<p>偽終端可以用來使交互式的程序運行在非交互的狀態中。許多程序需要一個終</p>

<p>端 </p>

<p>來運行,18.7節中的call進程就是一個例子。它假定標準輸入是一個終端并</p>

<p>在啟動 </p>

<p>時將其設置為初始模式(18.20程序)。該程序不能從一個shell程序中被運</p>

<p>行來自 </p>

<p>動撥號到遠程系統,登錄,取出信息和登出。 </p>

<p>同修改所有交互式程序來支持批處理模式的操作比較,一個更好的解決方法是</p>

<p>提 </p>

<p>供一種手段來通過一個script來驅動交互式程序。expect程序[Libes</p>

<p>1990;1991] </p>

<p>提供了這樣的方法。類似于19.5節的pty程序,它使用偽終端來運行其他程</p>

<p>序。但 </p>

<p>是,expect還提供了一種編程語言用于檢查程序的輸出來確定以什么作為輸</p>

<p>入發送 </p>

<p>給該程序。當一個交互式的程序開始從一個script運行時,我們不能僅僅是</p>

<p>將scr </p>

<p>ipt中的所有內容輸入到程序中去。相應的,我們要通過檢查程序的輸出來決</p>

<p>定下 </p>

<p>一步輸入的內容。 </p>

<p>運行協同進程 </p>

<p>在14.10的程序例子中,我們不能調用使用標準輸入/輸出庫進行輸入、輸出</p>

<p>的協 </p>

<p>同進程,這是因為當我們通過管道與協同進程進行通訊時,標準輸入/輸出庫</p>

<p>會將 </p>

<p>標準輸入、輸出的內容放到緩沖區中,從而引起死鎖。如果協同進程是一個已</p>

<p>經編 </p>

<p>譯的程序而我們又沒有源程序,我們就無法在源程序中加入fflush語句來解</p>

<p>決這個 </p>

<p>問題。圖14.9顯示了一個進程驅動協同進程的情況。我們需要做的是將一個</p>

<p>偽終端 </p>

<p>放到兩個進程之間,如圖19.5所示。 </p>

<p>圖19.5 用偽終端驅動一個協同進程 </p>

<p>現在協同進程的標準輸入和標準輸出就象一個終端設備一樣,所以標準輸入/</p>

<p>輸出 </p>

<p>庫會將這兩個流設置為行緩沖的。 </p>

<p>父進程有兩種不同的方法在自身和協同進程之間獲得偽終端(這種情況下的父</p>

<p>進程 </p>

<p>可以象程序14.9,使用兩個管道和協同進程進行通訊;或者象程序15.1那</p>

<p>樣,使用 </p>

<p>一個流管道)。一個方法是父進程直接調用pty_fork函數(19.4節)而不是</p>

<p>fork。 </p>

<p>另一種方法是exec該pty程序,將協同進程作為參數(19.5節)。我們將在</p>

<p>說明pt </p>

<p>y程序后介紹這兩種方法。 </p>

<p>觀看長時間運行程序的輸出 </p>

<p>使用任一個標準shell,我們都可以將一個需要長時間運行的程序放到后臺運</p>

<p>行。 </p>

<p>但是如果我們將該程序的標準輸出重定向到一個文件,并且如果它產生的輸出</p>

<p>不多 </p>

<p>,我們就不能方便地監控程序的進展,這是因為標準的輸入/輸出庫會將標準</p>

<p>輸出 </p>

<p>放在緩沖區中保存。我們看到的將只是成塊的輸出結果,有時甚至可能是</p>

<p>8192字節 </p>

<p>一塊。 </p>

<p>如果我們有源程序,我們可以加入fflush調用。另一種方法是,我們可以在</p>

<p>pty程 </p>

<p>序下運行該程序,讓標準輸入/輸出庫認為輸出是終端。圖19.6說明了這個結</p>

<p>構, </p>

<p>我們將這個緩慢輸出的程序稱為slowout。從登錄shell到pty進程的</p>

<p>fort/exec箭頭 </p>

<p>用虛線表示,以強調pty進程是作為后臺任務運行的。 </p>

<p>19.3 打開偽終端設備 </p>

<p>在SVR4和4.3+BSD系統中打開偽終端設備的方法有所不同。我們提供兩個函</p>

<p>數來處 </p>

<p>理所有細節:ptym_open用來打開下一個有效的偽終端主設備,ptys_open</p>

<p>用來打開 </p>

<p>相應的從設備。 </p>

<p>圖19.6 使用偽終端運行一個緩慢輸出的程序 </p>

<p>#include &quot;ourhdr.h&quot; </p>

<p>int ptym_open(char *pts_name); </p>

<p>返回:如果操作成功,返回偽終端主設備文件 </p>

<p>述符;否則返回-1 </p>

<p>int ptys_open(int fdm, char *pts_name); </p>

<p>返回:如果操作成功,返回偽終端從設備文件 </p>

<p>述符;否則返回-1 </p>

<p>通常我們不直接調用這兩個函數--函數pty_fork(19.4節)調用它們并</p>

<p>fork出一個 </p>

<p>子進程。 </p>

<p>ptym_open決定下一個有效的偽終端主設備并打開該設備。這個調用必須分</p>

<p>配一個 </p>

<p>數組來存放主設備或從設備的名稱,并且如果調用成功,相應的主設備或從設</p>

<p>備的 </p>

<p>名稱會通過pts_name返回。這個名稱和ptym_open返回的文件描述符將傳給</p>

<p>ptys_o </p>

<p>pen,該函數用來打開一個從設備。 </p>

<p>在我們講解pty_fork函數之后,使用兩個函數來打開這兩個設備的原因將會</p>

<p>很明顯 </p>

<p>。通常,一個進程調用ptym_open來打開一個主設備并且得到從設備的名</p>

<p>稱。該進 </p>

<p>程然后fork子進程,子進程在調用setid建立新的會話后調用ptys_open來</p>

<p>打開從設 </p>

<p>備。這就是從設備如何成為子進程的控制終端的過程。 </p>

<p>19.1.1 系統V的版本4 </p>

<p>所有在SVR4系統下的偽終端的流實現細節在AT&amp;T[1990d]的第十二章中有所</p>

<p>說明。 </p>

<p>三個函數在下列手冊頁中描述:grantpt(3),unlockpt(3),和</p>

<p>ptsname(3)。 </p>

<p>偽終端主設備是/dev/ptmx。這是一個流的增殖設備。這意味著當我們打開</p>

<p>該增殖 </p>

<p>設備,其open例程自動決定第一個未被使用的偽終端主設備并打開這個設</p>

<p>備。(在 </p>

<p>下一節我們將看到在Berkeley系統中,我們必須自己找到第一個未被使用的</p>

<p>偽終端 </p>

<p>主設備。) </p>

<p>_______________________________________________________________________</p>

<p>________ </p>

<p>#include &lt;sys/types.h&gt; </p>

<p>#include &lt;sys/stat.h&gt; </p>

<p>#include &lt;errno.h&gt; </p>

<p>#include &lt;fcntl.h&gt; </p>

<p>#include &lt;stropts.h&gt; </p>

<p>#include &quot;ourhdr.h&quot; </p>

<p>extern char *ptsname(int); /* prototype not in any system</p>

<p>header */ </p>

<p>int </p>

<p>ptym_open(char *pts_name) </p>

<p>{ </p>

<p>char *ptr; </p>

<p>int fdm; </p>

<p>strcpy(pts_name, &quot;/dev/ptmx&quot;); /* in case open fails */ </p>

<p>if ( (fdm = open(pts_name, O_RDWR)) &lt; 0) </p>

<p>return(-1); </p>

<p>if (grantpt(fdm) &lt; 0) { /* grant access to slave */ </p>

<p>close(fdm); </p>

<p>return(-2); </p>

<p>} </p>

<p>if (unlockpt(fdm) &lt; 0) { /* clear slave's lock flag */ </p>

<p>close(fdm); </p>

<p>return(-3); </p>

<p>} </p>

<p>if ( (ptr = ptsname(fdm)) == NULL) { /* get slave's name */ </p>

<p>close(fdm); </p>

<p>return(-4); </p>

<p>} </p>

<p>strcpy(pts_name, ptr); /* return name of slave */ </p>

<p>return(fdm); /* return fd of master */ </p>

<p>} </p>

<p>int </p>

<p>ptys_open(int fdm, char *pts_name) </p>

<p>{ </p>

<p>int fds; </p>

<p>/* following should allocate controlling terminal */ </p>

<p>if ( (fds = open(pts_name, O_RDWR)) &lt; 0) { </p>

<p>close(fdm); </p>

<p>return(-5); </p>

<p>} </p>

<p>if (ioctl(fds, I_PUSH, &quot;ptem&quot;) &lt; 0) { </p>

<p>close(fdm); </p>

<p>close(fds); </p>

<p>return(-6); </p>

<p>} </p>

<p>if (ioctl(fds, I_PUSH, &quot;ldterm&quot;) &lt; 0) { </p>

<p>close(fdm); </p>

<p>close(fds); </p>

<p>return(-7); </p>

<p>} </p>

<p>if (ioctl(fds, I_PUSH, &quot;ttcompat&quot;) &lt; 0) { </p>

<p>close(fdm); </p>

<p>close(fds); </p>

<p>return(-8); </p>

<p>} </p>

<p>return(fds); </p>

<p>} </p>

<p>_______________________________________________________________________</p>

<p>________ </p>

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
麻豆成人免费电影| 久久精品久久综合| 中文字幕第一页久久| 精品日韩成人av| 日韩三级伦理片妻子的秘密按摩| 在线亚洲一区观看| 欧美少妇xxx| 欧美男女性生活在线直播观看| 欧美三级午夜理伦三级中视频| 色婷婷av一区二区三区gif| 色综合色综合色综合色综合色综合| proumb性欧美在线观看| 色综合久久综合网97色综合| 色婷婷激情一区二区三区| 欧美日韩亚洲国产综合| 欧美人妖巨大在线| 精品国产123| 国产精品视频免费看| 中文字幕佐山爱一区二区免费| 亚洲欧洲综合另类| 日精品一区二区| 国产综合色产在线精品| 成人app网站| 欧美日韩你懂得| 精品sm在线观看| 亚洲色图制服诱惑| 视频一区中文字幕国产| 精品一区二区免费在线观看| 成人ar影院免费观看视频| 欧美日韩一区二区三区在线看| 日韩精品一区二区在线观看| 日本一区二区三区国色天香| 一区二区三区精品视频在线| 经典一区二区三区| 色综合久久久久综合| 337p粉嫩大胆噜噜噜噜噜91av| 日韩一区欧美一区| 久久精品国产99| 99v久久综合狠狠综合久久| 欧美片网站yy| 亚洲色图欧美偷拍| 国产一区视频在线看| 色综合久久中文字幕| 久久久精品人体av艺术| 丝袜a∨在线一区二区三区不卡| 国产黑丝在线一区二区三区| 欧美色男人天堂| 亚洲天堂成人在线观看| 国产综合久久久久久鬼色| 欧美日韩高清一区| 亚洲欧美日韩国产综合| 韩国在线一区二区| 91精品国产麻豆| 午夜欧美视频在线观看| eeuss鲁片一区二区三区在线看| 26uuu亚洲婷婷狠狠天堂| 性做久久久久久免费观看欧美| 成人avav影音| 亚洲国产精品激情在线观看| 狠狠色综合日日| 日韩精品专区在线影院观看| 日韩精品免费视频人成| 91成人网在线| 亚洲欧美偷拍另类a∨色屁股| 高清beeg欧美| 国产精品久线观看视频| 国产盗摄女厕一区二区三区| 久久嫩草精品久久久久| 国产一区久久久| 日韩精品中午字幕| 捆绑调教一区二区三区| 日韩精品一区二区三区四区视频| 午夜精品久久久久久久久久久| 在线观看视频一区| 亚洲欧美电影院| 91麻豆成人久久精品二区三区| 中文字幕一区二区三区乱码在线| 成人午夜私人影院| 国产精品乱人伦| 成人av第一页| 亚洲男人电影天堂| 欧美色中文字幕| 日本aⅴ精品一区二区三区| 欧美一级黄色片| 久久av老司机精品网站导航| 欧美成va人片在线观看| 九九国产精品视频| 国产欧美一区二区三区沐欲| 成人网页在线观看| 亚洲精品老司机| 欧美精品一卡二卡| 精品一区二区av| 中文一区二区在线观看| 色噜噜久久综合| 日韩不卡一二三区| 国产亚洲污的网站| 成人18精品视频| 亚洲国产成人av网| 精品福利一区二区三区| 国产91精品一区二区麻豆网站| 亚洲另类春色校园小说| 欧美日韩午夜在线视频| 久99久精品视频免费观看| 欧美韩国日本一区| 欧美色图一区二区三区| 久久97超碰色| 亚洲精品中文字幕乱码三区| 日韩一区二区在线观看视频播放| 国产精品一卡二| 亚洲综合一区二区精品导航| 欧美成人福利视频| 91成人在线观看喷潮| 国产伦精品一区二区三区视频青涩 | 91蜜桃在线观看| 午夜精品一区二区三区电影天堂 | 亚洲在线成人精品| 欧美大片一区二区三区| 91麻豆免费看| 国产精品91xxx| 日韩综合在线视频| 亚洲乱码精品一二三四区日韩在线| 日韩三级视频中文字幕| 色综合色综合色综合色综合色综合 | 欧美精品v国产精品v日韩精品| 国产丶欧美丶日本不卡视频| 免费在线看成人av| 亚洲品质自拍视频网站| 国产亚洲精品bt天堂精选| 91精品婷婷国产综合久久竹菊| av在线免费不卡| 国产毛片精品一区| 免费观看日韩电影| 三级影片在线观看欧美日韩一区二区| 中文字幕欧美日韩一区| 久久综合国产精品| 欧美一区午夜视频在线观看| 在线视频一区二区三| 一本色道久久综合狠狠躁的推荐| 国产高清不卡二三区| 国精产品一区一区三区mba视频| 日本视频一区二区| 日韩一区欧美二区| 午夜激情久久久| 日韩在线观看一区二区| 亚洲18影院在线观看| 亚洲成人tv网| 视频一区二区三区中文字幕| 五月天亚洲精品| 肉肉av福利一精品导航| 偷偷要91色婷婷| 青青草国产精品97视觉盛宴| 视频一区二区国产| 美国十次了思思久久精品导航| 免费日韩伦理电影| 欧美aa在线视频| 精品一区二区三区的国产在线播放| 欧美aaa在线| 国产精品一区二区三区四区 | 亚洲欧美乱综合| 一区二区三区久久久| 亚洲一区精品在线| 亚洲成人精品影院| 免费观看久久久4p| 国产美女一区二区| 99国产欧美久久久精品| 欧美亚洲自拍偷拍| 日韩欧美精品在线| 久久久久久99久久久精品网站| 国产欧美一区二区三区在线老狼| 中日韩av电影| 亚洲午夜一区二区| 美女视频黄久久| 丁香啪啪综合成人亚洲小说| 91蜜桃视频在线| 欧美一区二区在线视频| 久久免费午夜影院| 一区二区三区小说| 久久精品久久99精品久久| 国产老妇另类xxxxx| 99精品国产91久久久久久| 欧美顶级少妇做爰| 国产精品免费丝袜| 亚洲成av人影院| 国产福利电影一区二区三区| 91精品1区2区| 欧美喷水一区二区| 亚洲欧洲99久久| 精品一区二区三区在线播放 | 一区二区在线观看免费| 免费观看久久久4p| 99re热这里只有精品免费视频| 在线播放欧美女士性生活| 亚洲精品一区二区三区蜜桃下载| 国产午夜久久久久| 日韩黄色一级片| 91麻豆免费看| 国产精品美女久久久久久| 日韩不卡一二三区| 在线观看日韩一区| 国产精品卡一卡二|