歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> 更多Linux >> UNIX學習之UNIX編程資料大收集二

UNIX學習之UNIX編程資料大收集二

日期:2017/2/27 9:35:12   编辑:更多Linux
  當命令行參數的個數不為1時,程序使用fork系統調用產生一個子進程。子進程通過系統調用getpid獲得自己的進程標識符,然後調用exec執行命令行中用戶提交的命令,如果exec執行失敗,則子進程調用exit(5)終止。父進程使用wait系統調用等待子進程暫停或終止,然後輸出從wait中返回的信息。下面以三種方式執行該程序:    1〕 不帶命令行參數    % ./feew  pid=-1, H_stat=0, L_stat=0  %    不產生子進程,從運行結果來看,當無子進程時,wait的返回值為-1。    2〕 帶命令行參數,參數為合法的可執行命令    % ./feew /bin/date  Child pid = 1725  1998年 2月16日(星期一) 15時59分14秒 CST  pid=1725, H_stat=0, L_stat=0  %    產生子進程。子進程輸出其進程標識符後,再調用exec執行從命令行中提交的命令(/bin/date),同時父進程等待子進程暫停或終止,然後輸出從wait中得到的信息:子進程標識符或狀態參數stat的高八位、低八位的內容。從中可以看到:子進程因調用一個隱含的exit(0)而終止,終止時傳給父進程的值為0。    3〕 帶命令行參數,但參數不合法    %./feew /etc/shudown  Child pid = 1760  /etc/shutdown: 只有超級用戶(root)能運行 /etc/shutdown。  pid=1760, H_stat=2, L_stat=0  %    子進程創建成功。但由於以普通用戶的身份執行/etc/shutdown,因此exec失敗,爾後調用exit(5)而終止;父進程調用wait得到返回值:子進程號和狀態參數stat的高八位、低八位的內容。從執行結果可以看出:子進程因調用exit(5)而終止,終止時傳給父進程的值為5。    5.3 進程管理    進程管理包括的面很廣,諸如進程的用戶標識符管理、進程標識符管理等。進程的用戶標識符有兩個:實際用戶標識符(real user    id)和有效用戶標識符(effective user id),其對應的組標識符分別稱為實際組標識符(real group    id)和有效組標識符(effective groud    id)。一般而言,進程的實際用戶標識符為運行該進程的用戶標識符,通常只用於系統記帳,其他功能由有效用戶標識符來完成,如用有效用戶標識符來完成對新創建文件賦予屬性關系、檢查文件的存取權限和利用kill系統調用向進程發送信號的權限。一般情況下,一進程的有效用戶標識符和實際用戶標識符是相等的,但系統允許改變進程的有效用戶標識符。    1. 進程的用戶標識符管理    UNIX系統提供了一組系統調用來管理進程的用戶標識符,它們的使用形式是:    #include <sys/types.h>  #include <unistd.h>  uid_t getuid (void);  uid_t geteuid (void);  gid_t getgid (void);  gid_t getegid (void);  int setuid(uid_t uid);  int setgid(gid_t gid);    說明:前四個系統調用沒有參數,分別返回調用進程的實際用戶標識符、有效用戶標識符、    實際用戶組標識符和有效組標識符。這些系統調用的執行總能獲得成功,不會發生任何錯誤。系統調用setuid和setgid用於設置進程的實際用戶(組)標識符和有效用戶(組)標識符,如調用進程的有效用戶標識符是超級用戶標識符,則將調用的進程實際用戶(組)標識符和有效用戶(組)標識符設置為uid或gid;如調用進程的有效用戶標識符不是超級用戶標識符,但其實際用戶(組)標識符等於uid或gid時,則其有效用戶(組)標識符被設置為uid或gid;否則setuid或setgid調用失敗。系統調用setuid或setgid調用成功時返回0,失敗時返回-1。    2. 進程標識符管理    UNIX系統使用進程標識符來管理當前系統中的進程。為對具有某類似特性的進程統一管理,系統又引入了進程組的概念,以組標識符來區別進程是否同組。進程的組標識符是從父進程繼承下來的,所以,通常進程的組標識符就是和它相關聯的注冊進程的標識符。進程的標識符是由系統為之分配的,不能被修改;組標識符可通過setpgrp系統調用修改。    相關系統調用的格式如下:    #include <sys/types.h>  #include <unistd.h>  pid_t getpid(void);  pid_t getpgrp(void);  pid_t getppid(void);  pid_t getpgid(pid_t pid);    說明:前三個系統調用分別返回調用進程的進程標識符、進程組標識符和其父進程標識符。它們總能成功地返回。第四個調用置進程組標識符,它將調用進程的進程組標識符改為調用進程的進程標識符,使其成為進程組首進程,並返回這一新的進程組標識符。    下面我們來看一個實例:    /* setuid.c */  main(argc, argv)  int argc;  char *argv[];  {  int ret, uid;  uid = atoi(argv[1]);  printf("Before uid=%d, euid=%d\n", getuid(), geteuid());  ret = setuid(uid);  printf("After uid=%d, euid=%d\n", getuid(), geteuid());  printf("ret = %d\n", ret);  }    下面分三種情況討論該程序的執行:    1、 如果執行該程序的用戶為超級用戶,則只要命令行所給的用戶標識符大於0,無論所給的用戶標識符是否存在,執行總能成功。    #./setuid 3434  Before uid=0, euid=0  After uid=3434, euid=3434  ret = 0  #    結果分析:將進程的實際和有效用戶標識符均改為3434。    2、 如果執行該程序的用戶為一般用戶,用id命令得到用戶uid和gid後,再調用該程序,過程如下:    %id  uid=1111(yds) gid=20(user)  %./setuid 3434  Before uid=1111, euid=1111  After uid=1111, euid=1111  ret = -1  %./setuid 1111  Before uid=1111, euid=1111  After uid=1111, euid=1111  ret = 0  %    結果分析:當命令行參數為1111時,setuid執行成功,因為用戶的uid就是1111。    值得注意的是:注冊程序login    是個典型的setuid系統調用程序,login進程的有效用戶是超級用戶,該進程在建立用戶的Shell進程前,調用setuid將實際和有效用戶標識符調整為注冊用戶的用戶實際和有效標識符。    第六章 設備輸入/輸出控制    6.1 概述    UNIX將設備看成文件,這是UNIX的一大特色。這裡需要介紹一個設備號的概念。設備特別文件與兩個設備號有關-主設備號和次設備號。主設備號告訴操作系統,當涉及文件名時,將使用哪種設備類型。對於每一種類型的設備都有一段駐留在操作系統中的程序代碼,以控制相應類型的設備,這段代碼被稱為"設備驅動程序"。次設備號被傳遞給設備驅動程序,這個號碼用來決定使用哪種物理設備。例如,決定在一塊多重驅動控制卡上,哪個磁盤驅動器將被訪問,以及該磁盤驅動器中哪一部分將被使用;或者,當一個磁盤驅動器所請求的操作已經完成後,應該被恢復原狀。幾個設備(如同類型的磁盤驅動器)可以用同一個主設備號,但它們將有不同的次設備號。看下面的例子:    %ls -l /dev/ttyq*  crw--w---- 2 yds user 15, 1 2月 17日 09時03分 ttyq1  crw--w---- 2 yds user 15, 14 2月 16日 17時00分 ttyq14  %    上例中15是主設備號,1和14是次設備號。    用戶可以使用系統提供的統一而且獨立於設備的界面-對文件進行操作的系統調用來操作設備,而沒有必要涉及設備的具體細節。大部分對文件進行操作的系統調用對它們仍起作用,例如,用open打開設備,用read/write對設備進行讀/寫,設備操作完成後,用close關閉設備。但有的系統調用在對設備文件進行操作時,其功效有所不同。如create及open的創建方式都不能創建設備文件。    6.2 設備輸入/輸出控制-ioctl系統調用    ioctl是UNIX系統專門提供的用於設備控制的系統調用。該系統調用與設備類型(即主設備號)相關。不同的設備,系統提供了不同的控制命令。    ioctl的調用格式是:    ioctl(int fd, int cmd,arg…)    說明:參數fd是一設備文件的文件描述字,cmd是控制命令,它與設備相關,不同類型的設備有不同的控制命令。參數arg沒有固定的數據結構,它隨cmd的不同而不同。    第七章 高級編程    7.1 處理信號    信號是UNIX進程間最基本的通訊手段,主要作用是實現進程間異步事件的通訊。信號是傳送到進程的"軟中斷",它通知進程在它們的環境中出現了非正常事件。進程接收到信號後要進行處理,處理方式為以下四種之一:    (1)缺省方式(SIG_DFL):這是進程對信號的一般處理方式,在無特殊情況下,進程在接收到信號後將終止執行。有一些信號,在終止進程運行前需將終止進程的正文段、數據段、user結構和棧段內容寫到當前目錄的core文件中,以備調試工具分析與使用。    (2)忽略方式(SIG_IGN):進程接收到一個已指明忽略的信號,則將該信號清除後,立即返回,不在任何工作。信號SIGKILL不能被忽略。    (3)保持方式(SIG_HOLD):當進程處於該方式時,將接收的信號保存起來,等該進程的保持方式解除後,再進行處理。    (4)捕獲方式(設置信號處理函數):這是用戶設置的信號處理方式,當進程接收到這種信號時




Copyright © Linux教程網 All Rights Reserved