void write_or_die(int fd, const void *buf, size_t count) { if (write_in_full(fd, buf, count) < 0) { check_pipe(errno); die_errno("write error"); } }
/* * Some cases use stdio, but want to flush after the write * to get error handling (and to get better interactive * behaviour - not buffering excessively). * * Of course, if the flush happened within the write itself, * we've already lost the error code, and cannot report it any * more. So we just ignore that case instead (and hope we get * the right error code on the flush). * * If the file handle is stdout, and stdout is a file, then skip the * flush entirely since it's not needed. */ void maybe_flush_or_die(FILE *f, const char *desc) { static int skip_stdout_flush = -1; struct stat st; char *cp; if (f == stdout) { if (skip_stdout_flush < 0) { cp = getenv("GIT_FLUSH"); if (cp) skip_stdout_flush = (atoi(cp) == 0); else if ((fstat(fileno(stdout), &st) == 0) && S_ISREG(st.st_mode)) skip_stdout_flush = 1; else skip_stdout_flush = 0; } if (skip_stdout_flush && !ferror(f)) return; } if (fflush(f)) { check_pipe(errno); die_errno("write failure on '%s'", desc); } }
t_bool check_pipe(t_token *b, t_token *e, t_node **root, int flag) { t_token *begin; t_token *end; if (flag && check_grammar_exec(b, e) != TRUE) return (FALSE); begin = (flag) ? (b) : (NULL); if (there_are_pipe(b, e) == TRUE && get_next_pipe(e, &begin, &end) == TRUE) { if (!end || end == e) check_bloc_exec(begin, end, root); else { if (check_pipe_ext(root) == ERROR) return (ERROR); if (check_pipe(b, e, &((*root)->child->nd), 0) != TRUE) return (FALSE); if (add_child(root) == EXIT_FAILURE) return (ERROR); if (check_bloc_exec(begin, end, &((*root)->child->nd)) != TRUE) return (FALSE); } } else return ((check_bloc_exec(begin, e, root) != TRUE) ? (FALSE) : (TRUE)); return (TRUE); }
int check_valid_pipe(char **pattern, t_conf **list) { t_conf *tmp; int curs; int pos; tmp = *list; while (tmp && !check_pipe(tmp->line)) tmp = tmp->next; while (tmp) { curs = -1; while (tmp->line[++curs] != '-' && tmp->line[curs]); pos = reduc_valid(pattern, tmp->line, curs); if (pos == -1) return (-1); pos = 0; while (pos != -1 && pattern[pos]) if (comp_from_char(tmp->line, curs + 1, pattern[pos++])) pos = -1; if (pos != -1) return (-1); tmp = tmp->next; } return (check_valid_link(list, pattern)); }
t_bool check_pipe(t_token *b, t_token *e, t_node **root, int flag) { t_token *begin; t_token *end; if (flag && check_grammar_exec(b, e) != TRUE) return (FALSE); begin = (flag) ? (b) : (NULL); if (there_are_pipe(b, e) == TRUE) { if (get_next_pipe(e, &begin, &end) == TRUE) { if (!end || end == e) check_bloc_exec(begin, end, root); else { add_node(root, PIPE, "|"); add_child(root); check_pipe(b, e, &((*root)->child->nd), 0); add_child(root); if (check_bloc_exec(begin, end, &((*root)->child->nd)) != TRUE) return (FALSE); } } } else if (check_bloc_exec(begin, e, root) != TRUE) return (FALSE); return (TRUE); }
int perf_data__open(struct perf_data *data) { if (check_pipe(data)) return 0; if (!data->file.path) data->file.path = "perf.data"; return open_file(data); }
void check_left_command(char *command){ boolean isValidPipe; isValidPipe = check_pipe(command); if(isValidPipe == FALSE){ yyerror("Invalid verb to the left side of sentence\n"); } }
int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg) { if (write_in_full(fd, buf, count) < 0) { check_pipe(errno); fprintf(stderr, "%s: write error (%s)\n", msg, strerror(errno)); return 0; } return 1; }
void fprintf_or_die(FILE *f, const char *fmt, ...) { va_list ap; int ret; va_start(ap, fmt); ret = vfprintf(f, fmt, ap); va_end(ap); if (ret < 0) { check_pipe(errno); die_errno("write error"); } }
static int packet_write_fmt_1(int fd, int gently, const char *fmt, va_list args) { struct strbuf buf = STRBUF_INIT; ssize_t count; format_packet(&buf, fmt, args); count = write_in_full(fd, buf.buf, buf.len); if (count == buf.len) return 0; if (!gently) { check_pipe(errno); die_errno("packet write with format failed"); } return error("packet write with format failed"); }
static int check_valid_link(t_conf **list, char **pattern) { int curs; t_conf *tempo; curs = -1; tempo = *list; while (pattern[++curs + 1]); while (tempo && !check_pipe(tempo->line)) tempo = tempo->next; if (check_tab_link(pattern[0], tempo) == 0) return (-2); if (check_tab_link(pattern[curs], tempo) == 0) return (-2); free_tab(pattern); return (0); }
void process_multiple() { /* Arguments: none Purpose: this function will split a sequence of commands by semicolon and execute them in order */ char* list_cmds[20]; //we assume no more than 20 commands char *tmp_cmd = (char *)malloc(sizeof(char)*100); memset(tmp_cmd,0,100); int cmd_num = 0; int x,y=0; for(x=0;x<strlen(line);++x){ if(line[x] != ';'){ tmp_cmd[y] = line[x]; ++y; } else { tmp_cmd[y] = '\0'; list_cmds[cmd_num] = (char *)calloc(100,sizeof(char)*strlen(tmp_cmd)); //memset(list_cmds[cmd_num],0,strlen(tmp_cmd)+1); strcpy(list_cmds[cmd_num],tmp_cmd); memset(tmp_cmd, 0, 100); ++cmd_num; y = 0; } } tmp_cmd[y+1] = '\0'; list_cmds[cmd_num] = (char *)malloc(sizeof(char)*strlen(tmp_cmd)); strcpy(list_cmds[cmd_num],tmp_cmd); memset(tmp_cmd,0,100); for(x=0;x<=cmd_num;++x){ if(!check_pipe(list_cmds[x])){ parse_args(list_cmds[x]); strcpy(tmp_cmd,args[0]); execute(tmp_cmd); clear_args(); free(list_cmds[x]); } } free(tmp_cmd); }
int perf_data__switch(struct perf_data *data, const char *postfix, size_t pos, bool at_exit) { char *new_filepath; int ret; if (check_pipe(data)) return -EINVAL; if (perf_data__is_read(data)) return -EINVAL; if (asprintf(&new_filepath, "%s.%s", data->file.path, postfix) < 0) return -ENOMEM; /* * Only fire a warning, don't return error, continue fill * original file. */ if (rename(data->file.path, new_filepath)) pr_warning("Failed to rename %s to %s\n", data->file.path, new_filepath); if (!at_exit) { close(data->file.fd); ret = perf_data__open(data); if (ret < 0) goto out; if (lseek(data->file.fd, pos, SEEK_SET) == (off_t)-1) { ret = -errno; pr_debug("Failed to lseek to %zu: %s", pos, strerror(errno)); goto out; } } ret = data->file.fd; out: free(new_filepath); return ret; }
int main(int argc, char *argv[], char *envp[]) { read_config(); //read the config file char c; //reading one letter at time here //building a command line which will eventually get parsed line = (char *)malloc(sizeof(char) * 100); memset(line,0,100); char *cmd = (char *)malloc(sizeof(char) * 100); //the program (command w/o args) char *printBuff = (char *)malloc(sizeof(char)*100); //a printing buffer (for use with raw tty) //holder for history if stuff is typed, then history is used to go back to typed stuff char *historyHold = (char *)malloc(sizeof(char)*100); path = (char*)malloc(sizeof(char)*100); fullPath = (char*)malloc(sizeof(char)*100); memset(printBuff,0,100); memset(historyHold,0,100); memset(cmd,0,100); signal(SIGINT, handle_sig); //register interrupt signal (for CTRL+C) int promptLen; //making sure we dont backspace the prompt int fromHistory = 0; //a type of check to see if our line is from history (not user typed) if(fork() == 0) { execve("/usr/bin/clear", argv, envp); //simply clear the screen exit(1); } else { wait(NULL); //wait to clear screen } get_path(); //gets the 2dir path for prompt tty_raw_mode();//set terminal into raw mode sprintf(printBuff,"%s:%s",path,PROMPT); //build print buff promptLen = strlen(printBuff); curPos = promptLen; //leave a space write(1,printBuff,promptLen); //print initial prompt memset(printBuff,0,100); //clear printBuff clear_args(); //just get any initial crap out /* MAIN LOOP */ while(1) { read(0,&c,1); //read 1 character from stdin if(((c >= 32) && c!=127) || c == 10) { //here, we only want to process characters that are //"readable" (or enter). special characters will be //handled differently tabPressNo = 0; //they didnt press tab write(1,&c,1); //write char (echo is off for raw mode) ++curPos; switch(c) { case '\n': //end of the line (enter was pressed after input) if(line[0] == '\0') { //they didnt type anything sprintf(printBuff,"%s:%s",path,PROMPT); write(1,printBuff,promptLen); } else if(strcmp(line,"exit")==0) { printf("\n"); //for niceness quit_raw_mode(); //play nice and restore term state return 0; //quit if they type "exit" } else { //prepare to actually process strncat(line,"\0",1); if(line[0] != '!') { add_history(line); //add command to history } int pipe = 0; int separ = check_separ(line); if(!separ){ pipe = check_pipe(line); } if(!separ && !pipe){ //try to execute the command if there werent pipes or semicolons parse_args(line); //build array of arguments strcpy(cmd, args[0]); //cmd = program to run execute(cmd); clear_args(); //resets all arg array strings } c = '\0'; memset(cmd, 0, 100); //clear the cmd array //reprint prompt sprintf(printBuff,"%s:%s",path,PROMPT); promptLen = strlen(printBuff); curPos = promptLen; write(1,printBuff,promptLen); } memset(line,0,100); //clear line array memset(historyHold,0,100);//clear history hold break; default: strncat(line, &c, 1);//build the line break; } } else if(c == 8) { //backspace pressed if(curPos > promptLen) { backspace(); //backspace until we reach prompt line[strlen(line)-1] = 0; //thank god this finally works --curPos; } } else if(c == 27) { //the user pressed some sort of //escape sequence char c1; char c2; read(0,&c1,1); read(0,&c2,1); //ok, we have the two parts of the //escape sequence in c1 and c2 if(c1 == 91 && c2 == 65) { //this is the escape for the up arrow //which we want to use for history //browsing char *tmpLine; tmpLine = prev_history(); if(tmpLine != 0) { if(line[0] != '\0' && fromHistory==0) { //store what user currently has typed (if anything) memset(historyHold,0,100); strncpy(historyHold,line,strlen(line)); } clear_line(strlen(line)); //clears whatever is at the prompt memset(line,0,100); strncpy(line,tmpLine,strlen(tmpLine)); //copy this command free(tmpLine); //play nice write(1,line,strlen(line)); //write old command fromHistory = 1; //current line has been replaced by history curPos = strlen(line) + promptLen; //so we know where are } } else if(c1 == 91 && c2 == 66) { //this is the escape for the down arrow //which should make us go "forward" //in history (if we are back in it) char *tmpLine; tmpLine = next_history(); //get the next history if(tmpLine != 0) { //next_history gave us a line clear_line(strlen(line)); //clear old line from screen memset(line,0,100); //clear old line in mem strncpy(line,tmpLine,strlen(tmpLine)); //copy new line to old line write(1,line,strlen(line)); //write new line to screen curPos = strlen(line) + promptLen; //update pos free(tmpLine); } else if(historyHold[0] != '\0') { //if we dont have a next_line, lets see if //we had some buffer before browsing history clear_line(strlen(line)); memset(line,0,100); strncpy(line,historyHold,strlen(historyHold)); write(1,line,strlen(line)); curPos = strlen(line) +promptLen; fromHistory = 0; //back to user typed } else { //it was blank before history was browsed clear_line(strlen(line)); memset(line,0,100); curPos = promptLen; } } } else if(c == '\t') { //tab press. should i dare try to do tab //completion? i guess... //if this is the 2nd time in a row pressing tab //they want a listing of everything that can be //completed if(tabPressNo) { //print everything in tabHold tabPressNo = 0; if(tabCompHold[0] != NULL) { int i = 1; char *x = tabCompHold[0]; char *tmp = (char*)malloc(sizeof(char)*100); memset(tmp,0,100); write(1,"\n",1); while(x != NULL) { sprintf(tmp,"%s\t",x); write(1,tmp,strlen(tmp)); memset(tmp,0,100); x = tabCompHold[i]; ++i; } write(1,"\n",1); //reprint prompt sprintf(printBuff,"%s:%s",path,PROMPT); promptLen = strlen(printBuff); curPos = promptLen + strlen(line); write(1,printBuff,promptLen); //write the line again write(1,line,strlen(line)); clear_tab_hold(); } } else { //otherwise just let tab_complete //print a single completion char *tabcomp; tabcomp = tab_complete(line); if(tabcomp != NULL) { //tab comp found a single thing, so //lets just complete it int i = 1; char c = tabcomp[0]; while(c!='\0') { write(1,&c,1); strncat(line,&c,1); c = tabcomp[i]; ++i; } curPos += strlen(tabcomp); //set our new position free(tabcomp); } ++tabPressNo; } } else if(c == '\177') { //other form of backspace if(curPos > promptLen) { backspace(); //backspace until we reach prompt line[strlen(line)-1] = 0; //thank god this finally works --curPos; } } memset(printBuff,0,100); //clear printing buffer } printf("\n"); //for niceness quit_raw_mode(); //so we dont get stuck in it return 0; //goodbye }
/** * Main program execution */ int main (int argc, char *argv[]) { TOKENIZER *tokenizer; char string[1024] = ""; char *tok; int br; int most_recent_job = 0; ProcessMap *jobs = new_map(); //Set up signal handling signal(SIGINT, SIG_IGN); signal(SIGTSTP, SIG_IGN); signal(SIGTTOU, SIG_IGN); signal(SIGTTIN, SIG_IGN); signal(SIGTERM, SIG_IGN); string[1023] = '\0'; /* ensure that string is always null-terminated */ printf("\nEnter a command or type ctrl-d to end session.\n" ); write(1, "\nmy-sh$ ", 8); //Input loop while ((br = read( STDIN_FILENO, string, 1023 )) > 0) { if (br <= 1) { write(1, "my-sh$ ", 8); continue; } string[br-1] = '\0'; tokenizer = init_tokenizer(string); //Create linked list of tokens LinkedList *input_command = new_list(256); while( (tok = get_next_token( tokenizer )) != NULL ) { push_back(input_command, tok); free(tok); } free_tokenizer(tokenizer); int executed = 0; int error = 0; //Checks for fg or bg if (get_length(input_command) == 1) { char *only_token = pop_back(input_command); if (compare_strings(only_token, "fg")) { if (move_to_foreground(jobs, &most_recent_job) == -1) error = 1; executed = 1; } else if (compare_strings(only_token, "bg")) { if (move_to_background(jobs, &most_recent_job) == -1) error = 1; executed = 1; } else { push_back(input_command, only_token); } free(only_token); } //Process input for pipes or background if an error has already been detected, go to the next command if (!executed && !error) { //Sees if a background ampersand is detected bool is_background = determine_background(input_command); LinkedList *full_command = copy_list(input_command); if (is_background) { printf("Running: "); print_list(input_command); } //Test for pipes bool is_pipe = false; LinkedList *first_command_list = new_list(50); LinkedList *second_command_list = new_list(50); int valid_pipe = find_piping(input_command, &is_pipe, first_command_list, second_command_list); //Command blocks are created from the command lists CommandBlock *first_command = new_command_block(first_command_list); CommandBlock *second_command = new_command_block(second_command_list); //Runs a function to check that there are no invalid redirections in the case of a piping if (is_pipe) { valid_pipe = valid_pipe && check_pipe(first_command, second_command); } //Notifies user of any incorrect pipe commands if (!is_pipe && !first_command->valid) { printf("Invalid command structure\n"); } else if (is_pipe && (!first_command->valid || !second_command->valid || !valid_pipe) ) { printf("Invalid command structure\n"); } //If it is a pipe and all necessary conditions are valid, then the piping occurs if (is_pipe && first_command->valid && second_command->valid && valid_pipe) { if (pipe_job (first_command, second_command, is_background, full_command, jobs, &most_recent_job) == -1) error = 1; } // No piping else if (!is_pipe && first_command->valid) { if (job (first_command, is_background, full_command, jobs, &most_recent_job) == -1) error = 1; } destroy_list(first_command_list); destroy_list(second_command_list); destroy_block(first_command); destroy_block(second_command); destroy_list(full_command); } destroy_list(input_command); monitor_background_jobs (jobs, &most_recent_job); if (error) perror("ERROR "); write(1, "my-sh$ ", 8); } destroy_map(jobs); printf( "\nSession ended\n" ); return 0; }