LINUX編程常用的函數


/*******************************************************************

**2007年04月11日記錄於ccidnet的BLOG, 2010年5月20日因BLOG搬家轉移至此

********************************************************************/

 

總共分為12部分分別是:進程、線程、消息隊列、信號量集、共享內存、PGSQL編程、MYSQL編程、網絡編程、文件訪問、標准I/O、系統數據文件和信息、信號
          (一)     進程
1.     進程ID為0的進程通常是調度進程,常常被稱為交換進程
進程ID為1的進程通常是init進程,在自舉過程結束時由內核調用
進程ID為2的進程頁守護進程,負責支持虛擬存儲系統的分頁操作
2.     pid_t getpid( void ); 返回值:調用進程的進程ID     #include <unistd.h>
3.     pid_t getppid( void ); 返回值:調用進程的父進程ID  
4.     uid_t getuid( void ); 返回值:調用進程的實際用戶ID
5.     uid_t geteuid( void ); 返回值:調用進程的有效用戶ID
6.     gid_t getgid( void ); 返回值:調用進程的實際組ID
7.     gid_t getegid( void ); 返回值:調用進程的有效組ID
8.     pid_t fork( void );創建子進程,返回值:子進程返回0,父進程返回子進程ID,出錯-1
9.     #include<sys/wait.h> pid_t wait(int *statloc);//statloc 保存進程終止狀態的指針
10.     #include<sys/wait.h>pid_t waitpid(pid_t pid,int *statloc,int options);
pid ==-1 等待任一子進程
pid >0 等待其子進程ID與pid相等的子進程
pid == 0 等待其組ID等於調用進程組ID的任一子進程
pid <-1 等待其組ID等於pid絕對值的任一子進程
options:
WCONTINUED 若實現支持作業控制,那么由pid指定的任一子進程在暫停后已經繼續,但其狀態尚未報告,則返回其狀態
WNOHANG 若由pid指定的子進程並不是立即可用的,則waitpid阻塞,此時其返回0
WUNTRACED 若實現支持作業控制,而由pid指定的任一子進程已處於暫停狀態,並且其狀態自暫停以來還未報告過,則返回其狀態
11.#include<unistd.h> int setuid(uid_t uid); 設置實際實際用戶ID和有效用戶ID;
int setgid(gid_t gid); 設置實際組ID和有效組ID;成功返回0,錯誤-1
12.#include<stdlib.h>int system(const char *cmdstring)
system返回值如下            
-1出現錯誤  
    0調用成功但是沒有出現子進程  
    >0   成功退出的子進程的id


            (二)線程


1. #include<thread.h> int pthread_equal(pthread_t tid1, pthread_t tid2);
//相等返回非0,否則返回0
2. pthread_t pthread_self(void);返回調用線程的ID
3. int pthread_create(pthread_t *restrict tidp,
  const pthread_attr_t *restrict attr, void *(*start_rtn)(void), void *restrict arg) ;
創建線程:成功返回0,否則返回錯誤編號
4. void pthread_exit(void *rval_ptr);//終止線程
5. int pthread_join(pthread_t thread, void **rval_ptr);
//自動線程置於分離狀態,以恢復資源。成功返回0,否則返回錯誤編號
6. int pthread_cancel(pthread_t tid);
//請求取消同一進程中的其他線程;成功返回0,否則返回錯誤編號
7. void pthread_cleanup_push(void (*rtn)(void *), void *arg);
    //建立線程清理處理程序
8. void pthread_cleanup_pop(int execute);//調用建立的清理處理程序
9. int pthread_detach(pthread_t tid);//使線程進入分離狀態,已分離也不出錯
10.int pthread_mutex_init(pthread_mutex_t *restrict mutex,
  const pthread_nutexattr_t *restrict attr)//初始化互斥量;成功0,失敗返回錯誤編號
11.int pthread_mutex_destroy(pthread_mutex_t *mutex);
//若有調用malloc動態分配內存則用該函數釋放;成功0,失敗返回錯誤編號
12.int pthread_mutex_lock(pthread_mutex_t *mutex);//鎖住互斥量
  int pthread_mutex_trylock(pthread_mutex_t *mutex);//嘗試上鎖
  int pthread_mutex_unlock(pthread_mutex_t *mutex);//解鎖
  成功返回0,否則返回錯誤編號
13.int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr)//初始化讀寫鎖
  int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);//釋放資源,在釋放內存之前使用
成功返回0,否則返回錯誤編號
14.int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);//在讀模式下鎖定讀寫鎖
  int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);//在寫模式下鎖定讀寫鎖
  int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);//鎖住讀寫鎖
15.int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);//嘗試在讀模式下鎖定讀寫鎖
  int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);//嘗試在寫模式下鎖定讀寫鎖
成功返回0,否則返回錯誤編號
16.int pthread_cond_init(pthread_cond_t *restrict cond, pthread_condattr_t * restrict attr)
//初始化條件變量
  int pthread_cond_destroy(pthread_cond_t *cond);//去除初始化條件變量
成功返回0,否則返回錯誤編號
17.int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex)
  int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex,
  const struct timespec *restrict timeout);
  //等待條件變為真,如果在給定的時間內條件不能滿足,那么會生成一個代表出錯碼的返回變量 ;成功返回0,錯誤返回錯誤編號
18.int pthread_cond_signal(pthread_cond_t *cond);//喚醒等待該條件的某個線程
  int pthread_cond_broadcast(pthread_cond_t *cond)//喚醒等待該條件的所有線程
19.int pthread_attr_init(pthread_attr_t *attr);//初始化線程屬性
  int pthread_attr_destroy(pthread_attr_t *attr);//釋放內存空間(動態分配時調用)
成功返回0,否則返回錯誤編號
20.int pthread_attr_getdetachstate(const pthread_attr_t *restrict attr, int *detachstate);
//獲取線程的分離狀態
  int pthread_attr_setdetachstate(const pthread_attr_t *restrict attr, int detachstate);
  //設置分離狀態 PTHREAD_CREATE_DETACHED:以分離狀態啟動線程
  PTHREAD_CREATE_JOINABLE:正常啟動線程,應用程序可以獲取線程的終止狀態
    成功返回0,否則返回錯誤編號
21.int pthread_attr_getstack(const pthread_attr_t *restrict attr,void **restrict stackaddr, size_t *restrict stacksize);//獲取線程的棧位置
int pthread_attr_setstack(const pthread_attr_t *attr, void *stackaddr, size_t *stacksize)
//設置新建線程的棧位置 ;成功返回0,否則返回錯誤編號
              (三)消息隊列
1.每個隊列都有一個msqid_ds結構與之相關聯:
    struct msqid_ds{
      struct ipc_perm msg_perm;
          msgqnum_t msg_qnum; //消息的數量
      msglen_t msg_qbytes; //最大消息的長度
      pid_t msg_lspid;   //最后一個發送到消息隊列的進程ID
      pid_t msg_lrpid;   //最后一個讀取消息的進程ID
      time_t msg_stime;   //最后一次發送到消息隊列的時間
      time_t msg_rtime;   //最后一次讀取消息的時間
      time_t msg_ctime; //最后一次改變的時間
      。
      。
      。
  };
  struct ipc_perm{
      uid_t uid;//擁有者有效的用戶ID
      gid_t gid;//擁有者有效的組ID
      uid_t cuid;//創建者有效的用戶ID
      uid_t cgid;//創建者有效的組ID
      mode_t mode; //權限
      。
      。
  }
2.#include <sys/msg.h> int msgget(key_t key, int flag);
//打開一個現存的隊列或創建一個新隊列;成功返回0,出錯返回-1
3.int msgctl(int msqid, int cmd, struct msqid_ds *buf);//對消息隊列執行多種操作
cmd 可選:
IPC_STAT 取此消息隊列的msqid_ds結構,並將它放在buf指向的結構
  IPC_SET:按由buf指向結構中的值,設置與此隊列相關結構中的下列四個字段:msg_perm.uid,msg_perm.gid,msg_perm.mode和msg_qbytes.此命令只有下列兩種進程才能執行(1)其有效用戶ID等於msg_perm.cuid或msg_perm.uid;(2)具有超級用戶特權的進程
  IPC_RMID:從系統中刪除消息隊列以及仍在該隊列中的所有數據。
成功返回0,失敗返回-1
4.int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag)//發送消息到消息隊列中
成功返回0, 不成功返回-1並設置errno,錯誤碼:
EACCES   對調用程序來說,調用被否定
EAGAIN   操作會阻塞進程,但(msgflg & IPC_NOWAIT) != 0
EIDRM     msqid已經從系統中刪除了
EINTR     函數被信號中斷
EINVAL     參數msqid無效,消息類型<1,或者msgsz越界了
flag可以指定為IPC_NOWAIT 則不會阻塞直接返回EAGAIN
注:參數msgp指向用戶定義的緩沖區,他是如下的結構
struct mymsg
{
long mtypes;     消息類型
char *mtext;   消息文本
}mymsg_t
5.ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);//讀取消息
成功則返回消息的數據部分的長度,出錯則返回-1
type: type==0返回隊列中的第一個消息
  type>0 返回隊列中消息類型為type的第一個消息
  type<0返回隊列中消息類型值小於或等於type絕對值的消息(多個取類型值最小的)
        (四) 信號量
1. 內核為每個信號量集合設置了一個semid_ds結構:
  struct demid_ds{
    struct ipc_perm sem_perm;
    unsigned short sem_nsems; //信號量的個數
    time_t sem_otime; //上一次semop的時間
    time_t sem_ctime;//上一次change的時間
    。
    。
 };
2#include<sys/sem.h>. int semget(key_t key, int nsems, int flag);//創建信號量
成功返回一個對應於信號量集標識符的非負整數,不成功返回-1並設置errno,錯誤碼:
EACCES   存在key的信號量,但沒有授予權限
EEXIST   存在key的信號量,但是
    ( (semflg & IPC_CREATE) && (semflg & IPC_EXCL) ) != 0
EINVAL   nsems <= 0或者大於系統的限制,或者nsems與信號量集的大小不符
ENOENT   不存在key的信號量,而且(semflg & IPC_CTEATE) == 0
ENOSPC   要超出系統范圍內對信號量的限制了
功能:
函數返回與參數key相關的信號量集標識符。
如果鍵值為IPC_PRIVATE,或者semflg&IPC_CREAT非零且沒有信號量集或標識符關聯於key,那么函數就創建標識符及與之相關的信號量集。
參數nsems指定了集合中信號量元素的個數,可用0到nsems-1的整數來引用信號量集合中的單個信號量元素。
參數semflg指定信號量集的優先級,權限的設置與文件權限設置相同,並可以通過semclt來修改權限值,在使用信號量元素之前,應該用semctl對其進行初始化。
注意:
函數如果試圖創建一個已經存在的信號量集,如果semflg值中包含了IPC_CREAT和IPC_EXCL,則失敗並設置errno為EEXIST;否則返回一個已經存在的信號量集的句柄。
3.int semctl(int semid, int semnum, int cmd, …);//信號量控制
如果成功返回一個非負的值,具體返回值取決於cmd的值。
cmd值GETVAL、GETPID、GETNCNT和GETZCNT使semctl返回與cmd相關的值。
如果成功,所有其它的cmd返回0。
如果不成功semctl返回-1並設置errno,必須檢測的錯誤碼:
EACCES   對調用程序來說,操作被否定
EINVAL   semid的值或cmd的值無效,或者semnum的值為負或者太大
EPERM   cmd的值為IPC_RMID或IPC_SET,且調用程序沒有所要求的特權
ERANGE cmd為SETVAL或SETALL,而且要設置的值越界了
功能:
函數semctl為信號量集semid的semnum個元素提供了控制操作。參數cmd指定了操作類型,第四個參數arg可選,是否使用取決於cmd的值。
cmd的值:
GETALL   在arg.array中返回信號量集的值
GETVAL   返回一個特定信號量元素的值
GETPID   返回最后一個操縱元素的進程的進程ID
GETNCNT   返回等待元素增加的進程的個數
GETZCNT   返回等待元素變成零的進程的個數
IPC_RMID   刪除semid標識的信號量集
IPC_SET   設置來之arg.buf的信號量集的權限
IPC_STAT   將信號量集semid的semid_ds結構成員拷貝到arg.buf中
SETALL   用arg.array來設置信號量集的值
SETVAL   將一個特定的信號量元素的值設定為arg.val
其中有幾個命令需要一個arg參數來讀取或存儲結構
參數arg的類型為union semun,必須要定義這個類型的數據:
union semum
{
int       val
struct semid_ds   *buf;
unsigned short   *array;
}arg;
4. int semop(int semid, struct sembuf *sops, size_t nsops);//信號量的操作
成功返回0,不成功返回-1並設置errno,必須檢測的錯誤碼:
E2BIG   nsops的值太大
EACCES 對調用程序來說,操作被否定
EAGAIN 操作會阻塞進程但是(sem_flg&IPC_NOWAIT)!= 0
EFBIG   某一個sops條目的sem_num值小於0,或大於信號量集中元素的數目
EIDRM   信號量集標識符semid已經從系統中刪除了
EINTR   semop被信號中斷
EINVAL   semid的值無效,或者請求做SEM_UNDO操作的獨立信號量集的數量
超出了限制
ENOSPC 已經超出了對請求SEM_UNDO的進程數的限制
ERANGE 操作會造成semval或semadj值得溢出
功能:
semop函數在單個信號量集上原子的執行sops數組中指定的所有操作。如果其中任何一個單獨的元素操作會使進程阻塞,進程就會阻塞而不會執行任何操作。
說明:
結構struct sembuf指定了一個信號量元素操作,包含下列成員。
short sem_num   信號量元素的數量(信號量元素在信號量集中的序號)
short sem_op   要執行的特定元素操作
short sem_flg   為操作指定選項的標志符
sem_op如果是大於零的整數,semop就將這個值與sem_num號信號量元素相加,並喚醒所有等待該元素增加的進程。
  如果為零,且信號量元素值不為0,semop就會阻塞調用進程(進程在等待0),並增加等待那個信號量元素值變為零的進程計數。
  如果sem_op為負數,那么,如果結果不能為負的話,semop就將sem_op值添加到相應的信號量元素值上去。如果操作可能會使元素值為負,semop就將進程阻塞在使信號量元素值增加的事件上。如果結果值為0,那么semop就喚醒等待0的進程。
              (五)共享內存
1.內核為每個共享內存設置了一個 shmid_ds結構,它的成員如下:
Struct shmid_ds{
struct ipc_perm shm_perm;   //操作權限結構
size_t     shm_segsz;   //用字節表示的段的長度
pid_t     shm_lpid;   //最后一個操作的進程ID
pid_t     shm_cpid;   //創建者的進程ID
shmatt_t   shm_nattch   //當前連接的進程數量
time_t     shm_atime;   //最后一次調用shmat的時間
time_t     shm_dtime;   //最后一次調用shmdt的時間
time_t     shm_ctime;   //最后一次調用shmtl的時間


}
2.include<sys/shm.h> int shmget(key_t key, size_t size, int flag);//創建共享內存
size指的是共享內存段的格式n*sizeof(int)則共享內存段將用來存儲int類型數據n個
成功返回一個對應於共享內存段標識符的非負整數,不成功返回-1並設置errno,錯誤碼:
EACCES   key的共享標識符存在,但沒有授予相關的權限
EEXIST   key的共享標識符存在,但((shmflg&IPC_CREAT) && (shmflg&IPC_EXCL)!=0
EINVAL   要創建共享內存段,但size是無效的
EINVAL   沒有共享內存段要創建,但size與系統設置的限制或與key所代表的共享段的長度不相符
ENOENT   key的共享內存表示符不存在,但(shmflg&IPC_CREAT)== 0
ENOMEM   沒有足夠的內存空間來創建指定的共享內存段
ENOSPC   要超出系統范圍內對共享標識符的限制了
功能:
shmget函數返回一個與參數key相關的共享內存段標識符。
如果鍵位IPC_CREAT或者shmflg&IPC_CREAT非零,而且沒有共享內存段或標識符與key相關聯,函數就創建這個段,共享內存段被初始化為零。
3. int shmctl(int shmid, int cmd, struct shmid_ds *buf);//共享內存的控制
成功返回0,不成功返回-1並設置errno,錯誤碼:
EACCES   cmd為IPC_STAT,但是調用程序沒有讀權限
EINVAL   shmid或cmd的值無效
EPERM   cmd為IPC_RMID或IPC_SET,調用程序沒有正確的權限
cmd值:
IPC_RMID 刪除共享內存段,並銷毀相應的shmid_ds
IPC_SET   用buf中的值來設置共享內存段shmid的字段值
IPC_STAT 將共享內存段shmid中的當前值拷貝到buf中去
IPC_LOCK 將共享內存段鎖定在內存中(只有超級用戶可以執行)
    IPC_UNLOCK 解鎖共享內存
4.void *shmat(int shmid, const void *shmaddr, int shmflg);//共享內存段的連接
成功返回內存段的起始地址,不成功shmat返回-1並設置errno,必須檢測的錯誤碼:
EACCES   調用程序的操作權限別否定
EINVLA   shmid和shmaddr的無效
EMFILE   連接到進程上的共享內存段的樹木超出了限制
ENOMEM 進程數據空間不足以容納共享內存段
功能:
函數將shmid指定的共享內存段連接到調用進程的地址空間,並為shmid增加shm_nattch的值。
如果shmaddr為0,則此段連接到由內核選擇的第一個可用的地址上
如果shmaddr非0,並且沒有指定SHM_RND,則此段連接到addr所指定的地址上
如果shmaddr非0,並且指定了SHM_RND,則此段連接到(addr-(addr mod ulus SHMLBA))所表示的地址上。
5. int shmdt(const void *shmaddr);//分離共享內存
成功返回0,不成功返回-1並設置errno,錯誤碼:
EINVAL shmaddr不對應於共享內存段的起始地址
功能:
用完一個共享內存,調用其來分離共享內存段,並對shm_nattch進行減操作。
最后一個分離共享內存段的進程應該通過調用shmctl來釋放共享內存段
        (六)PGSQL編程
1.PGconn *PQconnectdb(const char *conninfo);//與數據庫服務器建立一個新的連接
conninfo可以包含的內容有:host,hostaddr, port, dbname, user, password, connect_timeout, options,tty,sslmode,requiressl,service
2.//與數據庫服務器建立一個新的連接(PQconnectdb的前身)
PGconn *PQsetdbLogin(const char *pghost,//IP
            const char *pgport,//斷口
            const char *pgoptions,// 發送給服務器的命令行選項
            const char *pgtty,//服務器日志的輸出方向
            const char *dbName,//數據庫名
            const char *login,//用戶
                const char *pwd);//密碼
3. PGconn *PQsetdb(char *pghost,char *pgport,     char *pgoptions,char *pgtty,char *dbName);//與數據庫服務器建立一個新的連接
這是一個調用 PQsetdbLogin() 的宏,只是login和pwd參數用空(null )代替。 提供這個函數是為了與非常老版本的程序兼容。
4. PGconn *PQconnectStart(const char *conninfo);
PostgreSQLPollingStatusType PQconnectPoll(PGconn *conn);
//與數據庫服務器建立一個非阻塞的連接
5. PQconninfoOption *PQconndefaults(void);//返回缺省的連接選項
typedef struct PQconninfoOption
{
char   *keyword;   /* 選項的鍵字 */
char   *envvar;   /* 退守的環境變量名 */
char   *compiled; /* 退守的編譯時缺省值 */
char   *val;     /* 選項的當前值,或者 NULL */
char   *label;   /* 連接對話里字段的標識 */
char   *dispchar; /* 在連接對話里為此字段顯示的字符。
      數值有:
              ""     原樣現實輸入的數值
              "*"   口令字段 - 隱藏數值
              "D"   調試選項 - 缺省的時候不顯示 */
  int   dispsize; /* 對話中字段的以字符計的大小 */
}PQconninfoOption;
6. void PQfinish(PGconn *conn);//關閉連接
7. void PQreset(PGconn *conn);//重建新的連接
8. //以非阻塞模式重置與服務器的通訊端口。
int PQresetStart(PGconn *conn);
PostgreSQLPollingStatusType PQresetPoll(PGconn *conn);
9. char *PQdb(const PGconn *conn);//返回連接的數據庫名
10. char *PQuser(const PGconn *conn);//返回連接的用戶名
11. char *PQpass(const PGconn *conn);//返回連接密碼
12. char *PQhost(const PGconn *conn);//返回連接主機名
13. char *PQport(const PGconn *conn);//返回連接端口
14. char *PQtty(const PGconn *conn);//返回連接的調試控制台TTY
15. char *PQoptions(const PGconn *conn);//返回連接請求傳遞的命令行選項
16. ConnStatusType PQstatus(const PGconn *conn);//返回連接狀態
  這個狀態可以是一系列值之一。 不過,我們在一個異步連接過程外面只能看到其中的兩個: CONNECTION_OK 或 CONNECTION_BAD。一個與數據庫的成功的連接返回狀態 CONNECTION_OK。 一次失敗的企圖用狀態 CONNECTION_BAD 標識。 通常,一個 OK 狀態將保持到 PQfinish,但是一個通訊失敗可能會導致狀態過早地改變為 CONNECTION_BAD 。這時應用可以試着調用 PQreset 來恢復。
17. PGTransactionStatusType PQtransactionStatus(const PGconn *conn);
//返回當前服務器的事務內狀態。
狀態可以是 PQTRANS_IDLE (當前空閑), PQTRANS_ACTIVE (正在處理一個命令), PQTRANS_INTRANS (空閑,在一個合法的事務塊內),或者 PQTRANS_INERROR (空閑,在一個失敗的事務塊內)。如果連接有問題,則返回 PQTRANS_UNKNOWN。只有在一個查詢發送給了服務器並且還沒有完成的時候才返回 PQTRANS_ACTIVE。
18. const char *PQparameterStatus(const PGconn *conn, const char *paramName);// 查找服務器的一個當前參數設置
19. int PQprotocolVersion(const PGconn *conn);查詢所使用的前/后端協議。
20. int PQserverVersion(const PGconn *conn);//返回服務器的版本
21. char *PQerrorMessage(const PGconn *conn);// 返回連接中操作產生的最近的錯誤信息。
22. int PQsocket(const PGconn *conn);// 獲取與服務器連接的套接字的文件描述符編號。 一個有效的描述符應該是大於或等於 0;結果為 -1 表示當前沒有與服務器的連接打開。 (在正常的操作中,這個結果不會改變,但是可能在啟動或者重置的過程中變化。)
23. int PQbackendPID(const PGconn *conn);// 返回處理此連接的服務器服務器的進程號ID(PID)。
24. SSL *PQgetssl(const PGconn *conn);// 返回連接使用的 SSL 結構,或者如果沒有使用 SSL 的話返回 NULL。
25. PGresult *PQexec(PGconn *conn, const char *command);// 給服務器提交一條命令並且等待結果。
26. PGresult *PQexecParams(PGconn *conn,
              const char *command,
              int nParams,
              const Oid *paramTypes,
              const char * const *paramValues,
              const int *paramLengths,
              const int *paramFormats,
              int resultFormat);
//向服務器提交一條命令並且等待結果,還有額外的傳遞與 SQL 命令文本獨立的參數的能力。
27. 用給定的參數提交請求,創建一個准備好的語句,然后等待結束。
PGresult *PQprepare(PGconn *conn,
            const char *stmtName,
            const char *query,
            int nParams,
            const Oid *paramTypes);
28. PGresult *PQexecPrepared(PGconn *conn,
                const char *stmtName,
                int nParams,
                const char * const *paramValues,
                const int *paramLengths,
                const int *paramFormats,
                int resultFormat);
//發送一個請求,執行一個帶有給出參數的准備好的語句,並且等待結果。
29. 返回命令的結果狀態。
ExecStatusType PQresultStatus(const PGresult *res);
PQresultStatus可以返回下面數值之一:
PGRES_EMPTY_QUERY 發送給服務器的字串是空的
PGRES_COMMAND_OK 成功完成一個不返回數據的命令
PGRES_TUPLES_OK 成功執行一個返回數據的查詢查詢(比如 SELECT 或者 SHOW)。
PGRES_COPY_OUT (從服務器)Copy Out (拷貝出)數據傳輸開始
PGRES_COPY_IN Copy In (拷貝入)(到服務器)數據傳輸開始
PGRES_BAD_RESPONSE 服務器的響應無法理解
PGRES_NONFATAL_ERROR 發生了一個非致命錯誤(通知或者警告)PGRES_FATAL_ERROR 發生了一個致命錯誤
30. char *PQresStatus(ExecStatusType status);// PQresStatus 把PQresultStatus返回的枚舉類型轉換成一個描述狀態碼的字符串常量。 調用者不應該釋放結果。
31. char *PQresultErrorMessage(const PGresult *res);
  返回與查詢關聯的錯誤信息,或在沒有錯誤時返回一個空字符串。
如果有錯誤,那么返回的字串將包括一個結尾的新行。調用者不應該直接釋放結果。在相關的 PGresult 句柄傳遞給 PQclear 之后,它會自動釋放。
32. char *PQresultErrorField(const PGresult *res, int fieldcode);
// 返回一個獨立的錯誤報告字段。
33. void PQclear(PGresult *res);// PQclear 釋放於PGresult相關聯的存儲空間。 任何不再需要的查詢結果在不需要的時候都應該用PQclear釋放掉。
34. PGresult* PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status);
// 構造一個帶有給出的狀態的,空的PGresult對象。
35. int PQntuples(const PGresult *res)//返回查詢結果里的行(元組)個數。 36. int PQnfields(const PGresult *res);
// 返回查詢結果里數據行的數據域 (字段)的個數。
37. char *PQfname(const PGresult *res, int column_number);
// 返回與給出的數據域編號相關聯的數據域(字段)的名稱。數據域編號從 0 開始。調用者不應該直接釋放結果。在相關聯的 PGresult 句柄傳遞給 PQclear 之后,結果會被自動釋放。
38. int PQfnumber(const PGresult *res,const char *column_name);
//返回與給出的數據域名稱相關聯的數據域(字段)的編號。
39. Oid PQftable(const PGresult *res, int column_number);
//返回我們抓取的字段所在的表的 OID。字段編號從 0 開始。
40. int PQftablecol(const PGresult *res, int column_number);
//返回組成聲明的查詢結果字段的字段號(在它的表內部)。查詢結果字段編號從 0 開始,但是表字段編號不會是 0。
41. int PQfformat(const PGresult *res, int column_number);
  //返回說明給出字段的格式的格式代碼。0開始
42. Oid PQftype(const PGresult *res, int column_number);
// 返回與給定數據域編號關聯的數據域類型。 返回的整數是一個該類型的內部 OID 號。數據域編號從0 開始。
43. int PQfmod(const PGresult *res, int column_number);
// 返回與給定字段編號相關聯的類型修飾詞。 字段編號從 0 開始。
44. int PQfsize(const PGresult *res, int column_number);
//返回與給定字段編號關聯的字段以字節計的大小。 字段編號從0 開始。
45. int PQbinaryTuples(const PGresult *res);
//如果PGresult包含二進制元組數據時返回 1如果包含 ASCII數據返回 0。
46. char *PQgetvalue(const PGresult *res,int row_number, int column_number);//返回一個PGresult 里面一行的單獨的一個字段的值。
47. int PQgetisnull(const PGresult *res,int row_number, int column_number);
//測試一個字段是否為空(NULL)。行和字段編號從 0 開始。
48. int PQgetlength(const PGresult *res,int row_number,int column_number);//返回以字節計的字段的長度。行和字段編號從 0 開始。
49. char *PQcmdStatus(PGresult *res);
// 返回產生PGresult的 SQL 命令的命令狀態字符串。
50. char *PQcmdTuples(PGresult *res);// 返回被 SQL 命令影響的行的數量。 51. Oid PQoidValue(const PGresult *res); // 返回一個插入的行的對象標識   (OID)—— 如果SQL 命令是INSERT,或者是一個包含合適 INSERT 語句的准                   備好的 EXECUTE的時候。否則,函數返回 InvalidOid。如果受 INSERT 影響的                           表不包含 OID, 也返回 InvalidOid。
52. char *PQoidStatus(const PGresult *res);//如果 SQL 命令是INSERT,或者包含合適 INSERT 的准備好語句 EXECUTE 了 。返回一個被插入的行的 OID 的字串。 (如果 INSERT 並非恰好插入一行,或者目標表沒有OID,那么字串將是 0。) 如果命令不是INSERT,則返回一個空字串。
53. int PQsendQuery(PGconn *conn, const char *command);
//向服務器提交一個命令而不等待結果。 如果查詢成功發送則返回 1,否則返回 0。 (此時,可以用PQerrorMessage獲取關於失敗的信息)。
54. int PQsendQueryParams(PGconn *conn,
              const char *command,
              int nParams,
              const Oid *paramTypes,
              const char * const *paramValues,
              const int *paramLengths,
              const int *paramFormats,
              int resultFormat);
// 給服務器提交一個命令和(命令需要的)分隔的參數,而不等待結果。
55. int PQsendPrepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes);
//發送一個請求,創建一個給定參數的准備好語句,而不等待結束。
56. int PQsendQueryPrepared(PGconn *conn,
                const char *stmtName,
                int nParams,
                const char * const *paramValues,
                const int *paramLengths,
                const int *paramFormats,
                int resultFormat);
//發送一個執行帶有給出參數的准備好的語句的請求,不等待結果。
57. PGresult *PQgetResult(PGconn *conn);
//等待從前面 PQsendQuery,PQsendQueryParams, PQsendPrepare, 或者 PQsendQueryPrepared 調用返回的下一個結果, 然后返回之。當命令結束並且沒有更多結果后返回 NULL。
58. int PQconsumeInput(PGconn *conn);
// 如果存在服務器來的輸入可用,則使用之。
59. int PQisBusy(PGconn *conn);
// 在查詢忙的時候返回 1 ,也就是說,PQgetResult 將阻塞住等待輸入。一個 0 的返回表明這時調用 PQgetResult等以確保不阻塞
60. int PQsetnonblocking(PGconn *conn, int arg);// 把連接的狀態設置為非阻塞。 如果arg為 1,把連接狀態設置為非阻塞, 如果arg為 0, 把連接狀態設置為阻塞。如果 OK 返回 0,如果錯誤返回 -1。
61. int PQisnonblocking(const PGconn *conn);
// 返回數據庫連接的阻塞狀態。 如果連接設置為非阻塞狀態,返回 1,如果是阻塞狀態返回 0。
62. int PQflush(PGconn *conn);
// 試圖把任何正在排隊的數據沖刷到服務器,如果成功(或者發送隊列為空 )返回 0,如果因某種原因失敗返回 -1,或者是在無法把發送隊列中的所有數據都發送出去,返回 1。(這種情況只有在連接不為阻塞模式的時候才會出現)。
63. PGcancel *PQgetCancel(PGconn *conn);// 創建一個數據結構,這個數據結構包含通過特定數據庫連接取消一個命令所需要的信息。
64. void PQfreeCancel(PGcancel *cancel);
// 釋放 PQgetCancel 創建的數據結構。
65. int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize);
// 要求服務器放棄處理當前命令。
66. int PQrequestCancel(PGconn *conn); //要求服務器放棄處理當前命令。
      (七)MYSQL編程
1.數據類型:
MYSQL
這個結構表示對一個數據庫連接的句柄,它被用於幾乎所有的MySQL函數。
MYSQL_RES
這個結構代表返回行的一個查詢的(SELECT, SHOW, DESCRIBE, EXPLAIN)的結果。從查詢返回的信息在本章下文稱為結果集合。
MYSQL_ROW
這是一個行數據的類型安全(type-safe)的表示。當前它實現為一個計數字節的字符串數組。(如果字段值可能包含二進制數據,你不能將這些視為空終止串,因為這樣的值可以在內部包含空字節) 行通過調用mysql_fetch_row()獲得。
MYSQL_FIELD
這個結構包含字段信息,例如字段名、類型和大小。其成員在下面更詳細地描述。你可以通過重複調用mysql_fetch_field()對每一列獲得MYSQL_FIELD結構。字段值不是這個結構的部分;他們被包含在一個MYSQL_ROW結構中。
MYSQL_FIELD_OFFSET
這是一個相對一個MySQL字段表的偏移量的類型安全的表示。(由mysql_field_seek()使用。) 偏移量是在一行以內的字段編號,從0開始。
my_ulonglong
該類型用於行編號和mysql_affected_rows()、mysql_num_rows()和mysql_insert_id()。這種類型提供0到1.84e19的一個範圍。在一些系統上,試圖打印類型my_ulonglong的值將不工作。為了打印出這樣的值,將它變換到unsigned long並且使用一個%lu打印格式。例如:
printf (Number of rows: %lu/n", (unsigned long) mysql_num_rows(result));
MYSQL_FIELD結構包含列在下面的成員:
char * name
字段名,是一個空結尾的字符串。
char * table
包含該字段的表的名字,如果它不是可計算的字段。對可計算的字段,table值是一個空字符串。
char * def
這字段的缺省值,是一個空結尾的字符串。只要你使用,只有你使用mysql_list_fields()才可設置它。
enum enum_field_types type
字段類型。type值可以是下列之一:
類型值             類型含義
FIELD_TYPE_TINY     TINYINT字段
FIELD_TYPE_SHORT     SMALLINT字段
FIELD_TYPE_LONG     INTEGER字段
FIELD_TYPE_INT24     MEDIUMINT字段
FIELD_TYPE_LONGLONG     BIGINT字段
FIELD_TYPE_DECIMAL     DECIMAL或NUMERIC字段
FIELD_TYPE_FLOAT     FLOAT字段
FIELD_TYPE_DOUBLE     DOUBLE或REAL字段
FIELD_TYPE_TIMESTAMP     TIMESTAMP字段
FIELD_TYPE_DATE     DATE字段
FIELD_TYPE_TIME     TIME字段
FIELD_TYPE_DATETIME     DATETIME字段
FIELD_TYPE_YEAR     YEAR字段
FIELD_TYPE_STRING     字符串(CHAR或VARCHAR)字段
FIELD_TYPE_BLOB     BLOB或TEXT字段(使用max_length決定最大長度)
FIELD_TYPE_SET     SET字段
FIELD_TYPE_ENUM     ENUM字段
FIELD_TYPE_NULL     NULL- 類型字段
FIELD_TYPE_CHAR     不推薦;使用FIELD_TYPE_TINY代替
你可以使用IS_NUM()宏來測試字段是否有一種數字類型。將type值傳給IS_NUM()並且如果字段是數字的,它將計算為TRUE:
if (IS_NUM(field->type))
  printf("Field is numeric/n");
unsigned int length
字段寬度,在表定義中指定。
unsigned int max_length
對結果集合的字段的最大寬度(對實際在結果集合中的行的最長字段值的長度)。如果你使用mysql_store_result()或mysql_list_fields(),這包含字段最大長度。如果你使用mysql_use_result(),這個變量的值是零。
unsigned int flags
字段的不同位標志。flags值可以是零個或多個下列位設置:
標志值             標志含義
NOT_NULL_FLAG     字段不能是NULL
PRI_KEY_FLAG     字段是一個主鍵的一部分
UNIQUE_KEY_FLAG     字段是一個唯一鍵的一部分
MULTIPLE_KEY_FLAG     字段是一個非唯一鍵的一部分。
UNSIGNED_FLAG     字段有UNSIGNED屬性
ZEROFILL_FLAG     字段有ZEROFILL屬性
BINARY_FLAG     字段有BINARY屬性
AUTO_INCREMENT_FLAG     字段有AUTO_INCREMENT屬性
ENUM_FLAG             字段是一個ENUM(不推薦)
BLOB_FLAG             字段是一個BLOB或TEXT(不推薦)
TIMESTAMP_FLAG     字段是一個TIMESTAMP(不推薦)
BLOB_FLAG、ENUM_FLAG和TIMESTAMP_FLAG標志的使用是不推薦的,因為他們指出字段的類型而非它的類型屬性。對FIELD_TYPE_BLOB、FIELD_TYPE_ENUM或FIELD_TYPE_TIMESTAMP,最好是測試field->type。下面例子演示了一個典型的flags值用法:
if (field->flags & NOT_NULL_FLAG)
  printf("Field can't be null/n");
你可以使用下列方便的宏決來確定flags值的布爾狀態:
IS_NOT_NULL(flags)     真,如果該字段被定義為NOT NULL
IS_PRI_KEY(flags)     真,如果該字段是一個主鍵
IS_BLOB(flags)     真,如果該字段是一個BLOB或TEXT(不推薦;相反測試field->type)
unsigned int decimals
對數字字段的小數位數。

2. my_ulonglong mysql_affected_rows(MYSQL *mysql) 返回被最新的UPDATE, DELETE或INSERT查詢影響的行數。
  void mysql_close(MYSQL *mysql)     關閉一個服務器連接。

  MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)     連接一個MySQL服務器。該函數不推薦;使用mysql_real_connect()代替。

  my_bool mysql_change_user(MYSQL *mysql, const char *user, const char *password, const char *db)     改變在一個打開的連接上的用戶和數據庫。

  int mysql_create_db(MYSQL *mysql, const char *db)     創建一個數據庫。該函數不推薦;而使用SQL命令CREATE DATABASE。

  void mysql_data_seek(MYSQL_RES *result, unsigned long long offset)     在一個查詢結果集合中搜尋一任意行。

  void mysql_debug(char *debug)     用給定字符串做一個DBUG_PUSH。

  int mysql_drop_db(MYSQL *mysql, const char *db)     拋棄一個數據庫。該函數不推薦;而使用SQL命令DROP DATABASE。

  int mysql_dump_debug_info(MYSQL *mysql)     讓服務器將調試信息寫入日志文件。

  my_bool mysql_eof(MYSQL_RES *result)     確定是否已經讀到一個結果集合的最後一行。這功能被反對; mysql_errno()或mysql_error()可以相反被使用。

  unsigned int mysql_errno(MYSQL *mysql)     返回最近被調用的MySQL函數的出錯編號。

  char *mysql_error(MYSQL *mysql)     返回最近被調用的MySQL函數的出錯消息。

  unsigned int mysql_escape_string(char *to, const char *from, unsigned int length)     用在SQL語句中的字符串的轉義特殊字符。

  MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)     返回下一個表字段的類型。

  MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)     返回一個表字段的類型,給出一個字段編號。

  MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)     返回一個所有字段結構的數組。

  unsigned long *mysql_fetch_lengths(MYSQL_RES *result)返回當前行中所有列的長度。

  MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)     從結果集合中取得下一行。

  unsigned int mysql_field_count(MYSQL *mysql)     把列光標放在一個指定的列上。

  MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)     返回最近查詢的結果列的數量。

  MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)返回用於最後一個mysql_fetch_field()的字段光標的位置。

  void mysql_free_result(MYSQL_RES *result)     釋放一個結果集合使用的內存。

  char *mysql_get_client_info(void)     返回客戶版本信息。

  char *mysql_get_host_info(MYSQL *mysql)       返回一個描述連接的字符串。

  unsigned int mysql_get_proto_info(MYSQL *mysql)     返回連接使用的協議版本。

  char *mysql_get_server_info(MYSQL *mysql)     返回服務器版本號。

  char *mysql_info(MYSQL *mysql)     返回關於最近執行得查詢的信息。

  MYSQL *mysql_init(MYSQL *mysql)     獲得或初始化一個MYSQL結構。

  my_ulonglong mysql_insert_id(MYSQL *mysql)返回有前一個查詢為一個AUTO_INCREMENT列生成的ID。

  int mysql_kill(MYSQL *mysql, unsigned long pid)     殺死一個給定的線程。

  MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)     返回匹配一個簡單的正則表達式的數據庫名。

  MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)     返回匹配一個簡單的正則表達式的列名。

  MYSQL_RES *mysql_list_processes(MYSQL *mysql)     返回當前服務器線程的一張表。

  MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)     返回匹配一個簡單的正則表達式的表名。

  unsigned int mysql_num_fields(MYSQL_RES *result)     返回一個結果集合重的列的數量。

  my_ulonglong mysql_num_rows(MYSQL_RES *result)     返回一個結果集合中的行的數量。

  int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)     設置對mysql_connect()的連接選項。

  int mysql_ping(MYSQL *mysql)     檢查對服務器的連接是否正在工作,必要時重新連接。

  int mysql_query(MYSQL *mysql, const char *query)執行指定為一個空結尾的字符串的SQL查詢。

  MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned int client_flag)     連接一個MySQL服務器。

int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length)     執行指定為帶計數的字符串的SQL查詢。

int mysql_reload(MYSQL *mysql)     告訴服務器重裝授權表。

MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)     搜索在結果集合中的行,使用從mysql_row_tell()返回的值。

MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)     返回行光標位置。

int mysql_select_db(MYSQL *mysql, const char *db)     連接一個數據庫。

int mysql_shutdown(MYSQL *mysql)     關掉數據庫服務器。

char *mysql_stat(MYSQL *mysql)     返回作為字符串的服務器狀態。

MYSQL_RES *mysql_store_result(MYSQL *mysql)     檢索一個完整的結果集合給客戶。

unsigned long mysql_thread_id(MYSQL *mysql)     返回當前線程的ID。

MYSQL_RES *mysql_use_result(MYSQL *mysql)     初始化一個一行一行地結果集合的檢索。
         
(八)網絡編程
  1、socket函數:為了執行網絡輸入輸出,一個進程必須做的第一件事就是調用socket函數獲得一個文件描述符。
#include<socket.h>
int socket(int family, int type, int protocol);//成功返回非負描述字;失敗返回-1
  第一個參數指明了協議簇,目前支持5種協議簇,最常用的有AF_INET(IPv4協議)和AF_INET6(IPv6協議);第二個參數指明 套接口類型,有三種類型可選:SOCK_STrEAM(字節流套接口)、SOCK_DGrAM(數據報套接口)和SOCK_rAW(原始套接口);如果套 接口類型不是原始套接口,那么第三個參數就為0。

  2、connect函數:當用socket建立了套接口后,可以調用connect為這個套接字指明遠程端的地址;如果是字節流套接口,connect就使用三次握手建立一個連接;如果是數據報套接口,connect僅指明遠程端地址,而不向它發送任何數據。
int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
//成功返回0;失敗返回-1
  第一個參數是socket函數返回的套接口描述字;第二和第三個參數分別是一個指向套接口地址結構的指針和該結構的大小。
  這些地址結構的名字均已“sockaddr_”開頭,並以對應每個協議族的唯一后綴結束。以IPv4套接口地址結構為例,它以“sockaddr_in”命名,定義在頭文件<netinet/in.h>;以下是結構體的內容:
struct in_addr {
in_addr_t s_addr; //IPV4地址
};
struct sockaddr_in {
uint8_t sin_len;//無符號的8位整數
sa_family_t sin_family;//套接口地址結構地址族,這里為AF_INET
in_port_t sin_port;//TCP或UDP端口
struct in_addr sin_addr;//地址
char sin_zero[8];
};

  3、bind函數:為套接口分配一個本地IP和協議端口,對於網際協議,協議地址是32位IPv4地址或128位IPv6地址與16位的 TCP或UDP端口號的組合;如指定端口為0,調用bind時內核將選擇一個臨時端口,如果指定一個通配IP地址,則要等到建立連接后內核才選擇一個本地 IP地址。
int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);//成功0失敗-1
  第一個參數是socket函數返回的套接口描述字;第二和第第三個參數分別是一個指向特定於協議的地址結構的指針和該地址結構的長度。

  4、listen函數:listen函數僅被TCP服務器調用,它的作用是將用sock創建的主動套接口轉換成被動套接口,並等待來自客戶端的連接請求。
int listen(int sockfd, int backlog);//成功返回0;失敗-1
第一個參數是socket函數返回的套接口描述字;第二個參數規定了內核為此套接口排隊的最大連接個數。由於listen函數第二個參數的原 因,內核要維護兩個隊列:以完成連接隊列和未完成連接隊列。未完成隊列中存放的是TCP連接的三路握手為完成的連接,accept函數是從以連接隊列中取 連接返回給進程;當以連接隊列為空時,進程將進入睡眠狀態。
  5、accept函數:accept函數由TCP服務器調用,從已完成連接隊列頭返回一個已完成連接,如果完成連接隊列為空,則進程進入睡眠狀態。
int accept(int sockfd,struct sockaddr * cliaddr,socklen_t * addrlen);  
// 返回:非負描述字---成功   -1---失敗
  第一個參數是socket函數返回的套接口描述字;第二個和第三個參數分別是一個指向連接方的套接口地址結構和該地址結構的長度;該函數返回的是一個全新的套接口描述字;如果對客戶段的信息不感興趣,可以將第二和第三個參數置為空。

  6、inet_pton函數:將點分十進制串轉換成網絡字節序二進制值,此函數對IPv4地址和IPv6地址都能處理。
int inet_pton(int family,const char * strptr,void * addrptr);
//返回:1---成功 0---輸入不是有效的表達格式 -1---失敗
  第一個參數可以是AF_INET或AF_INET6:第二個參數是一個指向點分十進制串的指針:第三個參數是一個指向轉換后的網絡字節序的二進制值的指針。

  7、inet_ntop函數:和inet_pton函數正好相反,inet_ntop函數是將網絡字節序二進制值轉換成點分十進制串。
const char * inet_ntop(int family,const void *addrptr,char * strptr,size_t len);
//返回:指向結果的指針---成功   NULL---失敗
  第一個參數可以是AF_INET或AF_INET6:第二個參數是一個指向網絡字節序的二進制值的指針;第三個參數是一個指向轉換后的點分十進制串的指針;第四個參數是目標的大小,以免函數溢出其調用者的緩沖區。
     8. int send(int sockfd, const void *msg, int len, int flags);
  Sockfd是你想用來傳輸數據的socket描述符,msg是一個指向要發送數據的指針。
  Len是以字節為單位的數據的長度。flags一般情況下置為0(關於該參數的用法可參照man手冊)。
  char *msg = "Beej was here!"; int len, bytes_sent; ... ...
  len = strlen(msg); bytes_sent = send(sockfd, msg,len,0); ... ...
  send()函數返回實際上發送出的字節數,可能會少於你希望發送的數據。所以需要對send()的返回值進行測量。當send()返回值與len不匹配時,應該對這種情況進行處理。

  9.int recv(int sockfd,void *buf,int len,unsigned int flags);
  Sockfd是接受數據的socket描述符;buf 是存放接收數據的緩沖區;len是緩沖的長度。Flags也被置為0。Recv()返回實際上接收的字節數,或當出現錯誤時,返回-1並置相應的errno值。
  10. int sendto(int sockfd, const void *msg,int len,unsigned int flags,const struct sockaddr *to, int tolen);
  該函數比send()函數多了兩個參數,to表示目地機的IP地址和端口號信息,而tolen常常被賦值為sizeof (struct sockaddr)。Sendto 函數也返回實際發送的數據字節長度或在出現發送錯誤時返回-1。
  11. int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);
   from是一個struct sockaddr類型的變量,該變量保存源機的IP地址及端口號。fromlen常置為sizeof(struct sockaddr)。當recvfrom()返回時,fromlen包含實際存入from中的數據字節數。Recvfrom()函數返回接收到的字節數或 當出現錯誤時返回-1,並置相應的errno。
  應注意的一點是,當你對於數據報socket調用了connect()函數時,你也可以利用send()和recv()進行數據傳輸,但該socket仍然是數據報socket,並且利用傳輸層的UDP服務。但在發送或接收數據報時,內核會自動為之加上目地和源地址信息。
  12. struct hostent *gethostbyname(const char *name); //實現域名和IP的轉換
  函數返回一種名為hosten的結構類型,它的定義如下:
  struct hostent {
     char *h_name; /* 主機的官方域名 */
     char **h_aliases; /* 一個以NULL結尾的主機別名數組 */
     int h_addrtype; /* 返回的地址類型,在Internet環境下為AF-INET */
     int h_length; /*地址的字節長度 */
     char **h_addr_list; /* 一個以0結尾的數組,包含該主機的所有地址*/
     };

13. int getsockopt(int sockfd,int level,int optname,void *optval,socklen_t *optlen)
int setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t *optlen)

level指定控制套接字的層次.可以取三種值: 1)SOL_SOCKET:通用套接字選項. 2)IPPROTO_IP:IP選項. 3)IPPROTO_TCP:TCP選項.
optname指定控制的方式(選項的名稱),我們下面詳細解釋

optval獲得或者是設置套接字選項.根據選項名稱的數據類型進行轉換


選項名稱 說明 數據類型
========================================================================
SOL_SOCKET
------------------------------------------------------------------------
SO_BROADCAST 允許發送廣播數據 int
SO_DEBUG 允許調試 int
SO_DONTROUTE 不查找路由 int
SO_ERROR 獲得套接字錯誤 int
SO_KEEPALIVE 保持連接 int
SO_LINGER 延遲關閉連接 struct linger
SO_OOBINLINE 帶外數據放入正常數據流 int
SO_RCVBUF 接收緩沖區大小 int
SO_SNDBUF 發送緩沖區大小 int
SO_RCVLOWAT 接收緩沖區下限 int
SO_SNDLOWAT 發送緩沖區下限 int
SO_RCVTIMEO 接收超時 struct timeval
SO_SNDTIMEO 發送超時 struct timeval
SO_REUSERADDR 允許重用本地地址和端口 int
SO_TYPE 獲得套接字類型 int
SO_BSDCOMPAT 與BSD系統兼容 int
======================================================================
IPPROTO_IP
--------------------------------------------------------------------------
IP_HDRINCL 在數據包中包含IP首部 int
IP_OPTINOS IP首部選項 int
IP_TOS 服務類型
IP_TTL 生存時間 int
======================================================================
IPPRO_TCP
--------------------------------------------------------------------------
TCP_MAXSEG TCP最大數據段的大小 int
TCP_NODELAY 不使用Nagle算法 int
======================================================================
關於這些選項的詳細情況請查看 Linux Programmer''s Manual
14. TCP客戶端的過程
  socket()->[*對所要連接的server對應的sockaddr_in結構中的sin_family,sin_addr.s_addr,sin_port賦值*]->connect()-> { write()->read()-> } close()
    TCP服務端的過程
  socket()->[*對server所對應的sockaddr_in機構中的sin_family,sin_addr.s_addr,sin_port進行賦值*]->bind()->listen()->{ accept()-> read()->write()-> }close()

15.UDP客戶的過程
  [*對所要連接的server對應的sockaddr_in結構中的sin_family,sin_addr.s_addr,
sin_port賦值*]->socket()->{ sendto()->recvfrom()-> } close()
UDP服務端的過程
  socket()->[對server對應的sockaddr_in結構中的sin_family,sin_addr.s_addr,
sin_port賦值] –>bind()->{ recvfrom()->sendto()-> }close()
          (九)文件訪問
1. #include<fcntl.h>
  int open(const char *pathname, int oflag, …)//打開或創建文件
  若成功返回文件描述符,出錯返回-1;參數說明:
  pathname:要打開或創建文件的名字
oflag:以下三個只選其一:
O_RDONLY(只讀打開)、O_WRONLY(只寫打開)、O_RDWR(讀寫打開)
以下可選:
O_APPEND 每次寫時都追加到文件的尾端
    O_CREAT 若此文件不存在,則創建它(需第三個參數來指定權限)
    O_EXCL 如果同時指定了CREAT而文件已經存在則出錯。
    O_TRUNC 如果此文件存在而且為只寫或只讀,則將其長度截為0
    O_NOCTTY 如果pathname指的是終端設備,則不將該設備分配作為此進程的控制終端。
    O_NONBLOCK 如果pathname指的是一個FIFO、一個塊特殊文件或一個字符特殊文件,則此選項為文件的本次打開操作和后續的I/0操作設置非阻塞模式
    O_DSYNC 使每次write等待物理I/0操作完成,但是如果寫操作並不影響讀取剛寫入的數據,則不等待文件屬性被更新。
    O_RSYNC 使每一個以文件描述符作為參數的read操作等待,直至任何對文件同一部分進行的未決寫操作都完成
    O_SYNC 使每次write都等到物理I/O操作完成,包括由write操作引起的文件屬性更新所需的I/0。
 
2.creat(const char *pathname, mode_t mode);//創建文件
若成功返回只寫打開的文件描述符,失敗返回-1
相當於open(pathname, O_WRONLY | O_CREAT | O_TRUNC,mode)
mode的選項:
S_IRUSR   // user-read(文件所有者讀)
  S_IWUSR   // user-write(文件所有者寫)
  S_IXUSR   // user-execute(文件所有者執行)
  S_IRGRP   // group-read
  S_IWGRP   // group-write
  S_IXGRP   // group-execute
  S_IROTH   // other-read
  S_IWOTH   // other-write
  S_IXOTH   // other-execute
3.int close(int filedes)//關閉打開的文件;成功返回0,失敗返回-1
4.off_t lseek(int filedes, off_t, int whence)
//為一個打開的文件設置其偏移量,成功返回新的文件偏移量 出錯返回-1
若whence是SEEK_SET,則將該文件的偏移量設置為距文件開始處offset個字節
若whence是SEEK_CUR,則將該文件的偏移量設置為當前值加offset(可正、負)
若whence是SEEK_END,則將該文件偏移量設置為文件長度加offset(可正、負)
5.ssize_t read(int filedes, void *buf, size_t nbytes);//從打開的文件中讀數據;成功返回讀到的字節數,若已到文件結尾則返回0,出錯返回-1
6.ssize_t write(int filedes, const void *buf, size_t nbytes)
//向打開的文件寫數據;若成功則返回已寫的字節數,出錯則返回-1
7.ssize_t pread(int filedes, void *buf, size_t nbytes, off_t offset);
//指定偏移量讀文件;返回讀到的字節數,已到文件結尾返回0,出錯返回-1
8.ssize_t pwrite(int filedes, void *buf, size_t nbytes, off_t offset);
//指定偏移量寫文件;返回寫入的字節數,若出錯則返回-1
9.int dup(int filedes);//復制一個現存的文件描述符
int dup2(int filedes, int filedes2)//將filedes復制到filedes2
//若成功則返回新的文件描述符,若出錯則返回-1
10.#include<fcntl.h>
int fcntl(int filedes, int cmd, …);//改變已打開的文件的性質
若成功則依賴cmd,若出錯則返回-1,主要有5種功能:
(1)復制一個現有的描述符(cmd = F_DUPFD)
  復制文件描述符filedes,返回新文件描述符
(2)獲得/設置文件描述符標記(cmd=F_GETFD或F_SETFD)
  返回文件描述符標記(F_GETFD)
(3)獲得/設置文件狀態標志(cmd=F_GETFL或F_SETFL)
  返回文件狀態標志(前面提到過,如O_RDONLY)
(4)獲得/設置異步I/O所有權(cmd=F_GETOWN或F_SETOWN)
(5)獲得/設置記錄鎖(cmd=F_GETLK、F_SETLK或F_SETLKW)
11.#include<unistd.h> #include<sys/ioctl.h> #include<stropts.h>
  int ioctl(int filedes, int request,…);//通用I/O操作
  失敗返回-1,成功返回其他值
12.#include<sys/stat.h>
  int stat(const char *restrict pathname, struct stat *restrict buf)
  //返回與此命名有關的信息結構
  int fstat(int filedes, struct stat *buf);//獲取已在filedes上打開的文件的有關信息
  int lstat(const char *restrict pathname, struct stat *restrict buf);//返回該符號鏈接的有關信息               三個函數的返回值:成功0失敗-1
  struct stat{
      mode_t   st_mode; //文件的類型和權限
      ino_t   st_ino;//i節點號
      dev_t   st_dev;//設備號
      dev_t   st_rdev;//特殊文件的設備號
      nlink_t   st_nlink;//鏈接號
      uid_t     st_uid;//擁有者的用戶ID
      gid_t     st_gid;//擁有者的組ID
      off_t     st_size;//文件的大小
      time_t     st_atime;//上次訪問的時間
      time_t     st_mtime;//上一次修改文件的時間
      time_t     st_ctime;//上一個改變文件狀態的時間
      blksize_t   st_blksize;//最優I/O塊大小
      blkcnt_t     st_blocks;//分配的硬盤塊號碼
  };  
13.int access(const char *pathname, int mode);//測試文件的訪問權限
  成功返回0,失敗返回-1;mode有如下幾個選項:
    R_OK 測試讀權限 W_OK測試寫權限 X_OK測試執行權限 F_OK 測試文件是否存在
14.#include <sys/stat.h> mode_t umask(mode_t cmask); //返回原來的屏蔽字
15.#include <sys/stat.h> int chmod(const char *pathname, mode_t mode);
  int fchmod(int filedes, mode_t mode);//更改文件的訪問權限,成功返回0,失敗返回-1
  mode的選項除了以上的9個權限之外,還有:S_ISUID 執行時設置用戶ID   S_ISGID 執行時設置組ID   S_ISVTX 保存正本(粘住位) S_IRWXU 用戶讀寫執行 S_IRWXG 組讀寫執行
16.int chown(const char *pathname, uid_t owner, gid_t group);
  int fchown(int filedes, uid_t owner, gid_t group);
  int lchown(const char *pathname ,uid_t owner, gid_t group);
  //更改文件的用戶ID和組ID;成功返回0,失敗返回-1
17.int truncate(const char *pathname, off_t length);
  int ftruncate(int filedes, off_t length);//截短文件 成功返回0出錯返回-1
18.int link(const char *existingpath, const char *newpath);
//在目錄existingpath下創建新目錄newpath,成功返回0失敗返回-1
19.#include<unistd.h>int unlink(const char *pathname)//刪除目錄,成功0失敗返回-1
20.#include <stdio.h>int remove(const char *pathname);//刪除目錄,成功返回0失敗返回-1
21.int rename(const char *oldname, const char *newname);//更改文件名,成功返回0失敗-1
22.#include<utime.h> int utime(const char *pathname, const struct utimbuf *times);
  //更改文件的訪問和修改時間;成功返回0,失敗-1
  struct utimbuf {
    time_t actime; //訪問時間
    time_t modtime;//修改時間
  }
23.#include <sys/stat.h> int mkdir(const char *pathname, mode_t mode);//創建文件(0/-1)
24.int rmdir(const char *pathname);//刪除文件 (0/-1)
25.#include <unistd.h>int chdir(const char *pathname);
  int fchdir(int filedes);//更改當前的工作目錄 返回值:(0/-1)
26.char *getcwd(char *buf, size_t size );//獲取當前工作目錄的絕對路徑名 返回值(buf/NULL)
            (十)標准I/O
1.#include<stdio.h> #include <wchar.h>
int fwide(FILE *fp, int mode);//設置流定向(寬定向返回正/字節定向返回負/未定向返回0)
mode參數值為負:試圖使指定的流是字節定向的;正:寬定向;0不試圖設置流的定向
2.void setbuf(FILE *restrict fp, char *restrict buf);
int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);// 返回(0/-1)
//更改緩沖類型(流被打開后也應該在對該流未執行任何操作時調用)
mode 參數的選項:_IOFBF (全緩沖)   _IOLBF (行緩沖)_IONBF(不帶緩沖,將忽略buf和size)
3.int fflush(FILE *fp);//沖洗流,將流中的數據傳給內核,然后清空緩沖區。返回(0/EOF)
4.FILE *fopen(const char *restrict pathname, const char *restrict type);//打開指定的文件
FILE *freopen(const char *restrict pathname, const char *restrict type, FILE* restrict fp)
  //在一個指定的流上打開文件,若流已打開則先關閉流,若已定向則清除定向。
FILE *fdopen(int filedes, const char *type);
  //獲取一個現有的文件描述符,並使一個標准的I/O流與該描述符相結合。
  //成功返回文件指針,出錯返回NULL
5.int fclose(FILE *fp);//關閉一個打開的流,返回(0/EOF)
6.int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void); //讀取一個字符;成功返回下一個字符,若已到文件結尾或出錯返回EOF
7.int ferror(FILE *fp);
int feof(FILE *fp);//測試文件是否出錯和到達結尾;為真返回非0,否則返回0
void clearerr(FILE *fp);//清除錯誤和結束標志
8.int ungetc(int c, FILE *fp);//將字符壓回流中;成功返回c,出錯返回EOF
9.int putc(int c, FILE *fp);
int fputc(int c, FILE *fp);
int putchar(int c);//輸出函數,成功返回c,出錯返回EOF
10.char *fgets(char *restrict buf, int n, FILE *restrict fp);
  char *gets(char *buf);//每次輸入一行;成功返回buf,出錯或文件結尾則返回NULL
11.int fputs(const char *restrict str, FILE *restrict fp);
  int puts(const char *str);//輸出一行的函數;成功返回非負值,出錯則返回EOF
12.size_t fread(void *restrict ptr, size_t size,size_t nobj,FILE *restrict fp);
  size_t fwrite(const void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp);
  //二進制I/O操作,返回讀或寫的對象數(即nobj)
13.long ftell(FILE *fp);//返回當前的文件位置指示;成功返回當前文件位置指示,失敗-1L
  int fseek(FILE *fp, long offset, int whence);//為打開的文件設置新的偏移量(0/非0)
  void rewind(FILE *fp);//將一個流設置到文件的起始位置
14.off_t ftello(FILE *fp);//成功返回當前文件的位置指示(與上就差返回類型),失敗返回-1
  int fseeko(FILE *fp, off_t offset, int whence);//成功返回0,失敗返回非0
15.int fgetpos(FILE *restrict fp, fpos_t *restrict pos);
//將文件位置指示器的當前值存入指向的對象中
  int fsetpos(FILE *fp, const fpos_t *pos);//用pos的值將流重新定位到該位置;成功0失敗非0;
16.int printf(const char *restrict format,...);
  int fprintf(FILE *restrict fp, const char *restrict format,…);//成功返回輸出字符數/負值
  int sprintf(char *restrict buf, const char *restrict format,…);
  int snprintf(char *restrict buf, size_t n, const char *restrict format,…);
  //成功返回存入數組的字符數,出錯則返回負值
17.scanf(const char *restrict format, …);
  int fscanf(FILE *restrict fp, const char *restrict format,…);
  int sscanf(const char *restrict buf, const char *restrict format, …);
  //返回指定的輸入項數;若輸入出錯或在任意變換前已到達文件結尾則返回EOF
18.int fileno(FILE *fp);//獲取文件描述符;返回該流相關聯的文件描述符
19.char *tmpnam(char *ptr);//創建臨時文件   //返回指向唯一路徑的指針
  FILE *tmpfile(void); //若成功則返回文件指針,若出錯則返回NULL
20.char *tempnam(const char *directory, const char *prefix);//指定目錄和前綴創建臨時文件
21.int mkstemp(char *template)//指定臨時文件的名字創建;成功返回文件描述符,出錯返回-1
        (十一)系統數據文件和信息
1.include<pwd.h> struct passwd *getpwuid(uid_t uid);
struct passwd *getpwnam(const char *name);//獲取口令文件返回passwd結構,出錯返NULL
struct passwd {
  char *pw_name; //用戶名
  char *pw_passwd; //加密口令
  uid_t blog_uid; //數值用戶ID
  gid_t blog_gid;   //數值組ID
  char *pw_gecos; //注釋字段
  char *pw_dir; //出始工作目錄
  char *pw_shell;//初始shell(用戶程序)
};
2.struct passwd *getpwent(void);//返回口令文件(/etc/passwd)中的下一項記錄,調用用一定要使用endpwent()來關閉; 出錯或者到達文件結尾則返回NULL
void setpwent(void);//打開文件(未打開時)然后反繞它所使用的文件(定位到開始處)
void endpwent(void);//關閉使用的文件
3.#include <shadow.h>   /etc/shadow
  struct spwd *getspnam(const char *name);//獲取陰影口令文件返回spwd結構
  struct spwd *getspent(void);//獲取陰影口令文件中的下一項並返回spwd結構;出錯返回NULL
  void setspent(void); //打開文件(未打開時)然后反繞文件
  void endspent(void);//關閉文件
  struct spwd {
    char *sp_namp; //用戶登錄名
    char *sp_pwdp;//加密口令
    int sp_lstchg; //上次更改口令以來經過的時間
    int sp_max; //經過多少天后允許被修改
    int sp_warn; //到期警告天數
    int sp_inact; //帳戶不活動之前剩余天數
    int sp_expire; //帳戶到期天數
    unsigned int sp_flag;//保留字
  }
4.#include <grp.h> struct group *getgrgid(gid_t gid);//根據組ID返回相應的group結構
struct gourp *getgrnam(const char *name);根據組名獲取組結構
//成功返回相對應的組結構,出錯返回NULL
struct group {
  char *gr_name;//組名
  char *gr_passwd;//加密口令
  int gr_gid;//組ID
  char **gr_mem;//指向各用戶名的指針的數組
};
5.struct group *getgrent(void);//返回/etc/group文件中的下一項並返回指針返回NULL
void setgrent(void);// 打開文件(未打開時)然后反繞文件
void endgrent(void);//關閉文件
6.int uname(struct utsname *name);
//返回與當前主機和操作系統有關的信息,成功返回非負,出錯返回-1
struct utsname {
char sysname[]; //操作系統名
char nodename[]; //節點名
char release[]; //當前操作系統的版本
char version[]; //這個版本的序號
char machine[]; //主機名
}
7.int gethostname(char *name, int namlen);//獲取主機名給name,成功返回0失敗返回-1
8.#include<time.h> time_t time(time_t *calptr);//返回當前的時間和日期並存於calptr,出錯-1
9.#include<sys/time.h>int gettimeofday(struct timeval *restrict tp, void *restrict tzp);
//獲取精確到微秒的時間並存於tp中,返回值:總是0, tzp的唯一合法值是NULL
struct tmeval {
  time_t tv_sec; //秒
  long tv_usec ;//微秒
}
10. struct tm *gmtime(const time_t *calptr);//將日歷時間轉成國際標准時間的年月日時分秒周日
  struct tm *localtime(const time_t *calptr);// 將日歷時間轉換成本地時間(考慮到本地時間和夏時指標志)返回指向tm結構的指針
  struct tm {
    int tm_sec; //秒數 [0-60] 60可以表示潤秒
    int tm_min; //分鍾 [0-59]
    int tm_hour; //小時 [0-23]
    int tm_mday; //日 [1-31]
    int tm_mon; //月 [0-11]
    int tm_year;//年 [1900-]
    int tm_wday; //星期 [0-6]
    int tm_yady;//一年的第幾天 [0-365]
    int tm_sidst; //是否為夏時制
  };
11.time_t mktime(struct tm *tmptr);//以本地時間的信息轉化成time_t的值,返回:日歷時間/-1
12.char *asctime(const struct tm *tmptr);
  char *ctime(const time_t *calptr);
  //將各自的時間參數轉化成如”Tue Feb 10 18:20:15 2007/n/0”的格式
13.size_t strftime(char *restrict buf, size_t maxsize, const char *restrict format, const struct tm *restrict tmptr);//將時間tmptr以指定的format格式存於buf中,返回存入的字符數/失敗0
  format中可以用以下符號表示要輸出的格式:
  %a 縮寫的周日名 Tue               %A 全周日名     Tuesday
  %b 縮寫的月名   Feb               %B 全月名       February
  %c 日期和時間 Tue Feb 10 13:02:15 2007 %C 年/100 [0-99]   7
  %d 月日[0-31] 10                 %D 日期[MM/DD/YY] 07/02/10
  %e 月日[1-31](一位數字加空格) 2       %F [YYYY-MM-DD] 2007-02-10
  %g 基於周的年的最后兩位數   07       %G 基於周的年     2007
  %h 與%b相同                     %H 小時(24小時制):[00-23]
  %I 小時(12小時制)[01-12]           %j   年日[001-366]
  %m 月[01-12]                     %M 分[00-59]
  %n 換行符                       %p AM/PM       PM
  %r 本地時間(12小時) 06:27:38 PM     %R 與%H:%M相同 18:27
  %S 秒[00-60]                     %t 水平制表符
  %T 與“%H:%M:%S” 18:27:38     %u 周日[1-7]
  %U 星期日周數[00-53]                 %V 周數[01-53]
  %w 周日[0-6]                     %W 星期一周數
  %x 日期                         %X 時間
  %y 年的最后兩位數     07             %Y 年     2007
  %z UTC偏移量   -0500             %Z 時區名 EST
  %% 轉換一個%     %
            (十二)信號
1.UNIX信號表 []內為默認處理動作 core表示動作的同時產生core jump,並生成一個core文件:
SIGABRT     由調用abort函數產生,進程非正常退出       [終止+core]
SIGALRM     用alarm函數設置的timer超時或setitimer函數設置的interval timer超時[終止]
SIGBUS     某種特定的硬件異常,通常由內存訪問引起         [終止+core]
SIGCANCEL     由Solaris Thread Library內部使用,通常不會使用       [忽略]
SIGCHLD     進程Terminate或Stop的時候,SIGCHLD會發送給它的父進程。缺省情況下該Signal會被忽略                                   [忽略]
SIGCONT     當被stop的進程恢復運行的時候,自動發送               [繼續/忽略]
SIGEMT     和實現相關的硬件異常                             [終止+core]
SIGFPE     數學相關的異常,如被0除,浮點溢出,等等               [終止+core]
SIGFREEZE     Solaris專用,Hiberate或者Suspended時候發送           [忽略]
SIGHUP     發送給具有Terminal的Controlling Process,當terminal被disconnect時候發送-----連接斷開                         [終止]            
SIGILL     非法指令異常                                 [終止+core]
SIGINFO     BSD signal。由Status Key產生,通常是CTRL+T。發送給所有Foreground Group的進程                                     [忽略]
SIGINT     由Interrupt Key產生,通常是CTRL+C或者DELETE。發送給所有ForeGround Group的進程                                   [終止]
SIGIO     異步IO事件                                   [忽略/終止]
SIGIOT     實現相關的硬件異常,一般對應SIGABRT                 [終止+core]
SIGKILL     無法處理和忽略。中止某個進程                         [終止]
SIGLWP     由Solaris Thread Libray內部使用                   [忽略]
SIGPIPE     在reader中止之后寫Pipe的時候發送                   [終止]
SIGPOLL     當某個事件發送給Pollable Device的時候發送             [終止]
SIGPROF     Setitimer指定的Profiling Interval Timer所產生         [終止]
SIGPWR     和系統相關。和UPS相關。電源失效/重起動           [終止/忽略]  
SIGQUIT     輸入Quit Key的時候(CTRL+/)發送給所有Foreground Group的進程[終+core]
SIGSEGV     非法內存訪問                                   [終止+core]
SIGSTKFLT     Linux專用,數學協處理器的棧異常                     [終止]
SIGSTOP     中止進程。無法處理和忽略。                         [暫停進程]
SIGSYS     非法系統調用                                 [終止+core]
SIGTERM     請求中止進程,kill命令缺省發送                     [終止]
SIGTHAW     Solaris專用,從Suspend恢復時候發送                 [忽略]
SIGTRAP     實現相關的硬件異常。一般是調試異常                   [終止+core]
SIGTSTP     Suspend Key,一般是Ctrl+Z。發送給所有Foreground Group的進程[暫停進程]
SIGTTIN     當Background Group的進程嘗試讀取Terminal的時候發送       [暫停進程]
SIGTTOU     當Background Group的進程嘗試寫Terminal的時候發送       [暫停進程]
SIGURG     當out-of-band data接收的時候可能發送                 [忽略]
SIGUSR1     用戶自定義signal 1                               [終止]
SIGUSR2     用戶自定義signal 2                               [終止]
SIGVTALRM     setitimer函數設置的Virtual Interval Timer超時的時候     [終止
SIGWAITING     Solaris Thread Library內部實現專用                   [忽略
SIGWINCH     當Terminal的窗口大小改變的時候,發送給Foreground Group的所有進程[忽略]
SIGXCPU     當CPU時間限制超時的時候                     [終止+core/忽略]
SIGXFSZ     進程超過文件大小限制                         [終止+core/忽略]
SIGXRES     Solaris專用,進程超過資源限制的時候發送               [忽略]
不產生core文件的幾個條件(1)進程是設置用戶ID的,而且當前用戶並非程序文件的所有者(2)進程是設置組ID的,而且當前用戶並非該程序文件的組所有者(3)用戶沒有寫當前工作目錄的權限(4)文件已存在,而且用戶對該文件沒有寫權限(5)文件太大。

2.#include <signal.h> void (*signal(int signo, void(*func)(int)))(int);
  //捕捉信號並處理,返回之前的signal處理函數,錯誤返回SIG_ERR
  signo:信號名                      
  Func:函數地址,或者是SIG_IGN (忽略Signal)或SIG_DFL(缺省行為)。原型為:void (*)(int)。不過很多UNIX的實現也會傳入一些和實現相關的參數. 如果用exec創建子進程,那么子進程的所有Signal狀態是缺省或者忽略:1. 如果父進程忽略了某個Signal,那么父進程用exec創建子進程時子進程的這個Signal的狀態也是忽略2. 如果在父進程的某個Signal注冊了Signal處理函數的話,那么這個子進程的該Signal的狀態會恢復成缺省狀態,因為注冊的函數地址肯定在另外一個進程中無法調用。如果用fork創建子進程,那么子進程會繼承所有父進程的Signal狀態。            

3. int kill(pit_t pid, int signo);//發送信號給進程或進程組
pid的值>0 將該信號發送給進程ID為pid的進程
  pid==0 將該信號發送給與發送進程屬於同一進程組的所有進程,且發送進程具有向其發信號的權限
  pid < 0 將該信號發送給其進程組ID等於pid的絕對值,而且發送進程具有向其發送信號的權限
  pid == -1將該信號發送給發送進程有權限向他們發送信號的系統上的所有進程
int raise(int signo);//進程給自身發送信號;成功返回0,錯誤返回-1

4. unsigned int alarm(unsigned int second);//返回前一個alarm的剩余時間值,單位秒
SIGALRM的缺省行為是中止進程。同一個進程只能有一個alarm。調用alarm函數會取消前一個alarm,並返回前一個alarm的剩余時間。如果second值為0,則只是取消前一個alarm。
  int pause(void);//Pause函數暫停當前進程運行,知道某個信號被捕捉signal被catch

5. int sigemptyset(sigset_t *set); 初始化sigset_t,所有signal都不包括在內
int sigfillset(sigset_t *set); 初始化sigset_t,包括所有signal
  int sigaddset(sigset_t *set, int signo); 添加signal
int sigdelset(sigset_t *set, int signo); 刪除signal
//成功返回0,錯誤返回-1
int sigismember(sigset_t *set, int signo);
//返回1如果是,不是則返回0

6. int sigprocmask(int how, const sigset_t *restrict set, sig_set *restrict oset);
//成功返回0,錯誤返回-1; how參數的意義如下:
SIG_BLOCK     在原來的mask基礎上Block signal set
SIG_UNBLOCK     在原來的mask基礎上Unblock signal set
SIG_SETMASK     設置mask為指定的signal set
  set:signal set,如果=NULL則忽略how參數(again,又是一個不太合適的設計,不利於差錯和記憶)
oset:返回當前process的signal mask

7. int sigpending(sigset_t *set);//成功返回0,錯誤返回-1 函數返回當前被block而沒有deliver的signal的集合到set中

8.int sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oact);//檢查或修改與指定信號相關聯的處理動作(或同時執行兩種操作)
struct sigaction {
    void           (*sa_handler)(int);// signal處理函數
    sigset_t     sa_mask;
    int         sa_flags;
    void         (*sa_sigaction)(int, siginfo_t *, void *)
};// sa_mask:當signal函數被調用的時候,自動block這些signal。當signal處理函數返回的時候,mask會恢復到初始值。同時,操作系統也會自動把該signal加到mask中,防止重入 ;   sa_flags:定義如下:
SA_INTERRUPT     被該signal中斷的系統調用不會自動重啟
SA_NOCLDSTOP     如果signo是SIGCHLD,當子進程stop的時候不產生該signal
SA_NOCLDWAIT     如果signo是SIGCHLD,子進程不會變成zombie。當調用wait的時候,調用進程會一直等待直到所有子進程結束
SA_NODEFER     在signal處理函數中系統不會自動block該signal
SA_ONSTACK     如果調用了sigaltstack指定一個額外的stack,那么該signal發送的時候,進程處於此stack中
SA_RESETHAND     恢復為初始化值,SA_SIGINFO flag也會被清除
SA_RESTART     被該signal中斷的系統調用會自動重啟
SA_SIGINFO     為signal處理函數提供額外信息

9. int sigsetjmp(sigjmp_buf env, int savemask); //保存信號屏蔽字
//直接調用返回0,從siglongjmp返回的時候返回非0
void siglongjmp(sigjmp_buf env, int val);//恢復信號屏蔽字
  //如果sigsetjmp的savemask為非0,則sigsetjmp會在env參數中記住當前process的signal mask。一般情況下如果和signal打交道的話都需要調用這兩個函數。

10.int sigsuspend(const sigset_t *sigmask);//將信號屏蔽字設置為sigmask指定的值。在捕捉到一個信號或發生了一個會終止該進程的信號前,該進程被掛起。如果捕捉到一個信號而且從該信號處理程序返回,則sigsuspend返回並將進程的信號屏蔽字設置為調用sigsuspend前的值 ;       返回-1並將errno設置為EINTR

11.void abort(void);//使異常程序終止                  
         
12. System函數除了會執行可執行文件創建子進程之外,還會設置sigmask為忽 略SIGINT,SIGQUIT並Block SIGCHLD。1.   忽略SIGINT和SIGQUIT的原因是,只有子進程應該處理這兩個signal,而父進程無需處理2.   Block SIGCHLD的原因是,System函數需要知道子進程的結束,而父進程不應該先提前知道,以免提前調用wait函數使得System函數本身無法獲得進程的退出值

13.unsigned int sleep(unsignes int seconds);//休眠函數,返回0或未休眠的秒數  
14.void gsignal(int signo, const char *msg);//字符串msg(通常是程序名)輸出到標准錯錯文件,后接一個冒號個一個空格再接着對該信號的說明,最后是一個換行符,類似於perror  
15.char *strsignal(int signo);//給出一個信號,strsignal將返回說明該信號的字符串,應用程序可用該字符串打印關於收到信號的出錯信息。類似於strerror


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com