Note that there are some explanatory texts on larger screens.

plurals
  1. POIO redirection and buffer issues, fflush and c
    primarykey
    data
    text
    <p>for my class we are to implement a shell with output redirection. I have the output redirection working, except my first command is always corrupted see: </p> <pre><code>$ echo this doesn't work H&lt;@?4echo No such file or directory $ echo this does work this does work </code></pre> <p>but every command afterwards seems fine. What technique do I use to find the bug that is causing this problem? </p> <p>I think it has something to do with not fflushing properly. I sprinkled it around my code (which was stupid) to see if it would help during the loop but it did not. I've also tried printing out my OrderedIds list which is just a list of commands to check if I could find H&lt;@?4 anywhere, but even when I initialized it, it did not work. </p> <p>Thanks for your help. </p> <pre><code>#define LENGTH 1000 #define MAXCMD 11 #define MAX_STR_LEN 20 void init(char *temp); void clean(char **orderedIds); void init_pid(int *temp); void reap(int *temp,int ret_status); void jobs(int *pid_list, char **orderedIds); int ioRedir(char **orderedIds); void reap(int *temp,int ret_status){//chainsaws all zombies int a; for (a=0; a&lt;LENGTH; a++ ){ waitpid(temp[a],&amp;ret_status,WNOHANG) == temp[a]; } } void init(char *temp){//Function to initialize/reset the cmd array int i; for(i=0; i&lt;LENGTH; i++){ temp[i] = 0; } } void init_pid(int *temp){//Function to initialize/reset the pid list int i; for(i=0; i&lt;LENGTH; i++){ temp[i] = -777; } } void clean(char **orderedIds){//garbage collection int i; for(i=0; i&lt;MAXCMD; i++){ free(orderedIds[i]); } free(orderedIds); } void jobs(int *pid_list, char **orderedIds){//function to check for background proccesses printf("Jobs:\n"); int y; for(y=0; y&lt;LENGTH; y++){ if(kill(pid_list[y], 0) == 0){ printf("%d\n", pid_list[y]); } } clean(orderedIds); printf("$ "); } int ioRedir(char **orderedIds){ int i; for ( i = 0; i&lt;MAXCMD; i++){ if(orderedIds[i] == NULL){ return -1; } if(strcmp(orderedIds[i],"&gt;")==0){ return (i+1); } } } int main (int argc, char *argv[], char *envp[]) { char temp[LENGTH]; char * tok; char c = '\0'; int saved_stdout; int pid_list[LENGTH]; int ret_status; int numFile; int pid_counter = 0; int outputfd = -1; char outputFile[MAX_STR_LEN]; pid_t pid; printf("$ "); int i, j, y, background= 0; init_pid(pid_list); while(c !=EOF) { //while not ^D // Source: LinuxGazzette Ramankutty outputfd = -1; fflush(0); c = getchar(); if(c=='\n'){ //entered command reap(pid_list, ret_status); char **orderedIds = malloc(MAXCMD * sizeof(char*)); for (i=0; i&lt;MAXCMD; i++){ orderedIds[i] = malloc(MAXCMD * sizeof(char*)); } int k=0; tok = strtok(temp, " \n\t\r"); while (tok !=NULL){ strcpy(orderedIds[k], tok); k++; tok = strtok (NULL, " \n\t\r"); } orderedIds[k] = NULL; //END with NULL init(temp); //initialize the array if(orderedIds[0] ==NULL){ printf("\n$ "); continue; } numFile = ioRedir(orderedIds); if(strcmp(orderedIds[0],"exit")==0){// if exit printf("now exiting...\n"); break; } if(strcmp(orderedIds[k-1], "&amp;")==0){//if background orderedIds[k-1] = NULL; background = 1; }else background = 0; if(strcmp(orderedIds[0], "jobs") == 0){//if jobs command jobs(pid_list, orderedIds); continue; } if(strcmp(orderedIds[0], "cd") == 0){ //if change directory command chdir(orderedIds[1]); printf("$ "); continue; } pid = fork(); if (pid!=0 &amp;&amp; background == 1) { //go to end of list in pid and put it in pid_list[pid_counter] = pid; pid_counter++; printf("To the background: %d\n", pid); } else if (pid==0 &amp;&amp; background == 1) { fclose(stdin); //close child's stdin fopen("/dev/null", "r"); //open a new stdin that is always empty. if(execvp(orderedIds[0], orderedIds)){ printf("%s\n", orderedIds[0]); puts(strerror(errno)); exit(127); } } if (pid != 0 &amp;&amp; !background){ //printf("Waiting for child (%d)\n", pid); fflush(0); pid = wait(&amp;ret_status); } else if (pid == 0 &amp;&amp; !background) { if(numFile &gt; 0){ strncpy(outputFile, orderedIds[numFile], strlen(orderedIds[numFile])); numFile = 0; //open the output file outputfd = open(outputFile, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRGRP | S_IROTH); if (outputfd &lt; 0) { exit(EXIT_FAILURE); } //close STDOUT if(close(STDOUT_FILENO) &lt; 0 ){ perror("close(2) file: STDOUT_FILENO"); close(outputfd); exit(EXIT_FAILURE); } //use dup to rerout the output if(saved_stdout = dup(outputfd) != STDOUT_FILENO){ perror("dup(2)"); close(outputfd); exit(EXIT_FAILURE); } close(outputfd); } if (execvp(orderedIds[0], orderedIds)){ printf("%s\n", orderedIds[0]); puts(strerror(errno)); exit(127); } } dup2(saved_stdout,outputfd); clean(orderedIds); fflush(0); printf("$ "); } else { strncat(temp, &amp;c, 1); } } fflush(0); return 0; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload