1. 程式人生 > >2018-2019 20165215 《資訊安全系統設計基礎》第六週學習總結

2018-2019 20165215 《資訊安全系統設計基礎》第六週學習總結

2018-2019 20165215 《資訊安全系統設計基礎》第六週學習總結


Linux系統呼叫學習

作業系統(Operating System,簡稱OS)完成的工作比喻為兩個角色:服務生和管家婆

  • 管家婆:
    • 通過「檔案」對I/O裝置進行了抽象
    • 通過「虛存」對主存和I/O裝置進行了抽象
    • 通過「程序」對CPU、主存和I/O裝置進行了抽象
  • 服務生:
    • GUI:為小白使用者提供服務,你只會用滑鼠就可以使用作業系統
    • Shell: 為高階使用者提供服務,你要記憶系統命令,更多通過鍵盤使用作業系統
    • 系統呼叫:為專業使用者程式設計師提供服務,你可以建立自己的工具讓大家更好的使用作業系統

兩個重要命令:

  • man -k key1|grep key2|...根據關鍵字檢索系統呼叫
  • grep -nr XXXX /usr/incldue查詢相關的巨集定義,結構體定義,型別定義等

其它知識點

  • man -k +函式名搜尋函式資訊
  • man +數字+函式查到相關的命令和函式
  • cat+檔名稱檢視文字檔案內容
  • od +檔名稱檢視二進位制檔案內容
  • SEE ALSO中得到相關係統呼叫的資訊

使用c語言實現who命令:

系統級I/O

  • 輸入/輸出(I/O)是在主存和外部裝置之間複製資料的過程
  • 文字檔案是隻含有ASCII或Unicode字元的普通檔案;二進位制檔案是所有其他的檔案。對核心而言,文字檔案和二進位制檔案沒有區別
  • 呼叫open函式來開啟一個已存在的檔案或者建立一個新檔案的
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(char *filename, int falgs, mode_t mode); 
/*  成功則返回新檔案描述符,出錯返回-1;
    char *filename:函式將filename轉換為一個檔案描述符,並返回描述符數字;返回的描述符總是在程序中當前沒有開啟的最小描述符;
    int flags:指明程序打算如何訪問這個檔案;
    mode_t mode:指定了新檔案的訪問許可權位。
*/
  • 呼叫close函式關閉一個開啟的檔案
#include <unistd.h>

int close(int fd);
/*  成功則返回0,出錯則為-1。 */
  • 通過分別呼叫read和write函式來執行輸入和輸出
#include <unistd.h>

ssize_t read(int fd, void *buf, size_t n);
/* 成功則返回讀的位元組數,若EOF則為0,若出錯則為-1。  */

ssize_t write(int fd, const void *buf, size_t n);
/*  成功則返回寫的位元組數,若出錯則為-1。  */
  • 在x86-64系統中,size_t被定義為un-signed long,而ssize_t被定義為long
  • 核心用描述符表、檔案表和v-node表這三個相關的資料結構來表示開啟的檔案;程式剛剛啟動的時候,0是標準輸入,1是標準輸出,2是標準錯誤,如果此時去開啟一個新的檔案,它的檔案描述符會是3;不同的檔案描述符也會指向同一個檔案

  • 重定向的兩種方式:
    • linux>ls>foo.txt使得shell載入和執行ls程式,將標準輸出重定向到磁碟檔案foo.txt
    • 使用dup2函式,複製描述符表表項oldfd到描述符表表項newfd,覆蓋描述符表表項newfd
    #include<unistd.h>
    
    int dup2(int oldfd,int newfd);
    /*返回,若成功則為非負的描述符,若出錯則為-1*/

    head,tail的使用

    通過man headman tail查詢可知head、tail的作用分別是顯示一個檔案的前十行和後十行

一、虛擬碼:

  • head
void main( ){
   計數標誌 count=0;
    迴圈按字元讀入檔案
    {
        輸出字元; 
        if(讀入字元為回車符){cout++;}
        if(count==10){退出迴圈}
    }
}
  • tail
void main(){
    統計檔案總行數n;
    計數標誌 count=0
    迴圈按字元讀入檔案
    {
       if(讀入字元為回車符){cout++;}
       if(count>=n-10){
           輸出字元
       }
    }
}

二、產品程式碼

  • head
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc,char *argv[])
{

    int count=0;
    char ch;
    int fd=0;

    fd=open(argv[argc-1],O_RDONLY,0);  
    if(fd==-1){printf("Error!\n");exit(1);}

    while(read(fd,&ch,1)!=0)
    {
        putchar(ch); 
        if(ch == '\n'){count++;}
        if(count == 10){break;}
    }

    close(fd);

    return 0;
}
  • tail
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int  ct(int fd)
{
    int count=0;
    char c;
    while(read(fd,&c,1)!=0)
    {
       if(c == '\n')
        count++;
    }
    return count;
}
void mh(int fd,int n)
{
    int count=0;
    char c;
    while (read(fd, &c, 1)!=0) {
           if (c=='\n') {
           count++;
           }
           if (count>=n-10) {
           putchar(c);
           }
    }
}
int main()
{
    int fd=0,ft=0;
    int count;
    fd=open("aaa.txt",O_RDONLY);
    count=ct(fd);
    close(fd);
    ft=open("aaa.txt",O_RDONLY);
    mh(fd,count);
    close(ft);
    return 0;
}

執行截圖: