Пример #1
0
int main (int argc, char **argv)
{


    char * cmdLine;
    char * username;
    char ** cmd;
    char hostname[256];
    size_t len = 256;
    struct sigaction new_action, old_action;

    /* Inicializa a lista que guarda os processos que rodam em background */
    childs = malloc(sizeof(LIST));
    ListCreate(childs);
    /* Inicializa a variável que guarda o ID do processo atual do foreground */
    fgChildPid = 0;
    child_handler_lock = 0;
    /* Set up the structure to specify the new action. */
    new_action.sa_handler = termination_handler;
    sigemptyset (&new_action.sa_mask);
    new_action.sa_flags = 0;

    sigaction (SIGINT, NULL, &old_action);
    if (old_action.sa_handler != SIG_IGN)
        sigaction (SIGINT, &new_action, NULL);
    sigaction (SIGHUP, NULL, &old_action);
    if (old_action.sa_handler != SIG_IGN)
        sigaction (SIGHUP, &new_action, NULL);
    sigaction (SIGTERM, NULL, &old_action);
    if (old_action.sa_handler != SIG_IGN)
        sigaction (SIGTERM, &new_action, NULL);

    new_action.sa_handler = child_handler;
    sigemptyset (&new_action.sa_mask);
    new_action.sa_flags = 0;

    sigaction (SIGCHLD, NULL, &old_action);
    if (old_action.sa_handler != SIG_IGN)
        sigaction (SIGCHLD, &new_action, NULL);

    new_action.sa_handler = sigtstop_handler;
    sigemptyset (&new_action.sa_mask);
    new_action.sa_flags = 0;

    sigaction (SIGTSTP, NULL, &old_action);
    if (old_action.sa_handler != SIG_IGN)
        sigaction (SIGTSTP, &new_action, NULL);
    /*inicializa lista que guarda o historico de comandos */
    history = malloc(sizeof(struct node));
    history->cmd = NULL;
    history->next = NULL;

    /* Pega o nome do usuario atual e da máquina */
    username = getlogin();
    gethostname(hostname, len);
    asprintf(&userdir, "/home/%s", username);
    /* Coloca o diretório do usuário como diretório inicial */
    chdir(userdir);
    while (1)
    {
        printPrompt(username, hostname);
        output_r = input_r = 0;
        rewind(stdin);
        cmdLine = readline();
        if(strcmp(cmdLine, "") != 0)
        {
            add_history(cmdLine);
            cmd = parse(cmdLine);
            int cmd_id = isBuiltIn(cmd[0]);
            if(cmd_id >= 0) callBuiltIn(cmd_id, cmd[1]);
            else
            {
                if((childPid = fork()) == 0)
                {
                    if(output_r)
                    {
                        fd_out = open(output_r_filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR, 0666);
                        dup2(fd_out, 1);
                    }
                    if(input_r)
                    {
                        fd_in = open(input_r_filename, O_RDONLY, 0666);
                        dup2(fd_in, 0);
                    }
                    fgChildPid = childPid;
                    int i = execvp(cmd[0], cmd);
                    if (output_r) close(fd_out);
                    if (input_r) close(fd_in);
                    if(i < 0)
                    {
                        printf("%s: command not found\n", cmd[0]);
                        exit(101);
                    }
                }
                else
                {
                    /*Após criar o processo filho, o pai insere em uma lista ligada o novo processo */
                    int status;
                    pid_t pidfg;
                    ITEM * p;
                    p = malloc(sizeof(ITEM));
                    p->pid = childPid;
                    p->isBackground = isBackground;
                    strcpy(p->status, "Running");
                    strcpy(p->command, cmdLine);
                    ListInsert(childs, p);
                    isBackground = 0;
                    /*E espera ele terminar, caso seja um processo de foreground */
                    if(!p->isBackground) {
                        child_handler_lock = 1;
                        pidfg = waitpid(childPid, &status, WUNTRACED);
                        child_handler_lock = 0;
                        if ((pidfg >= 0) && (WIFSTOPPED(status) == 0)) ListRemoveByPid(childs, childPid);
                    }
                }
            }
            free_parse();
            free(cmdLine);
        }
    }
}
Пример #2
0
bool continueFunction (loadedFunction * fun) {
	bool keepLooping = true;
	bool advanceNow;
	unsigned int param;
	sludgeCommand com;

	if (fun -> cancelMe) {
		abortFunction (fun);
		return true;
	}

//	if (numBIFNames) newDebug ("*** Function:", allUserFunc[fun -> originalNumber]);

	//debugOut ("SLUDGER: continueFunction\n");

	while (keepLooping) {
		advanceNow = true;
		param = fun -> compiledLines[fun -> runThisLine].param;
		com = fun -> compiledLines[fun -> runThisLine].theCommand;
//		fprintf (stderr, "com: %d param: %d (%s)\n", com, param,
//				(com < numSludgeCommands) ? sludgeText[com] : ERROR_UNKNOWN_MCODE); fflush(stderr);

		if (numBIFNames) {
			setFatalInfo (
				(fun -> originalNumber < numUserFunc) ? allUserFunc[fun -> originalNumber] : "Unknown user function",
				(com < numSludgeCommands) ? sludgeText[com] : ERROR_UNKNOWN_MCODE);
//			newDebug (
//				(com < numSludgeCommands) ? sludgeText[com] : "Unknown SLUDGE machine code",
//				param);
		}

		//debugOut ("SLUDGER: continueFunction - in da loop: %s\n", sludgeText[com]);

		switch (com) {
			case SLU_RETURN:
			if (fun -> calledBy) {
				loadedFunction * returnTo = fun -> calledBy;
				if (fun -> returnSomething) copyVariable (fun -> reg, returnTo -> reg);
				finishFunction (fun);
				fun = returnTo;
				restartFunction (fun);
			} else {
				finishFunction (fun);
				advanceNow = false;		// So we don't do anything else with "fun"
				keepLooping = false;	// So we drop out of the loop
			}
			break;

			case SLU_CALLIT:
			switch (fun -> reg.varType) {
				case SVT_FUNC:
				pauseFunction (fun);
				if (numBIFNames) setFatalInfo (
					(fun -> originalNumber < numUserFunc) ? allUserFunc[fun -> originalNumber] : "Unknown user function",
					(fun -> reg.varData.intValue < numUserFunc) ? allUserFunc[fun -> reg.varData.intValue] : "Unknown user function");

				if (! startNewFunctionNum (fun -> reg.varData.intValue, param, fun, fun -> stack)) return false;
				fun = allRunningFunctions;
				advanceNow = false;		// So we don't do anything else with "fun"
				break;

				case SVT_BUILT:
					{
					builtReturn br = callBuiltIn (fun -> reg.varData.intValue, param, fun);

					switch (br) {
						case BR_ERROR:
							return fatal("Unknown error. This shouldn't happen. Please notify the SLUDGE developers.");

						case BR_PAUSE:
						pauseFunction (fun);
						// No break!

						case BR_KEEP_AND_PAUSE:
						keepLooping = false;
						break;

						case BR_ALREADY_GONE:
						keepLooping = false;
						advanceNow = false;
						break;

						case BR_CALLAFUNC:
						{
							int i = fun -> reg.varData.intValue;
							setVariable (fun -> reg, SVT_INT, 1);
							pauseFunction (fun);
							if (numBIFNames) setFatalInfo (
								(fun -> originalNumber < numUserFunc) ? allUserFunc[fun -> originalNumber] : "Unknown user function",
								(i < numUserFunc) ? allUserFunc[i] : "Unknown user function");
							if (! startNewFunctionNum (i, 0, fun, noStack, false)) return false;
							fun = allRunningFunctions;
							advanceNow = false;		// So we don't do anything else with "fun"
						}
						break;

						default:
						break;
					}
				}
				break;

				default:
				return fatal (ERROR_CALL_NONFUNCTION);
			}
			break;

			// These all grab things and shove 'em into the register

			case SLU_LOAD_NULL:
			setVariable (fun -> reg, SVT_NULL, 0);
			break;

			case SLU_LOAD_FILE:
			setVariable (fun -> reg, SVT_FILE, param);
			break;

			case SLU_LOAD_VALUE:
			setVariable (fun -> reg, SVT_INT, param);
			break;

			case SLU_LOAD_LOCAL:
			if (! copyVariable (fun -> localVars[param], fun -> reg)) return false;
			break;

			case SLU_AND:
			setVariable (fun -> reg, SVT_INT, getBoolean (fun -> reg) && getBoolean (fun -> stack -> thisVar));
			trimStack (fun -> stack);
			break;

			case SLU_OR:
			setVariable (fun -> reg, SVT_INT, getBoolean (fun -> reg) || getBoolean (fun -> stack -> thisVar));
			trimStack (fun -> stack);
			break;

			case SLU_LOAD_FUNC:
			setVariable (fun -> reg, SVT_FUNC, param);
			break;

			case SLU_LOAD_BUILT:
			setVariable (fun -> reg, SVT_BUILT, param);
			break;

			case SLU_LOAD_OBJTYPE:
			setVariable (fun -> reg, SVT_OBJTYPE, param);
			break;

			case SLU_UNREG:
			if (dialogValue != 1) fatal (ERROR_HACKER);
			break;

			case SLU_LOAD_STRING:
				if (! loadStringToVar (fun -> reg, param)) {
					return false;
				}
			break;

			case SLU_INDEXGET:
			case SLU_INCREMENT_INDEX:
			case SLU_DECREMENT_INDEX:
			switch (fun -> stack -> thisVar.varType) {
				case SVT_NULL:
				if (com == SLU_INDEXGET) {
					setVariable (fun -> reg, SVT_NULL, 0);
					trimStack (fun -> stack);
				} else {
					return fatal (ERROR_INCDEC_UNKNOWN);
				}
				break;

				case SVT_FASTARRAY:
				case SVT_STACK:
				if (fun -> stack -> thisVar.varData.theStack -> first == NULL) {
					return fatal (ERROR_INDEX_EMPTY);
				} else {
					int ii;
					if (! getValueType (ii, SVT_INT, fun -> reg)) return false;
					variable * grab = (fun -> stack -> thisVar.varType == SVT_FASTARRAY) ?
						fastArrayGetByIndex (fun -> stack -> thisVar.varData.fastArray, ii)
							:
						stackGetByIndex (fun -> stack -> thisVar.varData.theStack -> first, ii);

					trimStack (fun -> stack);

					if (! grab) {
						setVariable (fun -> reg, SVT_NULL, 0);
					} else {
						int ii;
						switch (com) {
							case SLU_INCREMENT_INDEX:
							if (! getValueType (ii, SVT_INT, * grab)) return false;
							setVariable (fun -> reg, SVT_INT, ii);
							grab -> varData.intValue = ii + 1;
							break;

							case SLU_DECREMENT_INDEX:
							if (! getValueType (ii, SVT_INT, * grab)) return false;
							setVariable (fun -> reg, SVT_INT, ii);
							grab -> varData.intValue = ii - 1;
							break;

							default:
							if (! copyVariable (* grab, fun -> reg)) return false;
						}
					}
				}
				break;

				default:
				return fatal (ERROR_INDEX_NONSTACK);
			}
			break;

			case SLU_INDEXSET:
			switch (fun -> stack -> thisVar.varType) {
				case SVT_STACK:
				if (fun -> stack -> thisVar.varData.theStack -> first == NULL) {
					return fatal (ERROR_INDEX_EMPTY);
				} else {
					int ii;
					if (! getValueType (ii, SVT_INT, fun -> reg)) return false;
					if (! stackSetByIndex (fun -> stack -> thisVar.varData.theStack -> first, ii, fun -> stack -> next -> thisVar)) {
						return false;
					}
					trimStack (fun -> stack);
					trimStack (fun -> stack);
				}
				break;

				case SVT_FASTARRAY:
				{
					int ii;
					if (! getValueType (ii, SVT_INT, fun -> reg)) return false;
					variable * v = fastArrayGetByIndex (fun -> stack -> thisVar.varData.fastArray, ii);
					if (v == NULL) return fatal ("Not within bounds of fast array.");
					if (! copyVariable (fun -> stack -> next -> thisVar, * v)) return false;
					trimStack (fun -> stack);
					trimStack (fun -> stack);
				}
				break;

				default:
				return fatal (ERROR_INDEX_NONSTACK);
			}
			break;

			// What can we do with the register? Well, we can copy it into a local
			// variable, a global or onto the stack...

			case SLU_INCREMENT_LOCAL:
			{
				int ii;
				if (! getValueType (ii, SVT_INT, fun -> localVars[param])) return false;
				setVariable (fun -> reg, SVT_INT, ii);
				setVariable (fun -> localVars[param], SVT_INT, ii + 1);
			}
			break;

			case SLU_INCREMENT_GLOBAL:
			{
				int ii;
				if (! getValueType (ii, SVT_INT, globalVars[param])) return false;
				setVariable (fun -> reg, SVT_INT, ii);
				setVariable (globalVars[param], SVT_INT, ii + 1);
			}
			break;

			case SLU_DECREMENT_LOCAL:
			{
				int ii;
				if (! getValueType (ii, SVT_INT, fun -> localVars[param])) return false;
				setVariable (fun -> reg, SVT_INT, ii);
				setVariable (fun -> localVars[param], SVT_INT, ii - 1);
			}
			break;

			case SLU_DECREMENT_GLOBAL:
			{
				int ii;
				if (! getValueType (ii, SVT_INT, globalVars[param])) return false;
				setVariable (fun -> reg, SVT_INT, ii);
				setVariable (globalVars[param], SVT_INT, ii - 1);
			}
			break;

			case SLU_SET_LOCAL:
			if (! copyVariable (fun -> reg, fun -> localVars[param])) return false;
			break;

			case SLU_SET_GLOBAL:
//			newDebug ("  Copying TO global variable", param);
//			newDebug ("  Global type at the moment", globalVars[param].varType);
			if (! copyVariable (fun -> reg, globalVars[param])) return false;
//			newDebug ("  New type", globalVars[param].varType);
			break;

			case SLU_LOAD_GLOBAL:
//			newDebug ("  Copying FROM global variable", param);
//			newDebug ("  Global type at the moment", globalVars[param].varType);
			if (! copyVariable (globalVars[param], fun -> reg)) return false;
			break;

			case SLU_STACK_PUSH:
			if (! addVarToStack (fun -> reg, fun -> stack)) return false;
			break;

			case SLU_QUICK_PUSH:
			if (! addVarToStackQuick (fun -> reg, fun -> stack)) return false;
			break;

			case SLU_NOT:
			setVariable (fun -> reg, SVT_INT, ! getBoolean (fun -> reg));
			break;

			case SLU_BR_ZERO:
			if (! getBoolean (fun -> reg)) {
				advanceNow = false;
				fun -> runThisLine = param;
			}
			break;

			case SLU_BRANCH:
			advanceNow = false;
			fun -> runThisLine = param;
			break;

			case SLU_NEGATIVE:
			{
				int i;
				if (! getValueType (i, SVT_INT, fun -> reg)) return false;
				setVariable (fun -> reg, SVT_INT, -i);
			}
			break;

			// All these things rely on there being somet' on the stack

			case SLU_MULT:
			case SLU_PLUS:
			case SLU_MINUS:
			case SLU_MODULUS:
			case SLU_DIVIDE:
			case SLU_EQUALS:
			case SLU_NOT_EQ:
			case SLU_LESSTHAN:
			case SLU_MORETHAN:
			case SLU_LESS_EQUAL:
			case SLU_MORE_EQUAL:
			if (fun -> stack) {
				int firstValue, secondValue;

				switch (com) {
					case SLU_PLUS:
					addVariablesInSecond (fun -> stack -> thisVar, fun -> reg);
					trimStack (fun -> stack);
					break;

					case SLU_EQUALS:
					compareVariablesInSecond (fun -> stack -> thisVar, fun -> reg);
					trimStack (fun -> stack);
					break;

					case SLU_NOT_EQ:
					compareVariablesInSecond (fun -> stack -> thisVar, fun -> reg);
					trimStack (fun -> stack);
	               fun -> reg.varData.intValue = ! fun -> reg.varData.intValue;
					break;

					default:
					if (! getValueType (firstValue, SVT_INT, fun -> stack -> thisVar)) return false;
					if (! getValueType (secondValue, SVT_INT, fun -> reg)) return false;
					trimStack (fun -> stack);

					switch (com) {
						case SLU_MULT:
						setVariable (fun -> reg, SVT_INT, firstValue * secondValue);
						break;

						case SLU_MINUS:
						setVariable (fun -> reg, SVT_INT, firstValue - secondValue);
						break;

						case SLU_MODULUS:
						setVariable (fun -> reg, SVT_INT, firstValue % secondValue);
						break;

						case SLU_DIVIDE:
						setVariable (fun -> reg, SVT_INT, firstValue / secondValue);
						break;

						case SLU_LESSTHAN:
						setVariable (fun -> reg, SVT_INT, firstValue < secondValue);
						break;

						case SLU_MORETHAN:
						setVariable (fun -> reg, SVT_INT, firstValue > secondValue);
						break;

						case SLU_LESS_EQUAL:
						setVariable (fun -> reg, SVT_INT, firstValue <= secondValue);
						break;

						case SLU_MORE_EQUAL:
						setVariable (fun -> reg, SVT_INT, firstValue >= secondValue);
						break;

						default:
						break;
					}
				}
			} else {
				return fatal (ERROR_NOSTACK);
			}
			break;

			default:
			return fatal (ERROR_UNKNOWN_CODE);
		}

		if (advanceNow) fun -> runThisLine ++;

	}
	return true;
}