嗨,我一直在用c编写外壳程序,尝试重定向时被卡住了。
shell命令有效,但是重定向不起作用,它给我“无法创建输出文件!:无效的参数”,与输入相同。
我想要这样的东西:
输出重定向:ls -al > output.txt
输入重定向:cat < out.txt&
myprog < myfile > theoutput
这是我编写的代码:
#include "command_line.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/errno.h>
#include <signal.h>
#include <sys/wait.h>
#define MAX_LINE_LENGTH 512
#define MAXARGS 512
extern char ** environ;
void unix_error(char * msg);
pid_t Fork(void);
int cdHandler(char ** argv);
void childHandler(int sig);
void exithandler(int sig) {}
int main(int argc,
const char ** argv) {
//silently reap children
struct sigaction sa;
sa.sa_handler = & childHandler;
sigemptyset( & sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, & sa, 0) == -1) {
perror(0);
exit(1);
}
signal(SIGINT, exithandler);
//kill foreground processes without killing shell
char cmdline[MAX_LINE_LENGTH];
struct CommandLine command;
for (;;) {
printf("> ");
fgets(cmdline, MAX_LINE_LENGTH, stdin);
if (feof(stdin)) {
printf("exit");
exit(0);
}
bool gotLine = parseLine( & command, cmdline);
//pid_t pid = Fork();
int stat;
if (gotLine) {
if (command.arguments[0] == NULL) {
return;
}
if (!cdHandler(command.arguments)) {
//child runs user job
pid_t pid = Fork();
if (pid == 0) {
printCommand( & command);
char * com[MAX_ARGS];
int i = 0;
for (; i < command.argCount; i++) {
if (strcmp(command.arguments[i], ">") != 0 && strcmp(command.arguments[i], "<") != 0) {
com[i] = command.arguments[i];
} else if (strcmp(command.arguments[i], ">") == 0) {
char * filename = command.arguments[i + 1];
printf("-----%s------ \n", filename);
int outputfileptr = open(command.arguments[i + 1], "w+");
if (outputfileptr == -1)
{
perror("Cannot create output file!");
return;
}
dup2(outputfileptr, 1);
close(outputfileptr);
i++;
} else if (strcmp(command.arguments[i], "<") == 0) {
char * filename = command.arguments[i + 1];
int inputfileptr = open(filename, "r");
if (inputfileptr == -1) {
perror("Input file does not exist!");
return;
}
// Run dup2 again to redirect input/output
dup2(inputfileptr, 0);
close(inputfileptr);
i++;
}
}
printf("%s /n", com[0]);
if (execvp(command.arguments[0], command.arguments) < 0) {
printf("There was a Command error \n");
exit(0);
}
} else {
//parent
if (!command.background)
waitpid(pid, & stat, WUNTRACED);
}
}
}
}
return;
printCommand( & command);
freeCommand( & command);
}
//error handling for fork method
pid_t Fork(void) {
pid_t pid = 0;
if ((pid = fork()) < 0) {
unix_error("fork error");
}
return pid;
}
//prints out message is an error to address error occured
void unix_error(char * msg) {
fprintf(stderr, "%s : %s\n", msg, strerror(errno));
exit(0);
}
int cdHandler(char ** argv) {
if (!strcmp(argv[0], "cd")) {
if (chdir(argv[1]) != 0)
perror("cd did not change directory");
return 1;
}
if (!strcmp(argv[0], "exit"))
exit(0);
return 0;
}
void childHandler(int sig) {
int ps;
int saved_errno = errno;
while (waitpid((pid_t)(-1), & ps, WNOHANG) > 0) {
if (WIFEXITED(ps)) {
printf("Exit status: %d\n", WEXITSTATUS(ps));
} else if (WTERMSIG(ps)) {
printf("Exit signal: %d\n", WTERMSIG(ps));
}
}
errno = saved_errno;
}