亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

linux編程-信號講解

2019-11-11 04:33:35
字體:
來源:轉載
供稿:網友
Signal()函數使用簡介

         signal()是一種系統調用,用于通知運行時系統,當某種特定的“軟件中斷”發生時調用特定的程序。它的真正的名字應該是“Call_that_routine_when_this_interrupt_Comes_in(當該中斷發生時調用那個程序)", 調用signal()函數,并通過參數傳遞告訴它終端類型以及用于處理中斷的程序。

         ANSIC 標準中,signal()函數的聲明如下:void (*signal (int sig ,void (*func)(int))) (int) ;

         函數返回與給定sig信號相關聯的func的以前值這個函數的模樣很恐怖,它的意思是:signal是一個函數,

他返回一個函數指針,后者所指向的函數接受一個int參數并返回void 。

        

         可以用typedef進行簡化:

         typedef void (*ptr_to_func)  (int) ;

         ptr_to_func signal (int , ptr_to_func );

 

        實例:捕捉段錯誤信號的信號處理函數:

 

#include <signal.h>

#include <stdio.h>

void handler(int s)

{

         if (s == SIGBUS) PRintf(" now got a bus error signal/n");

         if (s == SIGSEGV) printf(" now got a segmentation violation signal/n");

 

         if (s == SIGILL) printf(" now got an illegal instruction signal/n");

         exit(1);

}

main () 

{

         int *p=NULL;

         signal(SIGBUS, handler);

         signal(SIGSEGV, handler);

         signal(SIGILL, handler);

         *p=0;

}

      由于p是一個空指針,對空指針賦值會引發一個段錯誤,于是程序捕捉到SIGSEGV信號,并打印消息”now got a segmentation violation signal“后退出。

      打開windows下的signal.h頭文件,發現在這個頭文件里定義了很多符號,但是沒有找到SIGBUS,所以上面的代碼在windows下編譯不通過: 

     error C2065: 'SIGBUS' : undeclared identifier

     把涉及到SIGBUS的相關部分刪去即可。

 使用setjmp、longjmp從信號中恢復:

 

#include <setjmp.h>

#include <signal.h>

#include <stdio.h>

jmp_buf buf;

void handler(int s)

{

       if (s == SIGINT) printf(" now got a SIGINT signal/n");

       longjmp(buf, 1);

 

}

main () 

{

        signal(SIGINT, handler);

        if (setjmp(buf)) {

                 printf("back in main/n");

                 return 0;

          }else

                 printf("first time through/n");

loop:

 

          goto loop;

}

 

linux系統signal信號機制詳解

信號機制是進程之間相互傳遞消息的一種方法,信號全稱為軟中斷信號,也有人稱作軟中斷。從它的命名可以看出,它的實質和使用很象中斷。所以,信號可以說是進程控制的一部分。

一. 信號的基本概念

本節先介紹信號的一些基本概念,然后給出一些基本的信號類型和信號對應的事件。基本概念對于理解和使用信號,對于理解信號機制都特別重要。下面就來看看什么是信號。

1、基本概念

軟中斷信號(signal,又簡稱為信號)用來通知進程發生了異步事件。進程之間可以互相通過系統調用kill發送軟中斷信號。內核也可以因為內部事件而給進程發送信號,通知進程發生了某個事件。注意,信號只是用來通知某進程發生了什么事件,并不給該進程傳遞任何數據。

收到信號的進程對各種信號有不同的處理方法。處理方法可以分為三類:第一種是類似中斷的處理程序,對于需要處理的信號,進程可以指定處理函數,由該函數來處理。第二種方法是,忽略某個信號,對該信號不做任何處理,就象未發生過一樣。第三種方法是,對該信號的處理保留系統的默認值,這種缺省操作,對大部分的信號的缺省操作是使得進程終止。進程通過系統調用signal來指定進程對某個信號的處理行為。

在進程表的表項中有一個軟中斷信號域,該域中每一位對應一個信號,當有信號發送給進程時,對應位置位。由此可以看出,進程對不同的信號可以同時保留,但對于同一個信號,進程并不知道在處理之前來過多少個。

2、信號的類型

發出信號的原因很多,這里按發出信號的原因簡單分類,以了解各種信號:

(1) 與進程終止相關的信號。當進程退出,或者子進程終止時,發出這類信號。

(2) 與進程例外事件相關的信號。如進程越界,或企圖寫一個只讀的內存區域(如程序正文區),或執行一個特權指令及其他各種硬件錯誤。

(3) 與在系統調用期間遇到不可恢復條件相關的信號。如執行系統調用exec時,原有資源已經釋放,而目前系統資源又已經耗盡。

(4) 與執行系統調用時遇到非預測錯誤條件相關的信號。如執行一個并不存在的系統調用。

(5) 在用戶態下的進程發出的信號。如進程調用系統調用kill向其他進程發送信號。

(6) 與終端交互相關的信號。如用戶關閉一個終端,或按下break鍵等情況。

(7) 跟蹤進程執行的信號。

Linux支持的信號列表如下。很多信號是與機器的體系結構相關的,首先列出的是POSIX.1中列出的信號:

信號 值 處理動作 發出信號的原因 

---------------------------------------------------------------------- 

SIGHUP 1 A 終端掛起或者控制進程終止 

SIGINT 2 A 鍵盤中斷(如break鍵被按下) 

SIGQU99v 3 C 鍵盤的退出鍵被按下 

SIGILL 4 C 非法指令 

SIGABRT 6 C 由abort(3)發出的退出指令 

SIGFPE 8 C 浮點異常 

SIGKILL 9 AEF Kill信號 

SIGSEGV 11 C 無效的內存引用 

SIGPipE 13 A 管道破裂: 寫一個沒有讀端口的管道 

SIGALRM 14 A 由alarm(2)發出的信號 

SIGTERM 15 A 終止信號 

SIGUSR1 30,10,16 A 用戶自定義信號1 

SIGUSR2 31,12,17 A 用戶自定義信號2 

SIGCHLD 20,17,18 B 子進程結束信號 

SIGCONT 19,18,25 進程繼續(曾被停止的進程) 

SIGSTOP 17,19,23 DEF 終止進程 

SIGTSTP 18,20,24 D 控制終端(tty)上按下停止鍵 

SIGTTIN 21,21,26 D 后臺進程企圖從控制終端讀 

SIGTTOU 22,22,27 D 后臺進程企圖從控制終端寫

下面的信號沒在POSIX.1中列出,而在SUSv2列出

信號 值 處理動作 發出信號的原因 

-------------------------------------------------------------------- 

SIGBUS 10,7,10 C 總線錯誤(錯誤的內存訪問) 

SIGPOLL A Sys V定義的Pollable事件,與SIGIO同義 

SIGPROF 27,27,29 A Profiling定時器到 

SIGSYS 12,-,12 C 無效的系統調用 (SVID) 

SIGTRAP 5 C 跟蹤/斷點捕獲 

SIGURG 16,23,21 B Socket出現緊急條件(4.2 BSD) 

SIGVTALRM 26,26,28 A 實際時間報警時鐘信號(4.2 BSD) 

SIGXCPU 24,24,30 C 超出設定的CPU時間限制(4.2 BSD) 

SIGXFSZ 25,25,31 C 超出設定的文件大小限制(4.2 BSD)

(對于SIGSYS,SIGXCPU,SIGXFSZ,以及某些機器體系結構下的SIGBUS,Linux缺省的動作是A (terminate),SUSv2 是C (terminate and dump core))。

下面是其它的一些信號

信號 值 處理動作 發出信號的原因 

---------------------------------------------------------------------- 

SIGIOT 6 C IO捕獲指令,與SIGABRT同義 

SIGEMT 7,-,7 

SIGSTKFLT -,16,- A 協處理器堆棧錯誤 

SIGIO 23,29,22 A 某I/O操作現在可以進行了(4.2 BSD) 

SIGCLD -,-,18 A 與SIGCHLD同義 

SIGPWR 29,30,19 A 電源故障(System V) 

SIGINFO 29,-,- A 與SIGPWR同義 

SIGLOST -,-,- A 文件鎖丟失 

SIGWINCH 28,28,20 B 窗口大小改變(4.3 BSD, Sun) 

SIGUNUSED -,31,- A 未使用的信號(will be SIGSYS)

(在這里,- 表示信號沒有實現;有三個值給出的含義為,第一個值通常在Alpha和Sparc上有效,中間的值對應i386和ppc以及sh,最后一個值對應mips。信號29在Alpha上為SIGINFO / SIGPWR ,在Sparc上為SIGLOST。)

處理動作一項中的字母含義如下 

A 缺省的動作是終止進程 

B 缺省的動作是忽略此信號 

C 缺省的動作是終止進程并進行內核映像轉儲(dump core) 

D 缺省的動作是停止進程 

E 信號不能被捕獲 

F 信號不能被忽略

上面介紹的信號是常見系統所支持的。以表格的形式介紹了各種信號的名稱、作用及其在默認情況下的處理動作。各種默認處理動作的含義是:終止程序是指進程退出;忽略該信號是將該信號丟棄,不做處理;停止程序是指程序掛起,進入停止狀況以后還能重新進行下去,一般是在調試的過程中(例如ptrace系統調用);內核映像轉儲是指將進程數據在內存的映像和進程在內核結構中存儲的部分內容以一定格式轉儲到文件系統,并且進程退出執行,這樣做的好處是為程序員提供了方便,使得他們可以得到進程當時執行時的數據值,允許他們確定轉儲的原因,并且可以調試他們的程序。

注意 信號SIGKILL和SIGSTOP既不能被捕捉,也不能被忽略。信號SIGIOT與SIGABRT是一個信號。可以看出,同一個信號在不同的系統中值可能不一樣,所以建議最好使用為信號定義的名字,而不要直接使用信號的值。

二、信 號 機 制

上一節中介紹了信號的基本概念,在這一節中,我們將介紹內核如何實現信號機制。即內核如何向一個進程發送信號、進程如何接收一個信號、進程怎樣控制自己對信號的反應、內核在什么時機處理和怎樣處理進程收到的信號。還要介紹一下setjmp和longjmp在信號中起到的作用。

1、內核對信號的基本處理方法

內核給一個進程發送軟中斷信號的方法,是在進程所在的進程表項的信號域設置對應于該信號的位。這里要補充的是,如果信號發送給一個正在睡眠的進程,那么要看該進程進入睡眠的優先級,如果進程睡眠在可被中斷的優先級上,則喚醒進程;否則僅設置進程表中信號域相應的位,而不喚醒進程。這一點比較重要,因為進程檢查是否收到信號的時機是:一個進程在即將從內核態返回到用戶態時;或者,在一個進程要進入或離開一個適當的低調度優先級睡眠狀態時。

內核處理一個進程收到的信號的時機是在一個進程從內核態返回用戶態時。所以,當一個進程在內核態下運行時,軟中斷信號并不立即起作用,要等到將返回用戶態時才處理。進程只有處理完信號才會返回用戶態,進程在用戶態下不會有未處理完的信號。

內核處理一個進程收到的軟中斷信號是在該進程的上下文中,因此,進程必須處于運行狀態。前面介紹概念的時候講過,處理信號有三種類型:進程接收到信號后退出;進程忽略該信號;進程收到信號后執行用戶設定用系統調用signal的函數。當進程接收到一個它忽略的信號時,進程丟棄該信號,就象沒有收到該信號似的繼續運行。如果進程收到一個要捕捉的信號,那么進程從內核態返回用戶態時執行用戶定義的函數。而且執行用戶定義的函數的方法很巧妙,內核是在用戶棧上創建一個新的層,該層中將返回地址的值設置成用戶定義的處理函數的地址,這樣進程從內核返回彈出棧頂時就返回到用戶定義的函數處,從函數返回再彈出棧頂時,才返回原先進入內核的地方。這樣做的原因是用戶定義的處理函數不能且不允許在內核態下執行(如果用戶定義的函數在內核態下運行的話,用戶就可以獲得任何權限)。

在信號的處理方法中有幾點特別要引起注意。第一,在一些系統中,當一個進程處理完中斷信號返回用戶態之前,內核清除用戶區中設定的對該信號的處理例程的地址,即下一次進程對該信號的處理方法又改為默認值,除非在下一次信號到來之前再次使用signal系統調用。這可能會使得進程在調用signal之前又得到該信號而導致退出。在BSD中,內核不再清除該地址。但不清除該地址可能使得進程因為過多過快的得到某個信號而導致堆棧溢出。為了避免出現上述情況。在BSD系統中,內核模擬了對硬件中斷的處理方法,即在處理某個中斷時,阻止接收新的該類中斷。

第二個要引起注意的是,如果要捕捉的信號發生于進程正在一個系統調用中時,并且該進程睡眠在可中斷的優先級上,這時該信號引起進程作一次longjmp,跳出睡眠狀態,返回用戶態并執行信號處理例程。當從信號處理例程返回時,進程就象從系統調用返回一樣,但返回了一個錯誤代碼,指出該次系統調用曾經被中斷。這要注意的是,BSD系統中內核可以自動地重新開始系統調用。

第三個要注意的地方:若進程睡眠在可中斷的優先級上,則當它收到一個要忽略的信號時,該進程被喚醒,但不做longjmp,一般是繼續睡眠。但用戶感覺不到進程曾經被喚醒,而是象沒有發生過該信號一樣。

第四個要注意的地方:內核對子進程終止(SIGCLD)信號的處理方法與其他信號有所區別。當進程檢查出收到了一個子進程終止的信號時,缺省情況下,該進程就象沒有收到該信號似的,如果父進程執行了系統調用wait,進程將從系統調用wait中醒來并返回wait調用,執行一系列wait調用的后續操作(找出僵死的子進程,釋放子進程的進程表項),然后從wait中返回。SIGCLD信號的作用是喚醒一個睡眠在可被中斷優先級上的進程。如果該進程捕捉了這個信號,就象普通信號處理一樣轉到處理例程。如果進程忽略該信號,那么系統調用wait的動作就有所不同,因為SIGCLD的作用僅僅是喚醒一個睡眠在可被中斷優先級上的進程,那么執行wait調用的父進程被喚醒繼續執行wait調用的后續操作,然后等待其他的子進程。

如果一個進程調用signal系統調用,并設置了SIGCLD的處理方法,并且該進程有子進程處于僵死狀態,則內核將向該進程發一個SIGCLD信號。

2、setjmp和longjmp的作用

前面在介紹信號處理機制時,多次提到了setjmp和longjmp,但沒有仔細說明它們的作用和實現方法。這里就此作一個簡單的介紹。

在介紹信號的時候,我們看到多個地方要求進程在檢查收到信號后,從原來的系統調用中直接返回,而不是等到該調用完成。這種進程突然改變其上下文的情況,就是使用setjmp和longjmp的結果。setjmp將保存的上下文存入用戶區,并繼續在舊的上下文中執行。這就是說,進程執行一個系統調用,當因為資源或其他原因要去睡眠時,內核為進程作了一次setjmp,如果在睡眠中被信號喚醒,進程不能再進入睡眠時,內核為進程調用longjmp,該操作是內核為進程將原先setjmp調用保存在進程用戶區的上下文恢復成現在的上下文,這樣就使得進程可以恢復等待資源前的狀態,而且內核為setjmp返回1,使得進程知道該次系統調用失敗。這就是它們的作用。

三、有關信號的系統調用

前面兩節已經介紹了有關信號的大部分知識。這一節我們來了解一下這些系統調用。其中,系統調用signal是進程用來設定某個信號的處理方法,系統調用kill是用來發送信號給指定進程的。這兩個調用可以形成信號的基本操作。后兩個調用pause和alarm是通過信號實現的進程暫停和定時器,調用alarm是通過信號通知進程定時器到時。所以在這里,我們還要介紹這兩個調用。

1、signal 系統調用

系統調用signal用來設定某個信號的處理方法。該調用聲明的格式如下:    void (*signal(int signum, void (*handler)(int)))(int); 在使用該調用的進程中加入以下頭文件:    #include <signal.h>

上述聲明格式比較復雜,如果不清楚如何使用,也可以通過下面這種類型定義的格式來使用(POSIX的定義):    typedef void (*sighandler_t)(int);    sighandler_t signal(int signum, sighandler_t handler); 但這種格式在不同的系統中有不同的類型定義,所以要使用這種格式,最好還是參考一下聯機手冊。

在調用中,參數signum指出要設置處理方法的信號。第二個參數handler是一個處理函數,或者是   SIG_IGN:忽略參數signum所指的信號。   SIG_DFL:恢復參數signum所指信號的處理方法為默認值。

傳遞給信號處理例程的整數參數是信號值,這樣可以使得一個信號處理例程處理多個信號。系統調用signal返回值是指定信號signum前一次的處理例程或者錯誤時返回錯誤代碼SIG_ERR。下面來看一個簡單的例子:

     #include <signal.h> 

#include <unistd.h> 

#include <stdio.h> 

void sigroutine(int dunno) { /* 信號處理例程,其中dunno將會得到信號的值 */ 

switch (dunno) { 

case 1: 

printf("Get a signal -- SIGHUP "); 

break; 

case 2: 

printf("Get a signal -- SIGINT "); 

break; 

case 3: 

printf("Get a signal -- SIGQU99 "); 

break; 

return; 

int main() { 

printf("process id is %d ",getpid()); 

signal(SIGHUP, sigroutine); //* 下面設置三個信號的處理方法 

signal(SIGINT, sigroutine); 

signal(SIGQU99v, sigroutine); 

for (;;) ; 

}

其中信號SIGINT由按下Ctrl-C發出,信號SIGQU99v由按下Ctrl-發出。該程序執行的結果如下:

     localhost:~$ ./sig_test 

process id is 463 

Get a signal -SIGINT //按下Ctrl-C得到的結果 

Get a signal -SIGQU99v //按下Ctrl-得到的結果 

//按下Ctrl-z將進程置于后臺 

[1]+ Stopped ./sig_test 

localhost:~$ bg 

[1]+ ./sig_test & 

localhost:~$ kill -HUP 463 //向進程發送SIGHUP信號 

localhost:~$ Get a signal – SIGHUP 

kill -9 463 //向進程發送SIGKILL信號,終止進程 

localhost:~$

2、kill 系統調用

系統調用kill用來向進程發送一個信號。該調用聲明的格式如下:   int kill(pid_t pid, int sig);   在使用該調用的進程中加入以下頭文件:   #include <sys/types.h>   #include <signal.h>

該系統調用可以用來向任何進程或進程組發送任何信號。如果參數pid是正數,那么該調用將信號sig發送到進程號為pid的進程。如果pid等于0,那么信號sig將發送給當前進程所屬進程組里的所有進程。如果參數pid等于-1,信號sig將發送給除了進程1和自身以外的所有進程。如果參數pid小于-1,信號sig將發送給屬于進程組-pid的所有進程。如果參數sig為0,將不發送信號。該調用執行成功時,返回值為0;錯誤時,返回-1,并設置相應的錯誤代碼errno。下面是一些可能返回的錯誤代碼:    EINVAL:指定的信號sig無效。    ESRCH:參數pid指定的進程或進程組不存在。注意,在進程表項中存在的進程,可能是一個還沒有被wait收回,但已經終止執行的僵死進程。    EPERM:進程沒有權力將這個信號發送到指定接收信號的進程。因為,一個進程被允許將信號發送到進程pid時,必須擁有root權力,或者是發出調用的進程的UID或EUID與指定接收的進程的UID或保存用戶ID(savedset-user-ID)相同。如果參數pid小于-1,即該信號發送給一個組,則該錯誤表示組中有成員進程不能接收該信號。

3、pause系統調用

系統調用pause的作用是等待一個信號。該調用的聲明格式如下:    int pause(void); 在使用該調用的進程中加入以下頭文件:    #include <unistd.h>

該調用使得發出調用的進程進入睡眠,直到接收到一個信號為止。該調用總是返回-1,并設置錯誤代碼為EINTR(接收到一個信號)。下面是一個簡單的范例:

#include <unistd.h>   #include <stdio.h>   #include <signal.h>   void sigroutine(int unused) 

{      printf("Catch a signal SIGINT ");   }

int main() 

{     signal(SIGINT, sigroutine);     pause();     printf("receive a signal ");   }

在這個例子中,程序開始執行,就象進入了死循環一樣,這是因為進程正在等待信號,當我們按下Ctrl-C時,信號被捕捉,并且使得pause退出等待狀態。

4、alarm和 setitimer系統調用

系統調用alarm的功能是設置一個定時器,當定時器計時到達時,將發出一個信號給進程。該調用的聲明格式如下:    unsigned int alarm(unsigned int seconds); 在使用該調用的進程中加入以下頭文件:    #include <unistd.h>

系統調用alarm安排內核為調用進程在指定的seconds秒后發出一個SIGALRM的信號。如果指定的參數seconds為0,則不再發送SIGALRM信號。后一次設定將取消前一次的設定。該調用返回值為上次定時調用到發送之間剩余的時間,或者因為沒有前一次定時調用而返回0。

注意,在使用時,alarm只設定為發送一次信號,如果要多次發送,就要多次使用alarm調用。

對于alarm,這里不再舉例?,F在的系統中很多程序不再使用alarm調用,而是使用setitimer調用來設置定時器,用getitimer來得到定時器的狀態,這兩個調用的聲明格式如下:

int getitimer(int which, struct itimerval *value);   int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue); 在使用這兩個調用的進程中加入以下頭文件:   #include <sys/time.h>

該系統調用給進程提供了三個定時器,它們各自有其獨有的計時域,當其中任何一個到達,就發送一個相應的信號給進程,并使得計時器重新開始。三個計時器由參數which指定,如下所示: TIMER_REAL:按實際時間計時,計時到達將給進程發送SIGALRM信號。 99vIMER_VIRTUAL:僅當進程執行時才進行計時。計時到達將發送SIGVTALRM信號給進程。 99vIMER_PROF:當進程執行時和系統為該進程執行動作時都計時。與99vIMER_VIR-TUAL是一對,該定時器經常用來統計進程在用戶態和內核態花費的時間。計時到達將發送SIGPROF信號給進程。

定時器中的參數value用來指明定時器的時間,其結構如下: struct itimerval { struct timeval it_interval; /* 下一次的取值 */ struct timeval it_value; /* 本次的設定值 */ };

該結構中timeval結構定義如下: struct timeval { long tv_sec; /* 秒 */ long tv_usec; /* 微秒,1秒 = 1000000 微秒*/ };

在setitimer調用中,參數ovalue如果不為空,則其中保留的是上次調用設定的值。定時器將it_value遞減到0時,產生一個信號,并將it_value的值設定為it_interval的值,然后重新開始計時,如此往復。當it_value設定為0時,計時器停止,或者當它計時到期,而it_interval為0時停止。調用成功時,返回0;錯誤時,返回-1,并設置相應的錯誤代碼errno: EFAULT:參數value或ovalue是無效的指針。 EINVAL:參數which不是99vIMER_REAL、99vIMER_VIRT或99vIMER_PROF中的一個。

下面是關于setitimer調用的一個簡單示范,在該例子中,每隔一秒發出一個SIGALRM,每隔0.5秒發出一個SIGVTALRM信號:

#include <signal.h> #include <unistd.h> #include <stdio.h> #include <sys/time.h> int sec; void sigroutine(int signo) { switch (signo) { case SIGALRM: printf("Catch a signal -- SIGALRM "); break; case SIGVTALRM: printf("Catch a signal -- SIGVTALRM "); break; } return; } int main() { struct itimerval value,ovalue,value2; sec = 5; printf("process id is %d ",getpid()); signal(SIGALRM, sigroutine); signal(SIGVTALRM, sigroutine); value.it_value.tv_sec = 1; value.it_value.tv_usec = 0; value.it_interval.tv_sec = 1; value.it_interval.tv_usec = 0; setitimer(99vIMER_REAL, &value, &ovalue);

value2.it_value.tv_sec = 0; value2.it_value.tv_usec = 500000; value2.it_interval.tv_sec = 0; value2.it_interval.tv_usec = 500000; setitimer(99vIMER_VIRTUAL, &value2, &ovalue);

for (;;) ; }

該例子的屏幕拷貝如下:

localhost:~$ ./timer_test process id is 579 Catch a signal – SIGVTALRM Catch a signal – SIGALRM Catch a signal – SIGVTALRM Catch a signal – SIGVTALRM Catch a signal – SIGALRM Catch a signal –GVTALRM


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久久久久久免费精品| 精品露脸国产偷人在视频| 久久香蕉国产线看观看av| 国产成人精品视| 91国产中文字幕| 日韩免费在线免费观看| 日韩在线观看视频免费| 成人在线免费观看视视频| 国产va免费精品高清在线观看| 成人激情视频在线观看| 日韩av在线不卡| 国产盗摄xxxx视频xxx69| 久久色精品视频| 亚洲国产精品成人一区二区| 亚洲欧美国产精品专区久久| 亚洲人成自拍网站| 亚洲一区二区日本| 亚洲成人a级网| 国产精品亚洲视频在线观看| 亚洲美腿欧美激情另类| 欧美性生活大片免费观看网址| 亚洲国产欧美精品| 国内精品小视频| 91视频国产高清| 日韩中文字幕免费视频| 欧洲中文字幕国产精品| 国产精品久久久一区| 国产欧美最新羞羞视频在线观看| 日韩欧美在线视频免费观看| 欧美日韩ab片| 成人国产精品色哟哟| 中文字幕少妇一区二区三区| 91精品91久久久久久| 亚洲mm色国产网站| 亚洲а∨天堂久久精品喷水| 国产精品久久久久久久一区探花| 欧美激情一区二区久久久| 精品呦交小u女在线| 在线精品视频视频中文字幕| 国内精品模特av私拍在线观看| 欧美在线www| 色综合91久久精品中文字幕| 这里只有精品视频| 91精品在线播放| 成人深夜直播免费观看| 2025国产精品视频| 欧美精品福利在线| 精品少妇v888av| 国产日韩欧美视频在线| 日本a级片电影一区二区| 午夜精品福利视频| 中文字幕最新精品| 亚洲最大av网| 欧美成人精品一区二区| 午夜精品一区二区三区在线视| 欧美成人国产va精品日本一级| 国产999视频| 欧美日韩性生活视频| 亚洲在线免费视频| 国产丝袜高跟一区| 欧美日韩在线视频一区| 国产精品综合久久久| 亚洲精品丝袜日韩| 国产精品18久久久久久麻辣| 久久91亚洲人成电影网站| 热re99久久精品国产66热| 中日韩美女免费视频网站在线观看| 亚洲天堂男人天堂女人天堂| 国产精品第8页| 欧美一级视频免费在线观看| 亚洲第一天堂av| 91久久综合亚洲鲁鲁五月天| 成人免费午夜电影| 影音先锋日韩有码| 黑人巨大精品欧美一区二区| 国产激情999| 国产精品自拍视频| 久久久久国产精品一区| 少妇高潮久久久久久潘金莲| 久久久人成影片一区二区三区观看| 欧美色欧美亚洲高清在线视频| 精品偷拍各种wc美女嘘嘘| 欧美日本亚洲视频| 久久久免费电影| 26uuu另类亚洲欧美日本老年| 北条麻妃99精品青青久久| 亚洲欧洲偷拍精品| 538国产精品一区二区在线| 欧美日韩国产中文字幕| 91精品国产高清久久久久久91| 亚洲一区二区三区香蕉| 亚洲一级黄色片| 91麻豆国产语对白在线观看| 久久久极品av| 久久久久久午夜| 成人欧美一区二区三区在线湿哒哒| 日韩经典第一页| 97超碰蝌蚪网人人做人人爽| 久久这里有精品视频| 欧美日韩第一页| 亚洲欧洲在线看| 久久99亚洲精品| 色综合久久精品亚洲国产| 欧美一区二区三区免费观看| 国产精品扒开腿做爽爽爽的视频| 久久激情五月丁香伊人| 91深夜福利视频| 欧美性极品xxxx娇小| 国产精品成人va在线观看| 亚洲va电影大全| 欧美理论在线观看| xxxx欧美18另类的高清| 亚洲肉体裸体xxxx137| 中文字幕日韩精品在线观看| 91国偷自产一区二区三区的观看方式| 久久久成人精品视频| 久久中文精品视频| 欧美亚洲另类视频| 久久91亚洲精品中文字幕| 啊v视频在线一区二区三区| 九九精品在线观看| 国产亚洲人成a一在线v站| 夜夜躁日日躁狠狠久久88av| 久久99久国产精品黄毛片入口| 国产狼人综合免费视频| 日韩视频永久免费观看| 91av在线免费观看| 亚洲高清久久网| 国产一区二区三区在线观看网站| 国产一区二区三区高清在线观看| 97久久伊人激情网| 国产精品视频精品| 亚洲aa中文字幕| 午夜欧美不卡精品aaaaa| 国产欧美日韩精品在线观看| 日本精品久久中文字幕佐佐木| 精品视频www| 欧美激情在线播放| 中文字幕av一区二区| 不用播放器成人网| 国产精品国语对白| 欧美激情网友自拍| 日韩精品中文字幕在线播放| 久久不射热爱视频精品| 精品福利在线看| 欧美色播在线播放| 欧美日韩福利在线观看| 蜜月aⅴ免费一区二区三区| 69视频在线播放| 欧美大肥婆大肥bbbbb| 国产日韩欧美一二三区| 亚洲第一在线视频| 欧美丰满少妇xxxxx做受| 日日狠狠久久偷偷四色综合免费| 丰满岳妇乱一区二区三区| 久久综合色影院| 成人免费观看49www在线观看| 伊人久久久久久久久久久| 91av视频导航| 日韩在线观看免费全集电视剧网站| 久久亚洲精品成人| 亚洲欧美一区二区三区四区| 中国人与牲禽动交精品| 欧美理论电影在线观看|