waitpid
表頭文件
#include<sys/types.h>
#include<sys/wait.h>
定義函數 pid_t waitpid(pid_t pid,int * status,int options);
函數說明
waitpid()會暫時停止目前進程的執行,直到有信號來到或子進程
結束。如果在調用 wait()時子進程已經結束,則 wait()會立即
返回子進程結束狀態值。 子進程的結束狀態值會由參數 status 返回,
而子進程的進程識別碼也會一起返回。如果不在意結束狀態值,則
參數 status 可以設成 NULL。參數 pid 爲欲等待的子進程識別碼,
其他數值意義如下:
pid<-1 等待進程組識別碼爲 pid 絕對值的任何子進程。
pid=-1 等待任何子進程,相當於 wait()。
pid=0 等待進程組識別碼與目前進程相同的任何子進程。
pid>0 等待任何子進程識別碼爲 pid 的子進程。
參數 option 可以爲 0 或下面的 OR 組合:
WNOHANG 如果沒有任何已經結束的子進程則馬上返回, 不予以等待。
WUNTRACED 如果子進程進入暫停執行情況則馬上返回,但結束狀態不予以理會。
子進程的結束狀態返回後存於 status,底下有幾個宏可判別結束情況:
WIFEXITED(status)如果子進程正常結束則爲非 0 值。
WEXITSTATUS(status)取得子進程 exit()返回的結束代碼,一般會先用 WIFEXITED 來判斷是否正常結束才能使用此宏。
WIFSIGNALED(status)如果子進程是因爲信號而結束則此宏值爲真
WTERMSIG(status) 取得子進程因信號而中止的信號代碼,一般會先用 WIFSIGNALED 來判斷後才使用此宏。
WIFSTOPPED(status) 如果子進程處於暫停執行情況則此宏值爲真。一般只有使用 WUNTRACED 時纔會有此情況。
WSTOPSIG(status) 取得引發子進程暫停的信號代碼,一般會先用 WIFSTOPPED 來判斷後才使用此宏。
如果執行成功則返回子進程識別碼(PID) ,如果有錯誤發生則返回
返回值-1。失敗原因存於 errno 中。
/******
* waitpid.c - Simple wait usage
*********/
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
pid_t childpid;
int status;
childpid = fork();
if ( -1 == childpid )
{
perror( "fork()" );
exit( EXIT_FAILURE );
}
else if ( 0 == childpid )
{
puts( "In child process" );
sleep( 3 );//讓子進程睡眠3秒,看看父進程的行爲
printf("\tchild pid = %d\n", getpid());
printf("\tchild ppid = %d\n", getppid());
exit(EXIT_SUCCESS);
}
else
{
waitpid( childpid, &status, 0 );
puts( "in parent" );
printf( "\tparent pid = %d\n", getpid() );
printf( "\tparent ppid = %d\n", getppid() );
printf( "\tchild process exited with status %d \n", status );
}
exit(EXIT_SUCCESS);
}
[root@localhost src]# gcc waitpid.c
[root@localhost src]# ./a.out
In child process
child pid = 4469
child ppid = 4468
in parent
parent pid = 4468
parent ppid = 4379
child process exited with status 0
[root@localhost src]#
如果將上面“waitpid( childpid, &status, 0 );”行註釋掉,程序執行效果如下:
[root@localhost src]# ./a.out
In child process
in parent
parent pid = 4481
parent ppid = 4379
child process exited with status 1331234400
[root@localhost src]# child pid = 4482
child ppid = 1
子進程還沒有退出,父進程已經退出了。
fork
頭文件:
#include <unistd.h>
函數定義:
int fork( void );
返回值:
子進程中返回0,父進程中返回子進程ID,出錯返回-1
函數說明:
一個現有進程可以調用fork函數創建一個新進程。由fork創建的新進程被稱爲子進程(child process)。fork函數被調用一次但返回兩次。兩次返回的唯一區別是子進程中返回0值而父進程中返回子進程ID。
子進程是父進程的副本,它將獲得父進程數據空間、堆、棧等資源的副本。注意,子進程持有的是上述存儲空間的“副本”,這意味着父子進程間不共享這些存儲空間,它們之間共享的存儲空間只有代碼段。
示例代碼:
#include <unistd.h>
#include <stdio.h>
int main(int argc, void ** argv )
{
int pid = fork();
if(pid < 0 ) {
// print("error!");
} else if( pid == 0 ) {
// print("This is the child process!");
} else {
// print("This is the parent process! child process id = %d", pid);
}
return 0;
}
execlp
相關函數:
fork,execl,execle,execv,execve,execvp
表頭文件:
#include<unistd.h>
定義函數:
int execlp(const char * file,const char * arg,……);
函數說明:
execlp()會從PATH 環境變量所指的目錄中查找符合參數file的文件名,找到後便執行該文件,然後將第二個以後的參數當做該文件的argv[0]、argv[1]……,最後一個參數必須用空指針(NULL)作結束。
返回值:
如果執行成功則函數不會返回,執行失敗則直接返回-1,失敗原因存於errno 中。
錯誤代碼 參考execve()。
範例:
/* 執行ls -al /etc/passwd execlp()會依PATH 變量中的/bin找到/bin/ls */
#include<unistd.h>
main()
{
execlp(“ls”,”ls”,”-al”,”/etc/passwd”,(char *)0);
}
執行:
-rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd
————————————————————————————————add by love_aiqiu
NAME
execl, execlp, execle, execv, execvp - execute a file
SYNOPSIS
#include <unistd.h>
extern char **environ;
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg , ..., char * const envp[]);
int execv(const char *path, char *const argv[]);
system
#include<stdlib.h>
int system(const char * string);
函數說明
system()會調用fork()產生子進程,由子進程來調用/bin/sh-c string來執行參數string字符串所代表的命令,此命>令執行完後隨即返回原調用的進程。在調用system()期間SIGCHLD 信號會被暫時擱置,SIGINT和SIGQUIT 信號則會被忽略。
返回值
=-1:出現錯誤
=0:調用成功但是沒有出現子進程
>0:成功退出的子進程的id
如果system()在調用/bin/sh時失敗則返回127,其他失敗原因返回-1。若參數string爲空指針(NULL),則返回非零值>。 如果system()調用成功則最後會返回執行shell命令後的返回值,但是此返回值也有可能爲 system()調用/bin/sh失敗所返回的127,因此最好能再檢查errno 來確認執行成功。
附加說明
在編寫具有SUID/SGID權限的程序時請勿使用system(),system()會繼承環境變量,通過環境變量可能會造成系統安全的問題。
範例
#i nclude<stdlib.h>
main()
{
system(“ls -al /etc/passwd /etc/shadow”);
}
執行結果:
-rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd
-r--------- 1 root root 572 Sep 2 15 :34 /etc/shado
例2:
char tmp[];
sprintf(tmp,"/bin/mount -t vfat %s /mnt/usb",dev);
system(tmp);
其中dev是/dev/sda1。