#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<sys/utsname.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<pwd.h>
#include<sys/wait.h>
#include<signal.h>
#define MAX_NO_OF_CMD_ELEMENTS (10)
struct utsname u; /* to get hostname*/
struct passwd *pw; /*to get username*/
int pid;
char* username, *hostname;
char cwd[100];
char *basedir;
int bg;
void init_prompt()
{
getcwd(cwd,100);
basedir = cwd;
uname(&u);
pw = getpwuid(getuid());
username = pw->pw_name;
hostname = u.nodename;
}
void prompt_me()
{
sleep(1);
getcwd(cwd,100);
bg =0;
printf("%s@%s:%s$ ",username,hostname,cwd);
}
void pinfo(char **argv)
{
char path[1024];
char c;
char buf[1024];
char filename[1000];
printf("pid --- %s\n",argv[1]);
sprintf(filename,"/proc/%s/status",argv[1]);
FILE *f = fopen(filename, "r");
FILE *fp;
char state;
fgets(buf,1024,f);
fgets(buf,1024,f);
sscanf(buf, "State: %c\n", &state);
printf("process state = %c\n", state);
fclose(f);
char target_path[1024];
sprintf(filename, "/proc/%d/exe",pid);
int len = readlink (filename, target_path, sizeof (target_path));
char buffer[1024];
if(len ==-1)
{
perror("readlink");
}
else
{
target_path[len] = '\0';
printf("executable path: %s\n", target_path);
}
}
void pwd_me()
{
getcwd(cwd,100);
printf("%s",cwd);
}
void cd_me(char **argv)
{
chdir(argv[1]);
if(getcwd(cwd,100)!=0)
{
perror(" ");
}
if(strcmp("~\0",argv[1])==0||strcmp("\0",argv[1])==0)
chdir(basedir);
}
void echo_me(char **argv,int num)
{
int i;
for(i=0;i<num;i++)
{
printf("%s", argv[i]);
if(i!=0 || i!=num-1)
{
printf(" ");
}
}
}
void execute(char **argv,int num)
{
int i;
pid_t pid;
int status;
if ((pid = fork()) < 0)
{ /* fork a child process*/
printf("*** ERROR: forking child process failed\n");
exit(1);
}
else if (pid == 0)
{ /* for the child process: */
if(strcmp(argv[0],"cd")==0)
cd_me(argv);
else if(strcmp(argv[0],"pwd")==0)
pwd_me();
else if(strcmp(argv[0],"echo")==0)
echo_me(argv,num);
else if(strcmp(argv[0],"pinfo")==0)
pinfo(argv);
else if(strcmp(argv[0],"exit")==0)
return;
int c;
if (c==execvp(argv[0], argv) < 0)
{ /* execute the command */
printf("%d\n", c);
printf("*** ERROR: exec failed\n");
perror(" ");
exit(1);
}
}
else if(bg!=1){
while (wait(&status) != pid);
}
}
void input()
{
int i,j,n,len,c;
char *buffer = 0;
size_t bufsize = 0;
ssize_t characters;
char *cmd[MAX_NO_OF_CMD_ELEMENTS+1];
characters = getline(&buffer, &bufsize, stdin);
len = strlen(buffer);
buffer[len-1]='\0';
if (characters > 0)
{
char *end_str1;
char *token1 = strtok_r(buffer, ";", &end_str1);
int count = 0, wordcnt;
while (token1 != NULL)
{
char *token2;
memset(cmd,0,sizeof(cmd));
char * cmd[MAX_NO_OF_CMD_ELEMENTS + 1]; /* 1+ for the NULL-terminator */
size_t wordcnt = 0;
char *end_str2;
count++;
token2 = strtok_r(token1, " ", &end_str2);
while ((NULL != token2)
&& (MAX_NO_OF_CMD_ELEMENTS > wordcnt)) /* Prevent writing
out of `cmd`'s bounds. */
{
cmd[wordcnt] = token2;
wordcnt++;
token2 = strtok_r(NULL, " ", &end_str2);
}
if(token2==NULL)
{
cmd[wordcnt] = NULL;
execute(cmd, wordcnt);
}
}
}
free(buffer);
}
int main()
{
init_prompt();
while(1)
{
prompt_me();
input();
}
}
我无法找到运行此程序时发生的无限循环的来源。请帮帮忙?
我认为它最有可能出现在输入功能中,但我不确定是否安全,我将整个程序包括在内。
答案 0 :(得分:1)
将以下行添加到while (token1 != NULL)
函数中input
循环的末尾:
token1 = strtok_r(NULL, ";", &end_str1);
问题是你没有更新token1,因此,token1将永远不会为NULL,因此while (token != NULL)
将永远循环。