2015-12-06 4 views
0

У меня есть программа клиент-сервер, где сервер является простой оболочкиExecve «/ bin/спящий режим» замораживания

команды работают отлично, аргументы передается в порядке, но я думаю, что execve замерзает

так вот простой код оболочки - первая половина ОС, чтобы проверить, если команда разрешена в этой оболочке

while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0){ //loop until connection has been terminated 
     if (!strcmp(buf, "quit\n")){ 
     printf("User %s disconnected.\n", username); 
     flag1 = 0; //the user will need to login again 
     } 
     if (flag1 == 1){ //the user is loged in 
     bg = p3parseline(buf, argv_for_shell); 
     strtok(buf, "\n"); 
     printf("User %s sent the command '%s' to be executed.\n", username, buf); 
     // temp = argv_for_shell[0]; 
     // strcat(temp, "\n"); 
    //check if the command is allowed 
    flag2 = 0; //set command allowed? flag back to false 
    file = Fopen("rrshcommands.txt", "r"); 
    while (Fgets(command, MAXLINE, file) != NULL){ 
     strtok(command, "\n"); 
     if (!strcmp(argv_for_shell[0], command)){ 
     flag2 = 1; 
     } 
    } 
    Fclose(file); 

    if (flag2 == 0){ //case where the command is not allowed 
     printf("The command '%s' is not allowed.\n", buf); 
     strcpy(buf, "Command not allowed\n"); 
     Rio_writen(connfd, buf, strlen(buf)); 
    } 
    else{ 
     if ((pid = fork()) == 0) { /* Child runs user job */ 
     printf("Fork/Execing the command %s on behalf of the user.\n", argv_for_shell[0]); 
     Dup2(connfd, 1); 

     if (execve(argv_for_shell[0], argv_for_shell, environ) < 0) { 
      printf("%s: Command not found.\n", argv_for_shell[0]); 
      exit(0); 
     } 
     printf("Finished execing\n"); 
     } 
     /* Parent waits for foreground job to terminate */ 
     if (!bg) { 
     int status; 
     if (waitpid(pid, &status, 0) < 0) 
      unix_error("waitfg: waitpid error"); 
     memset(&buf[0], 0, sizeof(buf)); //flush the buffer 
     Rio_writen(connfd, buf, strlen(buf)); 
     } 
     else{ 
     memset(&buf[0], 0, sizeof(buf)); //flush the buffer 
     Rio_writen(connfd, buf, strlen(buf)); 
     } 
     signal(SIGCHLD, reap_background); 
    } 
    } 

Я разместил вопрос ранее, что было связанно с этим, но была вызвана отдельным вопросом - чувство бесплатно прочитать это тоже

Я добавил заявление PRINTF ниже execve, чтобы подтвердить, если программа была добраться до этой точки, и это не

выход оболочки выглядит

User k logging in from 127.0.0.1 at TCP port 1024. 
User k successfully logged in. 
User k sent the command '/bin/sleep 1&' to be executed. 
Fork/Execing the command /bin/sleep on behalf of the user. 

какие-либо идеи?

+0

Функция: 'execve()' никогда не возвращается, если создание нового процесса не выполняется. Выложенный код, похоже, ожидает, что вызов 'execve()' будет возвращен как нормальная операция. – user3629249

+0

такой тип пары: 'memset (& buf [0], 0, sizeof (buf)); // сбросить буфер Rio_writen (connfd, buf, strlen (buf)); 'кажется немного« нечетным », поскольку массив buf [] установлен на все байты NUL, а затем вызывает« RioWriten() », используя' strlen (buf) ', но' strlen (buf) 'будет возвращать 0, поэтому пытается записать 0 байт. Однако мое исследование указывает 1) написание: 'rio_writen()' not 'RioWriten(), так где вы получаете альтернативное правописание? – user3629249

+0

Где находится 'bg'? возможно, пользовательская команда должна быть проанализирована немного больше, чтобы найти конечную '&' для установки переменной 'bg'. – user3629249

ответ

2

Этого можно ожидать, насколько я могу судить. Сначала вы fork(), затем вы печатаете «Fork/Execing command/bin/sleep от имени пользователя». Затем вы вызываете execve(). Вызов execve() никогда не вернется (при условии, что он преуспел), поскольку execve() заменит текущую программу.

Поэтому эта линия:

printf("Finished execing\n"); 

никогда не будет достигнута.

Именно поэтому вы (предположительно) сделали fork() в первую очередь. То, что вы должны делать, - wait() ing для завершения процесса fork().

Кроме того, для чего предназначена эта линия?

+0

, но я жду в следующем if statement.does, это нужно перенести? – kendall

+0

Правильно, но после этого вы ничего не печатаете, поэтому вывод, который вы вставили, был тем, что ожидалось. – abligh

+0

интересно, что вы говорите, что, поскольку gdb показывает строку 'if (! Bg)', а затем она зависает. Есть идеи? – kendall