GreyZhang/g_unix: some basic learning about unix operating system. (github.com)
继续分析我手里这个shell实现例程的分析,这一次看一下parseredirs这个函数的实现。通过对函数实现的分析,结合函数的名称缩写,基本上可以知道这个函数实现的是命令重定向的解析。
前面已经分析了peek的作用,这个其实只是实现了空白字符的修剪和字符的匹配判断。能够在这里进入到while循环的信息其实是带有<>这两个重定向符号的。接着,第一个gettoken函数实现了重定向符号的获取;而第二个gettoken则实现了对于文件名的有效信息的判断。在这个过程中,如果在字符串中存在一些空白的信息组合其实都被这些处理给滤除掉了,这个是非常巧妙的一个实现。
接下来的处理就是处理两种定向符号,这样就需要弄清楚两个相关的函数的实现和功能。
首先分析mkcopy,这个函数根据指定的字符串的起始位置进行字符串信息的复制。在复制之后,无论结束的地方是否是一个字符串的结束都会增加一个字符串结束符。
而redircmd其实是进行了命令的重新组合,根据传入的文件名、定向类型对传入的命令进行重新包装。这就是重定向命令的处理过程。这里的cmd用到了好几种概念,因此可能会看着有些让人糊涂。其实,最后返回的命令指针信息并不是一个重定向命令结构,但是两者由于存储排布有着很有规律的空间关系,因此进行二次解析也是很容易的。
这样,再次回到整个重定向解析函数,整个过程就比较容易理解了。如果这个函数处理的信息中并没有重定向符号,那么命令还是会按照原来的状态进行返回。否则,会根据定向符号的信息对命令进行二次加工,附加一些额外的信息,具体包括读写权限、文件描述等。而结合前面的代码分析也可以知道,加工后的命令是在堆栈中重新开辟申请到的空间中存储着。
而命令解析的第一步,其实就是进行命令的重定向处理。由于传递的信息是一个地址,而这个地址后面的信息解析又有固定的空间相对关系,因此这样的接口是可以兼容两种不同的命令信息的。由此,即使是不需要重定向处理的命令被处理一下也不会有什么影响。