系統(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)程
- 什么是進(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)資源所 描述 的活動單元鹅士。
- 進(jìn)程控制塊
- 進(jìn)程和程序的區(qū)別
- 程序生存期很長券躁,進(jìn)程運(yùn)行開始到運(yùn)行結(jié)束。程序可以開啟多個(gè)進(jìn)程,但是一個(gè)進(jìn)程只對應(yīng)一個(gè)程序也拜。
- 查看進(jìn)程的運(yùn)行狀態(tài)
- top
- 如何查看正在運(yùn)行的進(jìn)程
- ps:當(dāng)前終端由用戶啟動的進(jìn)程
- ps-a:系統(tǒng)后臺所有的進(jìn)程
- 如何創(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)行
- 進(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)程的危害:
- 系統(tǒng)允許存在的進(jìn)程數(shù)是有上限的。
- 若存在大量的僵尸進(jìn)程杯瞻,則可能創(chuàng)建新的進(jìn)程由于沒有
- 進(jìn)程號分配而失敗
- 僵尸進(jìn)程處理方式
- 將子進(jìn)程的善后處理方式交給祖宗進(jìn)程處理
- A-->B-->C:將B進(jìn)程kill镐牺,C進(jìn)程將會交給祖宗進(jìn)程來清理。
- 父進(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; }
- 將子進(jìn)程的善后處理方式交給祖宗進(jìn)程處理
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;
}