freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內容

[計算機軟件及應用]第10章系統(tǒng)調用-全文預覽

2024-11-06 23:18 上一頁面

下一頁面
  

【正文】 by execl, NULL)0) perror(Err on execl)。 ? 下面來看看實際的應用: // include main() { char *envp[]={PATH=/tmp, USER=lei, STATUS=testing, NULL}。這里的 NULL的作用和 argv數(shù)組里的 NULL作用是一樣的。 ? 回過頭來看一下 exec函數(shù)族,先看看 execve: int execve(const char *path, char *const argv[], char *const envp[])。 while(*envp) printf(%s\n, *(envp++))。 ? 可以通過以下這個程序來觀看傳到 argc、 argv和 envp里的都是什么東西: // int main(int argc, char *argv[], char *envp[]) { printf(\n ARGC \n%d\n, argc)。環(huán)境變量指的是一組值,從用戶登錄后就一直存在,很多應用程序需要依靠它來確定系統(tǒng)的一些細節(jié)。 稍稍深入 ? 上面 6個函數(shù)看起來似乎很復雜,但實際上,它們無論是作用還是用法上都非常相似,只有很微小的差別。只有調用失敗了,它們才會返回一個 1,從原程序的調用點接著往下執(zhí)行。 ? 其中只有 execve是真正意義上的系統(tǒng)調用,其它都是在此基礎上經(jīng)過包裝的庫函數(shù)。 int execle(const char *path, const char *arg, ..., char *const envp[])。父子進程都有工作要做,父進程利用工作的簡短間隙察看子進程是否已退出,如退出就收集它。 } }while(pr==0)。 } printf(some error occured\n)。 pc=fork()。而 WUNTRACED參數(shù)涉及到一些跟蹤調試方面的知識,有興趣的讀者可以自行查閱相關材料。 pid1時,等待一個指定進程組中的任何子進程,這個進程組的 ID等于 pid的絕對值。由于這些信息被存放在一個整數(shù)的不同二進制位中,所以用常規(guī)的方法讀取會非常麻煩,人們設計了一套專門的宏( macro)來完成這項工作。 } exit(0)。 else if(pc==0){ // 如果是子進程 printf(This is child process with pid of %d\n,getpid())。 ? 下面用一個例子來實戰(zhàn)應用 wait調用,程序中用到了系統(tǒng)調用 fork。 Wait ? wait的函數(shù)原型是: include sys/ // 提供類型 pid_t的定義 include sys/ pid_t wait(int *status) ? 進程一旦調用了 wait,就立即阻塞自己,由 wait自動分析是否當前進程的某個子進程已經(jīng)退出,如果讓它找到了這樣一個已經(jīng)變成僵尸的子進程, wait就會收集這個子進程的信息,并把它徹底銷毀后返回;如果沒有找到這樣一個子進程, wait就會一直阻塞在這里,直到有一個出現(xiàn)為止。在僵尸進程中保存著很多對程序員和系統(tǒng)管理員非常重要的信息。 ? 編譯這個程序: $ cc o zombi 后臺運行程序,以使能夠執(zhí)行下一條命令: $ ./zombie amp。 else if(pid==0) // 如果是子進程 exit(0)。在 Linux進程的5種狀態(tài)中,僵尸進程是非常特殊的一種,它已經(jīng)放棄了幾乎所有內存空間,沒有任何可執(zhí)行代碼,也不能被調度,僅僅在進程列表中保留一個位置,記載該進程的退出狀態(tài)等信息供其他進程收集,除此之外,僵尸進程不再占有任何內存空間。 ? 系統(tǒng)調用 setsid不帶任何參數(shù),調用之后,調用進程就會成立一個新的會話,并自任該會話的組長。例如: chdir(/)。 其他一些常見的系統(tǒng)調用 1. 系統(tǒng)調用 chdir include int chdir(const char *path)。 _exit(0)。 printf(content in buffer)。 ? exit()函數(shù)與 _exit()函數(shù)最大的區(qū)別就在于 exit()函數(shù)在調用 exit系統(tǒng)調用之前要檢查文件的打開情況,把文件緩沖區(qū)中的內容寫回文件,就是圖中的 “ 清理 I/O緩沖 ” 一項。 _exit在 Linux函數(shù)庫中的原型是: include void _exit(int status)。關于 wait的詳細情況,將在以后的篇幅中進行介紹。 printf(never be displayed!\n)。 ? 從 exit的名字就能看出,這個系統(tǒng)調用是用來終止一個進程的。如果出現(xiàn)第二種錯誤,說明系統(tǒng)已經(jīng)沒有可分配的內存,正處于崩潰的邊緣,這種情況對 Linux來說是很罕見的。父子進程的區(qū)別除了進程標志符( process ID)不同外,變量 pid的值也不相同, pid存放的是 fork的返回值。 else if(pid==0) printf(I am the child process, my process ID is %d\n,getpid())。 fork有一些很有意思的特征,下面通過一個小程序來對它有更多的了解。據(jù)說 fork的名字就是來源于這個與叉子的形狀頗有幾分相似的工作流程。) ? 再運行一遍: $./getpid_test The current process ID is 1981 ? 可以看到,盡管是同一個應用程序,每一次運行的時候,所分配的進程標識符都不相同。 getpid的作用很簡單,就是返回當前進程的進程 ID,請看以下的例子: // include main() printf(The current process ID is %d\n,getpid())。隨著Linux商業(yè)公司和以 Linux為生的人的增長,不兼容的情況也越來越罕見。 ? 需要注意的是, errno的值只在函數(shù)發(fā)生錯誤時設置,如果函數(shù)不發(fā)生錯誤, errno的值就無定義,并不會被置為 0。事實上,程序中用到的 time函數(shù)的原型就是它。 __res = 1。很容易就能發(fā)現(xiàn)規(guī)律, _syscall后面的數(shù)字和 typeN,argN的數(shù)目一樣多。 } ? 這是因為在 的形式實現(xiàn)了 time這個系統(tǒng)調用,省掉了調用 _syscall1宏展開得到函數(shù)原型這一步。這是最標準的系統(tǒng)調用的形式,宏_syscall1()展開來得到一個函數(shù)原型。 這樣,通過寄存器 %ecx返回到用戶空間的數(shù)值就是 1,而 errno則含有具體的出錯代碼。若 %eax的內容在 0xfffff001和 0xffffffff之間,即 1到 4095之間,表示出錯了,要轉向_syscall_error()并從那里返回。第二條指令是將相對于寄存器 %esp位移為8的內容存入寄存器 %ecx,即將參數(shù) len存入寄存器 %ecx,第三條指令就是把參數(shù) name存入寄存器 %ebx,第四條指令把代表 sethostname()的系統(tǒng)調用號 0x4a存入寄存器 %eax,接著就是中斷指令 int 0x80。 ? 參數(shù) name是要設置的主機名,而 len是該字符串的長度。系統(tǒng)調用只能發(fā)生在用戶空間。而對于系統(tǒng)調用服務程序而言,參數(shù)就可以直接從總控程序壓入的堆棧中復得;對參數(shù)的修改一可以直接在堆棧中進行;其實,這就是asmlinkage標志的作用。 ? 在 Linux中所有系統(tǒng)調用服務例程都使用了 asmlinkage標志。 ? ( 2在系統(tǒng)調用總控程序中,通過語句 “ call * SYMBOL_NAME(sys_call_table)(,%eax,4)”來調用各個服務程序( SYMBOL_NAME是定義在/include/linux/: define SYMBOL_NAME_LABEL(X) X),可以忽略)。 系統(tǒng)調用的進入 ? 系統(tǒng)調用的進入可分為 “ 用戶程序調用系統(tǒng)調用總控程序 (system_call)”和 “ 系統(tǒng)調用總控程序調用各個服務程序 ” 兩部分;下面將分別對這兩個部分進行詳細說明: ? ( 1) “ 用戶程序調用系統(tǒng)調用總控程序 ” 的實現(xiàn):Linux的系統(tǒng)調用使用第 0x80號中斷向量項作為總的入口,即系統(tǒng)調用總控程序的入口地址system_call就掛在中斷 0x80上。 sysem_call的代碼在源碼 /kernel/Entry(system_call)的下一行。 ? 進程可以跳轉到的內核位置叫做sysem_call。系統(tǒng)調用是這些規(guī)則的一個例外。區(qū)別僅僅在于,系統(tǒng)調用由操作系統(tǒng)核心提供,運行于核心態(tài);而普通的函數(shù)調用由函數(shù)庫或用戶自己提供,運行于用戶態(tài)。系統(tǒng)調用是不能更改的一種 Unix特征。第 10章系統(tǒng)調用 本章對 Linux系統(tǒng)調用的定義、基本原理、使用方法和注意事項作了概括的介紹,以便讀者對 Linux系統(tǒng)調用建立一個大致的印象。各種版本的Unix都提供經(jīng)良好定義的有限數(shù)目的入口點,經(jīng)過這些入口點進入內核,這些入口點被稱為系統(tǒng)調用 (system call)。從某種角度來看,系統(tǒng)調用和普通的函數(shù)調用非常相似。 ? 在 Linux中,系統(tǒng)調用的過程大體如圖 : ? 一般來說, CPU硬件決定了進程不能訪問內核所占內存空間也不能調用內核函數(shù),這被稱作 保護模式 。在 Intel CPU中,這個指令由中斷0x80實現(xiàn)。接著調用相應的函數(shù),在返回后做一些系統(tǒng)檢查,最后返回到進程(如果這個進程時間用盡,則返回到其他進程)。 ? 在很多情況下,系統(tǒng)調用是實現(xiàn)編程想法的簡潔有效的途徑,所以應該盡量多掌握一些系統(tǒng)調用,這會對程序設計過程帶來意想不到的幫助。中斷的進入的詳細過程可參見第 3章 “ 中斷和中斷處理 ” 。所以此 call語句就相當于直接調用對應的系統(tǒng)調用服務程序。 (__GNUC__ 2 || __GNUC_MINOR__ 7) define asmlinkage CPP_ASMLINKAGE__attribute__((regparm(0))) else define asmlinkage CPP_ASMLINKAGE endif ? 其中涉及到了 gcc的一些約定,總之,這個標志它可以告訴編譯器該函數(shù)不需要從寄存器中獲得任何參數(shù),而是從堆棧中取得參數(shù);即參數(shù)在堆棧中傳遞,而不是直接通過寄存器; ? 堆棧參數(shù)如下: EBX = 0x00 ECX = 0x04 EDX = 0x08 ESI = 0x0C EDI = 0x10 EBP = 0x14 EAX = 0x18 DS = 0x1C ES = 0x20 ORIG_EAX = 0x24 EIP = 0x28 CS = 0x2C EFLAGS = 0x30 ? 在進入系統(tǒng)調用總控程序前,用戶按照以上的對應順序將參數(shù)放到對應寄存器中,在系統(tǒng)調用總控程序一開始就將這些寄存器壓入堆棧;在退出總控程序前又按如上順序堆棧;用戶程序則可以直接從寄存器中復得被服務程序加工過了的參數(shù)。其作用歸結起來有如下三種可能: ( 1) 處理邊界錯誤, 0號系統(tǒng)調用就是用的此特殊的服務程序; ( 2) 用來替換舊的已淘汰了的系統(tǒng)調用,如: Nr 17, Nr 31, Nr 32, Nr 35, Nr 44, Nr 53, Nr 56, Nr58, Nr 98; ( 3) 用于將要擴展的系統(tǒng)調用,如: Nr 137, Nr 188, Nr 189; 系統(tǒng)調用總控程序 ? 系統(tǒng)調用總控程序 (system_call)可參見arch/i386/kernel/,其執(zhí)行流程如圖 : 圖 調用總控程序 (system_call)執(zhí)行流程圖 一個簡單的系統(tǒng)調用例子 ? 系統(tǒng)調用是 CPU主動地、同步地進入系統(tǒng)空間的手段。 ? int sethostname(const char *name,size_t len)。通過反匯編 :
點擊復制文檔內容
教學課件相關推薦
文庫吧 www.dybbs8.com
備案圖鄂ICP備17016276號-1