当前位置:Linux教程 - Linux资讯 - UNIX学习之UNIX编程资料大收集二

UNIX学习之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)捕获方式(设置信号处理函数):这是用户设置的信号处理方式,当进程接收到这种信号时
[1] [2] 下一页 

(出处:http://www.sheup.com)


上一页 [1] [2]