コード例 #1
0
ファイル: vogl_strutils.cpp プロジェクト: Cyberbanan/vogl
    char *vogl_strdup(const char *pStr)
    {
        if (!pStr)
            pStr = "";

        size_t l = strlen(pStr) + 1;
        char *p = (char *)vogl_malloc(l);
        if (p)
            memcpy(p, pStr, l);

        return p;
    }
コード例 #2
0
ファイル: vogl_file_utils.cpp プロジェクト: Nicky-D/vogl
void *file_utils::read_file_to_heap(const char *pPath, size_t &data_size)
{
    data_size = 0;

    FILE *pFile = vogl_fopen(pPath, "rb");
    if (!pFile)
        return NULL;

    vogl_fseek(pFile, 0, SEEK_END);
    uint64_t file_size = vogl_ftell(pFile);
    vogl_fseek(pFile, 0, SEEK_SET);

    if (file_size > VOGL_MAX_POSSIBLE_HEAP_BLOCK_SIZE)
    {
        vogl_fclose(pFile);
        return NULL;
    }

    data_size = static_cast<size_t>(file_size);
    VOGL_ASSERT(data_size == file_size);

    void *p = vogl_malloc(data_size);
    if (!p)
    {
        vogl_fclose(pFile);
        data_size = 0;
        return NULL;
    }

    bool success = (vogl_fread(p, 1, data_size, pFile) == data_size);

    vogl_fclose(pFile);

    if (!success)
    {
        vogl_free(p);
        data_size = 0;
        return NULL;
    }

    return p;
}
コード例 #3
0
ファイル: vogl_vector.cpp プロジェクト: IanAtLunarG/vogl
    bool elemental_vector::increase_capacity(uint32_t min_new_capacity, bool grow_hint, uint32_t element_size, object_mover pMover, bool nofail)
    {
        VOGL_ASSERT(m_size <= m_capacity);
#ifdef VOGL_64BIT_POINTERS
        VOGL_ASSERT(min_new_capacity < (0x400000000ULL / element_size));
#else
        VOGL_ASSERT(min_new_capacity < (0x7FFF0000U / element_size));
#endif

        if (m_capacity >= min_new_capacity)
            return true;

        size_t new_capacity = min_new_capacity;

        if ((grow_hint) && (!math::is_power_of_2(static_cast<uint64_t>(new_capacity))))
        {
            uint64_t new_capacity64 = math::next_pow2(static_cast<uint64_t>(new_capacity));
            if (new_capacity64 != static_cast<size_t>(new_capacity64))
                new_capacity64 = min_new_capacity;
            new_capacity = static_cast<size_t>(new_capacity64);
        }

        VOGL_ASSERT(new_capacity && (new_capacity > m_capacity));

        uint64_t desired_size64 = element_size * static_cast<uint64_t>(new_capacity);
        if ((desired_size64 != static_cast<size_t>(desired_size64)) || (desired_size64 > VOGL_MAX_POSSIBLE_HEAP_BLOCK_SIZE))
        {
            if (nofail)
                return false;

            char buf[256];
            sprintf(buf, "%s: Can't increase capacity to %" PRIu64 " items, %" PRIu64 " bytes", VOGL_FUNCTION_INFO_CSTR, static_cast<uint64_t>(new_capacity), desired_size64);
            VOGL_FAIL(buf);
        }

        const size_t desired_size = static_cast<size_t>(desired_size64);

        size_t actual_size;
        if (!pMover)
        {
            void *new_p = vogl_realloc(m_p, desired_size, &actual_size);
            if (!new_p)
            {
                if (nofail)
                    return false;

                char buf[256];
                sprintf(buf, "%s: vogl_realloc() failed allocating %u bytes", VOGL_FUNCTION_INFO_CSTR, (uint32_t)desired_size);
                VOGL_FAIL(buf);
            }
            m_p = new_p;
        }
        else
        {
            void *new_p = vogl_malloc(desired_size, &actual_size);
            if (!new_p)
            {
                if (nofail)
                    return false;

                char buf[256];
                sprintf(buf, "%s: vogl_malloc() failed allocating %u bytes", VOGL_FUNCTION_INFO_CSTR, (uint32_t)desired_size);
                VOGL_FAIL(buf);
            }

            (*pMover)(new_p, m_p, m_size);

            if (m_p)
                vogl_free(m_p);

            m_p = new_p;
        }

        if (actual_size > desired_size)
            m_capacity = static_cast<uint32_t>(actual_size / element_size);
        else
            m_capacity = static_cast<uint32_t>(new_capacity);

        return true;
    }
コード例 #4
0
ファイル: vogl_uuid.cpp プロジェクト: Daft-Freak/vogl
    // init_uuid() is slow (~40ms, maybe slower), and forces a disk flush on a file, so don't call it more than once.
    // I'm a paranoid nut so this hashes a bunch of shit. It's probably completely overkill for my needs - I should stop reading RFC's.
    static md5_hash init_uuid()
    {
        static uint64_t s_counter;

        // Get as much entropy as we can here

        const uint N = 2;
        void *p[N];
        memset(p, 0, sizeof(p));

        md5_hash_gen gen;
        timer_ticks tick_hist[N];
        for (uint i = 0; i < N; i++)
        {
            uint64_t start_rdtsc = utils::RDTSC();
            gen.update(start_rdtsc);

            gen.update(s_counter);
            gen.update((uint64_t) & s_counter);
            s_counter++;

            // Hash stack address of gen_uuid
            gen.update((uint64_t) & gen_uuid);

            // Hash the initial timer ticks, and time(NULL)
            gen.update(timer::get_init_ticks());
            gen.update((uint64_t)time(NULL));

            // Hash user ID, name, shell, home dir
            uid_t uid = geteuid();
            gen.update(uid);
            struct passwd *pw = getpwuid(uid);
            gen.update((uint64_t) & pw);
            if (pw)
            {
                gen.update(pw, sizeof(struct passwd));
                if (pw->pw_name)
                    gen.update(pw->pw_name, vogl_strlen(pw->pw_name));
                if (pw->pw_passwd)
                    gen.update(pw->pw_passwd, vogl_strlen(pw->pw_passwd));
                if (pw->pw_shell)
                    gen.update(pw->pw_shell, vogl_strlen(pw->pw_shell));
                if (pw->pw_dir)
                    gen.update(pw->pw_dir, vogl_strlen(pw->pw_dir));
                if (pw->pw_gecos)
                    gen.update(pw->pw_gecos, vogl_strlen(pw->pw_gecos));
            }

            uint8_vec buf;

            timer_ticks ticks = timer::get_ticks();
            gen.update(ticks);

            // This is obviously expensive (and questionable?), only do it once. But it helps us get some entropy from the disk subsystem.
            // This is also by far the slowest component of this function (~35ms out of ~40ms).
            if (!i)
            {
                uint64_t st = utils::RDTSC();
                timer tm;
                tm.start();

                const char *pFilename = "!_!_!_!_!_!_!_vogl_temp!_!_!_!_!_!_!_!_.txt";
                FILE *pFile = vogl_fopen(pFilename, "wb");
                gen.update_obj_bits(pFile);
                if (pFile)
                {
                    fwrite("X", 1, 1, pFile);
                    fflush(pFile);
                    fsync(fileno(pFile));
                    vogl_fclose(pFile);
                    remove(pFilename);
                }

                uint64_t t = utils::RDTSC() - st;
                gen.update(t);

                tm.stop();

                gen.update(tm.get_elapsed_ticks());
            }

            // Grab some bits from /dev/urandom (not /dev/random - it may block for a long time)
            {
                const uint N = 64;
                char buf[N];
                FILE *fp = vogl_fopen("/dev/urandom", "rb");
                gen.update_obj_bits(fp);
                if (fp)
                {
                    size_t n = fread(buf, 1, N, fp);
                    VOGL_NOTE_UNUSED(n);
                    vogl_fclose(fp);

                    gen.update(buf, sizeof(buf));
                }
            }

// It's fine if some/most/all of these files don't exist, the true/false results get fed into the hash too.
// TODO: Double check that all the files we should be able to read are actually getting read and hashed here.
#define HASH_FILE(filename)                                               \
    do                                                                    \
    {                                                                     \
        bool success = cfile_stream::read_file_into_array(filename, buf); \
        gen.update_obj_bits(success);                                     \
        gen.update(buf);                                                  \
    } while (0)
            HASH_FILE("/proc/sys/kernel/random/entropy_avail");
            HASH_FILE("/proc/self/statm");
            HASH_FILE("/proc/self/mounts");
            HASH_FILE("/proc/self/io");
            HASH_FILE("/proc/self/smaps");
            HASH_FILE("/proc/self/stack");
            HASH_FILE("/proc/self/status");
            HASH_FILE("/proc/self/maps");
            HASH_FILE("/proc/self/stat");
            HASH_FILE("/proc/self/stat");
            HASH_FILE("/proc/cpuinfo");
            HASH_FILE("/proc/meminfo");
            HASH_FILE("/proc/stat");
            HASH_FILE("/proc/misc");
            HASH_FILE("/proc/swaps");
            HASH_FILE("/proc/version");
            HASH_FILE("/proc/loadavg");
            HASH_FILE("/proc/interrupts");
            HASH_FILE("/proc/ioports");
            HASH_FILE("/proc/partitions");
            HASH_FILE("/proc/driver/rtc");
            HASH_FILE("/proc/self/net/wireless");
            HASH_FILE("/proc/self/net/netstat");
            HASH_FILE("/proc/self/net/netlink");
            HASH_FILE("/sys/class/net/eth0/address");
            HASH_FILE("/sys/class/net/eth1/address");
            HASH_FILE("/sys/class/net/wlan0/address");
#undef HASH_FILE

            gen.update(utils::RDTSC());

            // Hash thread, process ID's, etc.
            pid_t tid = (pid_t)syscall(SYS_gettid);
            gen.update_obj_bits(tid);

            pid_t pid = getpid();
            gen.update_obj_bits(pid);

            pid = getppid();
            gen.update_obj_bits(pid);
            gen.update((uint64_t) & pid);

            ticks -= timer::get_ticks();
            tick_hist[i] = ticks;
            gen.update(ticks);

            ticks = timer::get_ticks();

            // Get some entropy from the stack.
            char purposely_uninitialized_buf[256];
            gen.update(purposely_uninitialized_buf, sizeof(purposely_uninitialized_buf));

            // Get some entropy from the heap.
            p[i] = vogl_malloc(65536 * (i + 1));
            gen.update_obj_bits(p[i]);
            if (p[i])
            {
                for (uint j = 0; j < 16; j++)
                    gen.update_obj_bits(reinterpret_cast<const uint64_t *>(p)[j]);
            }

            struct timeval tv;
            gettimeofday(&tv, NULL);
            gen.update_obj_bits(tv);

            // Hash the current environment
            uint e = 0;
            while (environ[e])
            {
                gen.update(environ[e], vogl_strlen(environ[e]));
                ++e;
            }

            uint64_t s = utils::RDTSC();

            // Try to get some entropy from the scheduler.
            vogl_sleep(2);

            gen.update(utils::RDTSC() - s);

            ticks -= timer::get_ticks();
            gen.update(ticks);

            gen.update(utils::RDTSC() - start_rdtsc);
        }

        for (uint i = 1; i < N; i++)
        {
            uint64_t t = tick_hist[i] - tick_hist[i - 1];
            gen.update(t);
        }

        for (uint i = 0; i < N; i++)
            vogl_free(p[i]);

        return gen.finalize();
    }