Salutare tuturor,<br><br>Stiu ca este vacanta, dar ma gandesc ca poate cineva isi arunca un ochi si pe lista de discutii de la so si ajuta vreun disperat ca mine.<br>Eu ma confrunt cu urmatoarea problema :<br>- incerc sa rulez din shell-ul meu comenzi simple + cele 3 comenzi interne (exit, quit, cd) si dupa ce scriu dir sau alta comanda , imi da outputul acestia si apoi mi se blocheaza<br>
Am folosit copy / paste functia de executare a unui proces din laborator, iar parsarea o fac intr-o bucla (dupa modelul DisplayStructure.cpp) .<br><br>CloseProcess si Exec sunt din laborator.<br>CreateCommand -> creeaza o comanda (concateneaza verbul si parametri (dc exista) si o pune intre ghilimele ca sa o trimita la executie lui Exec .<br>
ExecuteCOmmand -> executa o comanda simpla (momentan).<br>Mainul -> luat cu copy paste din exemplele din parserul vostru<br>Blocarea apare la a doua comanda care ar urma sa fie scrisa, mai precis in bucla de for din main, intre cout << "> "; si getline(cin, line); <br>
<br>Redau mai jos bucata de cod care executa comanda si cea care se ocupa de citirea ei :<br>=================================================================<br>/*@ fn void CloseProcess(LPPROCESS_INFORMATION ppi)<br> @brief functia inchide procesul curent; functia este preluata mot-a-mot din laborator<br>
@param ppi : pointer catre structura de informatii a procesului<br> @return nimic<br>*/ <br>inline void CloseProcess(LPPROCESS_INFORMATION ppi)<br>{<br> CloseHandle(ppi->hThread);<br> CloseHandle(ppi->hProcess);<br>
}<br> <br>/*@ fn int Exec(const char *cmdLine)<br> @brief executa o comanda simpla; functia este preluata mot-a-mot din laborator<br> @param cmdLine : comanda care trebuie executata<br> @return -1 la esec; pidul procesului la succes<br>
*/<br>int Exec(const char *cmdLine)<br>{<br> STARTUPINFO si;<br> ZeroMemory(&si, sizeof(si));<br> si.cb = sizeof(si);<br> PROCESS_INFORMATION pi;<br> char *cmd = _strdup(cmdLine); // lpCommandLine not const<br>
BOOL bRes = CreateProcess(NULL, cmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL,<br> NULL, &si, &pi);<br> <br> <br> if (!bRes) {<br> cerr << "eroare la createprocess " << endl;<br>
free(cmd); // proper<br> return -1;<br> }<br> DWORD dwRes = WaitForSingleObject(pi.hProcess, INFINITE); // signaled = finished<br> <br> if (WAIT_FAILED == dwRes) {<br> cerr << "eroare la Wait for single object" <<endl;<br>
free(cmd); // proper<br> CloseProcess(&pi);<br> return -1;<br> }<br> bRes = GetExitCodeProcess(pi.hProcess, &dwRes);<br> <br> free(cmd);<br> CloseProcess(&pi);<br> <br>
if (!bRes) {<br> cerr << " eroare la closeprocess " << endl;<br> return -1;<br> }<br> <br> return static_cast<int>(dwRes);<br>}<br><br><br>/*! fn CreateCommand(simple_command_t comanda)<br>
@brief concateneaza verbul si parametri comenzii pentru o comanda simpla<br> @param comanda : comanda simpla<br> @return sirul rezultat din concatenare<br>*/<br><br>char* CreateCommand(simple_command_t *comanda){<br>
char* rez = (char*) calloc(256,sizeof(char));<br> if (!rez) {<br> cerr <<"Eroare la alocare"<<endl;<br> return NULL;<br> }<br> strcat_s(rez,256,comanda->verb->string);<br>
if (comanda->params != NULL) {<br> strcat_s(rez,256," ");<br> strcat_s(rez,256,comanda->params->string);<br> } <br> return rez;<br>}<br> <br><br>/*! fn ExecuteCommand(command_t* root);<br>
@brief executa o comanda primita de la utilizator<br> @param root : este comanda<br> @return nimic<br>*/<br><br>void ExecuteCommand(command_t *root) {<br> char *comanda, *comanda_exec;<br> int res,dim;<br>
//daca este o comanda simpla<br> <br> if(root->op == OP_NONE) { <br> comanda = CreateCommand(root->scmd);<br> <br> //daca este cumva exit/quit<br> ExitShell((char*) root->scmd->verb->string);<br>
<br> //daca este cd director<br> if (_stricmp(root->scmd->verb->string,"cd") == 0)<br> ChangeDirectory((const char*)root->scmd->params->string);<br> else {<br> dim = 3+strlen(comanda);<br>
comanda_exec =(char*) calloc(dim , sizeof(char));<br> if (comanda_exec == NULL) <br> return;<br> strcat_s(comanda_exec,dim,"\"");<br> strcat_s(comanda_exec,dim,comanda);<br>
strcat_s(comanda_exec,dim,"\"");<br> res = Exec(comanda_exec);<br> if (res < 0) {<br> cerr << "Execution failed for "<<root->scmd->verb->string<<endl;<br>
}<br> } <br> } <br>}<br><br>/*! fn int main()<br> @brief mainul; este mini-shellul in care se ruleaza comenzile<br> @param fara parametri<br> @return 0 la succes; -1 la esec<br>*/<br>int main(void)<br>
{<br> string line;<br> command_t* root = NULL; <br><br> for (;;) {<br> cout << "> "; <br> getline(cin, line); <br> if ((line.length() == 0) && !cin.good()) {<br>
// end of file reached<br> cerr << "End of file!" << endl;<br> return EXIT_SUCCESS;<br> }<br><br> if (parse_line(line.c_str(), &root)) {<br> <br>
if (root == NULL) {<br> cout << "Command is empty!" << endl;<br> }<br> else {<br> // root points to a valid command tree<br> // that we can use<br>
ExecuteCommand(root);<br> <br> }<br> }<br> else {<br> // there was an error parsing the command<br> cout << "Error parsing!" << endl;<br>
}<br> <br> cout << endl << endl;<br> free_parse_memory(); <br> }<br>}<br>===============================================<br><br><br>Multumesc mult de tot. <br>Astept un raspuns.<br>
<br>Ana<br>332cc<br>