?? sys.c
字號:
/** linux/kernel/sys.c** (C) 1991 Linus Torvalds*/#include <errno.h> // 錯誤號頭文件。包含系統中各種出錯號。(Linus 從minix 中引進的)。#include <linux/sched.h> // 調度程序頭文件,定義了任務結構task_struct、初始任務0 的數據,// 還有一些有關描述符參數設置和獲取的嵌入式匯編函數宏語句。#include <linux/tty.h> // tty 頭文件,定義了有關tty_io,串行通信方面的參數、常數。#include <linux/kernel.h> // 內核頭文件。含有一些內核常用函數的原形定義。#include <asm/segment.h> // 段操作頭文件。定義了有關段寄存器操作的嵌入式匯編函數。#include <sys/times.h> // 定義了進程中運行時間的結構tms 以及times()函數原型。#include <sys/utsname.h> // 系統名稱結構頭文件。// 返回日期和時間。intsys_ftime (){ return -ENOSYS;}//intsys_break (){ return -ENOSYS;}// 用于當前進程對子進程進行調試(degugging)。intsys_ptrace (){ return -ENOSYS;}// 改變并打印終端行設置。intsys_stty (){ return -ENOSYS;}// 取終端行設置信息。intsys_gtty (){ return -ENOSYS;}// 修改文件名。intsys_rename (){ return -ENOSYS;}//intsys_prof (){ return -ENOSYS;}// 設置當前任務的實際以及/或者有效組ID(gid)。如果任務沒有超級用戶特權,// 那么只能互換其實際組ID 和有效組ID。如果任務具有超級用戶特權,就能任意設置有效的和實際// 的組ID。保留的gid(saved gid)被設置成與有效gid 同值。intsys_setregid (int rgid, int egid){ if (rgid > 0) { if ((current->gid == rgid) || suser ()) current->gid = rgid; else return (-EPERM); } if (egid > 0) { if ((current->gid == egid) || (current->egid == egid) || (current->sgid == egid) || suser ()) current->egid = egid; else return (-EPERM); } return 0;}// 設置進程組號(gid)。如果任務沒有超級用戶特權,它可以使用setgid()將其有效gid// (effective gid)設置為成其保留gid(saved gid)或其實際gid(real gid)。如果任務有// 超級用戶特權,則實際gid、有效gid 和保留gid 都被設置成參數指定的gid。intsys_setgid (int gid){ return (sys_setregid (gid, gid));}// 打開或關閉進程計帳功能。intsys_acct (){ return -ENOSYS;}// 映射任意物理內存到進程的虛擬地址空間。intsys_phys (){ return -ENOSYS;}intsys_lock (){ return -ENOSYS;}intsys_mpx (){ return -ENOSYS;}intsys_ulimit (){ return -ENOSYS;}// 返回從1970 年1 月1 日00:00:00 GMT 開始計時的時間值(秒)。如果tloc 不為null,則時間值// 也存儲在那里。intsys_time (long *tloc){ int i; i = CURRENT_TIME; if (tloc) { verify_area (tloc, 4); // 驗證內存容量是否夠(這里是4 字節)。 put_fs_long (i, (unsigned long *) tloc); // 也放入用戶數據段tloc 處。 } return i;}/** Unprivileged users may change the real user id to the effective uid* or vice versa.*//** 無特權的用戶可以見實際用戶標識符(real uid)改成有效用戶標識符(effective uid),反之也然。*/// 設置任務的實際以及/或者有效用戶ID(uid)。如果任務沒有超級用戶特權,那么只能互換其// 實際用戶ID 和有效用戶ID。如果任務具有超級用戶特權,就能任意設置有效的和實際的用戶ID。// 保留的uid(saved uid)被設置成與有效uid 同值。intsys_setreuid (int ruid, int euid){ int old_ruid = current->uid; if (ruid > 0) { if ((current->euid == ruid) || (old_ruid == ruid) || suser ()) current->uid = ruid; else return (-EPERM); } if (euid > 0) { if ((old_ruid == euid) || (current->euid == euid) || suser ()) current->euid = euid; else { current->uid = old_ruid; return (-EPERM); } } return 0;}// 設置任務用戶號(uid)。如果任務沒有超級用戶特權,它可以使用setuid()將其有效uid// (effective uid)設置成其保留uid(saved uid)或其實際uid(real uid)。如果任務有// 超級用戶特權,則實際uid、有效uid 和保留uid 都被設置成參數指定的uid。intsys_setuid (int uid){ return (sys_setreuid (uid, uid));}// 設置系統時間和日期。參數tptr 是從1970 年1 月1 日00:00:00 GMT 開始計時的時間值(秒)。// 調用進程必須具有超級用戶權限。intsys_stime (long *tptr){ if (!suser ()) // 如果不是超級用戶則出錯返回(許可)。 return -EPERM; startup_time = get_fs_long ((unsigned long *) tptr) - jiffies / HZ; return 0;}// 獲取當前任務時間。tms 結構中包括用戶時間、系統時間、子進程用戶時間、子進程系統時間。intsys_times (struct tms *tbuf){ if (tbuf) { verify_area (tbuf, sizeof *tbuf); put_fs_long (current->utime, (unsigned long *) &tbuf->tms_utime); put_fs_long (current->stime, (unsigned long *) &tbuf->tms_stime); put_fs_long (current->cutime, (unsigned long *) &tbuf->tms_cutime); put_fs_long (current->cstime, (unsigned long *) &tbuf->tms_cstime); } return jiffies;}// 當參數end_data_seg 數值合理,并且系統確實有足夠的內存,而且進程沒有超越其最大數據段大小// 時,該函數設置數據段末尾為end_data_seg 指定的值。該值必須大于代碼結尾并且要小于堆棧// 結尾16KB。返回值是數據段的新結尾值(如果返回值與要求值不同,則表明有錯發生)。// 該函數并不被用戶直接調用,而由libc 庫函數進行包裝,并且返回值也不一樣。intsys_brk (unsigned long end_data_seg){ if (end_data_seg >= current->end_code && // 如果參數>代碼結尾,并且 end_data_seg < current->start_stack - 16384) // 小于堆棧-16KB, current->brk = end_data_seg; // 則設置新數據段結尾值。 return current->brk; // 返回進程當前的數據段結尾值。}/** This needs some heave checking ...* I just haven't get the stomach for it. I also don't fully* understand sessions/pgrp etc. Let somebody who does explain it.*//** 下面代碼需要某些嚴格的檢查…* 我只是沒有胃口來做這些。我也不完全明白sessions/pgrp 等。還是讓了解它們的人來做吧。*/// 將參數pid 指定進程的進程組ID 設置成pgid。如果參數pid=0,則使用當前進程號。如果// pgid 為0,則使用參數pid 指定的進程的組ID 作為pgid。如果該函數用于將進程從一個// 進程組移到另一個進程組,則這兩個進程組必須屬于同一個會話(session)。在這種情況下,// 參數pgid 指定了要加入的現有進程組ID,此時該組的會話ID 必須與將要加入進程的相同(193 行)。intsys_setpgid (int pid, int pgid){ int i; if (!pid) // 如果參數pid=0,則使用當前進程號。 pid = current->pid; if (!pgid) // 如果pgid 為0,則使用當前進程pid 作為pgid。 pgid = current->pid; // [??這里與POSIX 的描述有出入] for (i = 0; i < NR_TASKS; i++) // 掃描任務數組,查找指定進程號的任務。 if (task[i] && task[i]->pid == pid) { if (task[i]->leader) // 如果該任務已經是首領,則出錯返回。 return -EPERM; if (task[i]->session != current->session) // 如果該任務的會話ID return -EPERM; // 與當前進程的不同,則出錯返回。 task[i]->pgrp = pgid; // 設置該任務的pgrp。 return 0; } return -ESRCH;}// 返回當前進程的組號。與getpgid(0)等同。intsys_getpgrp (void){ return current->pgrp;}// 創建一個會話(session)(即設置其leader=1),并且設置其會話=其組號=其進程號。intsys_setsid (void){ if (current->leader && !suser ()) // 如果當前進程已是會話首領并且不是超級用戶 return -EPERM; // 則出錯返回。 current->leader = 1; // 設置當前進程為新會話首領。 current->session = current->pgrp = current->pid; // 設置本進程session = pid。 current->tty = -1; // 表示當前進程沒有控制終端。 return current->pgrp; // 返回會話ID。}// 獲取系統信息。其中utsname 結構包含5 個字段,分別是:本版本操作系統的名稱、網絡節點名稱、// 當前發行級別、版本級別和硬件類型名稱。intsys_uname (struct utsname *name){ static struct utsname thisname = { // 這里給出了結構中的信息,這種編碼肯定會改變。 "linux .0", "nodename", "release ", "version ", "machine " }; int i; if (!name) return -ERROR; // 如果存放信息的緩沖區指針為空則出錯返回。 verify_area (name, sizeof *name); // 驗證緩沖區大小是否超限(超出已分配的內存等)。 for (i = 0; i < sizeof *name; i++) // 將utsname 中的信息逐字節復制到用戶緩沖區中。 put_fs_byte (((char *) &thisname)[i], i + (char *) name); return 0;}// 設置當前進程創建文件屬性屏蔽碼為mask & 0777。并返回原屏蔽碼。intsys_umask (int mask){ int old = current->umask; current->umask = mask & 0777; return (old);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -