当前位置:  技术问答>linux和unix

linux c实现shell,但出现编译后,不能链接,望高手指点指点,谢谢啦

    来源: 互联网  发布时间:2017-01-26

    本文导语:  程序源码如下: #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #define  MAX_COMMAND_LEN 250 #define JOB_STATUS_FORMAT "[%d] %-22s %.40sn" struct jobSet { struct job *head; struct job *fg; }; struct ...

程序源码如下:
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define  MAX_COMMAND_LEN 250
#define JOB_STATUS_FORMAT "[%d] %-22s %.40sn"

struct jobSet
{
struct job *head;
struct job *fg;
};

struct childProgram
{
pid_t pid;
char **argv;
};

struct job
{
int jobId;
int numProgs;
int runningProgs;
char *text;
char *cmdBuf;
pid_t pgrp;
struct childProgram *progs;
struct job *next;
};

void freejob(struct job *cmd)
{
int i;

for(i = 0; i numProgs; i++)
{
free(cmd->progs[i].argv);
}
free(cmd->progs);
if(cmd->text)
free(cmd->text);
free(cmd->cmdBuf);
}

int getCommand(FILE *source, char *command)
{
if(source == stdin)
{
printf("#");
fflush(stdout);
}

if(!fgets(command, MAX_COMMAND_LEN, source))
{
if(source == stdin)
printf("n");
return 1;
}

command[strlen(command) - 1] = '';
return 0;

}

int praseCommand(char **commandPtr, struct job *job, int *isBg)
{
char *command;
char *returnCommand = NULL;
char *src, *buf;
int argc = 0;
int done = 0;
int argvAlloced;
char quote = '';
int count;
struct childProgram *prog;

while(**commandPtr &&isspace(**commandPtr))
(*commandPtr)++;

if(!**commandPtr || (**commandPtr == '#'))
{
job->numProgs = 0;
*commandPtr = NULL;
return 0;
}

*isBg = 0;
job->numProgs = 1;
job->progs = malloc(sizeof(*job->progs));

job->cmdBuf = command = calloc(1, strlen(*commandPtr) + 1);
job->text = NULL;
prog = job->progs;

argvAlloced = 5;
prog->argv = malloc(sizeof(*prog->argv) * argvAlloced);
prog->argv[0] = job->cmdBuf;

buf = command;
src = *commandPtr;
while(*src && !done)
{

if(quote == *src)
quote = '';

else if(quote)
{
if(*src == '\')
{
src++;
if(!*src)
{
fprintf(stderr, "character expected after \n");
freeJob(job);
return 1;
}
if(*src != quote)
*buf++ = '\';
}

*buf++ = *src;
}
else if(isspace(*src))
{
if(*prog->argv[argc])
{
buf++, argc++;
if((argc + 1) == argvAlloced)
{
argvAlloced += 5;
prog->argv = realloc(prog->argv, 
sizeof(*prog->argv) * argvAlloced);
}
prog->argv[argc] = buf;
}
}
else switch(*src)
{
case '"':
case ''': quote = *src; break;
case '#':  done = 1; break;
case '&':  *isBg = 1;
case ';':  done = 1; returnCommand = *commandPtr + (src - *commandPtr) + 1; break;
case '\': src++; 
      if(!*src)
      {
   freeJob(job);
   fprintf(stderr,"charecter expected after \n");
   return 1;
       }
default:   *buf++ = *src;
}
src++;
}

if(*prog->argv[argc])
{
argc++;
}
if(!argc)
{
freeJob(job);
return 0;
}
prog->argv[argc] = NULL;

if(!returnCommand)
{
job->text = malloc(strlen(*commandPtr) + 1);
strcpy(job->text, *commandPtr);
}
else
{
count = returnCommand - *commandPtr;
job->text = malloc(count + 1);
strncpy(job->text, *commandPtr, count);
job->text[count] = '';
}

*commandPtr = returnCommand;
return 0;
}

int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
{
struct job *job;

if(!strcmp(newJob.progs[0].argv[0], "exit"))
exit(0);
else if(!strcmp(newJob.progs[0].argv[0], "jobs"))
{
for(job = jobList->head; job; job = job->next)
printf(JOB_STATUS_FORMAT, job->jobId, "Running", job->text);
return 0;
}

if(!(newJob.progs[0].pid = fork()))
{
execvp(newJob.progs[0].argv[0], newJob.progs[0].argv);
fprintf(stderr, "exec() of %s failed: %sn", newJob.progs[0].argv[0], strerror(errno));
exit(1);
}
setpgid(newJob.progs[0].pid, newJob.progs[0].pid);

newJob.pgrp = newJob.progs[0].pid;
newJob.jobId = 1;
for(job = jobList->head; job; job->next)
if(job->jobId >= newJob.jobId)
newJob.jobId = job->jobId + 1;

if(!jobList->head)
job = jobList->head = malloc(sizeof(*job));
else
{
for(job = jobList->head; job->next; job = job->next)
job->next = malloc(sizeof(*job));
job = job->next;
}

*job = newJob;
job->next = NULL;
job->runningProgs = job->numProgs;

if(inBg)
{
printf("[%d] %dn", 
job->jobId, newJob.progs[newJob.numProgs - 1].pid);
}
else 
{
jobList->fg = job;

if(tcsetpgrp(0, newJob.pgrp))
perror("tcsetpgrp");
}

return 0;

}

void removejob(struct jobSet *jobList, struct job *job)
{
struct job *prevJob;

freeJob(job);
if(job == jobList->head)
jobList->head = job->next;
else
{
prevJob = jobList->head;
while(prevJob->next != job)
prevJob = prevJob->next;
prevJob->next = job->next;
}

free(job);
}

void checkJobs(struct jobSet *jobList)
{
struct job *job;
pid_t childpid;
int status;
int progNum;

while((childpid = waitpid(-1, &status, WNOHANG)) > 0)
{
for(job = jobList->head; job; job = job->next)
progNum = 0;
while(progNum numProgs &&
job->progs[progNum].pid != childpid)
progNum++;
if(progNum numProgs)
break;
}

job->runningProgs--;
job->progs[progNum].pid = 0;

if(!job->runningProgs)
{
printf(JOB_STATUS_FORMAT, job->jobId, "Done", job->text);
removeJob(jobList, job);
}

if(childpid == -1 && errno != ECHILD)
perror("waitpid");

}

int main(int argc, const char **argv)
{
char command[MAX_COMMAND_LEN + 1];
char *nextCommand = NULL;
struct jobSet jobList = {NULL, NULL};
struct job newJob;
FILE *input = stdin;
int i;
int status;
int inBg;

if(argc > 2)
{
fprintf(stderr, "unexpected arguments; usage: ladshl n");
exit(1);
}
else if(argc == 2)
{
input = fopen(argv[1], "r");
if(!input)
{
perror("fopen");
exit(1);
}
}

while(1)
{
if(!jobList.fg)
{
checkJobs(&jobList);
if(!nextCommand)
{
if(getCommand(input, command))
break;
nextCommand = command;
}

if(!praseCommand(&nextCommand, &newJob, &inBg) && newJob.numProgs)
runCommand(newJob, &jobList, inBg);
}
else 
{
i = 0;
while(!jobList.fg->progs[i].pid)
i++;

waitpid(jobList.fg->progs[i].pid, &status, 0);
jobList.fg->runningProgs--;
jobList.fg->progs[i].pid = 0;

if(!jobList.fg->runningProgs)
{
removeJob(&jobList, jobList.fg);
jobList.fg = NULL;
if(tcsetpgrp(0, getpid()))
perror("tcsrtpgrp");
}
}
}
return 0;
}


用gcc编译 gcc -o shell shell.c
/tem/cc4GxdCN.o: In function 'praseCommand':
shell.c(.text+0x2bb): undefined referenced to 'freeJob'
shell.c(.text+0x409): undefined referenced to 'freeJob'
shell.c(.text+0x48e): undefined referenced to 'freeJob'
/tmp//cc4GxdCN.o: In function 'removejob':
shell.c(.text+0x820): undefined referenced to 'freeJob'
/tmp//cc4GxdCN.o: In function 'checkJobs':
shell.c(.text+0x953): undefined referenced to 'removeJob'
/tmp//cc4GxdCN.o: In function 'main':
shell.c(.text+0x2bb): undefined referenced to 'removeJob'
collected2: ld returned 1 exit status

小弟最近在学习linux应用程序开发,有些地方还不太了解。望高手帮忙看一下,看看问题出在哪里,

|
大致看了下,有两点:
1、楼主的程序只是一个.c文件吗?(看样子像)
2、提示出现的是freeJob、removeJob没有定义,但你的函数名好像是小写的freejob、removejob。看看修改完会不会编译通过。

|
同意楼上,错字问题  freejob -> freeJob  removejob -> removeJob

    
 
 

您可能感兴趣的文章:

  • 关于Linux中romfs的问题,请高手指点指点
  • 菜鸟求救:在linux下安装jdk失败。初次使用linux,还请各路大虾指点指点,不甚感激!!!
  • 我的linux的安装问题,请大家给指点指点。多谢了!!!
  • 求高手指点,arm-linux
  • Linux 安装开发环境报错 求指点
  • 请各位使用过Linux的进来看看,指点指点(在线等待)! 谢谢
  • Linux的嵌入式开发,请高手指点
  • 刚刚进入linux下编程,请指点入门~~~
  • linux内核里面的所有头文件,有没有整理过的,请高手指点!谢谢!!!
  • 如何运程控制 linux 请高手指点。
  • 何运程控制 linux 请高手指点。
  • 想走嵌入式linux设备驱动方向,请多指点
  • 请指点: 在windows下能否通过程序来获取linux下的用户列表,甚至通过自己写的windows程序界面增加修改linux的用户
  • 板载AC97声卡的驱动问题,望Linux 高手指点
  • linux平台下面,能同时支持php,asp吗,如果可以,能不能详细指点。 在线等候!
  • 请linux的gnome开发高手指点
  • 关于在VMware下安装linux,请高手指点,先谢过!
  • 下一步该学习linux/unix的什么?请高手指点……
  • 有关linux这方面的应用和发展方向有哪位高手可以指点我一下!!!
  • linux下如何执行project文件,高人指点。
  • linux/centos源码安装nginx编译配置选项参数介绍
  • 嵌入式linux开发:一段代码在windows平台用VC编译运行正常,在linux平台用gcc编译运行正常,但是用arm-linux-gcc编译在嵌入式板子上运行就不正常.
  • linux 64位编译出错。linux 32位可以编译过。
  • 关于在linux交叉编译powerpc-e300c3-linux-gcc的编译问题
  • Linux下gcc编译时,如何以静态链接的形式编译?
  • linux下有没有能编译出16bit代码的C语言编译器?
  • 现要在一台Pentium100上安装LINUX操作系统,能不能不选用别的品牌的LINUX,而直接用内核编译,然后再加上编译器和SHELL等等其它东西?如
  • linux下可以编译c但是如何编译c++
  • arm-linux-gcc交叉编译出错,但gcc编译没错,什么原因呢???
  • 谁编译过PLX9054 Linux的驱动程序,我给100分教我编译和安装??
  • 何处有 Linux 内核编译配置详细的中文介绍? 我在重新配置编译时老是出错:-(
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 是否有人知道linux启动时最先出现的小企鹅图标在那儿出现的?
  • 新用linux的GDB, 版本是出现6.3.3.0,出现奇怪问题, 可能是环境设置的问题, 大人帮忙
  • FTP匿名登陆 LINUX 出现错误 linux FTP 550 permission
  • 传utf-8的网页到linux出现乱码
  • XP下安装Linux10 ,启动后没有出现Linux的入口,而是直接进入了XP ...
  • 用虚拟机装完LINUX为什么总会出现如图那的提示?
  • 啊??Linux按章出现问题了啊
  • linux服务器,大磁盘挂载分区,不定期出现“只读”现象
  • 用putty登linux出现如下问题
  • 用Vmware虚拟linux出现乱码
  • 安装Linux出现的问题。。
  • 第一次装linux5.0,光盘启动后按enter就出现Uncompressing Linux... Ok, booting the kernel.谁知道阿
  • linux 下用gdb调试器出现问题
  • 在redhat linux下安装网卡驱动出现问题
  • 安装红旗linux之后出现的问题
  • windows下telnet到linux下出现乱码
  • 在redhat linux 8.0 中文板上 , 有些地方出现乱码问题!
  • linux at 命令出现警告
  • 为什么每次登录 linux 都出现这句错误信息呢?
  • 求助:在Linux下安装mysql出现以下问题
  • linux c/c++ IP字符串转换成可比较大小的数字
  • 在win分区上安装linux和独立分区安装linux有什么区别?可以同时安装吗?(两个linux系统)
  • linux哪个版本好?linux操作系统版本详细介绍及选择方案推荐
  • 在虚拟机上安装的linux上,能像真的linux系统一样开发linux程序么?
  • secureCRT下Linux终端汉字乱码解决方法
  • 我重装window后,把linux的引导区覆盖了,进不了linux怎么办?急啊,望热心的人帮助 (现在有linux的盘)
  • Linux c字符串中不可打印字符转换成16进制
  • 安装vmware软件,不用再安装linux系统,就可以模拟linux系统了,然后可以在其上学习一下LINUX下的基本操作 了?
  • Linux常用命令介绍:更改所属用户群组或档案属性
  • 红旗Linux主机可以通过127.0.0.1访问,但如何是连网的Win2000机器通过Linux的IP去访问Linux
  • linux命令大全详细分类介绍及常用linux命令文档手册下载


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3