Date:2009.5.7
Content:UNIX環境下進階編程 Chapter1:UNIX System Overview
1、所用書籍:《UNIX環境下進階編程》
(Advanced Programming in the UNIX Environment: Second Edition)
2、執行個體代碼:http://www.apuebook.com/src.tar.gz
雖然提供了代碼,但是強力推薦自己在vim或者vi中敲入代碼。
3、預備知識
(1) C/C++語言知識:在編程之前,你至少知道什麼是函數、變數、結構體、指標、for/while/do..while等等。
(2) Linux知識:你至少會如何在vim/vi下編輯C/C++代碼,然後知道用cc命令來編譯你的C/C++代碼。
(3) 確定你的UNIX版本:我選擇的是Fedora Core10,核心版本為2.6,書中提供的代碼是在2.4環境下啟動並執行。所以Linux基礎差的人,可以直接裝RH9.0版本。
4、學習筆記
一、UNIX體系
1、系統調用System calls是核心的介面
2、shell是一種為其他應用程式提供介面的特殊的應用程式
3、Linux是GNU作業系統的核心,所以有人稱之為GUN/Linux,更簡便的稱謂是Linux(這就是為什麼GUN/Linux又叫Linux的原因)
二、登入
1、每當你登陸系統後,系統會找到口令檔案,一般在/etc/passwd中,口令檔案由下面七個部分組成:
sar:x:205:105:Stephen Rago:/home/sar:/bin/ksh
登入名稱:sar
密鑰:x
使用者id:205
使用者組id:105
注釋:Stephen Rago
父目錄:/home/sar
shell 程式:/bin/ksh
三、檔案和目錄
1、檔案名稱不能出現的兩個字元:斜杠'/'和Null 字元:null
2、執行個體1.3. List all the files in a directory
************************************************************
利用函數opendir, readdir, 以及 closedir操作目錄
opendir返回DIR結構體,然後將傳回值傳遞給readdir
readdir讀取每個DIR的執行個體,一般用迴圈操作
closedir使用者關閉
************************************************************
#include "apue.h"//自訂的標頭檔,包括很多通用的系統標頭檔<br />#include <dirent.h></p><p>int<br />main(int argc, char *argv[])<br />{<br /> DIR *dp;<br /> struct dirent *dirp;</p><p> if (argc != 2)<br /> err_quit("usage: ls directory_name");</p><p> if ((dp = opendir(argv[1])) == NULL)<br /> err_sys("can't open %s", argv[1]);<br /> while ((dirp = readdir(dp)) != NULL)<br /> printf("%s/n", dirp->d_name);</p><p> closedir(dp);<br /> exit(0);<br />}<br />
四、輸入輸出
1、檔案描述符:一般是一個小的非負整型數字
2、標準輸入、輸出、錯誤
3、執行個體1.4:非緩衝輸入輸出
************************************************************
常量:STDIN_FILENO、 STDOUT_FILENO 在標頭檔<unistd.h>定義
如果執行./a.out <file1>file2將會把file1的內容輸入到file2中
************************************************************
#include "apue.h"</p><p>#define BUFFSIZE 4096</p><p>int<br />main(void)<br />{<br /> int n;<br /> char buf[BUFFSIZE];</p><p> while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)<br /> if (write(STDOUT_FILENO, buf, n) != n)<br /> err_sys("write error");<br /> if (n < 0)<br /> err_sys("read error");</p><p> exit(0);<br />}</p><p>
4、執行個體1.5:拷貝標準的輸入到標準的輸出
************************************************************
fget()函數讀一完整的行,read函數讀指定位元組數
函數getc一次讀一個字元,然後函數putc將此字元寫到標準輸出,讀到輸入的最後一個位元組時
,getc返回常量EOF,該常量在stdio.h中定義
************************************************************
#include "apue.h"</p><p>int<br />main(void)<br />{<br /> int c;</p><p> while ((c = getc(stdin)) != EOF)<br /> if (putc(c, stdout) == EOF)<br /> err_sys("output error");</p><p> if (ferror(stdin))<br /> err_sys("input error");</p><p> exit(0);<br />}<br />
五、程式和進程
1、執行個體1.6 :列印當前進程ID
************************************************************
利用函數getpid()即可獲得當前進程ID
************************************************************
#include "apue.h"</p><p>int<br />main(void)<br />{<br /> printf("hello world from process ID %d/n", getpid());<br /> exit(0);<br />}<br />
2、執行個體1.7:從標準輸入讀命令並執行
********************************************************************
fget從標準輸入一次讀一行,當鍵入檔案結束字元作為行的第一個字元是,fgets返回null
fork建立一個新進程,新進程是調用進程的複製品,我們稱調用進程為父進程,新建立的為子進程
execlp用以執行從標準輸入讀入的命令
子進程調用execlp執行新程式檔案,而父進程希望等待子進程終止,這一要求有調用waitpid實現
********************************************************************
#include "apue.h"<br />#include <sys/wait.h></p><p>int<br />main(void)<br />{<br /> char buf[MAXLINE]; /* from apue.h */<br /> pid_t pid;<br /> int status;</p><p> printf("%% "); /* print prompt (printf requires %% to print %) */<br /> while (fgets(buf, MAXLINE, stdin) != NULL) {<br /> if (buf[strlen(buf) - 1] == "/n")<br /> buf[strlen(buf) - 1] = 0; /* replace newline with null */</p><p> if ((pid = fork()) < 0) {<br /> err_sys("fork error");<br /> } else if (pid == 0) { /* child */<br /> execlp(buf, buf, (char *)0);<br /> err_ret("couldn't execute: %s", buf);<br /> exit(127);<br /> }</p><p> /* parent */<br /> if ((pid = waitpid(pid, &status, 0)) < 0)<br /> err_sys("waitpid error");<br /> printf("%% ");<br /> }<br /> exit(0);<br />}<br />
六、錯誤處理
1、C語言提供兩種方式使用者列印錯誤資訊
#include <string.h>char *strerror(int errnum); |
Returns: pointer to message string |
#include <stdio.h>void perror(const char *msg); |