!C99Shell v. 2.0 [PHP 7 Update] [25.02.2019]!

Software: nginx/1.23.4. PHP/5.6.40-65+ubuntu20.04.1+deb.sury.org+1 

uname -a: Linux foro-restaurado-2 5.15.0-1040-oracle #46-Ubuntu SMP Fri Jul 14 21:47:21 UTC 2023
aarch64
 

uid=33(www-data) gid=33(www-data) groups=33(www-data) 

Safe-mode: OFF (not secure)

/home/sources/eaccelerator-eaccelerator-42067ac/   drwxrwxr-x
Free 83.29 GB of 96.73 GB (86.11%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     mm.c (34.65 KB)      -rw-rw-r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
   +----------------------------------------------------------------------+
   | eAccelerator project                                                 |
   +----------------------------------------------------------------------+
   | Copyright (c) 2004 - 2012 eAccelerator                               |
   | http://eaccelerator.net                                              |
   +----------------------------------------------------------------------+
   | This program is free software; you can redistribute it and/or        |
   | modify it under the terms of the GNU General Public License          |
   | as published by the Free Software Foundation; either version 2       |
   | of the License, or (at your option) any later version.               |
   |                                                                      |
   | This program is distributed in the hope that it will be useful,      |
   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
   | GNU General Public License for more details.                         |
   |                                                                      |
   | You should have received a copy of the GNU General Public License    |
   | along with this program; if not, write to the Free Software          |
   | Foundation, Inc., 59 Temple Place - Suite 330, Boston,               |
   | MA  02111-1307, USA.                                                 |
   |                                                                      |
   | A copy is availble at http://www.gnu.org/copyleft/gpl.txt            |
   +----------------------------------------------------------------------+
   $Id: mm.c 421 2010-07-11 21:03:14Z bart $
*/

/* libmm replacement */

#if !defined(MM_TEST_SHM) && !defined(MM_TEST_SEM)
# ifdef HAVE_CONFIG_H
#  include "config.h"
# endif
# include "php.h"
#endif

#ifdef WIN32
#  if 1
#    define MM_SHM_WIN32
#    define MM_SEM_WIN32
#  else
#    define MM_SHM_MALLOC
#    define MM_SEM_NONE
#  endif
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

#ifdef WIN32
#  include <limits.h>
#else
#  ifdef HAVE_UNISTD_H
#    include <unistd.h>
#  endif
#  ifdef HAVE_SYS_PARAM_H
#    include <sys/param.h>
#  endif
#  ifdef HAVE_LIMITS_H
#    include <limits.h>
#  endif
#endif

/* Enable the memory corruption check in debug builds (cheap red zone implementation) */
#ifdef DEBUG
#undef MM_CHECK
#endif
#define MM_PATTERN  0xdeadbeef

#if defined(MM_SHM_MMAP_FILE) || defined(MM_SHM_MMAP_ZERO) || defined(MM_SHM_MMAP_ANON) || defined(MM_SHM_MMAP_POSIX)
#  include <sys/mman.h>
#endif
#if defined(MM_SHM_IPC) || defined(MM_SEM_IPC)
#  include <sys/ipc.h>
#endif
#ifdef MM_SHM_IPC
#  include <sys/shm.h>
#endif
#if defined(MM_SHM_WIN32) || defined(MM_SEM_WIN32)
#  include <windows.h>
#endif
#ifdef MM_SHM_MALLOC
#  include <malloc.h>
#endif
#ifdef MM_SEM_IPC
#  include <sys/sem.h>
#endif
#ifdef MM_SEM_FLOCK
#  include <sys/file.h>
#endif
#ifdef MM_SEM_POSIX
#  include <semaphore.h>
#endif
#ifdef MM_SEM_PTHREAD
#  include <pthread.h>
#endif

struct mm_mutex;

typedef struct mm_free_bucket {
    size_t                 size;
    struct mm_free_bucket* next;
} mm_free_bucket;

typedef struct mm_core {
    size_t           size;
    void*            start;
    size_t           available;
    void*            attach_addr;
    struct mm_mutex* lock;
    mm_free_bucket*  free_list;
} mm_core;

typedef union mm_mem_head {
    size_t size;
    double a1;
    int (*a2)(int);
    void *a3;
} mm_mem_head;

#define MM_SIZE(sz)       (sizeof(mm_mem_head)+(sz))
#define PTR_TO_HEAD(p)    (((mm_mem_head *)(p)) - 1)
#define HEAD_TO_PTR(p)    ((void *)(((mm_mem_head *)(p)) + 1))

#define MM mm_core
#define MM_PRIVATE
#include "mm.h"

#if !defined(MM_TEST_SEM) && !defined(MM_TEST_SHM)
# include "debug.h"
#endif

typedef union mm_word {
    size_t size;
    void*  ptr;
    double d;
    int (*func)(int);
} mm_word;

#if (defined (__GNUC__) && __GNUC__ >= 2)
#define MM_PLATFORM_ALIGNMENT (__alignof__ (mm_word))
#else
#define MM_PLATFORM_ALIGNMENT (sizeof(mm_word))
#endif

#define MM_ALIGN(n) (void*)((((size_t)(n)-1) & ~(MM_PLATFORM_ALIGNMENT-1)) + MM_PLATFORM_ALIGNMENT)
/*#define MM_ALIGN(n) (void*)((1+(((size_t)(n)-1) / sizeof(mm_word))) * sizeof(mm_word))*/

#ifndef MAXPATHLEN
#  ifdef PATH_MAX
#    define MAXPATHLEN PATH_MAX
#  elif defined(_POSIX_PATH_MAX)
#    define MAXPATHLEN _POSIX_PATH_MAX
#  else
#    define MAXPATHLEN 256
#  endif
#endif

#undef MM_SHM_CAN_ATTACH

#if defined(MM_SEM_POSIX) || defined(MM_SEM_FCNTL) || defined(MM_SEM_FLOCK) || defined(MM_SEM_WIN32) || defined(MM_SHM_MMAP_POSIX) || defined(MM_SHM_MMAP_FILE)
static int strxcat(char* dst, const char* src, int size)
{
    int dst_len = strlen(dst);
    int src_len = strlen(src);
    if (dst_len + src_len < size) {
        memcpy(dst+dst_len, src, src_len+1);
        return 1;
    } else {
        memcpy(dst+dst_len, src, (size-1)-dst_len);
        dst[size-1] = '\000';
        return 0;
    }
}
#endif

#if defined(MM_SEM_SPINLOCK)

#if !((defined(__GNUC__) || !defined(__SUNPRO_C)) && \
    (defined(__i386__) || defined(__i386) || defined(__x86_64__)))
#  error "spinlocks are not implemented for your system"
#endif

#ifndef _POSIX_PRIORITY_SCHEDULING
#  error "Spinlocks require a working sched_yield implementation"
#endif

/*********************************/
/* Semaphores                    */
/********************************/

/* ######################################################################### */

#define MM_SEM_TYPE "spinlock"
#define MM_SEM_CAN_ATTACH

#include <sched.h>

typedef struct mm_mutex {
    volatile unsigned int locked;
} mm_mutex;

static void mm_do_lock_slow(volatile unsigned int* locked);

static int mm_init_lock(const char* key, mm_mutex* lock)
{
    lock->locked = 0;
    return 1;
}

static inline int mm_do_lock(mm_mutex* lock, int kind)
{
    int ret, i;
    __asm__ __volatile__
    ("xchgl %0, %1"
     : "=r"(ret), "=m"(lock->locked)
     : "0"(1), "m"(lock->locked)
     : "memory");

    if (ret) {
        /* We didn't immediately get the lock,
           try again 1000 times with pause instruction in the loop */
        for (i = 0; i < 1000; i++) {
            __asm__ __volatile__
            ("pause\n"
             "xchgl %0, %1"
             : "=r"(ret), "=m"(lock->locked)
             : "0"(1), "m"(lock->locked)
             : "memory");
            
            if (!ret) {
                return 1;
            }
        }

        if (ret) {
            /* Still no luck, try the slow approach */
            mm_do_lock_slow(&lock->locked);
        }
    }
    return 1;
}

static void mm_do_lock_slow(volatile unsigned int* locked)
{
    sched_yield();
    while(1) {
        int ret;
        __asm__ __volatile__
        ("pause\n"
         "xchgl %0, %1"
         : "=r"(ret), "=m"(*locked)
         : "0"(1), "m"(*locked)
         : "memory");

        if (!ret) {
            return;
        }

        /* Sleep for a while */
        struct timespec t;
        t.tv_sec = 0;
        t.tv_nsec = 2000000;
        nanosleep(&t, NULL);
    }
}

static inline int mm_do_unlock(mm_mutex* lock)
{
    __asm__ __volatile__
    ("movl $0, %0"
     : "=m"(lock->locked)
     : "m" (lock->locked)
     : "memory");
     
     return 1;
}

static void mm_destroy_lock(mm_mutex* lock)
{
}

/* ######################################################################### */

#elif defined(MM_SEM_PTHREAD)

#define MM_SEM_TYPE "pthread"

typedef struct mm_mutex {
    pthread_mutex_t mutex;
} mm_mutex;

static int mm_init_lock(const char* key, mm_mutex* lock)
{
    pthread_mutexattr_t mattr;

    if (pthread_mutexattr_init(&mattr) != 0) {
        return 0;
    }
    if (pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED) != 0) {
        return 0;
    }
    if (pthread_mutex_init(&lock->mutex, &mattr) != 0) {
        return 0;
    }
    pthread_mutexattr_destroy(&mattr);
    return 1;
}

static int mm_do_lock(mm_mutex* lock, int kind)
{
    if (pthread_mutex_lock(&lock->mutex) != 0) {
        return 0;
    }
    return 1;
}

static int mm_do_unlock(mm_mutex* lock)
{
    if (pthread_mutex_unlock(&lock->mutex) != 0) {
        return 0;
    }
    return 1;
}

static void mm_destroy_lock(mm_mutex* lock)
{
    pthread_mutex_destroy(&lock->mutex);
}

/* ######################################################################### */

#elif defined(MM_SEM_POSIX)

/* this one doesn't work! */

#define MM_SEM_TYPE "posix"

typedef struct mm_mutex {
    sem_t* sem;
} mm_mutex;

static int mm_init_lock(const char* key, mm_mutex* lock)
{
    int fd;
#ifdef SEM_NAME_LEN
    char s[SEM_NAME_LEN];

    strncpy(s, key, SEM_NAME_LEN - 1);
    strxcat(s, ".sem.XXXXXX", SEM_NAME_LEN);
#else
    char s[MAXPATHLEN];

    strncpy(s, key, MAXPATHLEN - 1);
    strxcat(s, ".sem.XXXXXX", MAXPATHLEN);
#endif
    if (mkstemp(s) == NULL) {
        perror(s);
        return 0;
    }
    if ((lock->sem = sem_open(s, O_CREAT, S_IRUSR | S_IWUSR, 1)) == (sem_t*)SEM_FAILED) {
        perror(s);
        return 0;
    }
    sem_unlink(s);
    return 1;
}

static int mm_do_lock(mm_mutex* lock, int kind)
{
    return (sem_wait(lock->sem) == 0);
}

static int mm_do_unlock(mm_mutex* lock)
{
    return (sem_post(lock->sem) == 0);
}

static void mm_destroy_lock(mm_mutex* lock)
{
    sem_close(lock->sem);
}

/* ######################################################################### */

#elif defined(MM_SEM_IPC)

#define MM_SEM_TYPE "sysvipc"

#ifndef HAVE_UNION_SEMUN
union semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
    struct seminfo *__buf;
};
#endif

typedef struct mm_mutex {
    int semid;
} mm_mutex;

static int mm_init_lock(const char* key, mm_mutex* lock)
{
    int rc;
    union semun arg;
    struct semid_ds buf;

    if ((lock->semid = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) < 0) {
        return 0;
    }

    arg.buf = &buf;
    do {
        rc = semctl(lock->semid, 0, IPC_STAT, arg);
    } while (rc < 0 && errno == EINTR);

    buf.sem_perm.uid = EA_USERID;

    do {
        rc = semctl(lock->semid, 0, IPC_SET, arg);
    } while (rc < 0 && errno == EINTR);

    arg.val = 1;
    do {
        rc = semctl(lock->semid, 0, SETVAL, arg);
    } while (rc < 0 && errno == EINTR);
    if (rc < 0) {
        do {
            semctl(lock->semid, 0, IPC_RMID, 0);
        } while (rc < 0 && errno == EINTR);
        return 0;
    }
    return 1;
}

static int mm_do_lock(mm_mutex* lock, int kind)
{
    int rc;
    struct sembuf op;

    op.sem_num = 0;
    op.sem_op  = -1;
    op.sem_flg = SEM_UNDO;
    do {
        rc = semop(lock->semid, &op, 1);
    } while (rc < 0 && errno == EINTR);
    return (rc == 0);
}

static int mm_do_unlock(mm_mutex* lock)
{
    int rc;
    struct sembuf op;

    op.sem_num = 0;
    op.sem_op  = 1;
    op.sem_flg = SEM_UNDO;
    do {
        rc = semop(lock->semid, &op, 1);
    } while (rc < 0 && errno == EINTR);
    return (rc == 0);
}

static void mm_destroy_lock(mm_mutex* lock)
{
    int rc;
    do {
        rc = semctl(lock->semid, 0, IPC_RMID, 0);
    } while (rc < 0 && errno == EINTR);
}

#elif defined(MM_SEM_FCNTL)

#define MM_SEM_TYPE "fcntl"

typedef struct mm_mutex {
    int fd;
} mm_mutex;

static int mm_init_lock(const char* key, mm_mutex* lock)
{
    char s[MAXPATHLEN];

    strncpy(s,key,MAXPATHLEN-1);
    strxcat(s,".sem.XXXXXX",MAXPATHLEN);
    lock->fd =mkstemp(s);
    if (lock->fd != -1) {
        unlink(s);
    }
    return (lock->fd != -1);
}

static int mm_do_lock(mm_mutex* lock, int kind)
{
    int rc;
    struct flock l;
    l.l_whence   = SEEK_SET;
    l.l_start    = 0;
    l.l_len      = 0;
    l.l_pid      = 0;
    if (kind == MM_LOCK_RD) {
        l.l_type     = F_RDLCK;
    } else {
        l.l_type     = F_WRLCK;
    }
    do {
        rc = fcntl(lock->fd, F_SETLKW, &l);
    } while (rc < 0 && errno == EINTR);
    return (rc == 0);
}

static int mm_do_unlock(mm_mutex* lock)
{
    int rc;
    struct flock l;
    l.l_whence   = SEEK_SET;
    l.l_start    = 0;
    l.l_len      = 0;
    l.l_pid      = 0;
    l.l_type     = F_UNLCK;
    do {
        rc = fcntl(lock->fd, F_SETLKW, &l);
    } while (rc < 0 && errno == EINTR);
    return (rc == 0);
}

static void mm_destroy_lock(mm_mutex* lock)
{
    close(lock->fd);
}

/* ######################################################################### */

#elif defined(MM_SEM_FLOCK)

/* this method is not thread safe */

#define MM_SEM_TYPE "flock"

static int   mm_flock_fd  = -1;
static pid_t mm_flock_pid = -1;

typedef struct mm_mutex {
    char filename[MAXPATHLEN];
} mm_mutex;

static int mm_init_lock(const char* key, mm_mutex* lock)
{
    strncpy(lock->filename,key,MAXPATHLEN-1);
    strxcat(lock->filename,".sem.XXXXXX",MAXPATHLEN);
    mm_flock_fd =mkstemp(lock->filename);
    if (mm_flock_fd != -1) {
#if defined(F_SETFD) && defined(FD_CLOEXEC)
        fcntl(mm_flock_fd, F_SETFD, FD_CLOEXEC);
#endif
        mm_flock_pid = getpid();
        return 1;
    }
    return 0;
}

static int mm_do_lock(mm_mutex* lock, int kind)
{
    pid_t pid = getpid();
    int rc;
    if (kind == MM_LOCK_RD) {
        kind = LOCK_SH;
    } else {
        kind = LOCK_EX;
    }

    if (mm_flock_fd == -1 || mm_flock_pid != pid) {
        mm_flock_fd = open(lock->filename, O_RDWR, S_IRUSR | S_IWUSR);
        if (mm_flock_fd == -1) {
            return 0;
        }
#if defined(F_SETFD) && defined(FD_CLOEXEC)
        fcntl(mm_flock_fd, F_SETFD, FD_CLOEXEC);
#endif
        mm_flock_pid = pid;
    }
    do {
        rc = flock(mm_flock_fd, kind);
    } while (rc < 0 && errno == EINTR);
    return (rc == 0);
}

static int mm_do_unlock(mm_mutex* lock)
{
    int rc;
    if (mm_flock_fd == -1) {
        mm_flock_fd = open(lock->filename, O_RDWR, S_IRUSR | S_IWUSR);
        if (mm_flock_fd == -1) {
            return 0;
        }
    }
    do {
        rc = flock(mm_flock_fd, LOCK_UN);
    } while (rc < 0 && errno == EINTR);
    return (rc == 0);
}

static void mm_destroy_lock(mm_mutex* lock)
{
    close(mm_flock_fd);
    unlink(lock->filename);
}

/* ######################################################################### */

#elif defined(MM_SEM_BEOS)

#define MM_SEM_TYPE "beos"
#error "Semophore type (MM_SEM_BEOS) is not implemented"

#elif defined(MM_SEM_OS2)

#define MM_SEM_TYPE "os2"
#error "Semophore type (MM_SEM_OS2) is not implemented"

#elif defined(MM_SEM_WIN32)

#define MM_SEM_TYPE "win32"
#define MM_SEM_CAN_ATTACH

typedef struct mm_mutex {
    HANDLE hMutex;
} mm_mutex;

static mm_mutex g_lock;

static int mm_attach_lock(const char* key, mm_mutex* lock)
{
    char* ch;
    char name[256];
    HANDLE hMutex;

    strncpy(name, key, 255);
    strxcat(name, ".sem", 255);
    for (ch = name; *ch; ++ch) {
        if (*ch == ':' || *ch == '/' || *ch == '\\') {
            *ch = '_';
        }
    }
    g_lock.hMutex = hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, name);
    if (!g_lock.hMutex) {
        return 0;
    }
    return 1;
}

static int mm_init_lock(const char* key, mm_mutex* lock)
{
    char* ch;
    char name[256];
    strncpy(name, key, 255);
    strxcat(name, ".sem", 255);
    for (ch = name; *ch; ++ch) {
        if (*ch == ':' || *ch == '/' || *ch == '\\') {
            *ch = '_';
        }
    }
    g_lock.hMutex = CreateMutex(NULL, FALSE, name);
    if (!g_lock.hMutex) {
        return 0;
    }
    return 1;
}

static void mm_destroy_lock(mm_mutex* lock)
{
    CloseHandle(g_lock.hMutex);
}

static int mm_do_lock(mm_mutex* lock, int kind)
{
    DWORD rv;

    rv = WaitForSingleObject(g_lock.hMutex, INFINITE);

    if (rv == WAIT_OBJECT_0 || rv == WAIT_ABANDONED) {
        return 1;
    }
    return 0;
}

static int mm_do_unlock(mm_mutex* lock)
{
    if (ReleaseMutex(g_lock.hMutex) == 0) {
        // Releasing the mutex doesn't seem to work under windows. It gives some
        // extremely obscure error code. Locking seems to work though. Because this
        // flood the error log of the win32 users we are not going to return 0 here
        // until a windows dev has found the problem.
    }
    return 1;
}

/* ######################################################################### */

#elif defined(MM_SEM_NONE)

#define MM_SEM_TYPE "none"
#define MM_SEM_CAN_ATTACH


typedef struct mm_mutex {
    int semid;
} mm_mutex;

static int mm_attach_lock(const char* key, mm_mutex* lock)
{
    return 1;
}

static int mm_init_lock(const char* key, mm_mutex* lock)
{
    return 1;
}

static void mm_destroy_lock(mm_mutex* lock)
{
}

static int mm_do_lock(mm_mutex* lock, int kind)
{
    return 1;
}

static int mm_do_unlock(mm_mutex* lock)
{
    return 1;
}

#else
#  error "Semaohore type is not selected. Define one of the following: MM_SEM_SPINLOCK, MM_SEM_PTHREAD, MM_SEM_POSIX, MM_SEM_IPC, MM_SEM_FCNTL, MM_SEM_FLOCK, MM_SEM_BEOS, MM_SEM_OS2, MM_SEM_WIN32"
#endif

int mm_lock(MM* mm, int kind)
{
    if (mm_do_lock(mm->lock, kind)) {
        return 1;
    } else {
#if !defined(MM_TEST_SEM) && !defined(MM_TEST_SHM)
        ea_debug_error("eAccelerator: Could not lock!\n");
#endif
        return 0;
    }
}

int mm_unlock(MM* mm)
{
    if (mm_do_unlock(mm->lock)) {
        return 1;
    } else {
#if !defined(MM_TEST_SEM) && !defined(MM_TEST_SHM)
        ea_debug_error("eAccelerator: Could not release lock!\n");
#endif
        return 0;
    }
}

/* Shared Memory Implementations */

/* ######################################################################### */

#if defined(MM_SHM_IPC)

#define MM_SHM_TYPE "sysvipc"

#ifndef SHM_R
# define SHM_R 0444 /* read permission */
#endif
#ifndef SHM_W
# define SHM_W 0222 /* write permission */
#endif

static MM* mm_create_shm(const char* key, size_t size)
{
    int fd;
    void** segment = NULL;
    if ((fd = shmget(IPC_PRIVATE, size, (IPC_CREAT | SHM_R | SHM_W))) >= 0) {
        MM* p;
        if ((p = (MM*)shmat(fd, NULL, 0)) != ((void *)-1)) {
            struct shmid_ds shmbuf;
            if (shmctl(fd, IPC_STAT, &shmbuf) == 0) {
                shmbuf.shm_perm.uid = getuid();
                shmbuf.shm_perm.gid = getgid();
                if (shmctl(fd, IPC_SET, &shmbuf) == 0) {
                    shmctl(fd, IPC_RMID, NULL);
                    p->size = size;
                    segment = (void**)((char*)p+sizeof(MM));
                    *segment = (void*)-1;
                    segment++;
                    p->start = segment;
                    return p;
                }
            }
            shmdt(p);
        }
        shmctl(fd, IPC_RMID, NULL);
    } else {
        size_t seg_size = 1024*1024;

        while (seg_size <= size/2) {
            seg_size *= 2;
        }
        while ((fd = shmget(IPC_PRIVATE, seg_size, (IPC_CREAT | SHM_R | SHM_W))) == -1) {
            if (seg_size <= 1024*1024) {
#if !defined(MM_TEST_SEM) && !defined(MM_TEST_SHM)
                ea_debug_error("eAccelerator: shmmax should be at least 2MB");
#endif
                return (MM*)-1;
            }
            seg_size /= 2;
        }
#if !defined(MM_TEST_SEM) && !defined(MM_TEST_SHM)
        ea_debug_error("eAccelerator: Could not allocate %d bytes, the maximum size the kernel allows is %d bytes. "
                       "Lower the amount of memory request or increase the limit in /proc/sys/kernel/shmmax.\n", size, seg_size);
#endif

        /* bart: Removed the code that tried to allocate more then one segment
         * because it didn't work, this part needs a redesign of the mm code to
         * allow this. It should allocate one to init the shared memory and add
         * the other to the free list.
         */
    }
    return (MM*)-1;
}

static void mm_destroy_shm(MM* mm)
{
    void** segment = (void**)((char*)mm+sizeof(MM));
    while (*segment != (void*)-1) {
        shmdt(*segment);
        ++segment;
    }
    shmdt(mm);
}

/* ######################################################################### */

#elif defined(MM_SHM_MMAP_ANON)

#define MM_SHM_TYPE "mmap_anon"

#ifndef MAP_ANON
#  ifdef MAP_ANONYMOUS
#    define MAP_ANON MAP_ANONYMOUS
#  endif
#endif

static MM* mm_create_shm(const char* key, size_t size)
{
    MM* p;
    p = (MM*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
    if (p != (MM*)-1) {
        p->size = size;
        p->start = (char*)p+sizeof(MM);
    }
    return p;
}

static void mm_destroy_shm(MM* mm)
{
    munmap(mm,mm->size);
}

/* ######################################################################### */

#elif defined(MM_SHM_MMAP_ZERO)

#define MM_SHM_TYPE "mmap_zero"

static MM* mm_create_shm(const char* key, size_t size)
{
    MM* p;
    int fd = open("/dev/zero", O_RDWR, S_IRUSR | S_IWUSR);
    if (fd == -1) {
        return (MM*)-1;
    }
    p = (MM*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    close(fd);
    if (p != (MM*)-1) {
        p->size = size;
        p->start = (char*)p+sizeof(MM);
    }
    return p;
}

static void mm_destroy_shm(MM* mm)
{
    munmap(mm,mm->size);
}

/* ######################################################################### */

#elif defined(MM_SHM_MMAP_POSIX)

#define MM_SHM_TYPE "mmap_posix"

/* Not Tested */

static MM* mm_create_shm(const char* key, size_t size)
{
    MM* p;
    int fd;
    char s[MAXPATHLEN];

    strncpy(s,key,MAXPATHLEN-1);
    strxcat(s,".shm.XXXXXX",MAXPATHLEN);
    if (mkstemp(s) == -1) {
        return (MM*)-1;
    }
    if ((fd = shm_open(s, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) == -1) {
        return (MM*)-1;
    }
    if (ftruncate(fd, size) < 0) {
        close(fd);
        shm_unlink(s);
        return (MM*)-1;
    }
    p = (MM*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    shm_unlink(s);
    close(fd);
    if (p != (MM*)-1) {
        p->size = size;
        p->start = (char*)p+sizeof(MM);
    }
    return p;
}

static void mm_destroy_shm(MM* mm)
{
    munmap(mm,mm->size);
}

/* ######################################################################### */

#elif defined(MM_SHM_MMAP_FILE)

#define MM_SHM_TYPE "mmap_file"

static MM* mm_create_shm(const char* key, size_t size)
{
    MM* p;
    int fd;
    char s[MAXPATHLEN];

    strncpy(s,key,MAXPATHLEN-1);
    strxcat(s,".shm.XXXXXX",MAXPATHLEN);
    fd = mkstemp(s);
    if (fd < 0) {
        return (MM*)-1;
    }
    if (ftruncate(fd, size) < 0) {
        return (MM*)-1;
    }
    p = (MM*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    close(fd);
    unlink(s);
    if (p != (MM*)-1) {
        p->size = size;
        p->start = (char*)p+sizeof(MM);
    }
    return p;
}

static void mm_destroy_shm(MM* mm)
{
    munmap(mm,mm->size);
}

/* ######################################################################### */

#elif defined(MM_SHM_BEOS)

#define MM_SHM_TYPE "beos"
#error "Shared memeory type (MM_SHM_BEOS) is not implemented"

/* ######################################################################### */

#elif defined(MM_SHM_OS2)

#define MM_SHM_TYPE "os2"
#error "Shared memeory type (MM_SHM_OS2) is not implemented"

/* ######################################################################### */

#elif defined(MM_SHM_WIN32)

#define MM_SHM_TYPE "win32"
#define MM_SHM_CAN_ATTACH

static MM* mm_attach_shm(const char* key, size_t size)
{
    HANDLE  shm_handle;
    MM*     mm;
    MM*     addr;
    MM**    addr_ptr;
    char    s[MAXPATHLEN];
    char*   ch;


    strcpy(s,key);
    for (ch = s; *ch; ++ch) {
        if (*ch == ':' || *ch == '/' || *ch == '\\') {
            *ch = '_';
        }
    }

    shm_handle = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, s);
    if (shm_handle) {
        mm = (MM*)MapViewOfFile(shm_handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
        if (mm == NULL) {
            return (MM*)-1;
        }
        /*
            if (mm->size != size) {
              UnmapViewOfFile(mm);
              CloseHandle(shm_handle);
              return (MM*)-1;
            }
        */
        addr_ptr = (MM**)(((char*)mm)+sizeof(MM));
        addr = *addr_ptr;
        if (addr != mm) {
            UnmapViewOfFile(mm);
            mm = (MM*)MapViewOfFileEx(shm_handle, FILE_MAP_ALL_ACCESS, 0, 0, 0, addr);
            if (mm == NULL) {
                return (MM*)-1;
            }
        }
        /*  CloseHandle(shm_handle);*/
        return mm;
    }
    return (MM*)-1;
}

static MM* mm_create_shm(const char* key, size_t size)
{
    HANDLE  shm_handle;
    MM*     mm;
    MM**    addr_ptr;
    char    s[MAXPATHLEN];
    char*   ch;


    strcpy(s,key);
    for (ch = s; *ch; ++ch) {
        if (*ch == ':' || *ch == '/' || *ch == '\\') {
            *ch = '_';
        }
    }

    shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, s);
    if (!shm_handle) {
        return (MM*)-1;
    }
    mm = (MM*)MapViewOfFileEx(shm_handle, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
    if (mm == NULL) {
        return (MM*)-1;
    }
    addr_ptr = (MM**)(((char*)mm)+sizeof(MM));
    *addr_ptr = mm;
    mm->size = size;
    mm->start = ((char*)mm)+sizeof(MM)+sizeof(void*);

    /*  CloseHandle(shm_handle);*/
    return mm;
}

static void mm_destroy_shm(MM* mm)
{
    UnmapViewOfFile(mm);
}

/* ######################################################################### */

#elif defined(MM_SHM_MALLOC)

#define MM_SHM_TYPE "malloc"

static void* mm_create_shm(const char* key, size_t size)
{
    MM* p = (MM*)malloc(sizeof(MM));
    if (p == NULL) {
        return (MM*)-1;
    }
    p->size  = size;
    p->start = NULL;
    return p;
}

static void mm_destroy_shm(MM* mm)
{
    free(mm);
}

/* ######################################################################### */

#else
#define MM_SHM_TYPE "none"
#  error "Shared memeory type is not selected. Define one of the following: MM_SHM_IPC, MM_SHM_MMAP_ANON, MM_SHM_MMAP_ZERO, MM_SHM_MMAP_FILE, MM_SHM_MALLOC, MM_SHM_BEOS, MM_SHM_OS2, MM_SHM_WIN32"
#endif

#ifdef MM_SHM_MALLOC
static void mm_init(MM* mm)
{
    mm->available = mm->size - sizeof(MM);
    mm->lock = malloc(sizeof(mm_mutex));
}

void* mm_malloc_nolock(MM* mm, size_t size)
{
    if (size > 0) {
        mm_mem_head *p = NULL;
        if (mm->available >= MM_SIZE(size)) {
            p = malloc(MM_SIZE(size));
            if (p != NULL) {
                p->size = MM_SIZE(size);
                mm->available -= MM_SIZE(size);
            }
        }
        if (p != NULL) {
            return HEAD_TO_PTR(p);
        }
    }
    return NULL;
}

void mm_free_nolock(MM* mm, void* x)
{
    if (x != NULL) {
        mm_mem_head *p;
        p = PTR_TO_HEAD(x);
        mm->available += p->size;
        free(p);
    }
}

size_t mm_maxsize(MM* mm)
{
    size_t ret;
    if (!mm_lock(mm, MM_LOCK_RD)) {
        return 0;
    }
    ret = mm->available - MM_SIZE(0);
    mm_unlock(mm);
    return ret;
}

#else
static void mm_init(MM* mm)
{
    mm->start = MM_ALIGN(mm->start);
    mm->attach_addr = (void*)mm;
    mm->lock = mm->start;
    mm->start = MM_ALIGN((void*)(((char*)(mm->start)) + sizeof(mm_mutex)));
    mm->available = mm->size - (((char*)(mm->start))-(char*)mm);
    mm->free_list = (mm_free_bucket*)mm->start;
    mm->free_list->size = mm->available;
    mm->free_list->next = NULL;
}

void* mm_malloc_nolock(MM* mm, size_t size)
{
    if (size > 0) {
        mm_mem_head* x = NULL;
        size_t realsize = (size_t)MM_ALIGN(MM_SIZE(size));
#if MM_CHECK
        realsize += (size_t)MM_ALIGN(sizeof(int));
#endif
        if (realsize <= mm->available) {
            /* Search for free bucket */
            mm_free_bucket* p = mm->free_list;
            mm_free_bucket* q = NULL;
            mm_free_bucket* best = NULL;
            mm_free_bucket* best_prev = NULL;
            while (p != NULL) {
                if (p->size == realsize) {
                    /* Found free bucket with the same size */
                    if (q == NULL) {
                        mm->free_list = p->next;
                        x = (mm_mem_head*)p;
                    } else {
                        q->next = p->next;
                        x = (mm_mem_head*)p;
                    }
                    break;
                } else if (p->size > realsize && (best == NULL || best->size > p->size)) {
                    /* Found best bucket (smallest bucket with the bigger size) */
                    best = p;
                    best_prev = q;
                }
                q = p;
                p = p->next;
            }
            if (x == NULL && best != NULL) {
                if (best->size-realsize < sizeof(mm_free_bucket)) {
                    realsize = best->size;
                    x = (mm_mem_head*)best;
                    if (best_prev == NULL) {
                        mm->free_list = best->next;
                    } else {
                        best_prev->next = best->next;
                    }
                } else {
                    if (best_prev == NULL) {
                        mm->free_list = (mm_free_bucket*)((char*)best + realsize);
                        mm->free_list->size = best->size-realsize;
                        mm->free_list->next = best->next;
                    } else {
                        best_prev->next = (mm_free_bucket*)((char*)best + realsize);
                        best_prev->next->size = best->size-realsize;
                        best_prev->next->next = best->next;
                    }
                    best->size = realsize;
                    x = (mm_mem_head*)best;
                }
            }
            if (x != NULL) {
                mm->available -= realsize;
            }
        }
        if (x != NULL) {
#ifdef MM_CHECK
            *(int *)((char *)x + realsize - (size_t)MM_ALIGN(sizeof(int))) = MM_PATTERN;
#endif
            return HEAD_TO_PTR(x);
        }
    }
    return NULL;
}

void mm_free_nolock(MM* mm, void* x)
{
    if (x != NULL) {
        if (x >= mm->start && x < (void*)((char*)mm + mm->size)) {
            mm_mem_head *p = PTR_TO_HEAD(x);
            size_t size = p->size;
            if ((char*)p+size <= (char*)mm + mm->size) {
                mm_free_bucket* b = (mm_free_bucket*)p;
                b->next = NULL;
                if (mm->free_list == NULL) {
                    mm->free_list = b;
                } else {
                    mm_free_bucket* q = mm->free_list;
                    mm_free_bucket* prev = NULL;
                    mm_free_bucket* next = NULL;
                    while (q != NULL) {
                        if (b < q) {
                            next = q;
                            break;
                        }
                        prev = q;
                        q = q->next;
                    }
                    if (prev != NULL && (char*)prev+prev->size == (char*)b) {
                        if ((char*)next == (char*)b+size) {
                            /* merging with prev and next */
                            prev->size += size + next->size;
                            prev->next = next->next;
                        } else {
                            /* merging with prev */
                            prev->size += size;
                        }
                    } else {
                        if ((char*)next == (char*)b+size) {
                            /* merging with next */
                            b->size += next->size;
                            b->next = next->next;
                        } else {
                            /* don't merge */
                            b->next = next;
                        }
                        if (prev != NULL) {
                            prev->next = b;
                        } else {
                            mm->free_list = b;
                        }
                    }
                }
                mm->available += size;
            }
        }
    }
}

size_t mm_maxsize(MM* mm)
{
    size_t ret = MM_SIZE(0);
    mm_free_bucket* p;
    if (!mm_lock(mm, MM_LOCK_RD)) {
        return 0;
    }
    p = mm->free_list;
    while (p != NULL) {
        if (p->size > ret) {
            ret = p->size;
        }
        p = p->next;
    }
    mm_unlock(mm);
    return ret - MM_SIZE(0);
}
#endif

void* mm_malloc_lock(MM* mm, size_t size)
{
    void *ret;
    if (!mm_lock(mm, MM_LOCK_RW)) {
        return NULL;
    }
    ret = mm_malloc_nolock(mm,size);
    mm_unlock(mm);
    return ret;
}

void mm_free_lock(MM* mm, void* x)
{
    mm_lock(mm, MM_LOCK_RW);
    mm_free_nolock(mm,x);
    mm_unlock(mm);
}

void mm_set_attach(MM* mm, void* attach_addr)
{
    mm->attach_addr = attach_addr;
}

void* mm_attach(size_t size, const char* key)
{
#ifdef MM_SHM_CAN_ATTACH
    MM* mm = mm_attach_shm(key, size);
    if (mm == (MM*)-1) {
        return NULL;
    }
#ifdef MM_SEM_CAN_ATTACH
    if (!mm_attach_lock(key, mm->lock)) {
        mm_destroy_shm(mm);
        return NULL;
    }
#endif
    return mm->attach_addr;
#else
    return NULL;
#endif
}

MM* mm_create(size_t size, const char* key)
{
    MM* p;
    if (size == 0) {
        size = 32 * 1024 * 1024;
    }
    p = mm_create_shm(key, size);
    if (p == (MM*)-1) {
        return NULL;
    }
    mm_init(p);
    if (p->lock == NULL) {
        mm_destroy_shm(p);
        return NULL;
    }
    if (!mm_init_lock(key, p->lock)) {
        mm_destroy_shm(p);
        return NULL;
    }
    return p;
}

void mm_destroy(MM* mm)
{
    if (mm != NULL) {
        mm_destroy_lock(mm->lock);
        mm_destroy_shm(mm);
    }
}

size_t mm_size(MM* mm)
{
    if (mm != NULL) {
        return mm->size;
    }
    return 0;
}

size_t mm_sizeof(MM* mm, void* x)
{
    mm_mem_head *p;
    size_t ret;
    if (mm == NULL || x == NULL || !mm_lock(mm, MM_LOCK_RD)) {
        return 0;
    }
    p = PTR_TO_HEAD(x);
    ret = p->size;
    mm_unlock(mm);
    return ret;
}

size_t mm_available(MM* mm)
{
    size_t available;
    if (mm != NULL && mm_lock(mm, MM_LOCK_RD)) {
        available = mm->available;
        mm_unlock(mm);
        return available;
    }
    return 0;
}

const char* mm_shm_type()
{
    return MM_SHM_TYPE;
}

const char* mm_sem_type()
{
    return MM_SEM_TYPE;
}

#if defined(MM_CHECK) && !(defined(MM_TEST_SHM) || defined(MM_TEST_SEM))
void mm_check_mem(void *x)
{
    mm_mem_head *p = PTR_TO_HEAD(x);
    if (*((unsigned int *)((char *)p + p->size - (size_t)MM_ALIGN(sizeof(int)))) != MM_PATTERN) {
        ea_debug_error("[EACCELERATOR] Corrupted memory detected\n");
    }
}
#else
void mm_check_mem(void *x) {}
#endif

#ifdef MM_TEST_SHM
int main()
{
    char key[] = "/tmp/mm";
    size_t size = 32*1024*1024;
    MM *mm = mm_create(size, key);
    if (mm == NULL) {
        return 1;
    }
    mm_destroy(mm);
    return 0;
}
#endif

#ifdef MM_TEST_SEM
int main()
{
    int ret = 0;
    char key[] = "/tmp/mm";
    size_t size = 1*1024*1024;
    MM *mm = mm_create(size, key);
    if (mm == NULL) {
        return 1;
    }
    if (!mm_lock(mm, MM_LOCK_RW)) {
        ret = 1;
    }
    if (!mm_unlock(mm)) {
        ret = 1;
    }
    if (!mm_lock(mm, MM_LOCK_RD)) {
        ret = 1;
    }
    if (!mm_unlock(mm)) {
        ret = 1;
    }
    mm_destroy(mm);
    return ret;
}
#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: et sw=4 ts=4 fdm=marker
 * vim<600: et sw=4 ts=4
 */

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.0 [PHP 7 Update] [25.02.2019] maintained by HackingTool | HackingTool | Generation time: 0.0138 ]--