Доброго времени суток! Есть небольшая программка. Вот ее исходник: | Код | #include <sys/types.h> #include <sys/stat.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dirent.h> #include <unistd.h>
#define MAXLINE 256 #define MAXPATH 256 #define MAXARGS 25 #define HASHSIZE 101
struct hashList { struct hashList *next; char *szCommand; char *szFullPath; };
static struct hashList *hashTable[HASHSIZE];
/* hash: form hash value for a command name */ unsigned hash(char *szCommand) { int i=0, sum=0; while(szCommand[i]) sum += szCommand[i++]; return sum % HASHSIZE; }
/* hashFind: find command in hash table */ struct hashList *hashFind(char *szCommand) { struct hashList *hp; for(hp=hashTable[hash(szCommand)]; hp !=NULL; hp=hp->next) if(strcmp(szCommand, hp->szCommand)==0) return hp; return NULL; /* not found */ }
/* hashInsert: insert command and path in hash table */ struct hashList *hashInsert(char *szCommand, char *szFullPath) { struct hashList *hp; unsigned hashVal; if((hp=hashFind(szCommand))==NULL) { /* not found */ hp=(struct hashList *)malloc(sizeof(*hp)); if(hp==NULL || (hp->szCommand = strdup(szCommand))==NULL || (hp->szFullPath = strdup(szFullPath))==NULL) return NULL; /* Couldn't add the hash entry */ hashVal=hash(szCommand); hp->next = hashTable[hashVal]; hashTable[hashVal]=hp; } return hp; }
int main() { const char *szPrompt = "msh> "; char sInputBuf[MAXLINE]; char szFilePath[MAXPATH]; char *szDirPath; char *szEnvPath=strdup(getenv("PATH")); char *szCommand; char *szArgs[MAXARGS]; DIR *dp; struct dirent *d; struct stat statBuf; struct hashList *hp; int i, status; pid_t pid;
/* Scan PATH directories and add commands to hash table */ szDirPath=strtok(szEnvPath, ":"); while( szDirPath != NULL ) { if((dp=opendir(szDirPath)) != NULL) { while((d=readdir(dp))) { if(d->d_ino != 0) { strcpy(szFilePath, szDirPath); strcat(szFilePath, "/"); strcat(szFilePath, d->d_name); if(lstat(szFilePath, &statBuf) >= 0) if(S_ISREG(statBuf.st_mode) && access(szFilePath,X_OK)==0) hashInsert(d->d_name, szFilePath); } } closedir(dp); } szDirPath = strtok(NULL, ":"); }
/* Get commands until Ctrl-D */ fputs(szPrompt, stdout); /* Prompt for command input */ while( fgets(sInputBuf, MAXLINE, stdin) != NULL ) {
/* Parse command line arguments */ szArgs[i=0] = strtok(sInputBuf, " \n"); while( i<MAXARGS && szArgs[i] != NULL ) szArgs[++i] = strtok(NULL, " \n");
if(szArgs[0] == NULL) szCommand = NULL; else { /* Find path to command */ if(strchr(szArgs[0], '/') != NULL) szCommand=szArgs[0]; /* path given */ else { /* look up full command path in hash table */ if((hp=hashFind(szArgs[0])) != NULL) { szCommand=hp->szFullPath; } else { szCommand = NULL; fprintf(stderr, "%s: command not found.\n", szArgs[0]); } } }
if(szCommand != NULL) { /* Fork and execute command, wait for completion */ if((pid=fork()) < 0) { /* Error */ perror("Error in fork()"); exit(1); } else if(pid == 0) { /* run command in child process */ execv(szCommand, szArgs); /* Reach here only if the command would not exec */ perror(szCommand); exit(1); } if(waitpid(pid, &status, 0) == -1) { perror("Error in waitpid()"); exit(1); } }
fputs(szPrompt, stdout); /* Prompt for next command */ } fputc('\n', stdout);
return 0; }
|
Подскажите, пожалуйста, кусок кода, который нужно сюда добавить, чтобы этот shell реагировал на команду, например, exit. К примеру, запускаешь shell, вводишь exit и работа shell'а прерывается.
|