示例#1
0
//--------------------------------------------------------------------------------------------------
ssize_t cgrp_GetProcessesList
(
    cgrp_SubSys_t subsystem,        ///< [IN] Sub-system of the cgroup.
    const char* cgroupNamePtr,      ///< [IN] Name of the cgroup.
    pid_t* pidListPtr,              ///< [OUT] Buffer that will contain the list of PIDs.
    size_t maxPids                  ///< [IN] The maximum number of pids pidListPtr can hold.
)
{
    // Open the cgroup's processes file for reading.
    int fd = OpenCgrpFile(subsystem, cgroupNamePtr, PROCS_FILENAME, O_RDONLY);

    if (fd < 0)
    {
        return LE_FAULT;
    }

    size_t numPids = BuildTidList(fd, pidListPtr, maxPids);

    if (numPids == LE_FAULT)
    {
        LE_ERROR("Error reading the '%s' cgroup's tasks.", cgroupNamePtr);
    }

    fd_Close(fd);

    return numPids;
}
示例#2
0
文件: proc.c 项目: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
static void SendStdPipeToLogDaemon
(
    proc_Ref_t procRef, ///< [IN] Process that owns the write end of the pipe.
    int pipefd[2],      ///< [IN] Pipe fds.
    int streamNum       ///< [IN] Either STDOUT_FILENO or STDERR_FILENO.
)
{
    if (pipefd[READ_PIPE] != -1)
    {
        // Send the read end to the log daemon.  The fd is closed once it is sent.
        if (streamNum == STDOUT_FILENO)
        {
            logFd_StdOut(pipefd[READ_PIPE],
                         app_GetName(procRef->appRef),
                         procRef->name,
                         procRef->pid);
        }
        else
        {
            logFd_StdErr(pipefd[READ_PIPE],
                         app_GetName(procRef->appRef),
                         procRef->name,
                         procRef->pid);
        }

        // Close the write end of the pipe because we don't need it.
        fd_Close(pipefd[WRITE_PIPE]);
    }
}
示例#3
0
文件: smack.c 项目: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
void smack_RevokeSubject
(
    const char* subjectLabelPtr     ///< [IN] Subject label.
)
{
    // Open the SMACK revoke file.
    int fd;

    do
    {
        fd = open(SMACK_REVOKE_FILE, O_WRONLY);
    }
    while ( (fd == -1) && (errno == EINTR) );

    LE_FATAL_IF(fd == -1, "Could not open %s.  %m.\n", SMACK_REVOKE_FILE);

    // Write the label to the SMACK revoke file.
    int numBytes = 0;

    do
    {
        numBytes = write(fd, subjectLabelPtr, strlen(subjectLabelPtr));
    }
    while ( (numBytes == -1) && (errno == EINTR) );

    LE_FATAL_IF(numBytes < 0, "Could not revoke SMACK label '%s'.  %m.", subjectLabelPtr);

    fd_Close(fd);

    LE_DEBUG("Revoked SMACK label '%s'.", subjectLabelPtr);
}
示例#4
0
//--------------------------------------------------------------------------------------------------
bool cgrp_IsEmpty
(
    cgrp_SubSys_t subsystem,        ///< [IN] Sub-system of the cgroup.
    const char* cgroupNamePtr       ///< [IN] Name of the cgroup.
)
{
    // Open the cgroup's tasks file for reading.
    int fd = OpenCgrpFile(subsystem, cgroupNamePtr, TASKS_FILENAME, O_RDONLY);

    if (fd < 0)
    {
        return false;
    }

    // Read a tid from the file.
    pid_t tid = GetTasksId(fd);
    fd_Close(fd);

    if (tid >= 0)
    {
        return false;
    }
    else if (tid == LE_OUT_OF_RANGE)
    {
        // No tasks.
        return true;
    }
    else
    {
        LE_ERROR("Error reading the '%s' cgroup's tasks.", cgroupNamePtr);
        return false;
    }
}
示例#5
0
//--------------------------------------------------------------------------------------------------
static le_result_t GetValue
(
    cgrp_SubSys_t subsystem,        ///< [IN] Sub-system of the cgroup.
    const char* cgroupNamePtr,      ///< [IN] Name of the cgroup.
    const char* fileNamePtr,        ///< [IN] File name to read from.
    char* bufPtr,                   ///< [OUT] Buffer to store the value in.
    size_t bufSize                  ///< [IN] Size of the buffer.
)
{
    // Open the file.
    int fd = OpenCgrpFile(subsystem, cgroupNamePtr, fileNamePtr, O_RDONLY);

    if (fd < 0)
    {
        return LE_FAULT;
    }

    // Read the value from the file.
    ssize_t numBytesRead;

    do
    {
        numBytesRead = read(fd, bufPtr, bufSize);
    }
    while ( (numBytesRead == -1) && (errno == EINTR) );

    // Check if the read value is valid.
    le_result_t result;

    if (numBytesRead == -1)
    {
        LE_ERROR("Could not read file '%s' in cgroup '%s'.  %m.", fileNamePtr, cgroupNamePtr);
        result = LE_FAULT;
    }
    else if (numBytesRead == bufSize)
    {
        // The value in the file is larger than the provided buffer.  Truncate the buffer.
        bufPtr[bufSize-1] = '\0';
        result = LE_OVERFLOW;
    }
    else
    {
        // Null-terminate the string.
        bufPtr[numBytesRead] = '\0';

        // Remove trailing newline characters.
        while ((numBytesRead > 0) && (bufPtr[numBytesRead - 1] == '\n'))
        {
            numBytesRead--;
            bufPtr[numBytesRead] = '\0';
        }

        result = LE_OK;
    }

    fd_Close(fd);

    return result;
}
示例#6
0
文件: proc.c 项目: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
static void RedirectStdStream
(
    int pipefd[2],      ///< [IN] Pipe fds.
    int streamNum       ///< [IN] Either STDOUT_FILENO or STDERR_FILENO.
)
{
    if (pipefd[READ_PIPE] != -1)
    {
        // Duplicate the write end of the pipe onto the process' standard stream.
        LE_FATAL_IF(dup2(pipefd[WRITE_PIPE], streamNum) == -1,
                    "Could not duplicate fd.  %m.");

        // Close the two ends of the pipe because we don't need them.
        fd_Close(pipefd[READ_PIPE]);
        fd_Close(pipefd[WRITE_PIPE]);
    }
}
示例#7
0
//--------------------------------------------------------------------------------------------------
void fa_event_DestructThread
(
    event_PerThreadRec_t* portablePerThreadRecPtr
)
{
    event_LinuxPerThreadRec_t* perThreadRecPtr =
        CONTAINER_OF(portablePerThreadRecPtr,
                     event_LinuxPerThreadRec_t,
                     portablePerThreadRec);

    // Close the epoll file descriptor.
    fd_Close(perThreadRecPtr->epollFd);

    // Close the eventfd for the Event Queue.
    fd_Close(perThreadRecPtr->eventQueueFd);

    le_mem_Release(perThreadRecPtr);
}
示例#8
0
//--------------------------------------------------------------------------------------------------
ssize_t cgrp_SendSig
(
    cgrp_SubSys_t subsystem,        ///< [IN] Sub-system of the cgroup.
    const char* cgroupNamePtr,      ///< [IN] Name of the cgroup.
    int sig                         ///< [IN] The signal to send.
)
{
    // Open the cgroup's procs file for reading.
    int fd = OpenCgrpFile(subsystem, cgroupNamePtr, PROCS_FILENAME, O_RDONLY);

    if (fd < 0)
    {
        return LE_FAULT;
    }

    // Iterate over the pids in the procs file.
    size_t numPids = 0;

    while (1)
    {
        pid_t pid = GetTasksId(fd);

        if (pid >= 0)
        {
            numPids++;

            kill_SendSig(pid, sig);
        }
        else if (pid == LE_OUT_OF_RANGE)
        {
            // No more PIDs.
            break;
        }
        else
        {
            LE_ERROR("Error reading the '%s' cgroup's tasks.", cgroupNamePtr);
            fd_Close(fd);
            return LE_FAULT;
        }
    }

    fd_Close(fd);
    return numPids;
}
示例#9
0
文件: smack.c 项目: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
bool smack_HasAccess
(
    const char* subjectLabelPtr,    ///< [IN] Subject label.
    const char* accessModePtr,      ///< [IN] Access mode.
    const char* objectLabelPtr      ///< [IN] Object label.
)
{
    CheckLabel(subjectLabelPtr);
    CheckLabel(objectLabelPtr);

    // Create the SMACK rule.
    char rule[SMACK_RULE_STR_BYTES];
    MakeRuleStr(subjectLabelPtr, accessModePtr, objectLabelPtr, rule, sizeof(rule));

    // Open the SMACK access file.
    int fd;

    do
    {
        fd = open(SMACK_ACCESS_FILE, O_RDWR);
    }
    while ( (fd == -1) && (errno == EINTR) );

    LE_FATAL_IF(fd == -1, "Could not open %s.  %m.\n", SMACK_ACCESS_FILE);

    // Write the rule to the SMACK access file.
    int numBytes = 0;

    do
    {
        numBytes = write(fd, rule, sizeof(rule)-1);
    }
    while ( (numBytes == -1) && (errno == EINTR) );

    LE_FATAL_IF(numBytes < 0, "Could not write SMACK rule '%s'.  %m.", rule);

    // Read the SMACK access file to see if access would be granted.
    char a;
    do
    {
        numBytes = read(fd, &a, 1);
    }
    while ( (numBytes == -1) && (errno == EINTR) );

    LE_FATAL_IF(numBytes <= 0, "Could not read '%s'.  %m.", SMACK_ACCESS_FILE);

    fd_Close(fd);

    return (a == '1');
}
示例#10
0
//--------------------------------------------------------------------------------------------------
void le_msg_HideService
(
    le_msg_ServiceRef_t serviceRef  ///< [in] Reference to the service.
)
//--------------------------------------------------------------------------------------------------
{
    // Stop monitoring the directory socket.
    le_event_DeleteFdMonitor(serviceRef->fdMonitorRef);
    serviceRef->fdMonitorRef = NULL;

    // Close the connection with the Service Directory.
    fd_Close(serviceRef->directorySocketFd);
    serviceRef->directorySocketFd = -1;
}
示例#11
0
//--------------------------------------------------------------------------------------------------
static le_result_t WriteToFile
(
    cgrp_SubSys_t subsystem,        ///< [IN] Sub-system of the cgroup.
    const char* cgroupNamePtr,      ///< [IN] Name of the cgroup.
    const char* fileNamePtr,        ///< [IN] File to write to.
    const char* string              ///< [IN] String to write into the file.
)
{
    // Get the length of the string.
    size_t len = strlen(string);
    LE_ASSERT(len > 0);

    // Open the file.
    int fd = OpenCgrpFile(subsystem, cgroupNamePtr, fileNamePtr, O_WRONLY);

    if (fd < 0)
    {
        return LE_FAULT;
    }

    // Write the string to the file.
    le_result_t result = LE_OK;
    ssize_t numBytesWritten = 0;

    do
    {
        numBytesWritten = write(fd, string, len);
    }
    while ((numBytesWritten == -1) && (errno == EINTR));

    if (numBytesWritten != len)
    {
        LE_ERROR("Could not write '%s' to file '%s' in cgroup '%s'.  %m.",
                 string, fileNamePtr, cgroupNamePtr);

        if (errno == ESRCH)
        {
            result = LE_OUT_OF_RANGE;
        }
        else
        {
            result = LE_FAULT;
        }
    }

    fd_Close(fd);

    return result;
}
示例#12
0
//--------------------------------------------------------------------------------------------------
static le_result_t GetProcessNameFromPid
(
    pid_t pId,      ///< [IN] The pid of the process whose name to find
    char* name,     ///< [OUT] A buffer to receive the name of the app
    size_t length   ///< [IN] The size of the buffer that receives the name
)
{
    char pathStr[LIMIT_MAX_PATH_BYTES] = "";
    char procPathStr[LIMIT_MAX_PATH_BYTES] = "";

    if (name != NULL)
    {

        // on linux, /proc/[pid]/cmdline contains the command and arguments separated by '\0's
        int result = snprintf(pathStr, sizeof(pathStr), "/proc/%d/cmdline", pId);
        if (result < 0 || result >= LIMIT_MAX_PATH_BYTES)
        {
            return LE_NOT_FOUND;
        }

        int fd = open(pathStr, O_RDONLY);
        if (fd)
        {
            result = read (fd, procPathStr, LIMIT_MAX_PATH_BYTES);
            fd_Close(fd);
            if (result == 0)
            {
                return LE_FAULT;
            }
            else if (strnlen(procPathStr, LIMIT_MAX_PATH_BYTES) ==  LIMIT_MAX_PATH_BYTES)
            {
                // We need the first parameter of the command line, which is path to a process.
                // This shouldn't be longer than LIMIT_MAX_PATH_BYTES.
                return LE_OVERFLOW;
            }
            // strip the path
            char* procNamePtr = le_path_GetBasenamePtr(procPathStr, "/");

            return le_utf8_Copy(name, procNamePtr, length, NULL);
        }
    }
    else
    {
        return LE_FAULT;
    }
    return LE_OK;
}
示例#13
0
//--------------------------------------------------------------------------------------------------
static le_result_t GetProcessNameFromPid
(
    pid_t pId,      ///< [IN] The pid of the process whose name to find
    char* name,     ///< [OUT] A buffer to receive the name of the app
    size_t length   ///< [IN] The size of the buffer that receives the name
)
{
    char pathStr[LIMIT_MAX_PATH_BYTES];

    if (name != NULL)
    {
        name[0] = '\0';
        // on linux, /proc/[pid]/cmdline contains the command and arguments separated by '\0's
        int result = snprintf(pathStr, sizeof(pathStr), "/proc/%d/cmdline", pId);
        if (result < 0 || result >= LIMIT_MAX_PATH_BYTES)
        {
            return LE_NOT_FOUND;
        }

        int fd = open(pathStr, O_RDONLY);
        if (fd)
        {
            result = read (fd, name, length);
            fd_Close(fd);
            if (result == 0)
            {
                return LE_FAULT;
            }
            else if (result == LIMIT_MAX_PATH_BYTES)
            {
                name[length - 1] = '\0';
                return LE_OVERFLOW;
            }
            // strip the path
            char* procNamePtr = le_path_GetBasenamePtr(name, "/");
            // memmove is safe for overlapping memory!!
            memmove(name, procNamePtr, strlen(procNamePtr) + 1);
        }
    }
    else
    {
        return LE_FAULT;
    }
    return LE_OK;
}
示例#14
0
文件: smack.c 项目: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
static void SetSmackNetlabelExceptions
(
    void
)
{
     // Open the calling process's smack file.
     int fd;

     do
     {
         fd = open(SMACK_NETLABEL_FILE, O_WRONLY);
     }
     while ( (fd == -1) && (errno == EINTR) );

     LE_FATAL_IF(fd == -1, "Could not open %s.  %m.\n", SMACK_NETLABEL_FILE);

     // Write netlabel to the file.
     int result;
     size_t netlabelExceptionSize;

     do
     {
         netlabelExceptionSize = strlen("127.0.0.1 -CIPSO");
         result = write(fd, "127.0.0.1 -CIPSO", netlabelExceptionSize);
     }
     while ( (result == -1) && (errno == EINTR) );

     LE_FATAL_IF(result != netlabelExceptionSize,
                 "Could not write to %s.  %m.\n", SMACK_NETLABEL_FILE);

     do
     {
         netlabelExceptionSize = strlen("0.0.0.0/0 @");
         result = write(fd, "0.0.0.0/0 @", netlabelExceptionSize);
     }
     while ( (result == -1) && (errno == EINTR) );

     LE_FATAL_IF(result != netlabelExceptionSize,
                 "Could not write to %s.  %m.\n", SMACK_NETLABEL_FILE);

     fd_Close(fd);
}
示例#15
0
文件: smack.c 项目: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
void smack_SetRule
(
    const char* subjectLabelPtr,    ///< [IN] Subject label.
    const char* accessModePtr,      ///< [IN] Access mode. See the function description for details.
    const char* objectLabelPtr      ///< [IN] Object label.
)
{
    CheckLabel(subjectLabelPtr);
    CheckLabel(objectLabelPtr);

    // Create the SMACK rule.
    char rule[SMACK_RULE_STR_BYTES];
    MakeRuleStr(subjectLabelPtr, accessModePtr, objectLabelPtr, rule, sizeof(rule));

    // Open the SMACK load file.
    int fd;

    do
    {
        fd = open(SMACK_LOAD_FILE, O_WRONLY);
    }
    while ( (fd == -1) && (errno == EINTR) );

    LE_FATAL_IF(fd == -1, "Could not open %s.  %m.\n", SMACK_LOAD_FILE);

    // Write the rule to the SMACK load file.
    int numBytes = 0;
    size_t ruleLength = strlen(rule);

    do
    {
        numBytes = write(fd, rule, ruleLength);
    }
    while ( (numBytes == -1) && (errno == EINTR) );

    LE_FATAL_IF(numBytes != ruleLength, "Could not write SMACK rule '%s'.  %m.", rule);

    fd_Close(fd);

    LE_DEBUG("Set SMACK rule '%s'.", rule);
}
示例#16
0
文件: smack.c 项目: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
le_result_t smack_GetProcLabel
(
    pid_t pid,                      ///< [IN] PID of the process.
    char* bufPtr,                   ///< [OUT] Buffer to store the proc's SMACK label.
    size_t bufSize                  ///< [IN] Size of the buffer.
)
{
    // Get the process's smack file name.
    char smackFile[LIMIT_MAX_PATH_BYTES];
    LE_ASSERT(snprintf(smackFile, sizeof(smackFile), "/proc/%d/attr/current", pid) < sizeof(smackFile));

    // Open the process's smack file.
    int fd;

    do
    {
        fd = open(smackFile, O_RDONLY);
    }
    while ( (fd == -1) && (errno == EINTR) );

    if (fd == -1)
    {
        LE_ERROR("Could not open %s.  %m.\n", smackFile);
        return LE_FAULT;
    }

    // Read the smack label.
    le_result_t result = fd_ReadLine(fd, bufPtr, bufSize);

    fd_Close(fd);

    if ( (result == LE_OUT_OF_RANGE) || (result == LE_FAULT) )
    {
        return LE_FAULT;
    }

    return result;
}
示例#17
0
文件: smack.c 项目: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
void smack_SetMyLabel
(
    const char* labelPtr            ///< [IN] Label to set the calling process to.
)
{
    CheckLabel(labelPtr);

    // Open the calling process's smack file.
    int fd;

    do
    {
        fd = open(PROC_SMACK_FILE, O_WRONLY);
    }
    while ( (fd == -1) && (errno == EINTR) );

    LE_FATAL_IF(fd == -1, "Could not open %s.  %m.\n", PROC_SMACK_FILE);

    // Write the label to the file.
    size_t labelSize = strlen(labelPtr);

    int result;

    do
    {
        result = write(fd, labelPtr, labelSize);
    }
    while ( (result == -1) && (errno == EINTR) );

    LE_FATAL_IF(result != labelSize,
                "Could not write to %s.  %m.\n", PROC_SMACK_FILE);

    fd_Close(fd);

    LE_DEBUG("Setting process' SMACK label to '%s'.", labelPtr);
}
示例#18
0
文件: proc.c 项目: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
static inline le_result_t StartProc
(
    proc_Ref_t procRef,             ///< [IN] The process to start.
    const char* workingDirPtr,      ///< [IN] The path to the process's working directory, relative
                                    ///       to the sandbox directory.
    uid_t uid,                      ///< [IN] The user ID to start the process as.
    gid_t gid,                      ///< [IN] The primary group ID for this process.
    const gid_t* groupsPtr,         ///< [IN] List of supplementary groups for this process.
    size_t numGroups,               ///< [IN] The number of groups in the supplementary groups list.
    const char* sandboxDirPtr       ///< [IN] The path to the root of the sandbox this process is to
                                    ///       run in.  If NULL then process will be unsandboxed.
)
{
    if (procRef->pid != -1)
    {
        LE_ERROR("Process '%s' (PID: %d) cannot be started because it is already running.",
                 procRef->name, procRef->pid);
        return LE_FAULT;
    }

    // Create a pipe for parent/child synchronization.
    int syncPipeFd[2];
    LE_FATAL_IF(pipe(syncPipeFd) == -1, "Could not create synchronization pipe.  %m.");

    // @Note The current IPC system does not support forking so any reads to the config DB must be
    //       done in the parent process.

    // Get the environment variables from the config tree for this process.
    EnvVar_t envVars[LIMIT_MAX_NUM_ENV_VARS];
    int numEnvVars = GetEnvironmentVariables(procRef, envVars, LIMIT_MAX_NUM_ENV_VARS);

    if (numEnvVars == LE_FAULT)
    {
        LE_ERROR("Error getting environment variables.  Process '%s' cannot be started.",
                 procRef->name);
        return LE_FAULT;
    }

    // Get the command line arguments from the config tree for this process.
    char argsBuffers[LIMIT_MAX_NUM_CMD_LINE_ARGS][LIMIT_MAX_ARGS_STR_BYTES];
    char* argsPtr[NUM_ARGS_PTRS];

    if (GetArgs(procRef, argsBuffers, argsPtr) != LE_OK)
    {
        LE_ERROR("Could not get command line arguments, process '%s' cannot be started.",
                 procRef->name);
        return LE_FAULT;
    }

    // Get the smack label for the process.
    // Must get the label here because smack_GetAppLabel uses the config and we can not
    // use any IPC after a fork.
    char smackLabel[LIMIT_MAX_SMACK_LABEL_BYTES];
    appSmack_GetLabel(app_GetName(procRef->appRef), smackLabel, sizeof(smackLabel));

    // Create pipes for the process's standard error and standard out streams.
    int stderrPipe[2];
    int stdoutPipe[2];
    CreatePipe(procRef, stderrPipe, STDERR_FILENO);
    CreatePipe(procRef, stdoutPipe, STDOUT_FILENO);

    // Create the child process
    pid_t pID = fork();

    if (pID < 0)
    {
        LE_EMERG("Failed to fork.  %m.");
        return LE_FAULT;
    }

    if (pID == 0)
    {
        // Wait for the parent to allow us to continue by blocking on the read pipe until it
        // is closed.
        fd_Close(syncPipeFd[WRITE_PIPE]);

        ssize_t numBytesRead;
        int dummyBuf;
        do
        {
            numBytesRead = read(syncPipeFd[READ_PIPE], &dummyBuf, 1);
        }
        while ( ((numBytesRead == -1)  && (errno == EINTR)) || (numBytesRead != 0) );

        LE_FATAL_IF(numBytesRead == -1, "Could not read synchronization pipe.  %m.");

        // The parent has allowed us to continue.

        // Redirect the process's standard streams.
        RedirectStdStream(stderrPipe, STDERR_FILENO);
        RedirectStdStream(stdoutPipe, STDOUT_FILENO);

        // Set the process's SMACK label.
        smack_SetMyLabel(smackLabel);

        // Set the umask so that files are not accidentally created with global permissions.
        umask(S_IRWXG | S_IRWXO);

        // Unblock all signals that might have been blocked.
        sigset_t sigSet;
        LE_ASSERT(sigfillset(&sigSet) == 0);
        LE_ASSERT(pthread_sigmask(SIG_UNBLOCK, &sigSet, NULL) == 0);

        SetEnvironmentVariables(envVars, numEnvVars);

        // Setup the process environment.
        if (sandboxDirPtr != NULL)
        {
            // Sandbox the process.
            sandbox_ConfineProc(sandboxDirPtr, uid, gid, groupsPtr, numGroups, workingDirPtr);
        }
        else
        {
            ConfigNonSandboxedProcess(workingDirPtr);
        }

        // Launch the child program.  This should not return unless there was an error.
        LE_INFO("Execing '%s'", argsPtr[0]);

        // Close all non-standard file descriptors.
        fd_CloseAllNonStd();

        execvp(argsPtr[0], &(argsPtr[1]));

        // The program could not be started.  Log an error message.
        log_ReInit();
        LE_FATAL("Could not exec '%s'.  %m.", argsPtr[0]);
    }

    procRef->pid = pID;
    procRef->paused = false;

    // Don't need this end of the pipe.
    fd_Close(syncPipeFd[READ_PIPE]);

    // Set the scheduling priority for the child process while the child process is blocked.
    SetSchedulingPriority(procRef);

    // Send standard pipes to the log daemon so they will show up in the logs.
    SendStdPipeToLogDaemon(procRef, stderrPipe, STDERR_FILENO);
    SendStdPipeToLogDaemon(procRef, stdoutPipe, STDOUT_FILENO);

    // Set the resource limits for the child process while the child process is blocked.
    if (resLim_SetProcLimits(procRef) != LE_OK)
    {
        LE_ERROR("Could not set the resource limits.  %m.");

        kill_Hard(procRef->pid);
    }

    LE_INFO("Starting process %s with pid %d", procRef->name, procRef->pid);

    // Unblock the child process.
    fd_Close(syncPipeFd[WRITE_PIPE]);

    return LE_OK;
}
示例#19
0
//--------------------------------------------------------------------------------------------------
static void StartDaemon
(
    DaemonObj_t* daemonPtr      ///< [IN] The daemon to start.
)
{
    const char* daemonNamePtr = le_path_GetBasenamePtr(daemonPtr->path, "/");

    // Kill all other instances of this process just in case.
    kill_ByName(daemonNamePtr);

    // Create a synchronization pipe.
    int syncPipeFd[2];
    LE_FATAL_IF(pipe(syncPipeFd) != 0, "Could not create synchronization pipe.  %m.");

    // Fork a process.
    pid_t pid = fork();
    LE_FATAL_IF(pid < 0, "Failed to fork child process.  %m.");

    if (pid == 0)
    {
        // Clear the signal mask so the child does not inherit our signal mask.
        sigset_t sigSet;
        LE_ASSERT(sigfillset(&sigSet) == 0);
        LE_ASSERT(pthread_sigmask(SIG_UNBLOCK, &sigSet, NULL) == 0);

        // The child does not need the read end of the pipe so close it.
        fd_Close(syncPipeFd[0]);

        // Duplicate the write end of the pipe on standard in so the execed program will know
        // where it is.
        if (syncPipeFd[1] != STDIN_FILENO)
        {
            int r;
            do
            {
                r = dup2(syncPipeFd[1], STDIN_FILENO);
            }
            while ( (r == -1)  && (errno == EINTR) );

            LE_FATAL_IF(r == -1, "Failed to duplicate fd.  %m.");

            // Close the duplicate fd.
            fd_Close(syncPipeFd[1]);
        }

        // Close all non-standard fds.
        fd_CloseAllNonStd();

        smack_SetMyLabel("framework");

        // Launch the child program.  This should not return unless there was an error.
        execl(daemonPtr->path, daemonNamePtr, (char*)NULL);

        // The program could not be started.
        LE_FATAL("'%s' could not be started: %m", daemonPtr->path);
    }

    // Store the pid of the running daemon process.
    daemonPtr->pid = pid;

    // Close the write end of the pipe because the parent does not need it.
    fd_Close(syncPipeFd[1]);

    // Wait for the child process to close the read end of the pipe.  This ensures that the
    // framework daemons start in the proper order.
    // TODO: Add a timeout here.
    ssize_t numBytesRead;
    int dummyBuf;
    do
    {
        numBytesRead = read(syncPipeFd[0], &dummyBuf, 1);
    }
    while ( ((numBytesRead == -1)  && (errno == EINTR)) || (numBytesRead != 0) );

    LE_FATAL_IF(numBytesRead == -1, "Could not read synchronization pipe.  %m.");

    // Close the read end of the pipe because it is no longer used.
    fd_Close(syncPipeFd[0]);

    LE_INFO("Started system process '%s' with PID: %d.", daemonNamePtr, pid);
}
示例#20
0
//--------------------------------------------------------------------------------------------------
le_result_t addr_GetLibDataSection
(
    pid_t pid,              ///< [IN] Pid to get the address for.  Zero means the calling process.
    const char* libNamePtr, ///< [IN] Name of the library.
    off_t* libAddressPtr    ///< [OUT] Address of the .data section of the library.
)
{
    // Build the path to the maps file.
    char fileName[LIMIT_MAX_PATH_BYTES];
    size_t snprintfSize;

    if (pid == 0)
    {
        snprintfSize = snprintf(fileName, sizeof(fileName), "/proc/self/maps");
    }
    else
    {
        snprintfSize = snprintf(fileName, sizeof(fileName), "/proc/%d/maps", pid);
    }

    if (snprintfSize >= sizeof(fileName))
    {
        LE_ERROR("Path to file '%s' is too long.", fileName);
        return LE_FAULT;
    }

    // Open the maps file.
    int fd = open(fileName, O_RDONLY);

    if (fd == -1)
    {
        LE_ERROR("Could not open %s.  %m.", fileName);
        return LE_FAULT;
    }

    // Search each line of the file to find the liblegato.so section.
    off_t address;
    char line[LIMIT_MAX_PATH_BYTES * 2];

    while (1)
    {
        le_result_t result = fd_ReadLine(fd, line, sizeof(line));

        if (result == LE_OK)
        {
            // The line is the section we are looking for if it specifies our library and has an
            // access mode of "rw-p" which we infer is the text section.
            if ( (strstr(line, libNamePtr) != NULL) && (strstr(line, "rw-p") != NULL) )
            {
                // The line should begin with the starting address of the section.
                // Convert it to an address value.
                char* endPtr;
                errno = 0;
                address = strtoll(line, &endPtr, 16);

                if ( (errno != 0) || (endPtr == line) )
                {
                    LE_ERROR("Error reading file %s.", fileName);
                    fd_Close(fd);
                    return LE_FAULT;
                }

                // Got the address.
                break;
            }
        }
        else if (result == LE_OUT_OF_RANGE)
        {
            // The end of the file is reached.
            return LE_NOT_FOUND;
        }
        else
        {
            LE_ERROR("Error reading '%s' while looking for '%s'.", fileName, libNamePtr);
            fd_Close(fd);
            return LE_FAULT;
        }
    }

    fd_Close(fd);

    *libAddressPtr = address;
    return LE_OK;
}