void freePipe(Pipe p)
{
  if ( p == NULL )
    return;

  freeCmd(p->head);
  freePipe(p->next);
  free(p);
} /*---------- End of freePipe ----------------------------------------------*/
static Pipe mkPipe()
{
  Pipe p;
  Cmd c;

  c = mkCmd(Tnil);		// at least one command

  // ignore NULL cmds--generated by empty line or error
  if ( c == NULL || c == &Empty )
    return NULL;

  // allocate the pipe structure
  p = ckmalloc(sizeof(*p));
  p->type = Pout;	// set type to Pout until we know differently
  p->head = c;

  while ( PipeToken(LA) ) {
    if ( LA == TpipeErr )
      p->type = PoutErr;	// reset type
    else if(LA == Tpipe)
      p->type = Pout;     //reset type
    if ( c->out != Tnil ) {
      printf("Ambiguous output redirect.\n");
      // skip to end of command
      do { 
	Next();
      } while ( !EndOfInput(LA) );
      freeCmd(c);
      return NULL;
    } else
      c->out = p->type == Pout ? Tpipe : TpipeErr;
    Next();
    c->next = mkCmd(p->type == Pout ? Tpipe : TpipeErr);
    if ( c->next == NULL || c->next == &Empty ) {
      if ( c->next == &Empty )
	printf("Invalid null command.\n");
      while ( !EndOfInput(LA) )
	Next();
      return NULL;
    }
    c = c->next;
  }

  // read next pipe on the line
  p->next = NULL;
  while ( !EndOfInput(LA) ) {
    p->next = mkPipe();
    if ( !p->next )
      break;
  }
  return p;
} /*---------- End of mkPipe ------------------------------------------------*/
Exemple #3
0
// reads command from fd
int readCmd(int fd, struct cmd *command) {
	command->params = (char **)
	allocate((MAX_CMD_PARAMS + 1) * sizeof (char *));
	int i = 0;
	char c, r;
	command->params[0] = NULL;
	// reads command name
	if ((r = readWord(fd, command->name, 256)) == 0) {
		freeCmd(command);
		return (-1);
	}
	// loads parametres
	while (1) {
		command->params[i] = NULL;
		if (r == '\r') {
			if (read(fd, &c, 1) != 1) {
				freeCmd(command);
				return (-1);
			}
			if (c == '\n')
			break; // \r\n sequence
		}
		if (r == '\n')
			break;
		// read another parameter
		command->params[i] = (char *) allocate(256 * sizeof (char));
		if ((r = readWord(fd, command->params[i], 256)) == 0) {
			command->params[i+1] = NULL;
			freeCmd(command);
			return (-1);
		}
		++i;
		if (i == MAX_CMD_PARAMS)
			break;
	}
	// returns number of read parameters
	return (i);
}
static void freeCmd(Cmd c)
{
  int i;

  if ( c == NULL || c == &Empty || c == &End ) return;

  freeCmd(c->next);

  if ( c->infile )
    free(c->infile);
  if ( c->outfile )
    free(c->outfile);
  if ( c->args ) {
    for ( i = 0; i < c->nargs; i++ )
      free(c->args[i]);
    free(c->args);
  }
  free(c);
} /*---------- End of freeCmd -----------------------------------------------*/
static Cmd mkCmd(Token inpipe)
{
  Cmd c;

  while ( CmdToken(LA) )	// skip over ; and &
    Next();

  if ( LA != Tword ) {		// a word begins every command
    if ( LA == Tend )
      return &End;

    if ( LA == Tnl || LA == Terror )
      // don't complain about empty lines or twice about same error
      return &Empty;
    printf(ERR_MSG);
#if 0
    while ( !CmdToken(LA) && !EndOfInput(LA) )	// kill rest of pipe
      Next();
#endif
    return NULL;
  }

  assert(LA == Tword);
  c = newCmd(Word);
  Next();
  c->in = inpipe;

  while ( InCmd(LA) ) {		// loop until next command
    switch ( LA ) {
    case Tin:
      if ( c->in != Tnil ) {	// two Tin in one command
	printf("Ambiguous input redirect.\n");
	// skip to end of line
	do {
	  Next();
	} while ( !EndOfInput(LA) );
	freeCmd(c);
	return NULL;
      }
      c->in = LA;
      Next();
      if ( LA != Tword ) {
	printf(ERR_MSG);
	// skip to end of line
	do {
	  Next();
	} while ( !EndOfInput(LA) );
	freeCmd(c);
	return NULL;
      }	
      c->infile = mkWord(Word);		// save "in" file
      Next();
      break;

    case Tout:
    case ToutErr:
    case Tapp:
    case TappErr:
      if ( c->out != Tnil ) {
	printf("Ambiguous output redirect.\n");
	// skip to end of line
	do {
	  Next();
	} while ( !EndOfInput(LA) );
	freeCmd(c);
	return NULL;
      }
      c->out = LA;			// remember which kind
      Next();
      if ( LA != Tword) {
	printf(ERR_MSG);
	// skip to end of line
	do {
	  Next();
	} while ( !EndOfInput(LA) );
	freeCmd(c);
	return NULL;
      }
      c->outfile = mkWord(Word);	// save "out" file
      Next();
      break;

    case Tword:
      if ( c->args == NULL ) {
	printf("Hmmm...\n");
	exit(-2);
      }
      // if we've exceeded the size of the arg array double it
      if ( c->nargs + 2 > c->maxargs ) {
	c->maxargs += c->maxargs;
	c->args = realloc(c->args, c->maxargs*sizeof(char *));
	if ( c->args == NULL ) {
	  perror("realloc");
	  exit(errno);
	}
      }
      c->args[c->nargs++] = mkWord(Word);	// save the arg
      Next();
      break;

    default:
      printf("Shouldn't get here\n");
      exit(-1);
      break;
    }
  }
  if ( LA == Terror ) {		// shouldn't happen, but what the heck ...
    freeCmd(c);
    return NULL;
  }
  if ( LA == Tsemi )		// skip over ending semi
    Next();
  else if ( LA == Tamp ){	// remember the &
    c->exec = Tamp;
    Next();
  }
  c->args[c->nargs] = NULL;
  return c;
} /*---------- End of mkCmd -------------------------------------------------*/
Exemple #6
0
int main(int argc, char **argv) {
	
	struct rusage usageBegin;
	getrusage(RUSAGE_SELF, &usageBegin);

	char *prompt = ";) ";
	printf("%s", prompt);
	fflush(stdout);
	int sequential = 1;

	struct node* tasks = NULL;

	struct node *paths = NULL;
	struct stat haspath;
	int canhas = stat("shell-config", &haspath);
	if(canhas==0){
		FILE * pathfile = fopen("shell-config", "r");		
		char* pathline = malloc(128*sizeof(char));
		while(fgets(pathline, 128, pathfile) != NULL){
			pathline[strlen(pathline)-1] = '/';
			list_insert(pathline, &paths);
		}
		free(pathline);
		fclose(pathfile);
	}

	char buffer[1024] = "initialized";
	int polloop = 1;
	while(polloop ==1){
		struct pollfd pfd = {0, POLLIN}; //"In" events check
		int input = poll(&pfd, 1, 1000); //Input will be a 1=yes, 0=no input in the past second.
		if(input ==0){
			//run through the grand linked list of background processes.
			struct node *checkup = tasks;
			struct node *suture = tasks;
			int checkstatus = 0;
			while(checkup!=NULL){
				pid_t childp = waitpid((*checkup).pid, &checkstatus, WNOHANG);
				if(childp != 0){
					printf("Parent got carcass of child process %d, return val %d\n", childp, checkstatus);
					if(checkup == tasks){
						tasks = (*checkup).next;
						free(checkup);
						checkup = tasks;
					}else{
						(*suture).next = (*checkup).next;
						free(checkup);
						checkup = (*suture).next;
					}
				}else{
					if(checkup != tasks){
						suture = (*suture).next;
					}
					checkup = (*checkup).next;
				}
			}

		} else if(input<0){
			//probably need to free junk before exit.
			polloop = 0;
		}else{
			//run our fgets and do stuff with their commands.
	
			if(fgets(buffer, 1024, stdin) != NULL){
				int buflen = 1023;
				int i = 0;
				while( i<buflen && buffer[i] != '#'){
					i++;
				}
				buffer[i] = '\0';
				buflen = i-1;
				//printf("Buffer:%s", buffer);
				char *** cmd = parseCommand(buffer);
				//char* test = "a b c d e f g";
				//char*** cmd[2] = {tokenify(test), NULL}; 
				/*int a = 0;
				int b = 0;
				for(; cmd[a]!=NULL; a++){
					for(; (cmd[a])[b] != NULL; b++){
						printf("Command: %s\n", (cmd[a])[b]);
					}
					b=0;
				}*/
		

				int com = 0; //Will be used to increment through cmd
				int built;
				//Sequential Running of cmd:
				for(; sequential==1 && cmd[com] != NULL; com++){	
					built = builtIn(cmd[com]);
					if(built == 1){
						sequential = changeMode(sequential, (cmd[com])[1]);
					} else if(built == -1){
						sequential = -1;
					} else{
						sequential = runSeq(cmd[com], paths);
					}
				}	
				int*** newpros;
				if (sequential == 0 && cmd[com]!=NULL){					
					newpros = parallel(cmd+com, paths, tasks);	
					sequential = (newpros[0])[0][0];
					if(sequential!=-2){
						int index = newpros[1][0][0];
						for(;index > 1; index--){
							/*printf("Index points:%p, Index is:%d\n", newpros[index], index);
							printf("Index[1] points:%p\n", newpros[index][1]);
							printf("Index[1][0] points:%d\n", newpros[index][1][0]);*/
							if(newpros[index][1][0]>0){
								list_insert( (char*)newpros[index][0], &tasks);
								(*tasks).pid = *(newpros[index][1]);
								(*tasks).status = 1; //1 for running
							}
							free(newpros[index][1]);
							free(newpros[index][0]);
							free(newpros[index]);	
						}
						free(newpros);
					}
				}
				if(sequential == -2){
					free(newpros[0][0]);
					free(newpros[0]);
					free(newpros);
					exit(2);
				}
				freeCmd(cmd);
				free(cmd);
				if(sequential == -1){ //totally wrong. fix. -- fixed 
					if(tasks!=NULL){
						struct node *waiter = tasks;
						while(waiter!=NULL){
							int rstatus = 0;
							pid_t childp = waitpid((*waiter).pid, &rstatus,0); 
							printf("Parent got carcass of child process %d, return val %d\n", childp, rstatus);
							waiter = (*waiter).next;
						}
						while((*tasks).next!=NULL){
							waiter = (*tasks).next;
							free(tasks);
							tasks = waiter;
						}
					free(tasks);
					}
					exitUsage(&usageBegin);
					exit(2);
				}
				printf("%s", prompt);
				fflush(stdout);
			}else{
				polloop = -1;
			}
		}
	}
	exitUsage(&usageBegin);
	printf("exited\n");
	return 0;	
}
Exemple #7
0
// function running in separate thread, handling data connection
int controlRoutine(struct control_info *info) {
	int fd = info->fd;
	struct cmd command;
	time_t now = time(NULL);
	struct state cstate = (struct state) { .logged = 0,
		.path = "/",
		.data_port = info->configuration->data_port,
		.transfer_count = 0,
		.data_sock = 0,
		.control_sock = 0,
		.port = 1,
		.last_accepted = 0,
		.addr_family = 1,
		.data_thread = 0,
		.transfer_type = Image,
		.client_addr = *(info->client_addr) };
	snprintf(cstate.dir, 32, "%d", (int)now);
	short abor = 0;
	if (isDir("/control_sockets") == -1)
		if (mkdir("/control_sockets", 0755) == -1) {
			perror("Failed to create control_sockets directory.");
			return (-1);
		}
	// reads commands from the accepted connection and executes it
	while (readCmd(fd, &command) != -1) {
		executeCmd(&command, &abor, fd, &cstate, info->configuration);
		freeCmd(&command);
		if (abor) break;
	}
	if (errno == EINTR)
		return (1);
	return (0);
}

// function running in separate thread, handles data connection
void *dataRoutine(void *arg) {
	struct data_info *info = (struct data_info *) arg;
	int sck;
	struct sockaddr_un sa;
	struct sockaddr_in in;
	bzero(&in, sizeof (in));
	bzero(&sa, sizeof (sa));
	struct state cstate = *(info->cstate);
	strncpy(sa.sun_path, info->control_sock, sizeof (sa.sun_path));
	sa.sun_family = AF_UNIX;

	// tries to create a connection
	// for communicating with the control thread
	if ((sck = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
		perror("Error creating control socket.");
		return (arg);
	}
	if (connect(sck, (struct sockaddr *) &sa, sizeof (sa)) == -1) {
		perror("Error connecting to control socket.");
		return (arg);
	}
	struct cmd command;
	cstate.data_sock = 0;
	// reads commands from control thread and executes them
	while (1) {
		// printf("Data socket: %d\n", cstate.data_sock);
		readUntil(command.name, sck, 0, 256);
		if (command.name[0] == 'Q') {
			break;
		}
		executeCmd(&command, NULL, sck, &cstate, info->configuration);
		// projects the changes to the control thread,
		info->cstate->data_sock = cstate.data_sock;
		info->cstate->last_accepted = cstate.last_accepted;
	}
	if (cstate.data_sock) {
		close(cstate.data_sock);
	}
	free(info);
	return (arg);
}