Linux网络编程学习(三) ----- 进程控制实例(第三章)
本节主要介绍一个进程控制的实例,功能就是在前台或者后台接收命令并执行命令,还能处理由若干个命令组成的命令行,该程序命名为samllsh。
基本逻辑就是
while(EOF not typed)
{
从用户终端取得命令行
执行命令
}
setp1:取得命令行内容,用uerin函数实现,处理步骤首先显示提示符,提示符的具体内容由用户通过参数传递给函数,然后每次从键盘读取一个字符,存入inpbuf中,结束时userin返回字符个数或者EOF(文件结尾),换行符也要存入inpbuf
代码如下:
#include "smallsh.h"
/* 程序缓冲区和指针 */
static char inpbuf[MAXBUF],tokbuf[2*MAXBUF],
*ptr = inpbuf,*tok = tokbuf;
/* userin()函数 */
int userin(chat* p)
{
int c,count;
ptr = inpbuf;
tok = tokbuf;
/* 显示提示 */
printf("%s ",p);
for (count = 0;;)
{
if ((c=getchar())==EOF)
return(EOF);
if (count < MAXBUF)
inpbuf[count++] = c;
if (c =='\n' && count < MAXBUF)
{
inpbuf[count] = '\0';
return(count);
}
/* 如果行过长重新输入 */
if (c == '\n')
{
printf("smallsh:input line too long\n");
count=0;
printf("%s ",p);
}
}
}
其中的头文件samllsh.h内容为
#include <stdio.h>
#define EOL 1 /* 行结束 */
#define ARG 2
#define AMPERSAND 3
#define SEMICOLON 4
#define MAXARG 512 /* 命令行参数个数的最大值 */
#define MAXBUF 512 /* 输入行的最大长度 */
#define FOREGROUND 0
#define BACKGROUND 1
step2:从userin构造的命令行缓冲区中分析出命令名和参数,采用gettok函数,其中的tptr是一个字符型指针,调用后该指针指向实际的解析出的内容,调用方法是toktype = gettok(&tptr)
int gettok(char* output)
{
int type;
outptr = tok;
/* 首先去除空白字符 */
for (;*ptr==''||*ptr=='\t';ptr++)
{
*tok++ = *ptr;
} switch(*ptr++)
{
case '\n':
type=EOL;
break;
case '&':
type=AMPERSAND;
break;
case ';':
type=SEMICOLON;
break;
default:
type=ARG;
while (inarg(*ptr))
{
*tok++ = *ptr++;
} }
*tok++ = '\0';
return (type);
}
step3:采用函数inarg用于确定一个字符是否可以作为参数的组成符,检查字符是否是smallsh的特殊字符,代码如下
static char special[]={‘‘,’\t’,’*’,’;’,’\n’,’\0’};
int inarg(char c)
{
char *wrk;
for (wrk = special;*wrk != ’\0’;wrk++)
{
if (c == *wrk) return(0);
}
return(1);
}
step4:程序procline使用函数gettok()分析命令行,处理过程中构造一张参数表,当遇到换行符或者分号时,就调用runcommand来执行被分析的命令行,假设已经用userin读入了一个输入行
#include "smallsh.h"
void procline()
{
char * arg[MAXARG+1];
int toktype;
int narg;
int type;
for(narg = 0;;)
{
switch(toktype = gettok(&arg[narg]))
{
case ARG:
if (narg<MAXARG)
narg++;
break:
case EOL:
case SEMICOLON:
case AMPERSAND:
type = (toktype==AMPERSAND)?BACKGROUND:FOREGROUND;
if (narg != 0)
{
arg[narg] = NULL;
runcommand(arg,type);
}
if (toktype==EOL)
return;
narg=0;
break;
}
}
}
step5:函数runcommand,实现启动命令进程,入参为一个整型参数where,如果where被设置为BACKGROUND,那么将忽略wait()的调用,并且runcommand只显示进程标识符就返回。wait()返回的是第一个结束的子进程的进程标识符,而不是最后一个被启动的子进程的进程标识符。
execvp()表明按当前环境变量Path中的目录来搜索命令中表明的程序文件
#include "smallsh.h"
int runcommand(char** cline,int where)
{
int pid,exitstat,ret;
if((pid = fork()) < 0)
{
perror("fork fail");
return(-1);
}
if (!pid)
{ /* 子进程代码 */
execvp(*cline,cline);
perror(*cline);
exit(127);
}
/* 父进程代码 */
/* 后台进程代码 */
if (where==BACKGROUND)
{
printf("[process id %d]\n",pid);
return(0);
}
/* 前台进程代码 */
while ((ret = wait(&exitstat))!= pid && ret != -1) ;
return (ret==-1?-1:exitstat);
}
step6:最后就是main函数了
#include "smallsh.h"
char *prompt = "command>";
void main()
{
while (userin(prompt)!=EOF)
{
procline();
}
}
Linux网络编程学习(三) ----- 进程控制实例(第三章)的更多相关文章
- Linux网络编程学习(二) ----- 进程控制(第三章)
1.进程和程序 程序是一个可执行文件,而一个进程是一个执行中的程序实例.一个进程对应于一个程序的执行,进程是动态的,程序是静态的,多个进程可以并发执行同一个程序.比如几个用户可以同时运行一个编辑程序, ...
- Linux网络编程学习(八) ----- 文件和记录锁定(第四章)
1.什么是文件和记录锁定? 文件锁定的是整个文件,而记录锁定只锁定文件的一部分,文件和记录锁分为咨询式锁定和强制锁定 1)咨询式锁定 某个进程对某个文件进行了咨询式锁定,其他想访问该文件的进程将会被操 ...
- Linux网络编程学习计划
由于网络编程是很重要的一块,自己这一块也比较欠缺,只知道一些皮毛,从今天开始系统学习<Linux网络编程>一书,全书分为十四个章节: 第一章 概论 P1-16 第二章 UNIX ...
- Linux网络编程学习路线
转载自:https://blog.csdn.net/lianghe_work/article 一.网络应用层编程 1.Linux网络编程01——网络协议入门 2.Linux网络编程02——无连接和 ...
- Linux网络编程——原始套接字实例:MAC 头部报文分析
通过<Linux网络编程——原始套接字编程>得知,我们可以通过原始套接字以及 recvfrom( ) 可以获取链路层的数据包,那我们接收的链路层数据包到底长什么样的呢? 链路层封包格式 M ...
- Linux网络编程学习(四) -----守护进程的建立(第三章)
本文介绍一个例程daemon_init() #include <sys/types.h> #include <signal.h> #include <unistd.h&g ...
- Linux网络编程学习(九) ----- 消息队列(第四章)
1.System V IPC System V中引入的几种新的进程间通信方式,消息队列,信号量和共享内存,统称为System V IPC,其具体实例在内核中是以对象的形式出现的,称为IPC 对象,每个 ...
- linux网络编程学习笔记之五 -----并发机制与线程�
进程线程分配方式 简述下常见的进程和线程分配方式:(好吧,我仅仅是举几个样例作为笔记...并发的水太深了,不敢妄谈...) 1.进程线程预分配 简言之,当I/O开销大于计算开销且并发量较大时,为了节省 ...
- linux网络编程学习笔记之四 -----多-threaded服务器
对于使用过程中并发.通过实现更轻量级线程. 每个线程都是一个独立的逻辑流. 主题是CPU在执行调度的最小独立单位,这个过程是资源分配单元.当然,这是在微内核操作系统说.总之,这是唯一的一个操作系统内核 ...
随机推荐
- Linux CentOS6.8 项目部署脚本实现
面向刚接触linux环境的新手,老鸟勿拍~ 部署环境及配置: tomcat9,maven3.3.9,git 1.12.0 ##定义一些变量,将需要用到的 source目录,项目目录,名称等定义变量,方 ...
- Spell checker using hash table
Problem description Given a text file, show the spell errors from it. (https://www.andrew.cmu.edu/c ...
- 绑定属性 - v-bind
未绑定 <!DOCTYPE html><html><head> <meta charset="utf-8"> <t ...
- LiquiBase 学习
preconditions mysql database is installed maven has been setted up properly add depedenceies apply p ...
- springMvc---跨服务器文件上传(实测总结)
序言: 该案例是采用springMvc实现跨服务器图片上传功能,其中用到的主要类和工具有:CommonsMultipartResolver.jquery.form.js.如果要实现多个文件上传,只需要 ...
- kolla单节点部署openstack
virtualbox环境: 双网卡:enp0s3(桥接) 192.168.102.194 enp0s8(桥接) 无ip 块存储 50G 关闭防火墙,selinux. 配置yum源:wget ...
- https://blog.csdn.net/doegoo/article/details/50749817
因为使用DiscuzX3.2进行系统的整合后,因为只是想在原J2EE的系统上增加论坛功能,而且J2EE中已经有一套用户的注册认证的体系,所以不需要在Discuz的系统中去注册以及登录功能,而是通过在J ...
- windows server 2008 R2之tomcat开机自启
方法一: 写一个批处理文件autostartup.bat用来启动tomcat,内容如下.复制时不要把复制内容也复制进去 set CATALINA_HOME=C:\apache-tomcat-8.5.3 ...
- glog学习(二):glog主要接口和类分析
1.glog的主要接口如下. #define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()#define SYSLOG(severity ...
- Session、Cookie、Cache、Token分别是什么及区别
一.Session 1 )Session 解释 Session 是单用户的会话状态.当用户访问网站时,产生一个 sessionid.并存在于 cookies中.每次向服务器请求时,发送这个 cooki ...