linux内核分析之sys.c

#include <errno.h>

#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/kernel.h>
#include <asm/segment.h>
#include <sys/times.h>
#include <sys/utsname.h>

这个文件中包含了绝大部分系统调用函数的实现,
如果系统调用在该内核版本中没实现,就直接返回ENOSYS
int sys_ftime()
{
 return -ENOSYS;
}

int sys_break()
{
 return -ENOSYS;
}

int sys_ptrace()
{
 return -ENOSYS;
}

int sys_stty()
{
 return -ENOSYS;
}

int sys_gtty()
{
 return -ENOSYS;
}

int sys_rename()
{
 return -ENOSYS;
}

int sys_prof()
{
 return -ENOSYS;
}
int sys_acct()
{
 return -ENOSYS;
}

int sys_phys()
{
 return -ENOSYS;
}

int sys_lock()
{
 return -ENOSYS;
}

int sys_mpx()
{
 return -ENOSYS;
}

int sys_ulimit()
{
 return -ENOSYS;
}

设置实际、有效用户组id
int sys_setregid(int rgid, int egid)
{
 if (rgid>0) {
   如果将要设置的实际组id和当前进程的组id相同或者是超级用户,则
   设置该组id
  if ((current->gid == rgid) ||
      suser())
   current->gid = rgid;
  else
   return(-EPERM);
 }
 
 if (egid>0) {
   如果将要设置的有效组id和当前进程的组id相同或者和当前进程的
   有效组id相同或者和设置组id相同,或者是超级用户,则设置有效组
   id。
  if ((current->gid == egid) ||
      (current->egid == egid) ||
      (current->sgid == egid) ||
      suser())
   current->egid = egid;
  else
   return(-EPERM);
 }
 return 0;
}

设置组id,将实际组id和有效组id设置为相同的值
int sys_setgid(int gid)
{
 return(sys_setregid(gid, gid));
}

取当前的系统时间
int sys_time(long * tloc)
{
 int i;
  当前的系统时间CURRENT_TIME定义为startup_time+jiffies/HZ,系统开机时间加上
  滴答数换算成秒数
 i = CURRENT_TIME;
 if (tloc) {
   验证用户数据区是否有效
  verify_area(tloc,4);
  采用该函数对用户数据区中的内存进行付值,当前是在内核数据段中
  put_fs_long(i,(unsigned long *)tloc);
 }
 return i;
}

设置实际和有效用户id
int sys_setreuid(int ruid, int euid)
{
 int old_ruid = current->uid;
 
 if (ruid>0) {
   如果实际用户id和当前进程的有效用户id相同或者是超级用户
   或者和当前进程的用户id相同,则设置当前进程的用户id
  if ((current->euid==ruid) ||
                    (old_ruid == ruid) ||
      suser())
   current->uid = ruid;
  else
   return(-EPERM);
 }
 if (euid>0) {
   如果当前用户id和有效用户id相同或者有效用户id和当前
   进程的有效用户id相同或者是超级用户,则设置有效用户id
  if ((old_ruid == euid) ||
                    (current->euid == euid) ||
      suser())
   current->euid = euid;
  else {
   current->uid = old_ruid;
   return(-EPERM);
  }
 }
 return 0;
}

设置用户id,将进程的用户id和有效用户id设置成相同的值
int sys_setuid(int uid)
{
 return(sys_setreuid(uid, uid));
}

超级用户设置系统开机时间
int sys_stime(long * tptr)
{
 if (!suser())
  return -EPERM;
 从用户数据段中得到从1970年1月1日0时开始的秒数,减去系统启动之后经历的
 秒数,设置开机时间
 startup_time = get_fs_long((unsigned long *)tptr) - jiffies/HZ;
 return 0;
}

设置tms数据结构的值
int sys_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;
}

设置brk值
int sys_brk(unsigned long end_data_seg)
{
  如果新的brk值在代码段和数据段末端不超过最后16k的范围内
  就可以设置新的brk值
 if (end_data_seg >= current->end_code &&
     end_data_seg < current->start_stack - 16384)
  current->brk = end_data_seg;
 return current->brk;
}

设置进程组id
int sys_setpgid(int pid, int pgid)
{
 int i;

 if (!pid)
  pid = current->pid;
 if (!pgid)
  pgid = current->pid;
 便利任务数组,如果该进程不是会话期的首进程可以重新设置新的进程组id
 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)
    return -EPERM;
   task[i]->pgrp = pgid;
   return 0;
  }
 没找到合适的进程
 return -ESRCH;
}

返回当前进程的进程组id
int sys_getpgrp(void)
{
 return current->pgrp;
}

设置进程的会话期
int sys_setsid(void)
{
  只有超级用户并且当前进程是领导进程才能设置新的会话期
 if (current->leader && !suser())
  return -EPERM;
 把当前进程置为领导者进程,脱离与控制终端的联系
 设置当前进程id为进程组id和会话期id
 current->leader = 1;
 current->session = current->pgrp = current->pid;
 current->tty = -1;
 return current->pgrp;
}

int sys_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++)
  put_fs_byte(((char *) &thisname)[i],i+(char *) name);
 return 0;
}

设置umask值
int sys_umask(int mask)
{
 int old = current->umask;
  对新的mask值进行范围约束,并设置当前mask值
 current->umask = mask & 0777;
 return (old);
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值