#include "Process.h"

bool CProcess::IS_DAEMON = false;

CProcess::CProcess()
	: m_pid(-1), m_launched(false)
{

}

CProcess::~CProcess()
{

}

bool CProcess::Daemon() {

	if (IS_DAEMON == false && daemon(1, 0) == -1) {
		cerr << "Error detaching";
		return false;
	}

	IS_DAEMON = true;
	return true;
}

bool CProcess::IsProcessRun(const char* pname) {
	char tempBuffer[512];
	FILE * fd = NULL;
	bool bRun = false;

	snprintf(tempBuffer, sizeof(tempBuffer), "pgrep -x %s | sort", pname);

	fd = popen(tempBuffer, "r");
	if (fd == NULL)
	{

		cerr << "[ERR] Process check failed. [popen error][" << strerror(errno) << "]" << endl;
		// 오류 발생시 true 반환하여 프로세스 실행 방지처리
		return true;
	}
	else
	{
	
		void(*intsave)(int) = signal(SIGINT, SIG_IGN);
		void(*quitsave)(int) = signal(SIGTERM, SIG_IGN);
		void(*chldave)(int) = signal(SIGCHLD, SIG_IGN);

		memset(tempBuffer, 0x00, sizeof(tempBuffer));
		while (fgets(tempBuffer, sizeof(tempBuffer) - 1, fd) != NULL)
		{
			string tempPid(tempBuffer);
			//Trim(tempPid);

			pid_t pid = atoi(tempPid.c_str());
			if (pid > 0)
			{
				bRun = true;
				break;
			}
		}

		signal(SIGINT, intsave);
		signal(SIGTERM, quitsave);
		signal(SIGCHLD, chldave);

		pclose(fd);
		return bRun;
	}
}

bool CProcess::IsCurrentProcessRun(const char* pname) {
	char tempBuffer[512];
	FILE * fd = NULL;
	bool bRun = false;

	snprintf(tempBuffer, sizeof(tempBuffer), "pgrep -x %s | sort", pname);

	fd = popen(tempBuffer, "r");
	if (fd == NULL)
	{
		
		cerr << "[ERR] Process duplication check failed. [popen error][" << strerror(errno) << "]"<< endl;
		// 오류 발생시 true 반환하여 프로세스 실행 방지처리
		return true;
	}
	else
	{
		memset(tempBuffer, 0x00, sizeof(tempBuffer));
		while (fgets(tempBuffer, sizeof(tempBuffer) - 1, fd) != NULL)
		{
			string tempPid(tempBuffer);
			//Trim(tempPid);

			pid_t pid = atoi(tempPid.c_str());
			if (pid  != getpid())
			{
				cerr << "[info] Process duplication found. pid[" << pid << "]" << endl;
				bRun = true;
				break;
			}
		}

		pclose(fd);
		return bRun;
	}
}

pid_t CProcess::Fork() {

	m_pid = ::fork();
	if (m_pid >= 0)  m_launched = true;

	return m_pid;
}

void CProcess::SetThreadSignal(int signum)
{
	sigset_t sig, old;
	sigemptyset(&sig);
	sigaddset(&sig, signum);
	sigprocmask(SIG_BLOCK, &sig, &old);
}

void CProcess::UnSetThreadSignal(int signum)
{
	sigset_t sig, old;
	sigemptyset(&sig);
	sigaddset(&sig, signum);
	sigprocmask(SIG_UNBLOCK, &sig, &old);
}