我遇到的问题似乎只是从我的知识中消失了.我正在编写一个简单的shell来学习一些用于Unisys实习的系统编程.在我的shell中,似乎我正在尝试的所有命令都在ls之外工作,甚至现在发现了wc命令. ls和wc在我自己输入时工作,但如果我给它参数,它将无法工作并给我一个错误说没有这样的文件或目录.
这是我的代码:
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#define BUF_SIZE 1024
#define DELims " -\r\t\n"
/****************************************************************
* Capture input from the user. Returns the input from the
* standard input file descriptor.
***************************************************************/
char * getInput (char **buffer, size_t buflen)
{
size_t bufsize = BUF_SIZE;
*buffer = malloc(sizeof(char) * bufsize + 1); // allocate space for the buffer
if (!*buffer)
{
fprintf(stderr, "Shell: buffer allocation error\n");
exit(EXIT_FAILURE);
}
printf("$$");
fflush(NULL);
int bytesRead = getline(&(*buffer), &bufsize, stdin);
if (bytesRead < 0)
{
printf("Getline error\n");
exit(EXIT_FAILURE);
}
return *buffer; // Not capturing return value right Now
}
/****************************************************************
* Tokenize the buffer input from stdin
***************************************************************/
char ** splitLine(char *line)
{
int bufsize = BUF_SIZE;
int pos = 0;
char **tokens = malloc (sizeof(char) * BUF_SIZE + 1);
char *token;
if (!tokens)
{
fprintf(stderr, "Shell: buffer allocation error\n");
exit(EXIT_FAILURE);
}
/* Tokenize the line */
token = strtok(line, DELims);
while (token != NULL)
{
tokens[pos] = token;
pos++;
if (pos > bufsize)
{
bufsize += BUF_SIZE;
tokens = realloc(tokens, bufsize * sizeof(char) + 1);
if (!tokens)
{
fprintf(stderr, "Shell: buffer allocation error\n");
exit(EXIT_FAILURE);
}
}
token = strtok(NULL, DELims); // continue grabbing tokens
}
tokens[pos] = NULL;
return tokens;
}
/****************************************************************
* Main function
***************************************************************/
int main (int argc, char **argv)
{
char *buf; // buffer to hold user input from standard input stream.
pid_t pid; // Parent id of the current process
int status;
/* Loop while the user is getting input */
while (getInput(&buf, sizeof(buf)))
{
char **args = splitLine(buf);
int i = 0;
/* Print tokens just to check if we are processing them correctly */
while (1)
{
char *token = args[i++];
if (token != NULL)
printf("Token #%d: %s\n", i, token);
else
break;
}
fflush(NULL);
/* Fork and execute command in the shell */
pid = fork();
switch(pid)
{
case -1:
{
/* Failed to fork */
fprintf(stderr, "Shell cannot fork: %s\n", strerror(errno));
continue;
}
case 0:
{
/* Child so run the command */
execvp(args[0], args); // Should not ever return otherwise there was an error
fprintf(stderr, "Shell: Couldn't execute %s: %s\n ", buf, strerror(errno));
exit(EX_DATAERR);
}
}
/* Suspend execution of calling process until receiving a status message from the child process
or a signal is received. On return of waitpid, status contains the termination
@R_55_4045@ion about the process that exited. The pid parameter specifies the set of child
process for which to wait for */
if ((pid = waitpid(pid, &status, 0) < 0))
{
fprintf(stderr, "Shell: waitpid error: %s\n", strerror(errno));
}
free(args);
}
free(buf);
exit(EX_OK);
}
例如,我在输出中尝试了以下命令:
ls -la(问题)
$$ls -la
Token #1: ls
Token #2: la
ls: la: No such file or directory
$$
wc -l(问题)
$$wc -l
Token #1: wc
Token #2: l
wc: l: open: No such file or directory
LS
$$ls
Token #1: ls
Makefile driver driver.dSYM main.c main.o
$$
ps -la
$$ps -la
Token #1: ps
Token #2: la
UID PID PPID cpu PRI NI VSZ RSS WCHAN STAT TT TIME COMMAND
0 2843 2405 0 31 0 2471528 8 - Us s000 0:00.08 login
501 2845 2843 0 31 0 2463080 1268 - S s000 0:01.08 -bash
501 4549 2845 0 31 0 2454268 716 - S+ s000 0:00.01 ./driv
0 4570 4549 0 31 0 2435020 932 - R+ s000 0:00.00 ps la
$$
哪个
$$which which
Token #1: which
Token #2: which
/usr/bin/which
哪个 – 哪个
$$which -a which
Token #1: which
Token #2: a
Token #3: which
/usr/bin/which
甚至最后是男人
GETLINE(3) BSD Library Functions Manual GETLINE(3)
NAME
getdelim, getline -- get a line from a stream
LIBRARY
Standard C Library (libc, -lc)
.
.
.
任何人都可以帮我指出我遇到这个问题的原因吗?
解决方法:
顺便说一下,它可能最好避免宏,你可以轻松地做到这一点.在这里,我会使用const char * delims来存储分隔符.我通常发现更容易声明一个接近其使用位置的变量 – 我认为这样可以更容易地发现错误并阅读代码.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。