void getListFromTree(t_btree *root) { if (root != NULL) { add_last(root->data); getListFromTree(root->left); getListFromTree(root->right); } else { add_last(INF); } }
/** * Update latency counter or add new entry if it doesn't exist */ static int update_last(struct ceph_daemon *d, const char *ds_n, int index, double cur_sum, uint64_t cur_count) { if((d->last_idx > index) && (strcmp(d->last_poll_data[index]->ds_name, ds_n) == 0)) { d->last_poll_data[index]->last_sum = cur_sum; d->last_poll_data[index]->last_count = cur_count; return 0; } if(!d->last_poll_data) { d->last_poll_data = malloc(1 * sizeof(struct last_data *)); if(!d->last_poll_data) { return -ENOMEM; } } else { struct last_data **tmp_last = realloc(d->last_poll_data, ((d->last_idx+1) * sizeof(struct last_data *))); if(!tmp_last) { return -ENOMEM; } d->last_poll_data = tmp_last; } return add_last(d, ds_n, cur_sum, cur_count); }
int main(int argc, char *argv[]) { /* Liste aufbauen */ pdllist l = create(); int i; pdllist lastl = l; for(i = 1; i < argc; i++) { l = add_last(l, argv[i]); del_all(lastl); lastl = l; } /* Kopieren */ lastl = l; l = copy_custom(l, copy_handler); del_all(lastl); /* Ausgeben */ printf("Einträge: \n"); pdllistitem item = l->first; int n = 1; while(item) { printf("%2d. %s\n", n, (char *)item->data); item = item->next; n++; } /* Löschen */ del_all_custom(l, delete_handler); return 0; }
nodeL* getListFromTree(nodeT* root) { if(root!=NULL) { int aux=root->data; add_last(aux); getListFromTree(root->left); getListFromTree(root->right); } return firstFromList; }
//---------------------------------------------------------------------------------------------------------------------- CStack::CStack(const CStack &v) { SItem *cur = v.top; top = NULL; while (cur) { add_last(cur->info); cur = cur->next; } }
void pseudo_cmd() { FILE* f; f = fopen("input.dat", "r"); FILE* g; g = fopen("output.dat", "a"); LIST* head = NULL; char com[15]; char subcom[15]; int x = 0; while (!feof(f)) { fscanf(f, " %[^\n]s", com); // fprintf(g, "%d \n", list_length(head)); // print_all(head, g); // fprintf(g, "///////\n"); // fprintf(g, "%s\n", com); sscanf(com, "%s %d", subcom, &x); if (!strcmp(subcom, "AF")) add_first(&head, x); else if (!strcmp(subcom, "AL")) add_last(&head, x); else if (!strcmp(subcom, "DF")) del_first(&head); else if (!strcmp(subcom, "DL")) del_last(&head); else if (!strcmp(subcom, "DOOM_THE_LIST")) doom_the_list(&head); else if (!strcmp(subcom, "DE")) del_x(&head, x); else if (!strcmp(subcom, "PRINT_ALL")) print_all(head, g); else if (!strcmp(subcom, "PRINT_F")) print_first_n(head, x, g); else if (!strcmp(subcom, "PRINT_L")) print_last_n(head, x, g); } doom_the_list(&head); }
//меню добавления узлов с клавиатуры NODE* add(NODE* list) { int uc; do { system("cls"); printf_s("\n ДОБАВЛЕНИЕ ДАННЫХ ВРУЧНУЮ\n\n"); puts(" 1 - В начало списка"); puts(" 2 - В произвольную позицию"); puts(" 3 - В конец списка"); puts(" 0 - Назад"); uc = userchoice(); switch (uc) { case 1: list = add_first(list); break; case 2: list = add_n(list); break; case 3: list = add_last(list); break; case 0: break; default: system("cls"); printf_s("\n ОШИБКА\n"); printf_s("\n Введите существующий пункт\n\n "); system("pause"); break; } } while (uc && uc < 0 || uc > 3); return list; }
//добавление узла в н-ную позицию NODE* add_n(NODE* list) { if (!list) { system("cls"); printf_s("\n Список пуст, запись будет осуществлена в начало\n\n "); system("pause"); list = add_first(list); } else { int n = get_n(amt(list), "Введите номер позиции, в которую следует добавить запись", "add"); if (n == 1) list = add_first(list); else if (n == amt(list) + 1) list = add_last(list); else { NODE* nta = fill_fields(); NODE *tmp = list; int i; for (i = 1; i < n - 1; i++) tmp = tmp->next; nta->next = tmp->next; tmp->next->prev = nta; nta->prev = tmp; tmp->next = nta; printf_s("\n Новая запись была добавлена в позицию № %d списка\n\n ", n); system("pause"); } } return list; }
void build_menu() { Preparat p; system("color 02"); menustart: system("cls"); printf("Alegeti optiunea:\n\n"); printf("1. Adauga element la inceputul listei.\n"); printf("2. Adauga element la sfarsitul listei.\n"); printf("3. Afiseaza lista din memorie.\n"); printf("4. Afiseaza lista din fisier.\n"); printf("5. Sterge un element din lista.\n"); printf("6. Incarca lista din fisier in memorie.\n"); printf("7. Sterge toate elementele listei din memorie.\n"); printf("8. Sorteaza elementele in fisier dupa metoda Shell.\n"); printf("9. Salveaza lista in fisier.\n"); printf("10. Modifica un element din lista.\n"); printf("11. Iesire din program.\n\n"); int option; scanf("%d", &option); system("cls"); switch (option) { case 1: printf("Nume preparat:"); scanf("%s", &p.nume); printf("Pret:"); scanf("%d", &p.pret); printf("Este nevoie de prescriptie medicala? (Da/Nu):"); scanf("%s", &p.pr_med); printf("Tip Preperat:"); scanf("%s", &p.tip); add_first(p); goto menustart; break; case 2: printf("Nume preparat:"); scanf("%s", &p.nume); printf("Pret:"); scanf("%d", &p.pret); printf("Este nevoie de prescriptie medicala? (Da/Nu):"); scanf("%s", &p.pr_med); printf("Tip Preperat:"); scanf("%s", &p.tip); add_last(p); goto menustart; break; case 3: display(0); getch(); goto menustart; break; case 4: display(1); getch(); goto menustart; break; case 5: printf("Indicati indexul elementului pentru a fi sters:"); int index; scanf("%d", &index); delete_at(index); getch(); goto menustart; break; case 6: read_from_file(); goto menustart; break; case 7: clear_list(); printf("Sters cu success!!"); getch(); goto menustart; break; case 8: file_shell_sort(); getch(); goto menustart; break; case 9: save_to_file(); goto menustart; break; case 10: printf("\nDati indexul elementului ce necesita modificare:"); int ind; scanf("%d", &ind); edit_at(ind); goto menustart; case 11: exit(0); break; default: printf("Optiune indicata gresit."); break; } }
void add_list_wrap(list_wrap* list_head,list_wrap* one_wrap) { add_last(list_head->list,one_wrap->list); }
int sh( int argc, char **argv, char **envp ) { signal(SIGINT, sig_handle); signal(SIGTERM, SIG_IGN); signal(SIGTSTP, SIG_IGN); char *prompt = calloc(PROMPTMAX, sizeof(char)); char *commandline = calloc(MAX_CANON, sizeof(char)); char *command, *arg, *aliashelp, *commandpath, *p, *pwd, *owd; /* Use these two save chars for strtok_r on command and alias commands*/ char *command_save, *alias_save; char **args = calloc(MAXARGS, sizeof(char*)); int uid, i, status, argsct, a, go = 1; int background, bg_pid = 0; struct passwd *password_entry; char *homedir; struct pathelement *pathlist, *history; struct aliaselement *aliases; const char sp[2] = " "; extern char **environ; glob_t globbuf; size_t glc; char **gl; pthread_t pt_warnload, pt_watchuser; /* for use with warnload */ float load = 0.0; int load_thread = 1; /* for use with watchuser */ static pthread_mutex_t user_lock = PTHREAD_MUTEX_INITIALIZER; int user_thread = 1; struct userarg *userargs; /* for use with file redirection */ int fid; int file_redirect, error_redirect, input_redirect = 0; int noclobber = 0; /* for use with pipe */ int ipc = 0; int ipc_err = 0; int pipefd[2]; char **pipeargs = calloc(5, sizeof(char*)); uid = getuid(); password_entry = getpwuid(uid); /* get passwd info */ homedir = getenv("HOME"); /* get homedir */ if ( (pwd = getcwd(NULL, PATH_MAX+1)) == NULL ) { perror("getcwd"); exit(2); } owd = calloc(strlen(pwd) + 1, sizeof(char)); memcpy(owd, pwd, strlen(pwd)); prompt[0] = ' '; prompt[1] = '\0'; /* Put PATH into a linked list */ pathlist = get_path(); /* By default, we have no history or aliases or users */ history = NULL; aliases = NULL; userargs = NULL; while ( go ) { /* wait on background processes */ bg_pid = waitpid(-1, &status, WNOHANG); if(bg_pid > 0) { printf("Background child [%d] exited with status: %d\n", bg_pid, WEXITSTATUS(status)); } /* print prompt */ printf("\n"); printf(prompt); printf(" ["); printf(pwd); printf("]> "); i = 0; /* get command line and process */ while (fgets(commandline, MAX_CANON, stdin) != NULL) { /* wait on background processes */ bg_pid = waitpid(-1, &status, WNOHANG); if(bg_pid > 0) { printf("Background child [%d] exited with status: %d\n", bg_pid, WEXITSTATUS(status)); } if (commandline[strlen(commandline) - 1] == '\n') { commandline[strlen(commandline) - 1] = 0; } /* Add the command to history */ history = add_last(history, commandline); /* Get the command */ command = strtok_r(commandline, sp, &command_save); if(command == NULL) { break; } /* Search for aliases */ a = 0; struct aliaselement *alias = aliases; while(alias != NULL) { if(strcmp(command, alias->name) == 0) { a = 1; break; } alias = alias->next; } /* If we have an alias */ i = 0; if(a) { /* parse alias command */ arg = calloc(strlen(alias->command) + 1, sizeof(char)); strcpy(arg, alias->command); aliashelp = strtok_r(arg, sp, &alias_save); while(aliashelp != NULL) { if(i == MAXARGS) { strcpy(args[0], "maxargs"); break; } args[i] = calloc(strlen(aliashelp) + 1, sizeof(char)); strcpy(args[i], aliashelp); aliashelp = strtok_r(NULL, sp, &alias_save); i++; } command = strtok_r(NULL, sp, &command_save); free(arg); } /* parse command line or remainder of command line if we have an alias */ while (command != NULL) { if(i == MAXARGS) { strcpy(args[0], "maxargs"); break; } args[i] = calloc(strlen(command) + 1, sizeof(char)); strcpy(args[i], command); command = strtok_r(NULL, sp, &command_save); i++; } /* SANITY CHECK: make sure the user passed in something */ if(args[0] == NULL) { break; } /* Expand wildcard characters */ glob(args[0], GLOB_NOCHECK, NULL, &globbuf); i = 1; while(args[i] != NULL) { glob(args[i], GLOB_APPEND | GLOB_NOCHECK, NULL, &globbuf); i++; } /* gl becomes our arguments, it is the expanded version of args */ gl = globbuf.gl_pathv; /* glc is the number of arguments. Use it for checking built in commands */ glc = globbuf.gl_pathc; /* Check for background & at end of last argument */ char* last_arg = gl[glc - 1]; char last_char = last_arg[(strlen(last_arg) - 1)]; if(strcmp(&last_char, "&") == 0) { last_arg[(strlen(last_arg) - 1)] = '\0'; background = 1; } /* Check for file output redirection (without appending) */ if(glc > 2 && (strcmp(gl[glc-2], ">") == 0 || strcmp(gl[glc-2], ">&") == 0)) { /* Don't overwrite an existing file if noclobber is set */ if(noclobber) { if(access(gl[glc-1], F_OK) == 0) { fprintf(stderr, "%s: File exists.\n", gl[glc-1]); free_args(args); break; } } /* Redirect the output to given file */ fid = open(gl[glc-1], O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP); if(fid == -1) { perror(gl[glc-1]); free_args(args); break; } close(1); dup(fid); /* Redirect error output to the given file */ if(strcmp(gl[glc-2], ">&") == 0) { close(2); dup(fid); error_redirect = 1; } close(fid); file_redirect = 1; /* Hide redirection character and filename */ gl[glc-2] = '\0'; gl[glc-1] = '\0'; glc = glc - 2; } /* Check for file output redirection (with appending) */ if(glc > 2 && (strcmp(gl[glc-2], ">>") == 0 || strcmp(gl[glc-2], ">>&") == 0)) { /* Don't append to a file that doesn't exist */ if(noclobber) { if(access(gl[glc-1], F_OK) != 0) { fprintf(stderr, "%s: No such file or directory.\n", gl[glc-1]); free_args(args); break; } } /* Redirect the output to given file */ fid = open(gl[glc-1], O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP); if(fid == -1) { perror(gl[glc-1]); free_args(args); break; } close(1); dup(fid); /* Redirect error output to the given file */ if(strcmp(gl[glc-2], ">>&") == 0) { close(2); dup(fid); error_redirect = 1; } close(fid); file_redirect = 1; /* Hide redirection character and filename */ gl[glc-2] = '\0'; gl[glc-1] = '\0'; glc = glc - 2; } /* Check for file input redirection */ if(glc > 2 && strcmp(gl[glc-2], "<") == 0) { /* Can't take input from a nonexisistent file */ if(access(gl[glc-1], F_OK) != 0) { fprintf(stderr, "%s: No such file or directory.\n", gl[glc-1]); free_args(args); break; } /* Open the file to read from */ fid = open(gl[glc-1], O_RDONLY); if(fid == -1) { perror(gl[glc-1]); free_args(args); break; } close(0); dup(fid); close(fid); input_redirect = 1; /* Hide redirection character and filename */ gl[glc-2] = '\0'; gl[glc-1] = '\0'; glc = glc - 2; } /* Check for inter-process communication */ if(glc > 2 && (strcmp(gl[1], "|") == 0 || strcmp(gl[1], "|&") == 0)) { ipc = 1; if(strcmp(gl[1], "|&") == 0) { ipc_err = 1; } /* Create our pipe */ if(pipe(pipefd) == -1) { perror("pipe"); free_args(args); break; } /* Put the command to the right of the pipe in a second arguments list */ i = 2; int p = 0; while(gl[i] != NULL) { pipeargs[p] = malloc(strlen(gl[i]) + 1 * sizeof(char)); pipeargs[p] = gl[i]; i++; p++; } gl[1] = '\0'; glc = 1; } /* check for each built in command and implement */ /* Built in warnload */ if(strcmp(gl[0], "warnload") == 0) { printf("Executing built-in [%s]\n", gl[0]); char *end; if(glc != 2) { printf("Usage: warnload LOAD\n"); } else if (strcmp(gl[1], "0.0") != 0 && (strtof(gl[1], &end) == 0 || strtof(gl[1], &end) < 0)) { printf("LOAD must be a positive floating point number\n"); } else if (strcmp(gl[1], "0.0") == 0) { load = 0.0; load_thread = 1; } else { load = strtof(gl[1], &end); if(load_thread != 0) { load_thread = 0; pthread_create(&pt_warnload, NULL, warnload, &load); } } } /* Built in watchuser */ else if(strcmp(gl[0], "watchuser") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc < 2) { fprintf(stderr, "watchuser: Too few arguements.\n"); } else if(glc > 3) { fprintf(stderr, "watchuser: Too many arguments.\n"); } else if (glc == 3 && strcmp(gl[2], "off") != 0) { printf("Usage: watchuser USERNAME [off]\n"); } else if (glc == 3 && strcmp(gl[2], "off") == 0 ){ /* remove the given username from watched users list */ if(user_thread == 0) { pthread_mutex_lock(&user_lock); userargs->users = remove_user(userargs->users, gl[1]); pthread_mutex_unlock(&user_lock); } else { printf("No watched users have been added yet\n"); } } else { /* Add the user to the list. Create the watchuser thread if it isn't already created */ if(user_thread == 1) { user_thread = 0; userargs = calloc(1, sizeof(struct userarg)); userargs->lock = user_lock; userargs->users = add_user(NULL, gl[1]); pthread_create(&pt_watchuser, NULL, watchuser, userargs); } else { pthread_mutex_lock(&user_lock); userargs->users = add_user(userargs->users, gl[1]); pthread_mutex_unlock(&user_lock); } } } /* WATCHMAIL NOT IMPLEMENTED */ else if(strcmp(gl[0], "watchmail") == 0) { printf("We were not able to implement watchmail as we could not figure out\nhow to correctly use pthread_cancel(3) to cancel threads\n"); } /* Build in fg */ else if(strcmp(gl[0], "fg") == 0) { printf("Executing build-in [%s]\n", gl[0]); /* No arguments, bring a default process into foreground */ if(glc == 1) { kill(0, SIGCONT); wait(NULL); } /* One argument, bring the process with pid into foreground */ else if(glc == 2) { if(atoi(gl[1])) { kill(atoi(gl[1]), SIGCONT); waitpid(atoi(gl[1]), NULL, 0); } else { fprintf(stderr, "pid must be an integer\n"); } } else { fprintf(stderr, "Usage: fg [pid]\n"); } } /* Built in list */ else if(strcmp(gl[0], "list") == 0) { printf("Executing built-in [%s]\n", gl[0]); i = 1; /* No arguments, print the current working directory */ if(glc < 2) { list(pwd); } else { /* list each of the arguments passed in */ while(i < glc) { list(gl[i]); printf("\n"); i++; } } } /* Built in exit */ else if (strcmp(gl[0], "exit") == 0) { printf("Executing built-in [%s]\n", gl[0]); go = 0; break; } /* Built in prompt */ else if (strcmp(gl[0], "prompt") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc < 2) { /* user didn't enter a prompt so request one */ printf("input prompt prefix:"); fgets(prompt, PROMPTMAX, stdin); if(prompt[strlen(prompt) - 1] == '\n') { prompt[strlen(prompt) - 1] = 0; } } else { /* set the prompt to be the first argument */ strncpy(prompt, gl[1], PROMPTMAX); } } /* Built in pwd */ else if (strcmp(gl[0], "pwd") == 0) { printf("Executing built-in [%s]\n", gl[0]); printf(pwd); printf("\n"); } /* Built in noclobber */ else if (strcmp(gl[0], "noclobber") == 0){ if(noclobber == 0) { noclobber = 1; } else { noclobber = 0; } printf("noclobber is set to %d\n", noclobber); } /* Built in pid */ else if (strcmp(gl[0], "pid") == 0) { printf("Executing built-in [%s]\n", gl[0]); printf("%d\n", getpid()); } /* Built in which */ else if (strcmp(gl[0], "which") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc < 2) { fprintf(stderr, "which: Too few arguments.\n"); } else { i = 1; while(i < glc) { char *wh; /* call the which function which will check for the command in the path */ wh = which(gl[i], pathlist); if(wh == NULL) { fprintf(stderr, "%s: Command not found.\n", gl[i]); } else { printf("%s\n", wh); } free(wh); i++; } } } /* Built in where */ else if (strcmp(gl[0], "where") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc < 2) { fprintf(stderr, "where: Too few arguments.\n"); } else { i = 1; while(i < glc) { where(gl[i], pathlist); i++; } } } /* Built in cd */ else if (strcmp(gl[0], "cd") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc > 2) { printf("cd: Too many arguments.\n"); } else { char *tmp; /* tmp will be the new directory or NULL on failure */ tmp = cd(gl[1], homedir, owd); if(tmp == NULL) { break; } else { free(owd); /* set owd to be the old (previous) working directory */ owd = pwd; /* set the new working directory */ pwd = tmp; } tmp = NULL; } } /* Built in printenv */ else if (strcmp(gl[0], "printenv") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc > 2) { fprintf(stderr, "%s: Too many arguments.\n", gl[0]); } else if (glc > 1) { /* print a particular environmental variable */ char *tmp; tmp = getenv(gl[1]); if(tmp == NULL) { fprintf(stderr, "%s: Environmental variable not found.\n", gl[1]); } else { printf("%s\n", tmp); } tmp = NULL; } else { /* print all environmental variables */ i = 0; while(environ[i] != NULL) { printf("%s\n", environ[i]); i++; } } } /* Built in setenv */ else if (strcmp(gl[0], "setenv") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc > 3) { fprintf(stderr, "%s: Too many arguments.\n", gl[0]); } else if (glc > 2) { /* set an environmental variable to the given value */ setenv(gl[1], gl[2], 1); } else if (glc > 1) { /* set an environmental variable to an empty value */ setenv(gl[1], "", 1); } else { /* print all environmental variables */ i = 0; while(environ[i] != NULL) { printf("%s\n", environ[i]); i++; } } /* in case we update the home directory */ homedir = getenv("HOME"); } /* Built in history */ else if (strcmp(gl[0], "history") == 0) { printf("Executing built-in [%s]\n", gl[0]); int n = 10; /* set how many history records to print */ if(glc > 1 && atoi(gl[1]) != 0) { n = atoi(gl[1]); } struct pathelement *curr = history; /* loop and print past commands */ while(curr != NULL && n > 0) { printf("%s\n", curr->element); curr = curr->next; n--; } } /* Built in alias */ else if (strcmp(gl[0], "alias") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc < 2) { /* list all aliases */ struct aliaselement *curr = aliases; while(curr != NULL) { printf("%s %s\n", curr->name, curr->command); curr = curr->next; } } else if(glc < 3) { /* list a specific alias */ struct aliaselement *curr = aliases; while(curr != NULL) { if(strcmp(gl[1], curr->name) == 0) { printf("%s\n", curr->command); } curr = curr->next; } } else { /* add an alias */ char buf[MAX_CANON]; snprintf(buf, MAX_CANON, "%s", gl[2]); i = 3; while(gl[i] != NULL && i < MAXARGS) { strcat(buf, " "); strcat(buf, gl[i]); i++; } aliases = add_alias(aliases, gl[1], buf); } } /* Built in kill */ else if (strcmp(gl[0], "kill") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc < 2) { fprintf(stderr, "kill: Too few arguments.\n"); } else if(glc < 3 || strchr(gl[1], '-') == NULL) { /* default kill with SIGINT */ i = 1; while(gl[i] != NULL) { kill_process(gl[i]); i++; } } else { /* kill with the given signal number */ char *signal; signal = strtok(gl[1], "-"); i = 2; while(gl[i] != NULL) { kill_process_signal(gl[i], signal); i++; } } } /* MAXARGS handler */ else if (strcmp(gl[0], "maxargs") == 0) { fprintf(stderr, "Error: Too many arguments.\n"); } /* Absolute/Relative paths */ else if (strncmp(gl[0], "/", 1) == 0 || strncmp(gl[0], "./", 2) == 0 || strncmp(gl[0], "../", 3) == 0) { if(access(gl[0], X_OK) == 0) { pid_t pid = fork(); if(pid == -1) { perror("fork"); } else if(pid == 0) { /* print what child is executing and execve it */ printf("Executing [%s]\n", gl[0]); /* If we are piping this is the command on the left, set standard output to the pipe output */ if(ipc) { close(1); dup(pipefd[1]); if(ipc_err) { close(2); dup(pipefd[1]); } close(pipefd[0]); close(pipefd[1]); } execve(gl[0], gl, environ); /* on exec error */ perror(gl[0]); exit(127); } else { /* if not a background process, wait */ if(!background) { /* If we are piping this is the command on the right. Wait for the first command to finish */ if(ipc) { waitpid(pid, &status, 0); pid_t pid2 = fork(); if(pid2 == -1) { perror("fork"); } else if (pid2 == 0) { /* Set stdin to be the pipe input */ close(0); dup(pipefd[0]); close(pipefd[1]); close(pipefd[0]); /* Which command should we run */ char* wh; wh = which(pipeargs[0], pathlist); if(wh == NULL) { fprintf(stderr, "%s: Command not found", pipeargs[0]); } else { execve(wh, pipeargs, environ); } } else { close(pipefd[0]); close(pipefd[1]); } } else { /* wait for chil process */ waitpid(pid, &status, 0); /* if child exits with non-zero status print it */ if(WEXITSTATUS(status) != 0) { printf("Exit: %d\n", WEXITSTATUS(status)); } } } } } else { /* path doens't exist */ fprintf(stderr,"%s: Command not found.\n", gl[0]); } } /* Executable */ else { char* wh; char* wh2; /* figure out which executable to execute */ wh = which(gl[0], pathlist); if(wh == NULL) { fprintf(stderr, "%s: Command not found.\n", gl[0]); } else { pid_t pid = fork(); if(pid == -1) { perror("fork"); } else if (pid == 0) { /* what we are executing */ printf("Executing [%s]\n", wh); /* If we are piping this is the command on the left, set standard output to be the pipe output*/ if(ipc) { close(1); dup(pipefd[1]); if(ipc_err) { close(2); dup(pipefd[1]); } close(pipefd[0]); close(pipefd[1]); } execve(wh, gl, environ); /* on execve error */ perror(wh); exit(127); } else { /* if not a background process, wait */ if(!background) { /* If we are piping this is the command on the right, wait for command on left to finish */ if(ipc) { waitpid(pid, &status, 0); pid_t pid2 = fork(); if(pid2 == -1) { perror("fork"); } else if (pid2 == 0) { /* Set standard input to be pipe input */ close(0); dup(pipefd[0]); close(pipefd[1]); close(pipefd[0]); /* Which command should we run */ wh2 = which(pipeargs[0], pathlist); if(wh2 == NULL) { fprintf(stderr, "%s: Command not found", pipeargs[0]); } else { execve(wh2, pipeargs, environ); } } else { close(pipefd[0]); close(pipefd[1]); } } else { /* wait for child */ waitpid(pid, &status, 0); /* if child exits with nonzero value print it */ if(WEXITSTATUS(status) != 0){ printf("Exit: %d\n", WEXITSTATUS(status)); } } } } free(wh); } } /* reset background */ background = 0; /* reset glob */ globfree(&globbuf); /* reset args */ free_args(args); free_args(pipeargs); /* if we redirected file output, reset it to the screen */ if(file_redirect == 1) { file_redirect = 0; fid = open("/dev/tty", O_WRONLY); close(1); dup(fid); if(error_redirect == 1) { error_redirect = 0; close(2); dup(fid); } close(fid); } /* if we redirected file input, reset it to the keyboard */ if(input_redirect == 1) { input_redirect = 0; fid = open("/dev/tty", O_RDONLY); close(0); dup(fid); close(fid); } ipc = 0; ipc_err = 0; sleep(1); /* Print prompt again */ printf(prompt); printf(" ["); printf(pwd); printf("]> "); } } /* free allocated memory */ free(prompt); free(commandline); free_args(args); free_args(pipeargs); free(args); free(pipeargs); free(owd); free(pwd); struct pathelement *tmp; while(pathlist != NULL) { tmp = pathlist->next; free(pathlist); pathlist = tmp; } while(history != NULL) { tmp = history->next; free(history->element); free(history); history = tmp; } struct aliaselement *temp; while(aliases != NULL) { temp = aliases->next; free(aliases->name); free(aliases->command); free(aliases); aliases = temp; } struct userelement *tem; while(userargs != NULL && userargs->users != NULL) { tem = userargs->users->next; free(userargs->users->username); free(userargs->users); userargs->users = tem; } if(userargs != NULL) { pthread_mutex_destroy(&userargs->lock); free(userargs); } globfree(&globbuf); return 0; } /* sh() */