歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Unix知識 >> Unix教程 >> UNIX學習之UNIX編程資料大收集二

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

日期:2017/2/27 17:42:32   编辑:Unix教程

  當命令行參數的個數不為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