139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania/*
239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * Copyright (C) 2009 The Android Open Source Project
339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * All rights reserved.
439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *
539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * Redistribution and use in source and binary forms, with or without
639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * modification, are permitted provided that the following conditions
739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * are met:
839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *  * Redistributions of source code must retain the above copyright
939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *    notice, this list of conditions and the following disclaimer.
1039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *  * Redistributions in binary form must reproduce the above copyright
1139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *    notice, this list of conditions and the following disclaimer in
1239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *    the documentation and/or other materials provided with the
1339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *    distribution.
1439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *
1539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
1839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
1939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
2239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
2539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * SUCH DAMAGE.
2739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania */
2839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
2939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <dirent.h>
3039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <errno.h>
3139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <fcntl.h>
3239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <limits.h>
3339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <stdio.h>
3439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <stdlib.h>
3539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <sys/stat.h>
3639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <sys/types.h>
3739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <sys/wait.h>
3839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <unistd.h>
3939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include "sysutil.h"
4039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
4139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catanianamespace {
4239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst int kError = -1;
4339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Max number of retries on EAGAIN and EINTR. Totally arbitrary.
4439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst int kMaxAttempts = 8;
4539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
4639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// How long to wait after a cache purge. A few seconds (arbitrary).
4739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst int kCachePurgeSleepDuration = 2; // seconds
4839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
4939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst bool kSilentIfMissing = false;
5039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
5139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst char *kKernelVersion = "/proc/version";
5239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst char *kScalingGovernorFormat = "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor";
5339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst char *kDropCaches = "/proc/sys/vm/drop_caches";
5439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst char *kSchedFeatures = "/sys/kernel/debug/sched_features";
5539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst char *kNewFairSleepers = "NEW_FAIR_SLEEPERS";
5639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst char *kNoNewFairSleepers = "NO_NEW_FAIR_SLEEPERS";
5739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst char *kNormalizedSleepers = "NORMALIZED_SLEEPER"; // no 's' at the end
5839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst char *kNoNormalizedSleepers = "NO_NORMALIZED_SLEEPER";
5939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
6039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst char *kDebugfsWarningMsg = "Did you 'adb root; adb shell mount -t debugfs none /sys/kernel/debug' ?";
6139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
6239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// TODO: Surely these file utility functions must exist already. A
6339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// quick grep did not turn up anything. Look harder later.
6439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
6539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniavoid printErrno(const char *msg, const char *filename)
6639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
6739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    fprintf(stderr, "# %s %s %d %s\n", msg, filename, errno, strerror(errno));
6839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
6939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
7039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Read a C-string from a file.  If the buffer is too short, an error
7139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// message will be printed on stderr.
7239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// @param filename Of the file to read.
7339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// @param start    Buffer where the data should be written to.
7439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// @param size     The size of the buffer pointed by str. Must be >= 1.
7539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// @return The number of characters read (not including the trailing'\0' used
7639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//         to end the string) or -1 if there was an error.
7739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaint readStringFromFile(const char *filename, char *const start, size_t size, bool must_exist=true)
7839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
7939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (NULL == start || size == 0)
8039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
8139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return 0;
8239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
8339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    char *end = start;
8439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    int fd = open(filename, O_RDONLY);
8539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
8639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (fd < 0)
8739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
8839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (ENOENT != errno || must_exist)
8939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
9039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            printErrno("Failed to open", filename);
9139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
9239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return kError;
9339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
9439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
9539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    bool eof = false;
9639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    bool error = false;
9739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    int attempts = 0;
9839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
9939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    --size; // reserve space for trailing '\0'
10039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
10139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    while (size > 0 && !error && !eof && attempts < kMaxAttempts)
10239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
10339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        ssize_t s;
10439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
10539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        s = read(fd, end, size);
10639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
10739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (s < 0)
10839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
10939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            error = EAGAIN != errno && EINTR != errno;
11039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            if (error)
11139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            {
11239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                printErrno("Failed to read", filename);
11339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            }
11439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
11539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        else if (0 == s)
11639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
11739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            eof = true;
11839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
11939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        else
12039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
12139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            end += s;
12239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            size -= s;
12339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
12439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        ++attempts;
12539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
12639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
12739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    close(fd);
12839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
12939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (error)
13039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
13139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return kError;
13239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
13339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    else
13439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
13539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        *end = '\0';
13639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (!eof)
13739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
13839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            fprintf(stderr, "Buffer too small for %s\n", filename);
13939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
14039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return end - start;
14139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
14239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
14339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
14439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Write a C string ('\0' terminated) to a file.
14539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//
14639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaint writeStringToFile(const char *filename, const char *start, bool must_exist=true)
14739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
14839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    int fd = open(filename, O_WRONLY);
14939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
15039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
15139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (fd < 0)
15239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
15339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (ENOENT != errno || must_exist)
15439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
15539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            printErrno("Failed to open", filename);
15639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
15739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return kError;
15839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
15939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
16039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    const size_t len = strlen(start);
16139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    size_t size = len;
16239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    bool error = false;
16339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    int attempts = 0;
16439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
16539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    while (size > 0 && !error && attempts < kMaxAttempts)
16639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
16739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        ssize_t s = write(fd, start, size);
16839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
16939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (s < 0)
17039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
17139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            error = EAGAIN != errno && EINTR != errno;
17239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            if (error)
17339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            {
17439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                printErrno("Failed to write", filename);
17539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            }
17639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
17739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        else
17839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
17939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            start += s;
18039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            size -= s;
18139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
18239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        ++attempts;
18339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
18439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    close(fd);
18539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
18639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (error)
18739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
18839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return kError;
18939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
19039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    else
19139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
19239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (size > 0)
19339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
19439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            fprintf(stderr, "Partial write to %s (%d out of %d)\n",
19539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                    filename, size, len);
19639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
19739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return len - size;
19839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
19939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
20039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
20139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaint writeIntToFile(const char *filename, long value)
20239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
20339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    char buffer[16] = {0,};
20439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    sprintf(buffer, "%ld", value);
20539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    return writeStringToFile(filename, buffer);
20639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
20739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
20839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// @return a message describing the reason why the child exited. The
20939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// message is in a shared buffer, not thread safe, erased by
21039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// subsequent calls.
21139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst char *reasonChildExited(int status)
21239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
21339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    static char buffer[80];
21439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
21539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (WIFEXITED(status))
21639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
21739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        snprintf(buffer, sizeof(buffer), "ok (%d)",  WEXITSTATUS(status));
21839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
21939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    else if (WIFSIGNALED(status))
22039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
22139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        snprintf(buffer, sizeof(buffer), "signaled (%d %s)",  WTERMSIG(status), strsignal(WTERMSIG(status)));
22239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
22339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    else
22439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
22539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        snprintf(buffer, sizeof(buffer), "stopped?");
22639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
22739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    return buffer;
22839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
22939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
23039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
23139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}  // anonymous namespace
23239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
23339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catanianamespace android {
23439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
23539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaint kernelVersion(char *str, size_t size)
23639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
23739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    return readStringFromFile(kKernelVersion, str, size);
23839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
23939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
24039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaint pidOutOfMemoryAdj()
24139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
24239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    char filename[FILENAME_MAX];
24339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
24439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    snprintf(filename, sizeof(filename), "/proc/%d/oom_adj", getpid());
24539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
24639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    char value[16];
24739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (readStringFromFile(filename, value, sizeof(value)) == -1)
24839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
24939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return -127;
25039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
25139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    else
25239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
25339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return atoi(value);
25439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
25539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
25639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
25739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniavoid setPidOutOfMemoryAdj(int level)
25839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
25939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    char filename[FILENAME_MAX];
26039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
26139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    snprintf(filename, sizeof(filename), "/proc/%d/oom_adj", getpid());
26239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    writeIntToFile(filename, level);
26339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
26439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
26539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniavoid disableCpuScaling()
26639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
26739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    for (int cpu = 0; cpu < 16; ++cpu) // 16 cores mobile phones, abestos pockets recommended.
26839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
26939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        char governor[FILENAME_MAX];
27039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        sprintf(governor, kScalingGovernorFormat, cpu);
27139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
27239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (writeStringToFile(governor, "performance", kSilentIfMissing) < 0)
27339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
27439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            if (cpu > 0 && errno == ENOENT)
27539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            {
27639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                break;  // cpu1 or above not found, ok since we have cpu0.
27739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            }
27839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            fprintf(stderr, "Failed to write to scaling governor file for cpu %d: %d %s",
27939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                    cpu, errno, strerror(errno));
28039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            break;
28139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
28239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
28339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
28439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
28539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaint schedFeatures(char *str, size_t size)
28639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
28739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    return readStringFromFile(kSchedFeatures, str, size);
28839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
28939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
29039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniabool newFairSleepers()
29139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
29239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    char value[256] = {0,};
29339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
29439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (readStringFromFile(kSchedFeatures, value, sizeof(value)) == -1)
29539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
29639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        printErrno(kDebugfsWarningMsg, kSchedFeatures);
29739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return false;
29839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
29939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    return strstr(value, "NO_NEW_FAIR_SLEEPERS") == NULL;
30039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
30139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
30239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniavoid setNewFairSleepers(bool on)
30339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
30439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    int retcode;
30539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
30639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (on)
30739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
30839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        retcode = writeStringToFile(kSchedFeatures, kNewFairSleepers);
30939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
31039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    else
31139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
31239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        retcode = writeStringToFile(kSchedFeatures, kNoNewFairSleepers);
31339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
31439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (retcode < 0)
31539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
31639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        fprintf(stderr, "# %s\n", kDebugfsWarningMsg);
31739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
31839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
31939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
32039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniabool normalizedSleepers()
32139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
32239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    char value[256] = {0,};
32339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
32439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (readStringFromFile(kSchedFeatures, value, sizeof(value)) == -1)
32539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
32639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        printErrno(kDebugfsWarningMsg, kSchedFeatures);
32739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return false;
32839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
32939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    return strstr(value, "NO_NEW_FAIR_SLEEPERS") == NULL;
33039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
33139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
33239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniavoid setNormalizedSleepers(bool on)
33339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
33439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    int retcode;
33539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
33639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (on)
33739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
33839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        retcode = writeStringToFile(kSchedFeatures, kNormalizedSleepers);
33939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
34039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    else
34139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
34239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        retcode = writeStringToFile(kSchedFeatures, kNoNormalizedSleepers);
34339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
34439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (retcode < 0)
34539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
34639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        fprintf(stderr, "# %s\n", kDebugfsWarningMsg);
34739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
34839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
34939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
35039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniapid_t forkOrExit()
35139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
35239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    pid_t childpid = fork();
35339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
35439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (-1 == childpid)
35539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
35639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        fprintf(stderr, "Fork failed: %d %s", errno, strerror(errno));
35739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        exit(EXIT_FAILURE);
35839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
35939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    return childpid;
36039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
36139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
36239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniavoid waitForChildrenOrExit(int num)
36339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
36439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    while (num > 0)
36539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
36639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        int status;
36739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        pid_t pid = wait(&status);
36839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (-1 == pid)
36939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
37039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            fprintf(stderr, "Wait failed\n");
37139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
37239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        else
37339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
37439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            if (!WIFEXITED(status))
37539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            {
37639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                fprintf(stderr, "Child pid %d did not exit cleanly %s\n",
37739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                        pid, reasonChildExited(status));
37839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                exit(EXIT_FAILURE);
37939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            }
38039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
38139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        --num;
38239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
38339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
38439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
38539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Sync and cache cleaning functions.  In the old hpux days I was told
38639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// to always call *sync twice. The same advice seems to be still true
38739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// today so *sync is called twice.
38839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Also we wait 'a little' to give a chance to background threads to
38939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// purge their caches.
39039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniavoid syncAndDropCaches(int code)
39139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
39239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    sync();
39339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    sync();
39439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    writeIntToFile(kDropCaches, code);
39539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    sleep(kCachePurgeSleepDuration);
39639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
39739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
39839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
39939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniavoid fsyncAndDropCaches(int fd, int code)
40039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
40139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    fsync(fd);
40239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    fsync(fd);
40339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    writeIntToFile(kDropCaches, code);
40439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    sleep(kCachePurgeSleepDuration);
40539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
40639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
40739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
40839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniavoid resetDirectory(const char *directory)
40939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
41039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    DIR *dir = opendir(directory);
41139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
41239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (NULL != dir)
41339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
41439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        struct dirent *entry;
41539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        char name_buffer[PATH_MAX];
41639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
41739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        while((entry = readdir(dir)))
41839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
41939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            if (0 == strcmp(entry->d_name, ".")
42039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                || 0 == strcmp(entry->d_name, "..")
42139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                || 0 == strcmp(entry->d_name, "lost+found"))
42239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            {
42339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                continue;
42439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            }
42539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            strcpy(name_buffer, directory);
42639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            strcat(name_buffer, "/");
42739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            strcat(name_buffer, entry->d_name);
42839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            unlink(name_buffer);
42939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
43039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        closedir(dir);
43139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    } else {
43239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        mkdir(directory, S_IRWXU);
43339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
43439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
43539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
43639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
43739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// IPC
43839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniabool writePidAndWaitForReply(int writefd, int readfd)
43939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
44039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (writefd > readfd)
44139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
44239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        fprintf(stderr, "Called with args in wrong order!!\n");
44339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return false;
44439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
44539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    pid_t pid = getpid();
44639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    char *start = reinterpret_cast<char *>(&pid);
44739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    size_t size = sizeof(pid);
44839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    bool error = false;
44939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    int attempts = 0;
45039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
45139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    while (size > 0 && !error && attempts < kMaxAttempts)
45239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
45339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        ssize_t s = write(writefd, start, size);
45439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
45539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (s < 0)
45639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
45739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            error = EAGAIN != errno && EINTR != errno;
45839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            if (error)
45939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            {
46039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                printErrno("Failed to write", "parent");
46139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            }
46239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
46339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        else
46439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
46539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            start += s;
46639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            size -= s;
46739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
46839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        ++attempts;
46939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
47039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
47139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (error || 0 != size)
47239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
47339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return false;
47439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
47539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
47639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    bool eof = false;
47739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    char dummy;
47839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    size = sizeof(dummy);
47939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    error = false;
48039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    attempts = 0;
48139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
48239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    while (size > 0 && !error && !eof && attempts < kMaxAttempts)
48339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
48439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        ssize_t s;
48539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
48639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        s = read(readfd, &dummy, size);
48739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
48839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (s < 0)
48939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
49039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            error = EAGAIN != errno && EINTR != errno;
49139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            if (error)
49239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            {
49339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                printErrno("Failed to read", "parent");
49439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            }
49539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
49639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        else if (0 == s)
49739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
49839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            eof = true;
49939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
50039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        else
50139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
50239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            size -= s;
50339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
50439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        ++attempts;
50539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
50639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (error || 0 != size)
50739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
50839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return false;
50939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
51039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    return true;
51139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
51239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
51339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
51439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
51539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniabool waitForChildrenAndSignal(int mProcessNb, int readfd, int writefd)
51639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
51739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (readfd > writefd)
51839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
51939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        fprintf(stderr, "Called with args in wrong order!!\n");
52039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return false;
52139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
52239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
52339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    bool error;
52439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    int attempts;
52539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    size_t size;
52639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
52739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    for (int p = 0; p < mProcessNb; ++p)
52839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
52939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        bool eof = false;
53039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        pid_t pid;
53139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        char *end = reinterpret_cast<char *>(&pid);
53239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
53339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        error = false;
53439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        attempts = 0;
53539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        size = sizeof(pid);
53639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
53739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        while (size > 0 && !error && !eof && attempts < kMaxAttempts)
53839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
53939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            ssize_t s;
54039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
54139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            s = read(readfd, end, size);
54239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
54339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            if (s < 0)
54439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            {
54539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                error = EAGAIN != errno && EINTR != errno;
54639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                if (error)
54739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                {
54839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                    printErrno("Failed to read", "child");
54939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                }
55039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            }
55139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            else if (0 == s)
55239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            {
55339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                eof = true;
554