Esempio n. 1
0
int Process::join(int pid)
{
	int status;

	if(pid < 1)
		return -1;

#ifdef  HAVE_WAITPID
	waitpid(pid, &status, 0);
#else
#ifdef  HAVE_WAIT4
	wait4(pid, &status, 0, NULL);
#else
	int result;
	while((result = wait(&status)) != pid && result != -1)
		;
#endif
#endif

	if(WIFEXITED(status))
		return WEXITSTATUS(status);
	else if(WIFSIGNALLED(status))
		return -WTERMSIG(status);
	else
		return -1;
}
Esempio n. 2
0
int execCommand(char *cmd)
{
	if (*cmd == '#') return 0;

	// remove comments
	int currentlyInString = 0;
	char *commentScan = cmd;

	while (*commentScan != 0)
	{
		if ((*commentScan) == '"') currentlyInString = !currentlyInString;
		else if (((*commentScan) == '#') && (!currentlyInString))
		{
			*commentScan = 0;
			break;
		};

		commentScan++;
	};

	if (*cmd == 0) return 0;

	char processedCommand[1024];
	char *put = processedCommand;
	char *scan = cmd;
	while (*scan != 0)
	{
		if (*scan == '\\')
		{
			scan++;
			if (*scan == 0) break;
			*put++ = *scan++;
			continue;
		}
		else if (*scan == '$')
		{
			char envname[256];
			char *envnameput = envname;
			scan++;
			while (isalnum(*scan))
			{
				*envnameput++ = *scan++;
			};

			*envnameput = 0;
			char *value = getenv(envname);
			if (value != NULL)
			{
				strcpy(put, value);
				put += strlen(value);
			};
		}
		else
		{
			*put++ = *scan++;
		};
	};
	*put = 0;

	int argc = 0;
	char **argv = NULL;
	char *nextToStrtok = processedCommand;

	while (1)
	{
		//char *token = strtok(nextToStrtok, nextSplitString);
		char *token = nextToStrtok;

#if 0
		nextToStrtok = NULL;
		if (token != NULL)
		{
			if (strlen(token) == 0) continue;
		};
#endif

		if (token != NULL)
		{
			while (isspace(*token)) token++;
			if (*token == 0)
			{
				token = NULL;
			}
			else
			{
				const char *termString = " \t";
				if (*token == '"')
				{
					termString = "\"";
					token++;
				};

				char *endpos = strpbrk(token, termString);
				if (endpos == NULL)
				{
					nextToStrtok = NULL;
				}
				else
				{
					*endpos = 0;
					nextToStrtok = endpos+1;
				};
			};
		};

		int shouldAdd = 0;
		if (token == NULL)
		{
			shouldAdd = 1;
		}
		else
		{
			if (strlen(token) > 0)
			{
				shouldAdd = 1;
			};
		};

		if (shouldAdd)
		{
			argv = realloc(argv, sizeof(char*)*(argc+1));
			argv[argc++] = token;
		};

		if (token == NULL) break;
	};

	if (argc == 1) return 0;

	if (strcmp(argv[0], "cd") == 0)
	{
		int status = cmd_cd(argc-1, argv);
		free(argv);
		return status;
	}
	else if (strcmp(argv[0], "exit") == 0)
	{
		int status = cmd_exit(argc-1, argv);
		free(argv);
		return status;
	}
	else if (strcmp(argv[0], "echo") == 0)
	{
		int status = cmd_echo(argc-1, argv);
		free(argv);
		return status;
	}
	else if (strcmp(argv[0], "diag") == 0)
	{
		_glidix_diag();
		free(argv);
		return 0;
	};

	char execpath[256];
	if (findCommand(execpath, argv[0]) == -1)
	{
		free(argv);
		fprintf(stderr, "%s: command not found\n", argv[0]);
		return 1;
	};

	pid_t pid = fork();
	if (pid == 0)
	{
		if (execv(execpath, argv) != 0)
		{
			perror(argv[0]);
			return 1;
		};

		// the compiler won't stop moaning otherwise.
		// even though execv() obviously doesn't return.
		return 0;
	}
	else
	{
		free(argv);
		shellChildPid = pid;
		int status;
		while (1)
		{
			int ret = waitpid(pid, &status, 0);
			
			// EINTR is the only possible error here, so if it occurs, try again.
			if (ret != -1)
			{
				break;
			};
		};

		shellChildPid = 0;
		
		if (WIFSIGNALLED(status))
		{
			int termsig = WTERMSIG(status);
			switch (termsig)
			{
			case SIGSEGV:
				fprintf(stderr, "Invalid memory access\n");
				break;
			case SIGSYS:
				fprintf(stderr, "Invalid system call\n");
				break;
			};
		};
		
		return status;
	};
};