对于重定向(>
)和高级(>+
),我不确定如何开始。我试图遍历我的空间链接lst(由;
和\n
空格标记化)并查看它是否">"并将我的重定向结构的progAndArgs
的prev节点和下一个节点保存为outFile。
我认为我正确地做了,但这很可能是错误的。
parse* p = tokenize_line_semicolons(pinput);
myPrint("HERE\n");
// setup redirection struct
parse *temp2_p = p;
space *spc2;
while (temp2_p != NULL) {
spc2 = tokenize_space(temp2_p->cmd);
space* temp_s = spc2;
char* prev = temp_s->spc;
if (strcmp(prev,"\n")==0)
error();
temp_s = temp_s->next;
while (temp_s != NULL) {
if (strcmp(temp_s->spc, ">") == 0) {
redirection r;
r.progAndArgs = prev;
if (temp_s->next->spc != NULL)
r.outFile = temp_s->next->spc;
else
error();
}
temp_s = temp_s->next;
}
temp2_p = temp2_p->next;
}
但是一旦我正确地获得了重定向结构,我就不能确定如何使用dup / dup2 / creat / write / open / read来做>和> +(我阅读了手册页)。请帮忙!
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
void myPrint(char *msg)
{
write(STDOUT_FILENO, msg, strlen(msg));
}
void error()
{
char error_message[30] = "An error has occurred\n";
write(STDOUT_FILENO, error_message, strlen(error_message));
}
typedef struct parse
{
char* cmd;
struct parse* next;
} parse;
typedef struct space
{
char* spc;
struct space* next;
} space;
typedef struct dble
{
space* s;
struct dble* next;
} dble;
typedef struct redirection
{
char* progAndArgs;
char* outFile;
} redirection;
char** p_to_char(space *s)
{
char** args = (char**)malloc(sizeof(char*)*514);
space *temp = s;
int i = 0;
while (temp != NULL) {
args[i] = strdup(temp->spc);
// myPrint(args[i]);
// myPrint("\n");
temp = temp->next;
i++;
}
return args;
}
parse* setparse(char* s)
{
parse* p = (parse*)malloc(sizeof(parse));
p->cmd = strdup(s);
p->next = NULL;
return p;
}
space* setspace(char* s)
{
space* sp = (space*)malloc(sizeof(space));
sp->spc = strdup(s);
sp->next = NULL;
return sp;
}
dble* setdble(space* spc)
{
dble* d = (dble*)malloc(sizeof(dble));
space* temp = spc;
while (temp != NULL) {
d->s = temp;
d->next = (dble*)malloc(sizeof(dble));
d = d->next;
temp = temp->next;
}
return d;
}
void show_parse(parse* p)
{
//myPrint("Show parse\n");
parse* temp = p;
while(temp != NULL) {
// myPrint(temp->cmd);
// myPrint("->");
temp = temp->next;
}
//myPrint("\n");
}
void show_space(space* sp)
{
// myPrint("Show space\n");
space* temp = sp;
while(temp != NULL) {
// myPrint(temp->spc);
// myPrint("->");
temp = temp->next;
}
//myPrint("\n");
}
// TODO - SEE IF DBLE PRINTING RIGHT OR SET UP WRONG
void show_dble(dble* d)
{
dble* temp = d;
//myPrint("Show dble\n");
while(temp != NULL) {
show_space(temp->s);
temp = temp->next;
}
//myPrint("\n");
}
/* tokenized by spaces's - SEPARATE COMMANDS AND PARAMETERS */
space* tokenize_space(char* cmd)
{
char* token_ptr = strdup(cmd);
char *token, *token2;
token = strtok_r(token_ptr, " ", &token2);
space* s = setspace(token);
space* fst = s;
while (token != NULL) {
token = strtok_r(NULL," ", &token2);
if (token==NULL){
return fst;
}
s->next = setspace(token);
s = s->next;
}
return fst;
}
/* tokenized by newline and ;'s - SEPARATE COMMANDS WITH PARAMTERS*/
parse* tokenize_line_semicolons(char* input)
{
//myPrint("Starting Tokens!\n");
if (strcmp(input,"\n")) {
error();
return NULL;
}
else {
myPrint("HERE\n");
char* token_ptr = input;
char *token;
token = strtok_r(token_ptr, ";\n", &token_ptr);
parse* p = setparse(token);
parse* fst = p;
while (token != NULL) {
token = strtok_r(NULL,";\n", &token_ptr);
if (token==NULL){
return fst;
}
p->next = setparse(token);
//tokenize_redirect(p);
p = p->next;
}
return fst;
}
}
void do_cd(char* param)
{
int v;
// myPrint(param);
// myPrint("\n");
if (strcmp(param, "") == 0 || strcmp(param, "~") == 0) {
char *directory = getenv("HOME");
v = chdir(directory);
} else if (param[0] == '/') {
//myPrint("~ /\n");
char* directory = param;
v = chdir(directory);
//exit(v);
} else {
char buf[100];
char *directory = getcwd(buf,100);
strcat(buf,"/");
strcat(buf,param);
//myPrint(directory);
v = chdir(directory);
}
if (v == -1) // chdir error returning
error();
}
int run_cmds(char* cmd, char** args, space* s)
{
// myPrint("START run_cmds!!! s->spc: ");
// myPrint(s->spc);
// myPrint(", cmd: ");
// myPrint(cmd);
// myPrint("\n");
// all cmds return 0 if pass (from exho $?)
if (strcmp(s->spc, "exit") == 0) {
// myPrint("DOING exit\n");
exit(0);
}
else if (strcmp(s->spc, "pwd") == 0) {
// myPrint("DOING pwd\n");
char* buff = (char*)malloc(sizeof(char)*100);
myPrint(getcwd(buff,100));
myPrint("\n");
} else if (strcmp(s->spc, "cd") == 0) {
//myPrint("DOING cd\n");
do_cd(s->next->spc);
}
else {
// myPrint("FORK");
// myPrint("\n");
pid_t pid = fork();
if (pid == 0) {
// myPrint("CHILD");
// myPrint("\n");
// myPrint(args[0]);
// myPrint("\n");
if (execvp(args[0], args) < 0)
error();
exit(0);
} else {
// myPrint("PARENT");
// myPrint("\n");
int status;
pid_t ppid = waitpid(pid,&status,WUNTRACED);
// myPrint("PARENT 2");
// myPrint("\n");
return ppid;
}
}
return 0;
}
//Redirect throws an error if the file already exists or no file specified
int main(int argc, char *argv[])
{
char cmd_buff[100];
char *pinput;
// implementing batch mode
if (argc > 1) {
int len = strlen(argv[1]);
if (argv[1][0] == '[' && argv[1][len-1] == ']') {
argv[1]++;
argv[1][len-2] = '\0';
}
FILE *fp = fopen(argv[1],"r");
if (fp == NULL) {
error();
exit(1);
}
char buff[514];
//myPrint("we are about to fgets\n");
while (fgets(buff,514,fp) != NULL) {
// myPrint("We are fgetsing\n");
// myPrint(buff);
tokenize_line_semicolons(buff);
}
fclose(fp);
} else if (argc >= 3) {
error();
exit(1);
}
while (1) {
myPrint("myshell> ");
pinput = fgets(cmd_buff, 100, stdin);
if (!pinput) {
myPrint("pinput\n");
exit(0);
}
// if 513th char is neither \n or null terminator, its invalid input
if (strlen(pinput) > 512) {
// myPrint(pinput);
// myPrint("\n");
error();
exit(1);
}
parse* p = tokenize_line_semicolons(pinput);
myPrint("HERE\n");
// setup redirection struct
parse *temp2_p = p;
space *spc2;
while (temp2_p != NULL) {
spc2 = tokenize_space(temp2_p->cmd);
space* temp_s = spc2;
char* prev = temp_s->spc;
if (strcmp(prev,"\n"))
error();
temp_s = temp_s->next;
while (temp_s != NULL) {
if (strcmp(temp_s->spc, ">") == 0) {
redirection r;
r.progAndArgs = prev;
if (temp_s->next->spc != NULL)
r.outFile = temp_s->next->spc;
else
error();
}
temp_s = temp_s->next;
}
temp2_p = temp2_p->next;
}
parse* temp_p = p;
space *spc;
dble *d = (dble*)malloc(sizeof(dble));
dble* tmp_d = d;
while (temp_p != NULL) {
spc = tokenize_space(temp_p->cmd);
d->s = spc;
d->next = (dble*)malloc(sizeof(dble));
d = d->next;
temp_p = temp_p->next;
}
show_parse(p);
show_dble(tmp_d);
char** args = p_to_char(spc);
//myPrint("HERE");
while (p != NULL) {
run_cmds(p->cmd, args, tmp_d->s);
p = p->next;
tmp_d = tmp_d->next;
}
}
}
答案 0 :(得分:1)
你调用setparse(token)使用它的参数而不检查它是否为null。