2 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 ///////////////////////////////////////////////////////////////////////////////
18 /// \ingroup tag_SystemManagerIf
19 /// \brief This file provides support for the System Manager client interface.
21 ///////////////////////////////////////////////////////////////////////////////
23 #include "system_service/ss_system_process.h"
25 #include <sys/types.h>
30 #include <elfio/elfio_dump.hpp>
42 #include "ss_system_if_interfaceunifiedlog.h"
44 const char* iProcess_DEFAULT_PROCESS_USER_NAME = "default_user";
45 uid_t iProcess_DEFAULT_PROCESS_USER = 4999;
46 gid_t iPrpocess_DEFAULT_PROCESS_GROUP = 4999;
49 * Process: Called when the class is instantiated.
53 Process::Process(int cpu_assign) :
54 m_lValidationTag(lProcess_VALIDATION_VALUE),
55 m_cpu_assign(cpu_assign),
57 m_eProcessLoadMode(NOWAIT),
67 * ~Process: Called when the object is destroyed.
72 // ASSERT_VALID (this);
75 // Set the validation tag to NOT valid
79 // Cleanup after ourselves...
81 if ((m_fAutoKill) && (m_tProcessId != -1) && (m_tProcessId != getpid())) {
82 KillProcess(); // Then remove the process from PosixBasedOS001
87 * Process: Used to create an object and copy another
88 * object to the new object.
90 * @param p_rhs_i Reference to the class being copied from.
91 * @return Process( const
93 Process::Process(const Process& p_rhs_i) {
94 // Copy data from the specified object to this object.
100 * operator=: Called when one object is assigned
103 * @param p_rhs_i Reference to the class being copied from.
106 Process& Process::operator= (const Process& p_rhs_i) {
107 // Don't do anything if we're being copied on to ourselves.
108 if (this == &p_rhs_i) return (*this);
110 // Copy data from the specified object to this object.
118 * Copy: Copies data members from the specified object to this object.
119 * No attempt is made to free dynamically allocated objects within
120 * this object (you must do that before calling this function).
125 void Process::Copy(const Process& p_rhs_i) {
126 // Copy data from the specified object to this object.
127 m_lValidationTag = p_rhs_i.m_lValidationTag;
129 m_tProcessId = p_rhs_i.m_tProcessId;
130 m_eProcessLoadMode = p_rhs_i.m_eProcessLoadMode;
131 m_strFile = p_rhs_i.m_strFile;
132 m_strlstArgv = p_rhs_i.m_strlstArgv;
133 m_strProcessName = p_rhs_i.m_strProcessName;
134 m_iErrorCode = p_rhs_i.m_iErrorCode;
135 m_fAutoKill = p_rhs_i.m_fAutoKill;
136 m_iReturnCode = p_rhs_i.m_iReturnCode;
140 * GetProcessReturnCode: This function will return the processes
141 * exit/return code. This is not the value of ERRNO as returned by
142 * GetLastPosixBasedOS001ErrorCode().
144 * @return code from the process
146 int Process::GetProcessReturnCode() {
147 int iProcessReturn = 0;
148 if (waitpid(m_tProcessId, &iProcessReturn, WNOHANG) > 0) {
149 m_iReturnCode = WEXITSTATUS(iProcessReturn);
152 return m_iReturnCode;
155 static int getIdsFromUserName(const char* user_name, uid_t *uid, gid_t *gid) {
159 if (NULL == user_name) {
163 static __thread size_t bufSize = 0;
164 static __thread char *buf = NULL;
166 struct passwd *result;
169 struct stat statInfo;
173 if (0 != stat("/etc/passwd", &statInfo) || 0 >= statInfo.st_size) {
174 throw "/etc/passwd is not exist";
177 bufSize = statInfo.st_size * 2;
179 // Since SystemManager is a resident service,
180 // the area secured here is not explicity released by free()
181 // in anticipation of release at the end of the process
182 buf = reinterpret_cast<char *>(malloc(sizeof(char) * bufSize));
192 ret = getpwnam_r(user_name, &pwd, buf, bufSize, &result);
193 if (ret == 0 && result != NULL) {
197 throw "getpwnam_r()";
204 catch (const char *e) {
205 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __PRETTY_FUNCTION__, "ERROR:%s", e);
212 * CreateProcess: This method will create a PosixBasedOS001 process with the executable provided and mode as a calling parameter.
213 * The caller can also provide a list of arguments that will be provided to the executable at startup.
214 * The calling p_strProcessName parameter is a textual name that will be
215 * associated with the newly created process by the OS. The process state information
216 * will be maintained by this object.
218 * Upon successful creation of the process, the scheduling policy and priority
219 * of the process will be set to the provided values. The user can change these
220 * values through the SetSchedulingPolicy() and SetPriority() method calls.
222 * @param p_strFile_i Path and Filename of executable to create process for
223 * @param p_strlstArgv_i List of ARGV values for new process
224 * @param p_eMode_i Mode to create and load new process
225 * WAIT - The invoked program is loaded into available memory, is executed,
226 * and then the original program resumes execution.
227 * NOWAIT - Causes the current program to execute concurrently with the new child process.
228 * @param p_strProcessName_i This is the name that will be registered to the OS for this process
229 * @param p_eSchedulingPolicy_i Scheduling Policy for this process
230 * FIFO - A fixed priority scheduler in which the highest ready process runs until it
231 * blocks or is preempted by a higher priority process.
232 * ROUND_ROBIN - The same as FIFO, except processes at the same priority level time-slice.
233 * OTHER - A general time sharing scheduler in which a process decays in priority if it
234 * consumes too much processor before blocking. It reverts to its default priority
235 * when it blocks. Should it fail to run over a 2 second period and it has decayed
236 * then it's boosted one priority level up to a maximum of its default priority.
237 * @param p_iPriority_i Priority for this process
238 * @param p_lSpawnFlags_i Spawning flags. These are PosixBasedOS001 specific....
241 void Process::CreateProcess(
242 const SS_String& p_strFile_i, // Path and Filename of executable to create process for
243 const StringList& p_strlstArgv_i, // List of ARGV values for new process
244 const eProcessLoadMode p_eMode_i, // Mode to create and load new process
245 const SS_String& p_strProcessName_i, // This is the name that will be registered to the OS for this process
246 const eProcessSchedulingPolicy p_eSchedulingPolicy_i, // Scheduling Policy for this process
247 const int p_iPriority_i, // Priority for this process
248 const char* unix_user_name,
249 const long p_lSpawnFlags_i // Posix Spawning flags. These are PosixBasedOS001 specific.... // NOLINT (runtime/int)
251 //========================================================================================
252 // Perform some idiot checking of the parameters that are passed in.
253 // Check the priority level that is being set to make sure it is in bounds.
254 // Then save off the calling parameters into the objects member variables.
255 // Also check the number of valid calling (argv[]) parameters passed in
256 //========================================================================================
257 m_iErrorCode = 0; // Initialize to NO ERROR
258 m_iReturnCode = 0; // Initialize value (0 usually means good in unix/PosixBasedOS001)
261 // Process filename os provided
263 if (p_strFile_i.empty()) {
264 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
268 // Save off process calling arguments
270 m_eProcessLoadMode = p_eMode_i;
272 m_strFile = p_strFile_i;
274 if (!p_strProcessName_i.empty())
275 m_strProcessName = p_strProcessName_i;
278 // Copy Argument List...
280 SetCallingArgumentList(p_strlstArgv_i);
283 // Valid number of calling arguments
285 int iNumberElements = m_strlstArgv.size();
286 if (iNumberElements > (iProcess_MAXIMUM_NUMBER_OF_PROCESS_ARGUMENTS - 3)) {
287 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
291 //========================================================================================
292 // Initialize to the beginning of the provided argument list.
293 // Allocate an array of buffer pointers that will be used for the ARGV calling parameters
294 // for the specified process.
295 // Set the ARGV[0] equal to the process name being created
296 // Set the ARGV[1] equal to the process name to be registered with the OS.
297 // If p_strProcessName_is NULL, do not set the cArgv[1] parameter
298 // Populate the array that will hold the argument list for the new process we are creating.
299 //========================================================================================
303 char * cArgv[iProcess_MAXIMUM_NUMBER_OF_PROCESS_ARGUMENTS];
305 cArgv[0] = basename(const_cast<char *>(p_strFile_i.c_str())); // Set the executable filename
307 // Go through the list of provided argv calling parameters to the CreateProcess
308 // function, and copy the arguments to the ARGV[] calling argument which will be passed
309 // into the process being created.
310 StringListIter at = m_strlstArgv.begin();
311 for (; at != m_strlstArgv.end(); at++, iLoop++) {
312 cArgv[iLoop] = const_cast<char *>(at->c_str());
318 CL_ProcessAttr_t clAttr;
319 CL_ProcessSchedPolicy_t clPolicy = CL_PROCESS_SCHED_POLICY_OTHER;
322 if (0 != CL_ProcessCreateAttrInit(&clAttr)) {
323 throw "CL_ProcessCreateAttrInit()";
327 // In order to collect even the child processes of the service, all are group leaders.
328 if (0 != CL_ProcessCreateAttrSetGroup(&clAttr, 1)) {
329 throw "CL_ProcessCreateAttrInit()";
332 if (0 != CL_ProcessCreateAttrSetCpuAssign(&clAttr, m_cpu_assign)) {
333 throw "CL_ProcessCreateAttrSetCpuAssign()";
336 switch (p_eSchedulingPolicy_i) {
338 clPolicy = CL_PROCESS_SCHED_POLICY_FIFO;
341 clPolicy = CL_PROCESS_SCHED_POLICY_RR;
344 clPolicy = CL_PROCESS_SCHED_POLICY_OTHER;
347 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __PRETTY_FUNCTION__, "p_eSchedulingPolicy_i = %d", p_eSchedulingPolicy_i);
351 switch (p_eSchedulingPolicy_i) {
354 if ((1 > p_iPriority_i) || (p_iPriority_i > 99)) {
355 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __PRETTY_FUNCTION__, "p_eSchedulingPolicy_i = %d", p_eSchedulingPolicy_i);
357 clPriority = p_iPriority_i;
362 if ((-20 > p_iPriority_i) || (p_iPriority_i > 19)) {
363 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __PRETTY_FUNCTION__, "p_eSchedulingPolicy_i = %d", p_eSchedulingPolicy_i);
365 clPriority = p_iPriority_i;
370 if (0 != CL_ProcessCreateAttrSetSchedule(&clAttr, clPolicy, clPriority)) {
371 throw "CL_ProcessCreateAttrSetSchedule()";
377 if (0 != getIdsFromUserName(unix_user_name, &uid, &gid)) {
378 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __PRETTY_FUNCTION__, "unexpected unix_user_name [%s]", unix_user_name);
383 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "!! uid=root %s", m_strFile.c_str());
386 if (0 != CL_ProcessCreateAttrSetUid(&clAttr, uid)) {
387 throw "CL_ProcessCreateAttrSetUid()";
390 if (0 != CL_ProcessCreateAttrSetGid(&clAttr, gid)) {
391 throw "CL_ProcessCreateAttrSetGid()";
394 if (0 != CL_ProcessCreateAttrSetDisableCloseFds(&clAttr)) {
395 throw "CL_ProcessCreateAttrSetDisableCloseFds()";
397 char environment_string[2048] = {0}; // Size is provisional
398 fprintf(stderr, "[%s](%d)Process Create Target : %s \n", __func__, __LINE__, m_strFile.c_str());
400 CheckLdPreLoad(&m_strFile, environment_string);
402 CreateProcess(&m_strFile, const_cast<char* const*>(cArgv), environment_string, &clAttr);
405 catch(const char *e) {
406 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __PRETTY_FUNCTION__, "%s", e);
411 * CreateProcess: This method will create a process with the executable provided and mode as a calling parameter.
412 * The caller can also provide a list of arguments that will be provided to the executable at startup.
413 * The calling p_strProcessName parameter is a textual name that will be
414 * associated with the newly created process by the OS. The process state information
415 * will be maintained by this object.
417 * @param p_str_file Path and Filename of executable to create process for
418 * @param c_argv use process arguments
419 * @param environment_string Set LD_PRELOAD string
420 * @param cl_attr CL_ProcessAttr_t
423 void Process::CreateProcess(const SS_String *p_str_file, char* const*c_argv, char* environment_string,
424 const CL_ProcessAttr_t *cl_attr) {
426 if ((p_str_file == NULL) || (c_argv == NULL) || (cl_attr == NULL)) {
427 throw "CreateProcess() Invaild Param";
431 if (environment_string[0] == '\0') {
432 // If there is no LD_PRELOAD setting, set envp to NULL
433 process_id = CL_ProcessCreate(p_str_file->c_str(), c_argv, NULL, cl_attr);
435 // vector holding preferences
436 std::vector<SS_String> *vec_environ = GetEnvironVector();
438 // Set LD_PRELOAD string as the last element
439 SS_String ld_preload_string = SS_String(environment_string);
440 vec_environ->push_back(environment_string);
442 // Number of acquired environment variables + 1(For terminal) memory allocation
443 size_t env_num = sizeof(char*) * (vec_environ->size() + 1);
444 char **p_environment = static_cast<char **>(malloc(env_num));
445 memset(p_environment, 0x00, env_num);
447 // Create environment variable list
449 char **p_environment_tmp = p_environment;
450 for (std::vector<SS_String>::iterator itr = vec_environ->begin(); itr != vec_environ->end(); itr++, i++) {
451 p_environment_tmp[i] = static_cast<char *>(malloc(sizeof(char) * (itr->length() + 1)));
453 snprintf(p_environment_tmp[i], itr->length() + 1, "%s", itr->c_str());
456 // Set envp for environment variable
457 process_id = CL_ProcessCreate(p_str_file->c_str(), c_argv, p_environment, cl_attr);
461 p_environment_tmp = p_environment;
462 for (std::vector<SS_String>::iterator itr = vec_environ->begin(); itr != vec_environ->end(); itr++, i++) {
463 free(p_environment_tmp[i]);
470 if (process_id == -1) {
471 throw "CL_ProcessCreate()";
474 m_tProcessId = process_id;
476 catch (const char *e) {
477 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __PRETTY_FUNCTION__, "%s", e);
481 * CreateProcess: This method will create a PosixBasedOS001 process with the executable provided and mode as a calling parameter.
482 * The caller can also provide a list of arguments that will be provided to the executable at startup.
483 * The calling p_strProcessName parameter is a textual name that will be
484 * associated with the newly created process by the OS. The process state information
485 * will be maintained by this object.
487 * @param p_strFile_i Path and Filename of executable to create process for
488 * @param p_strProcessName This is the name that will be registered to the OS for this process
491 void Process::CreateProcess(const SS_String& p_strFile_i, const SS_String& p_strProcessName,
492 const char* unix_user_name, const long p_lSpawnFlags_i) { // NOLINT (runtime/int)
493 StringList strlstArgv;
496 CreateProcess(p_strFile_i,
501 iProcess_DEFAULT_PROCESS_PRIORITY,
506 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
512 * CreateProcess: This method will create a process with the executable provided and mode as a calling parameter.
513 * The caller can also provide a list of arguments that will be provided to the executable at startup.
514 * The calling p_strProcessName parameter is a textual name that will be
515 * associated with the newly created process by the OS. The process state information
516 * will be maintained by this object.
519 * @param p_strFile_i Path and Filename of executable to create process for
520 * @param p_strProcessName This is the name that will be registered to the OS for this process
521 * @param p_iPriority_i Priority of process
524 void Process::CreateProcess(const SS_String& p_strFile_i, const SS_String& p_strProcessName, const int p_iPriority_i,
525 const char* unix_user_name, const long p_lSpawnFlags_i) { // NOLINT (runtime/int)
526 StringList strlstArgv;
529 eProcessSchedulingPolicy policy;
531 if (0 < p_iPriority_i) {
537 CreateProcess(p_strFile_i,
547 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
552 * CreateProcess: This method will create a process with the executable provided and mode as a calling parameter.
553 * The caller can also provide a list of arguments that will be provided to the executable at startup.
554 * The calling p_strProcessName parameter is a textual name that will be
555 * associated with the newly created process by the OS. The process state information
556 * will be maintained by this object.
558 * @param p_strFile_i Path and Filename of executable to create process for
559 * @param p_lSpawnFlags_i Spawning flags. These are PosixBasedOS001 specific.
562 void Process::CreateProcess(const SS_String& p_strFile_i, const char* unix_user_name, const long p_lSpawnFlags_i) { // NOLINT (runtime/int)
563 StringList strlstArgv;
566 CreateProcess(p_strFile_i,
569 basename(const_cast<char *>(p_strFile_i.c_str())),
571 iProcess_DEFAULT_PROCESS_PRIORITY,
576 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
583 * CreateProcess: This method will create a process with the executable provided and mode as a calling parameter.
584 * The caller can also provide a list of arguments that will be provided to the executable at startup.
585 * The calling p_strProcessName parameter is a textual name that will be
586 * associated with the newly created process by the OS. The process state information
587 * will be maintained by this object.
589 * @param p_strFile_i Path and Filename of executable to create process for
590 * @param p_strProcessName This is the name that will be registered to the OS for this process
591 * @param p_strlstArgv_i List of ARGV values for new process
592 * @param p_lSpawnFlags_i Spawning flags. These are PosixBasedOS001 specific.
595 void Process::CreateProcess(const SS_String& p_strFile_i, const SS_String& p_strProcessName_i,
596 const StringList& p_strlstArgv_i, const char* unix_user_name, const long p_lSpawnFlags_i) { // NOLINT (runtime/int)
598 CreateProcess(p_strFile_i,
603 iProcess_DEFAULT_PROCESS_PRIORITY,
608 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
613 void Process::CreateProcess(const SS_String& p_strFile_i, const SS_String& p_strProcessName_i, const int p_iPriority_i,
614 const StringList& p_strlstArgv_i, const char* unix_user_name, const long p_lSpawnFlags_i) { // NOLINT (runtime/int)
616 eProcessSchedulingPolicy policy;
618 if (0 < p_iPriority_i) {
624 CreateProcess(p_strFile_i,
634 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
640 * CreateProcessWait: This method will create a process with the executable provided.
641 * The process state information will be maintained by this object.
643 * @param p_strFile_i Path and Filename of executable to create process for
646 void Process::CreateProcessWait(const SS_String& p_strFile_i) {
647 StringList strlstArgv;
650 CreateProcess(p_strFile_i,
653 basename(const_cast<char *>(p_strFile_i.c_str())),
655 iProcess_DEFAULT_PROCESS_PRIORITY,
656 iProcess_DEFAULT_PROCESS_USER_NAME,
657 iProcess_DEFAULT_PROCESS_FLAGS);
660 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
665 * CreateProcessWait: This method will create a PosixBasedOS001 process with the executable provided.
666 * The process state information will be maintained by this object.
669 * @param p_strFile_i Path and Filename of executable to create process for
670 * @param p_strlstArguments_i List of process calling arguments
673 void Process::CreateProcessWait(const SS_String& p_strFile_i, const StringList& p_strlstArguments_i) {
675 CreateProcess(p_strFile_i,
678 basename(const_cast<char *>(p_strFile_i.c_str())),
680 iProcess_DEFAULT_PROCESS_PRIORITY,
681 iProcess_DEFAULT_PROCESS_USER_NAME,
682 iProcess_DEFAULT_PROCESS_FLAGS);
685 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
692 * KillProcess: This method will delete the process represented by this object. All variables associated
693 * with this object will be initialized to a know value.
698 void Process::KillProcess(int signal) {
699 //=====================================================================================
700 // Intialize the objects m_iErrorCode member variable to 0 (no error).
701 // Then try to delete the process that this object represents.
704 if (DoesProcessExist()) {
705 if (-1 == killpg(m_tProcessId, signal)) {
706 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
711 // If no errors, clear out any process specific member variables for this object
714 m_strProcessName = "";
718 * SetSchedulingPolicy: This method will change the scheduling policy for the process this
721 * @param p_eSchedulingPolicy_i Scheduling policy
724 void Process::SetSchedulingPolicy(
725 const eProcessSchedulingPolicy p_eSchedulingPolicy_i // Scheduling policy
727 //=======================================================================================
728 // Attempt to change the scheduling policy for the process that this object
729 // represents. If the change fails, restore the previous settings.
732 struct sched_param cur_sch_params;
733 sched_getparam(m_tProcessId, &cur_sch_params);
734 if (0 != sched_setscheduler(m_tProcessId, ConvertToPosixBasedOS001SchedularPolicy(p_eSchedulingPolicy_i),
736 m_iErrorCode = errno;
737 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
742 * SetPriority: This method will change the priority for the process this
745 * @param p_iPriority_i Scheduling Policy for this process
748 void Process::SetPriority(const int p_iPriority_i) {
749 //=======================================================================================
750 // Attempt to change the priority for the process that this object
751 // represents. If the change fails, restore the previous settings.
754 struct sched_param cur_sch_params;
755 sched_getparam(m_tProcessId, &cur_sch_params);
756 cur_sch_params.sched_priority = p_iPriority_i;
758 if (-1 == sched_setparam(m_tProcessId, &cur_sch_params)) {
759 m_iErrorCode = errno;
760 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
766 * IncreasePriorityByOne: This method will increase the priority for the process this
767 * object represents by one.
772 void Process::IncreasePriorityByOne(void) {
773 //================================================================================
774 // Retrieve the current priority of the process. Check to see if already at max.
775 // If so just return. Otherwise increase by one and set the priority...
778 int iCurrentPriority = GetPriority();
779 if (iCurrentPriority < iProcess_MAXIMUM_PROCESS_PRIORITY) {
780 SetPriority(iCurrentPriority + 1);
784 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
790 * DecreasePriorityByOne: This method will decrease the priority for the process this
791 * object represents by one.
796 void Process::DecreasePriorityByOne(void) {
797 //================================================================================
798 // Retrieve the current priority of the process. Check to see if already at minimum.
799 // If so just return. Otherwise decrease by one and set the priority...
802 int iCurrentPriority = GetPriority();
803 if (iCurrentPriority > 1) {
804 SetPriority(iCurrentPriority - 1);
808 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
816 ////////////////////////////////////////////////////////////////////////////////////////////////////
817 // ConvertToPosixBasedOS001SchedularPolicy
819 // This method will return to the caller the equivalent PosixBasedOS001 schedular policy for the process
820 // that this object represents
823 // Calling Arguments:
827 // FIFO, // A fixed priority scheduler in which the highest ready process runs until it
828 // // blocks or is preempted by a higher priority process.
829 // ROUND_ROBIN, // The same as FIFO, except processes at the same priority level time-slice.
830 // OTHER // A general time sharing scheduler in which a process decays in priority if it
831 // // consumes too much processor before blocking. It reverts to its default priority
832 // // when it blocks. Should it fail to run over a 2 second period and it has decayed
833 // // then it's boosted one priority level up to a maximum of its default priority.
835 int const Process::ConvertToPosixBasedOS001SchedularPolicy(const eProcessSchedulingPolicy p_eSchedulingPolicy_i) {
836 int iReturnValue = SCHED_RR; // Default is RR
837 switch (p_eSchedulingPolicy_i) {
840 iReturnValue = SCHED_FIFO;
846 iReturnValue = SCHED_RR;
852 iReturnValue = SCHED_OTHER;
860 ////////////////////////////////////////////////////////////////////////////////////////////////////
861 // ConvertFromPosixBasedOS001SchedularPolicy
863 // This method will return to the caller the eProcessSchedulingPolicy based on the PosixBasedOS001 schedular
864 // policy for the process that this object represents
867 // Calling Arguments:
868 // PosixBasedOS001 Scheduling Policy
871 // FIFO, // A fixed priority scheduler in which the highest ready process runs until it
872 // // blocks or is preempted by a higher priority process.
873 // ROUND_ROBIN, // The same as FIFO, except processes at the same priority level time-slice.
874 // OTHER // A general time sharing scheduler in which a process decays in priority if it
875 // // consumes too much processor before blocking. It reverts to its default priority
876 // // when it blocks. Should it fail to run over a 2 second period and it has decayed
877 // // then it's boosted one priority level up to a maximum of its default priority.
879 Process::eProcessSchedulingPolicy const Process::ConvertFromPosixBasedOS001SchedularPolicy
880 (const int p_iPosixBasedOS001chedulingPolicy_i) {
881 eProcessSchedulingPolicy ePolicy = ROUND_ROBIN; // Default is RR
882 switch (p_iPosixBasedOS001chedulingPolicy_i) {
891 ePolicy = ROUND_ROBIN;
906 * DoesProcessExist: This method will return a BOOLean indicating whether this
909 * @return BOOL TRUE - Process Exists, FALSE - Process does not exist
911 BOOL Process::DoesProcessExist(void) {
912 struct sched_param cur_sch_params;
913 if (-1 >= sched_getparam(m_tProcessId, &cur_sch_params)) { // or the segment data
923 * SetProcessName: This method will set this objects process name member variable to the
924 * provided string value.
926 * @param p_strProcessName_i Process Name to set the m_strProcessName member variable to
929 void Process::SetProcessName(const SS_String& p_strProcessName_i) {
933 assert(!p_strProcessName_i.empty());
935 m_strProcessName = p_strProcessName_i;
939 * GetSchedulingPolicy: This method will return to the caller the
940 * currently configured process scheduling policy.
942 * @return Process::eProcessSchedulingPolicy const
944 Process::eProcessSchedulingPolicy const Process::GetSchedulingPolicy(void) {
946 if (-1 == (policy = sched_getscheduler(m_tProcessId))) {
947 m_iErrorCode = errno;
948 return ROUND_ROBIN; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
951 return (ConvertFromPosixBasedOS001SchedularPolicy (policy));
957 * GetPriority: This method will return to the caller the currently configured
962 int const Process::GetPriority(void) {
963 struct sched_param cur_sch_params;
964 if (-1 >= sched_getparam(m_tProcessId, &cur_sch_params)) {
965 m_iErrorCode = errno;
966 return -1; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
969 return (cur_sch_params.sched_priority);
975 * SetCallingArgumentList: This method will set the calling argument list
976 * that this object represents.
978 * @param p_pcArgv_i Pointer to NULL terminated argument list.
979 * @param p_iArgc_i Number of parameters
982 void Process::SetCallingArgumentList(const char *p_pcArgv_i[], const int p_iArgc_i) {
983 ////////////////////////////////////////////////////////////////////////
984 // Set the executable filename first. This is always the 1st argument
985 // in the argument list. Then set the argument list for the process
986 // which is held in m_strlstArgv.
988 if (p_iArgc_i > (iProcess_MAXIMUM_NUMBER_OF_PROCESS_ARGUMENTS - 3)) {
989 return; // PAD THIS IS BAD!!! TODO: Change this to something meaningful
993 // First make sure that the argument list is empty.
995 if (!m_strlstArgv.empty()) {
996 m_strlstArgv.clear(); // Remove all elements from the current list
997 } // Process Argument list is NOT empty
1000 // Once empty, put the new arguments into the list
1002 StringListIter at = m_strlstArgv.begin();
1004 for (iLoop = 0; iLoop < p_iArgc_i; iLoop ++) {
1005 at = m_strlstArgv.insert(at, p_pcArgv_i[iLoop]);
1011 * SetCallingArgumentList: This method will set the calling argument
1012 * list that this object represents.
1014 * @param p_strlstParameters_i List of parameters
1017 void Process::SetCallingArgumentList(const StringList& p_strlstParameters_i) {
1018 if (p_strlstParameters_i.size()) {
1019 m_strlstArgv.clear(); // Empty the current list.
1020 m_strlstArgv = p_strlstParameters_i;
1025 * Search if libTestFwCommon.so is dynamically linked.
1027 * @param process_path Search target binary path
1030 static bool CheckLinkedTestfwLibrary(SS_String *process_path) {
1031 if (NULL == process_path) {
1032 fprintf(stderr, "[%s](%d)Invaild Param.\n", __func__, __LINE__);
1036 ELFIO::elfio reader;
1037 if (!reader.load(process_path->c_str())) {
1038 fprintf(stderr, "[%s](%d)%s is not ELF!\n", __func__, __LINE__, process_path->c_str());
1042 ELFIO::Elf_Half n = reader.sections.size();
1043 for ( ELFIO::Elf_Half i = 0; i < n; ++i ) {
1044 ELFIO::section* sec = reader.sections[i];
1045 if ( SHT_DYNAMIC == sec->get_type() ) {
1046 ELFIO::dynamic_section_accessor dynamic(reader, sec);
1048 ELFIO::Elf_Xword dynamic_num = dynamic.get_entries_num();
1049 if ( dynamic_num > 0 ) {
1050 for ( ELFIO::Elf_Xword i = 0; i < dynamic_num; ++i ) {
1051 ELFIO::Elf_Xword dynamic_tag = 0;
1052 ELFIO::Elf_Xword dynamic_value = 0;
1053 SS_String dynamic_str;
1054 dynamic.get_entry(i, dynamic_tag, dynamic_value, dynamic_str);
1056 // Search if the acquired dynamic section string contains libTestFwCommon.so
1057 if (SS_String::npos != dynamic_str.find("libTestFwCommon.so")) {
1058 fprintf(stderr, "[%s](%d)libTestFwCommon is linked.\n", __func__, __LINE__);
1062 // Check for continuation of dynamic section element
1063 if ( DT_NULL == dynamic_tag ) {
1068 // If dynamic section is not found
1069 fprintf(stderr, "[%s](%d)dynamic symbol is not find.\n", __func__, __LINE__);
1074 fprintf(stderr, "[%s](%d)libTestFwCommon is not find. \n", __func__, __LINE__);
1079 * This method is a private method to be called from CreateProcess func.
1080 * Check environment variable MOCK_LIBRARY where Mock Library Name to set in LD_PRELOAD is set
1081 * and output character string to set in LD_PRELOAD if there is setting.
1083 * @param process_path,environment_string
1086 void Process::CheckLdPreLoad(SS_String *process_path, char *environment_string) {
1087 if ((process_path == NULL || environment_string == NULL)) {
1088 fprintf(stderr, "[%s](%d)Invaild Param.\n", __func__, __LINE__);
1092 // Check if environment variable MOCK_LIBRARY for LD_PRELOAD setting is set
1093 char *value_mock_library = getenv("MOCK_LIBRARY");
1095 if (value_mock_library != NULL) {
1096 // When MOCK_LIBRARY is set
1097 fprintf(stderr, "[%s](%d)MOCK_LIBRARY = %s \n", __func__, __LINE__, value_mock_library);
1099 // Check whether the process to be started is a core unit or TestFW, and execute LD_PRELOAD if libTestFwCommon.so is linked
1100 if (CheckLinkedTestfwLibrary(process_path)) {
1101 SS_String key_value;
1102 SS_String key_ld_preload = "LD_PRELOAD=";
1104 // Create LD_PRELOAD setting string
1105 // LD_PRELOAD is enabled when the string is an envp argument in the form "LD_PRELOAD=hoge_mock.so hoge_mock.so ..."
1106 key_value = key_ld_preload + value_mock_library;
1107 strncpy(environment_string, key_value.c_str(), key_value.length());
1108 fprintf(stderr, "[%s](%d)Set envp: %s \n", __func__, __LINE__, environment_string);
1111 // If the unit does not require LD_PRELOAD setting, set envairoment_string to NULL.
1112 fprintf(stderr, "[%s](%d)Core Unit is not setting LD_PRELOAD\n", __func__, __LINE__);
1116 // If it is not set to MOCK_LIBRARY, it is not necessary to set LD_PRELOAD, so set envairoment_string to NULL.
1117 fprintf(stderr, "[%s](%d)The MOCK_LIBRARY variable was unestablished.\n", __func__, __LINE__);
1123 * Acquire the character string of the environment variable and set it in String Vector
1124 * and return in a pointer of Vector.
1126 * @param process_path,environment_string
1127 * @return vector<SS_String> pointer
1129 extern char ** environ;
1130 std::vector<SS_String> *Process::GetEnvironVector(void) {
1131 // If LD_PRELOAD is set, copy existing environment settings and set to environment_pointer
1133 std::vector<SS_String>* vector_environ = new std::vector<SS_String>;
1135 char **environ_tmp = environ;
1137 // Insert environ_string into the vector table
1139 while (environ_tmp[i] != NULL) {
1140 SS_String str_env(environ_tmp[i]);
1141 vector_environ->push_back(str_env);
1145 return vector_environ;
1147 // ----------------------------------------