系統(tǒng)與網(wǎng)絡(luò)編程-(dir,進(jìn)程)

系統(tǒng)與網(wǎng)絡(luò)編程

access使用

#include <stdio.h>
#include <unistd.h>

int main(int argc,char *argv[])
{
    int ret=-1;
    ret=access(argv[1],F_OK);
    if(ret==-1)
    {
        perror("access");
        return -1;
    }
    else if(ret==0)
    {
        printf("file exist\n");
    }
    return 0;
}
//111已存在将谊,222無

Paste_Image.png
#include <stdio.h>
#include <unistd.h>

int main(int argc,char *argv[])
{
    int ret=-1;
    ret=access(argv[1],W_OK|R_OK);
    if(ret==-1)
    {
        perror("access");
        return -1;
    }
    else if(ret==0)
    {
        printf("file exist\n");
    }
    return 0;
}
//查看用戶可執(zhí)行權(quán)限

Paste_Image.png

dir

  • opendir:打開指定的
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
int main(int argc,char *argv[])
{
    //打開指定的目錄倚聚,打開失敗返回NULL.成功則返回指向目錄的指針.
    DIR *pDir=(opendir(argv[1]));
    if(pDir==NULL)
    {
        perror("opendir:");
        return -1;
    }
    printf("opendir ok\n");
    close (pDir);
    return 0;
}
Paste_Image.png
  • readdir:讀取目錄下的內(nèi)容
int main(int argc,char *argv[])
{
    //打開指定的目錄狡相,打開失敗返回NULL.成功則返回指向目錄的指針.
    DIR *pDir=(opendir(argv[1]));
    if(pDir==NULL)
    {
        perror("opendir:");
        return -1;
    }
    printf("opendir ok\n");
    struct dirent *pDirent=NULL;
    pDirent = readdir(pDir);
    while(pDirent!=NULL)
    {
        printf("%s ",pDirent->d_name);
        pDirent=readdir(pDir);
        //readdir(pDir)每次都會獲得目錄里的信息
    }
    printf("\n");
    close (pDir);
}
Paste_Image.png
  • rewinddir(pDirent):返回到目錄的頭部
  • mkdir(pathname,mode):創(chuàng)建一個(gè)目錄
  • rmdir(pDirent):刪除一個(gè)目錄
  • stat:查看目標(biāo)文件目錄下的文件及屬性
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
int main(int argc,char *argv[])
{
    //打開指定的目錄亡脸,打開失敗返回NULL.成功則返回指向目錄的指針.
    DIR *pDir=(opendir(argv[1]));
    if(pDir==NULL)
    {
        perror("opendir:");
        return -1;
    }
    printf("opendir ok\n");
    struct stat fileStat;
    struct dirent *pDirent=NULL;
    int ret=-1;
    pDirent = readdir(pDir);
    while(pDirent!=NULL)
    {
        printf("%s ",pDirent->d_name);
        ret=stat(pDirent->d_name,&fileStat);
        if(ret==0)
        {
            switch(fileStat.st_mode&S_IFMT)
            {
                case S_IFREG:printf("這是一個(gè)普通文件\n");break;
                case S_IFDIR:printf("這是一個(gè)目錄文件\n");break;
                default:printf("其他類型的文件\n");break;
            }
        }
        else if(ret==-1)
        {
            perror("stat");
            break;
        }
        pDirent=readdir(pDir);
        //readdir(pDir)每次都會獲得目錄里的信息
    }
    printf("\n");
    closedir(pDir);
    
}
Paste_Image.png

進(jìn)程

  1. 什么是進(jìn)程
    • 進(jìn)程是操作系統(tǒng)結(jié)構(gòu)的基礎(chǔ)窍奋;是一個(gè)正在執(zhí)行的 程序 找默;計(jì)算機(jī)中正在運(yùn)行的程序?qū)嵗怪豢梢苑峙浣o 處理器 并由處理器執(zhí)行的一個(gè)實(shí)體测柠;由單一順序的執(zhí)行顯示,一個(gè)當(dāng)前狀態(tài)和一組相關(guān)的系統(tǒng)資源所 描述 的活動單元鹅士。
  2. 進(jìn)程控制塊
  3. 進(jìn)程和程序的區(qū)別
    • 程序生存期很長券躁,進(jìn)程運(yùn)行開始到運(yùn)行結(jié)束。程序可以開啟多個(gè)進(jìn)程,但是一個(gè)進(jìn)程只對應(yīng)一個(gè)程序也拜。
  4. 查看進(jìn)程的運(yùn)行狀態(tài)
    • top
  5. 如何查看正在運(yùn)行的進(jìn)程
    • ps:當(dāng)前終端由用戶啟動的進(jìn)程
    • ps-a:系統(tǒng)后臺所有的進(jìn)程
  6. 如何創(chuàng)建進(jìn)程
    • fork:父進(jìn)程創(chuàng)建子進(jìn)程以舒,父進(jìn)程會對子進(jìn)程進(jìn)行一次拷貝,其中使用的資源都會完全的拷貝一份慢哈。返回狀態(tài)也會被拷貝一份到子進(jìn)程蔓钟。
    • 子進(jìn)程id返回給父進(jìn)程,父進(jìn)程傳給子進(jìn)程數(shù)值0卵贱,父進(jìn)程若得到-1滥沫,說明子進(jìn)程未成功執(zhí)行
    • ./xxx &后臺運(yùn)行
  7. 進(jìn)程如何結(jié)束
    • kill -9 +num
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
    pid_t pid=-1;
    pid=fork();
    if(pid>0)//父進(jìn)程
    {
        printf("this is parent progress\n");    
    }
    else if(pid==0)//子進(jìn)程
    {
        printf("this is child progress\n"); 
    }
    else if(pid=-1)//創(chuàng)建進(jìn)程失敗
    {
        perror("fork");
        return -1;
    }
    while(1)
    {}
    printf("hello world\n");
    return 0;
}
Paste_Image.png
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
    pid_t pid=-1;
    int iNum=0;
    char caData[32]={'\0'};
    //子進(jìn)程創(chuàng)建后,與父進(jìn)程屬于兩個(gè)相互獨(dú)立的進(jìn)程.
    pid=fork();
    //fork成功:將子進(jìn)程的id返回給父進(jìn)程的PID键俱,將0返回子進(jìn)程的pid,
    //fork失敗:返回-1給父進(jìn)程的pid變量,子進(jìn)程便不會被創(chuàng)建
    if(pid>0)//父進(jìn)程
    {
        printf("this is parent progress\n");    
        strcpy(caData,"this is parent progress\n");
        iNum=3;//父進(jìn)程執(zhí)行3次兰绣,當(dāng)結(jié)束時(shí)會顯示終端~/1612/11/11.30....
    }
    else if(pid==0)//子進(jìn)程
    {
        printf("this is child progress\n"); 
        strcpy(caData,"this is child progress\n");
        iNum=6;
    
    }
    else if(pid=-1)//創(chuàng)建進(jìn)程失敗
    {
        perror("fork");
        return -1;
    }
    int i=0;
    for(;i<iNum;i++)
    {
        printf("%s",caData);
        sleep(1);
    }
    printf("hello world\n");
    return 0;
}
Paste_Image.png
  • 僵尸進(jìn)程:子進(jìn)程掛了但是父進(jìn)程很忙,導(dǎo)致子進(jìn)程被殺死后無人收拾<defunct>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
    pid_t pid=-1;
    pid=fork();
    if(pid>0)//父進(jìn)程
    {
        printf("this is parent progress\n");    
        while(1)
        {}
    }
    else if(pid==0)//子進(jìn)程
    {
        printf("this is child progress\n"); 
    }
    else if(pid=-1)//創(chuàng)建進(jìn)程失敗
    {
        perror("fork");
        return -1;
    }
    while(1)
    {}
    printf("hello world\n");
    return 0;
}
Paste_Image.png
  • 僵尸進(jìn)程
    • 如果一個(gè)進(jìn)程終止方妖,但是其父進(jìn)程尚未調(diào)用wait或者waitpid,對他進(jìn)行清理狭魂,這時(shí)的進(jìn)程狀態(tài)稱之為僵尸進(jìn)程。任何進(jìn)程在剛終止的時(shí)候都是僵尸進(jìn)程党觅,正常情況下僵尸進(jìn)程會立刻被父進(jìn)程清理雌澄。
    • 僵尸進(jìn)程的危害:
      1. 系統(tǒng)允許存在的進(jìn)程數(shù)是有上限的。
      2. 若存在大量的僵尸進(jìn)程杯瞻,則可能創(chuàng)建新的進(jìn)程由于沒有
      3. 進(jìn)程號分配而失敗
  • 僵尸進(jìn)程處理方式
    1. 將子進(jìn)程的善后處理方式交給祖宗進(jìn)程處理
      • A-->B-->C:將B進(jìn)程kill镐牺,C進(jìn)程將會交給祖宗進(jìn)程來清理。
    2. 父進(jìn)程自己調(diào)用響應(yīng)函數(shù)來對子進(jìn)程做善后處理
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    int main(void)
    {
        pid_t pid=-1;
        pid=fork();
        if(pid>0)//父進(jìn)程
        {
            printf("this is parent progress\n");    
            wait(NULL);//阻塞等待子進(jìn)程的結(jié)束,獲得子進(jìn)程的退出狀態(tài),并對子進(jìn)程做出清理工作.
            while(1)
            {}
        }
        else if(pid==0)//子進(jìn)程
        {
            printf("this is first child progress\n");   
            pid_t pid2=-1;
            pid=fork();
            if(pid2>0)
            {
                return 0;
            }
            else if(pid2==0)
            {
                printf("this is second child progress\n");  
                return 0;
            }
            else if(pid=-1)//創(chuàng)建進(jìn)程失敗
            {
                perror("fork");
                return -1;
            }
        }
        else if(pid=-1)//創(chuàng)建進(jìn)程失敗
        {
            perror("fork");
            return -1;
        }
        return 0;
    }
    
Paste_Image.png
Paste_Image.png
  • 編程實(shí)現(xiàn)每一秒鐘父進(jìn)程向文件中寫入信息魁莉,每一秒子進(jìn)程顯示文件大小睬涧。
#include <stdio.h>
#include <errno.h>  //errno  
#include <string.h>  //strerror()
#include <unistd.h>  //read()  write()
/*open*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc,char *argv[])
{
    pid_t pid=-1;
    pid=fork();
    int i=0;
        if(pid>0)//父進(jìn)程
        {
            int fd=-1;  
            fd=open(argv[1],O_RDWR|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR|S_IRGRP);
            
            if(fd==-1)
            {
                printf("open error:%s\n",strerror(errno));
                return -1;
            }
                char *pData="hello world";
            while(1)
            {
            #if 1
                write(fd,pData,strlen(pData));
                printf("insert success\n");
                sleep(1);
            #endif
            }
                close(fd);
        }
        else if(pid==0)//子進(jìn)程
        {
            int fd=-1;  
            fd=open(argv[1],O_RDWR|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR|S_IRGRP);
                off_t offset=-1;
            while(1)
            {
            #if 1
                offset=lseek(fd,0,SEEK_END);
                if(offset==-1)
                {
                    printf("lseek error:%s\n",strerror(errno));
                }
                else
                {
                    printf("file size:%ld\n",offset);
                }
                sleep(1);
            #endif
            }
                close(fd);
        }
        else if(pid=-1)//創(chuàng)建進(jìn)程失敗
        {
            perror("fork");
            return -1;
        }       
    return 0;
}
  • 一個(gè)進(jìn)程結(jié)束時(shí)會關(guān)閉所有的文件描述符,釋放在用戶空間分配的內(nèi)存旗唁,但它的PCB還保留著畦浓,如果進(jìn)程異常終止則保留著導(dǎo)致該進(jìn)程終止的信號
  • 如果正常終止則保留退出狀態(tài):在終端可以用“$?”來查看
  • 父進(jìn)程可以調(diào)用wait或waitpid獲取這些信息,然后徹底清楚掉這個(gè)進(jìn)程

homework

  • 實(shí)現(xiàn)將目標(biāo)目錄下的目錄及統(tǒng)統(tǒng)拷貝
#include <stdio.h>
#include <errno.h>
#include <string.h>
//open stat
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>//read() write()
//dir
#include <dirent.h>
#include <stdlib.h>
#define PER_IO_BYTES 4096
//拷貝文件需要考慮目錄文件及文本文件

int fileType(mode_t mode)//獲得文件類型
{
    int ret =-1;
    switch(mode & S_IFMT)//S_IFMT:掩碼,可獲得該文件類型
    {
        case S_IFREG:
            ret=0;
            break;
        case S_IFDIR:
            ret=1;
            break;
        default:
            ret=-1;
            break;
    }
    return ret;
}
void copyRegularFile(const char *pDestPathname,
                    const char *pSrcPathname)//拷貝普通文件
{
    if(pDestPathname==NULL||pSrcPathname==NULL)//形參有效性檢查
    {
        return;
    }
    int iDestFd=-1;//以寫的方式打開目標(biāo)文件
    iDestFd=open(pDestPathname,O_WRONLY|O_CREAT,
                 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
    if(iDestFd==-1)
    {
        perror("open dest");
        exit(EXIT_FAILURE);//文件返回狀態(tài)
    }
    int iSrcFd=-1;//以讀的方式打開源文件
    iSrcFd=open(pSrcPathname,O_RDONLY|O_CREAT,
                 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
    if(iSrcFd==-1)
    {
        perror("open src");
        exit(EXIT_FAILURE);//文件返回狀態(tài)
    }
    unsigned char caBuf[PER_IO_BYTES]={'\0'};
    int ret=-1;
    //從源文件循環(huán)讀取數(shù)據(jù)
    while(ret=read(iSrcFd,caBuf,PER_IO_BYTES))
    {
        //判斷數(shù)據(jù)讀取成功失敗與否
        if(ret==-1)
        {
            //如果發(fā)生的錯誤是EGAIN,EGAIR
            //需要重新讀取數(shù)據(jù)
            if(errno=EAGAIN||errno==EINTR)
            {
                continue;
            }
            //如果是其他錯誤,則顯示信息并退出程序
            perror("read src");
        //  close(iSrcFd);
        //  close(iDestFd);
            exit(EXIT_FAILURE);//文件返回狀態(tài)
        }
        //如果返回值為0,表示已讀到文件尾,沒有數(shù)據(jù)可讀
        //則文件拷貝結(jié)束
        else if(ret==0)
        {
            break;
        }
        while(1)
        {   //將讀到的數(shù)據(jù)寫入到目標(biāo)文件
            ret=write(iDestFd,caBuf,ret);
            if(ret==-1)
            {
                if(errno=EAGAIN||errno==EINTR)
                {
                    continue;
                }
                perror("write dest");
        //      close(iSrcFd);
        //      close(iDestFd);
                exit(EXIT_FAILURE);
            }
            break;
        }
    }
    close(iSrcFd);
    close(iDestFd);
}

void copyDirFile(const char *pDestDirName
                 , const char *pSrcDirName)
{
    if (NULL == pDestDirName || NULL == pSrcDirName)
    {
        return;
    }
    int ret = -1;
    ret = mkdir(pDestDirName, 0775);
    if (-1 == ret)
    {
        if (EEXIST != errno)
        {
            perror("mkdir");
            exit(EXIT_FAILURE);
        }
    }
    DIR *pDestDir = NULL;
    pDestDir = opendir(pDestDirName);
    if (NULL == pDestDir)
    {
        perror("open dest dir");
        exit(EXIT_FAILURE);
    }
    DIR *pSrcDir = NULL;
    pSrcDir = opendir(pSrcDirName);
    if (NULL == pSrcDir)
    {
        perror("open src dir");
        exit(EXIT_FAILURE);
    }
    char caDestFileName[64] = {'\0'};
    char caSrcFileName[64] = {'\0'};
    struct stat fileStat;
    struct dirent *pDirent = NULL;
    pDirent = readdir(pSrcDir);
    int iLen = 0;
    while (NULL != pDirent)
    {
        if (0 != strcmp(pDirent->d_name, "..")
            && 0 != strcmp(pDirent->d_name, "."))
        {
            strcpy(caSrcFileName, pSrcDirName);
            iLen = strlen(pSrcDirName);
            if (pSrcDirName[iLen-1] != '/')
            {
                strcat(caSrcFileName, "/");
            }
            strcat(caSrcFileName, pDirent->d_name);
            printf("%s\n", caSrcFileName);
/********************************************************/
            strcpy(caDestFileName, pDestDirName);
            iLen = strlen(pDestDirName);
            if (pDestDirName[iLen-1] != '/')
            {
                strcat(caDestFileName, "/");
            }
            strcat(caDestFileName, pDirent->d_name);
/********************************************************/
            ret = stat(caSrcFileName, &fileStat);
            if (-1 == ret)
            {
                perror("stat");
                exit(EXIT_FAILURE);
            }
            ret = fileType(fileStat.st_mode);
            switch (ret)
            {
            case 0:
                copyRegularFile(caDestFileName, caSrcFileName);
                break;
            case 1:
                copyDirFile(caDestFileName, caSrcFileName);
                break;
            default:
                break;
            }
        }
/********************************************************/
        pDirent = readdir(pSrcDir);
    }
}

int main(int argc,char *argv[])
{
    copyDirFile(argv[2],argv[1]);   
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末检疫,一起剝皮案震驚了整個(gè)濱河市讶请,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌屎媳,老刑警劉巖夺溢,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異烛谊,居然都是意外死亡风响,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門丹禀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來状勤,“玉大人鞋怀,你說我怎么就攤上這事∮担” “怎么了接箫?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵攒读,是天一觀的道長朵诫。 經(jīng)常有香客問我,道長薄扁,這世上最難降的妖魔是什么剪返? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮邓梅,結(jié)果婚禮上脱盲,老公的妹妹穿的比我還像新娘。我一直安慰自己日缨,他們只是感情好钱反,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著匣距,像睡著了一般面哥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上毅待,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天尚卫,我揣著相機(jī)與錄音,去河邊找鬼尸红。 笑死吱涉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的外里。 我是一名探鬼主播怎爵,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盅蝗!你這毒婦竟也來了鳖链?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤风科,失蹤者是張志新(化名)和其女友劉穎撒轮,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贼穆,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡题山,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了故痊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片顶瞳。...
    茶點(diǎn)故事閱讀 39,926評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出慨菱,到底是詐尸還是另有隱情焰络,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布符喝,位于F島的核電站闪彼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏协饲。R本人自食惡果不足惜畏腕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望茉稠。 院中可真熱鬧描馅,春花似錦、人聲如沸而线。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽膀篮。三九已至嘹狞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間各拷,已是汗流浹背刁绒。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留烤黍,地道東北人知市。 一個(gè)月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像速蕊,于是被迫代替她去往敵國和親嫂丙。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容