Linux系統編程複習

第一章:操作系統基本知識

1.根目錄下各個目錄的詳細介紹

/bin:二進制程序
/boot:啓動配置文件
/dev:設備文件 包含設備文件 終端設備,usb或連接到系統的任何設備
/etc:配置文件
/home:用戶家目錄
/lib:系統庫文件
/media:掛載可移動設備的臨時目錄
/mnt:掛載文件系統
/opt:提供一個可供選的應用
/proc:特殊的動態目錄,不同時間下,裏面的內容不一樣
/root:root用戶主目錄
/sbin:重要的系統二進制文件,通常由系統管理員使用
/sys:系統文件
/tmp:臨時文件
/usr:絕大多數用戶能訪問的應用程序
/var:經常變化的文件,如日誌或數據庫等

2.編寫函數,用strerror函數實現perror函數的功能。

先簡單介紹一下strerror和perror
在linux下的c語言程序運行過程當中有一個整形的errno全局變量一直存在,它的值即爲程序運行的錯誤碼的值.
將errno的值傳入strerror中,即可得到錯誤碼對應的錯誤名稱.
而perror則是將傳入自身的字符串最先打印,後面將錯誤名稱打印.

//通過標準錯誤的標號,獲得錯誤的描述字符串 ,將單純的錯誤標號轉爲字符串描述,方便用戶查找錯誤。
char  * strerror(int  errnum);
//簡單的說:就是errno轉爲錯誤字符串。

void perror(const char *s);
//將上一個函數的出錯信息輸出到標準設備。
//參數s所指的字符串先打印,後面跟上錯誤原因字符串。

答案如下:

void  myperror(char * str)
{
	extern int errno;
	char *error=strerror(errno);
	printf("%s: %s\n",str,error);
}

第二章:文件與目錄管理

1.什麼是文件描述符?什麼是流?二者有什麼區別和聯繫?

文件描述符是一個非負整數,它是文件進行輸入輸出的一個索引
流是對輸入輸出設備的抽象,具有方向性
同:1 都是程序和被操作文件之間連接,並可以在此基礎上進行讀着操作
2 都能和普通文件,設備文件等連接,用戶打開一個文件,要不返回一個文件描述符,要不返回一個流
3 都包含了很多庫函數
異:文件描述符是個整數,流是一個指向結構體的指針

2.用creat、open、close等系統調用,實現fopen、fclose的功能

3.設計一個程序,要求打開文件“pass”,如果沒有這個文件,新建此文件;讀取系統文件“etc/passwd”,把文件中的內容都寫入“pass”文件。

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
	int fd1, fd2;
	char buf[1024];

	fd1=open("pass",O_CREAT|O_RDWR|O_TRUNC,0666);
	assert(fd1 > 0);

	fd2=open("/etc/passwd", O_RDONLY);

	int len;
	while((len = read(fd2, buf, 1024)) > 0)
	{
	    write(fd1, buf, len);
	} 
	close(fd1);
	close(fd2);
}

4.填空

  1. 在Linux中,所有設備和磁盤文件的打開操作都可使用 open 系統調用來進行。
  2. 調用 creat 函數可以創建一個文件,調用 stat 函數可以獲取文件的屬性。
  3. 在Linux中,文件的權限分爲 owngroupother 三類,每類分爲 可讀可寫可執行 權限。
  4. 讀取一個目錄文件的內容時,可使用系統調用 opendir
  5. 若file文件存取權限爲- r – x r- - - - -,這表明屬主有 可讀 權限,組用戶有 可執行 權限,其他用戶有 可執行 權限。

第三章:進程管理

1

  1. 在Linux中,進程的控制塊是一個名爲 task_struct 的結構體。
  2. 在Linux環境下,進程的兩種運行模式爲 用戶模式root模式
  3. 在Linux的用戶空間中,創建一個新進程的方法是由某個已經存在的進程調用 forkvfork 函數,被創建的新進程稱爲 子進程 ,已存在的進程稱爲 父進程
  4. 就緒態的進程是一個只需要 CPU 資源即可運行的進程。
  5. 進程結束時可以調用exit、_exit、abort三個函數,其中 abort 屬於異常結束進程的方法。
  6. 某進程調用wait函數後,如果該進程沒有子進程,則該進程將 立即返回結束
  7. 產生殭屍進程的要素是:子進程退出父進程沒有回收內存資源 ;產生孤兒進程的要素是:父進程先與子進程退出,子進程被init進程收養
  8. 調用fork函數後在父進程中返回 子進程pid,在子進程中返回 0或負值(出錯)

2.列出你的系統中當前所有正在運行的守護進程,簡要說明其功能。

apmd:高級電源治理
Arpwatch:記錄日誌並構建一個在LAN接口上看到的以太網地址和ip地址對數據庫
Autofs:自動安裝治理進程automount,與NFS相關,依靠於NIS
Bootparamd:引導參數服務器,爲LAN上的無盤工作站提供引導所需的相關信息
crond:linux下的計劃任務
Dhcpd:啓動一個DHCP(動態IP地址分配)服務器
Gated:網關路由守候進程,使用動態的OSPF路由選擇協議
Httpd:WEB服務器
Inetd:支持多種網絡服務的核心守候程序

3.編寫一個程序,程序中創建一個子進程用來打開你的Linux系統中的瀏覽器;父進程等待子進程結束後輸出子進程的退出值。

#include <stdio.h>
#include<stdlib.h>
#include<wait.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
int mian(int argc,char argv[])
{
    pid_ t pid; .
    int pid_ wait,status;
    if((pid=fork())<0){
        perror("fork");
        exit(1);
    }
    else if(pid==O){
        execle("/usr/bin/google-chrome ,google-chrome,NULL);
    }
    else{
        pid_ wait=wait(&status); 
        if(WIFEXITED(status)){
            printf("%d)n" ,WEXITSTATUS(status));
        }
    }
    return 0;
}

第四章:管道與重定向

1

  1. 命令who 1>usrlist表示 輸出 重定向。

  2. dupdup2函數可以用來複制文件描述符。

  3. >>符號表示 追加 重定向。

  4. 編程將標準輸出重定向到文件描述符爲6對應的文件上,則應使用語句 dup2(6,1)

  5. 管道就是將前一個命令的 輸出端 作爲後一個命令的 輸入端,分爲 有名管道無名管道 兩種,其中 無名管道 只能在有親緣關係的進程間使用。

  6. 命名管道也稱爲FIFO文件。

  7. 使用pipe函數創建了匿名管道pfd,其中pfd[ 0 ]爲管道的讀端,pfd[ 1 ]爲管道的寫端。

2.請說明匿名管道和命名管道的異同點

異:1.匿名管道是由pipe函數創建 並打開的
命名管道是由mkfifo函數創建 的 ,打開用open
2. 匿名管道只能用於有親緣關係的進程之間的通信,而命名管道則可以用於任意兩個進程間的通信。
3. 匿名管道的生存依附於所在進程,命名管道的生存則不依附進程
同:1.都可以由read,write進行讀寫
2. 數據在這兩者中都遵循FIFO原則

3.通過管道模擬實現Shell命令:cat file | sort。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
int main(void)
{
   int fd[2]; 
   pid_t pid;
   int start_val;
   if(pipe(fd))
 {
    printf("pipe error!\n");
    exit(1);
 }
pid=fork();

  switch(pid)
 {
  case -1:
          printf("fork error!\n");
          exit(1);
  case 0:
         close(0);
         close(fd[1]);
         dup(fd[0]);
         printf("child program!\n");
         execlp("sort","sort",NULL);        
         exit(0);
  default:
          close(1);
          close(fd[0]);        
          dup(fd[1]);
          printf("parent program!\n");
          execlp("cat","cat","file.txt",NULL);
          wait(&start_val);
          exit(0);
 }
return 0;
}

第五章:信號

1

  1. 在實際應用中,一個用戶進程常常需要對多個信號做出處理。爲了方便對多個信號進行處理,在Linux系統中引入 信號集 的概念。

  2. 進程可以忽略大部分信號,除了 SIGSTOPSIGKILL 信號。

  3. 在kill(pid,signum)函數中,pid>0表示 將信號傳給進程識別碼爲 pid 的進程

  4. Ctrl+\發送一個 SIGQUIT 信號。

  5. SIGHUP信號的作用是 發送一個連接斷開信號 ,SIGCONT信號的作用是 讓一個停止的進程繼續執行

2有哪些事件或情況會產生信號?

1.當用戶按某些終端鍵時,將產生信號。
終端上按“Ctrl+c”組合鍵通常產生中斷信號 SIGINT,終端上按“Ctrl+\”鍵通常產生中斷信號 SIGQUIT,終端上按“Ctrl+z”鍵通常產生中斷信號 SIGSTOP 等。

2.硬件異常將產生信號。
比如數據運算時,除數爲0;或者無效的存放訪問等.這些條件通常由硬件檢測到,並通知內核,然後內核爲該條件發生時正在運行的進程產生適當的信號.。

3.軟件異常將產生信號。
當檢測到某種軟件條件已發生,並將其通知有關進程時,產生信號。

4.調用 kill() 函數將發送信號。
注意:接收信號進程和發送信號進程的所有者必須相同,或發送信號進程的所有者必須是超級用戶。

5.運行 kill 命令將發送信號。
此程序實際上是使用 kill 函數來發送信號。也常用此命令終止一個失控的後臺進程。

3.爲什麼說信號機制是一種異步通信方式?

因爲程序在運行的過程中並不知道將會發生什麼,因此進程不會去等某個事情發生,而是一直執行自己的事情,當發生一些特定的事件的時候,比如鍵盤ctrl+c的時候,我們會發送一個信號給進程,此時進程收到了信號,從而執行對信號的處理。因此信號機制是一種異步通信。

4.爲SIGUSR1信號安裝一個處理函數,當捕捉到該信號時,顯示當前的系統時間。用raise發送信號測試是否成功。

void func()
{
    time_t timep;
    time (&timep);
    printf(%s”,asctime(gmtime(&timep)));
}
void main() 
{
	signal(SIGUSR1,&func);
	raise()
}

Linux操作系統編程課程期末試卷

1.在UNIX/Linux系統中,可以認爲操作系統用了三張表來描述一個打開的文件,請問是哪三張表,這三張表各自描述了文件的哪些屬性,它們之間是如何聯繫起來的?

1.文件描述符表 文件表 索引節點表
2.文件描述符表: 文件描述符標誌,指向一個文件表項的指針
文件表: 文件狀態標誌,文件讀寫偏移量,指向該文件索引節點表項的指針.
索引節點表: 文件屬性,數據塊位置,當前文件長度
3.通過指針指向對應表項

2.在UNIX/Linux系統中/etc/shadow文件用來存儲用戶密碼。所有用戶都可以通過執行passwd命令( /usr/bin/passwd)修改自己的密碼(修改/etc/shadow文件),但非root的其他用戶對/etc/shadow文件沒有讀寫權限,如下圖所示:

圖一
passwd命令的文件權限如下圖所示:
圖二
請闡述爲什麼所有用戶都可以通過執行passwd命令修改自己的密碼(修改/etc/shadow文件)?
passwd這個命令設置了s(setuid)權限,當一個可以執行程序具有setuid權限,用戶執行這個程序時,將以這個程序所有着身份執行。而passwd的擁有者是root用戶,因此普通用戶雖然沒有讀寫/etc/shadow文件的權限但是可以修改自己的密碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章