Esempio n. 1
0
zend_bool apc_fcntl_nonblocking_lock(int fd)
{
    if(lock_reg(fd, F_SETLK, F_WRLCK, 0, SEEK_SET, 0) < 0) {
        if(errno==EACCES||errno==EAGAIN) return 0;
        else apc_eprint("apc_fcntl_lock failed:");
    }
    return 1;
}
Esempio n. 2
0
int apc_fcntl_create(const char* pathname)
{
    int fd;
    if(pathname == NULL) {
        char lock_path[] = "/tmp/.apc.XXXXXX";
        mktemp(lock_path);
        fd = open(lock_path, O_RDWR|O_CREAT, 0666);
        if(fd > 0 ) {
            unlink(lock_path);
            return fd;
        } else {
            apc_eprint("apc_fcntl_create: open(%s, O_RDWR|O_CREAT, 0666) failed:", lock_path);
            return -1;
        }
    }
    fd = open(pathname, O_RDWR|O_CREAT, 0666);
    if(fd > 0 ) {
        unlink(pathname);
        return fd;
    }
    apc_eprint("apc_fcntl_create: open(%s, O_RDWR|O_CREAT, 0666) failed:", pathname);
    return -1;
}
Esempio n. 3
0
apc_segment_t apc_mmap(char *file_mask, size_t size)
{
    apc_segment_t segment; 

    int fd = -1;
    int flags = MAP_SHARED | MAP_NOSYNC;
    int remap = 1;

    /* If no filename was provided, do an anonymous mmap */
    if(!file_mask || (file_mask && !strlen(file_mask))) {
#if !defined(MAP_ANON)
        apc_eprint("Anonymous mmap does not apear to be available on this system (MAP_ANON/MAP_ANONYMOUS).  Please see the apc.mmap_file_mask INI option.");
#else
        fd = -1;
        flags = MAP_SHARED | MAP_ANON;
        remap = 0;
#endif
    } else if(!strcmp(file_mask,"/dev/zero")) { 
        fd = open("/dev/zero", O_RDWR, S_IRUSR | S_IWUSR);
        if(fd == -1) {
            apc_eprint("apc_mmap: open on /dev/zero failed:");
            goto error;
        }
        remap = 0; /* cannot remap */
    } else if(strstr(file_mask,".shm")) {
        /*
         * If the filemask contains .shm we try to do a POSIX-compliant shared memory
         * backed mmap which should avoid synchs on some platforms.  At least on
         * FreeBSD this implies MAP_NOSYNC and on Linux it is equivalent of mmap'ing
         * a file in a mounted shmfs.  For this to work on Linux you need to make sure
         * you actually have shmfs mounted.  Also on Linux, make sure the file_mask you
         * pass in has a leading / and no other /'s.  eg.  /apc.shm.XXXXXX
         * On FreeBSD these are mapped onto the regular filesystem so you can put whatever
         * path you want here.
         */
        if(!mktemp(file_mask)) {
            apc_eprint("apc_mmap: mktemp on %s failed:", file_mask);
            goto error;
        }
        fd = shm_open(file_mask, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
        if(fd == -1) {
            apc_eprint("apc_mmap: shm_open on %s failed:", file_mask);
            goto error;
        }
        if (ftruncate(fd, size) < 0) {
            close(fd);
            shm_unlink(file_mask);
            apc_eprint("apc_mmap: ftruncate failed:");
            goto error;
        }
        shm_unlink(file_mask);
    } else {
        /*
         * Otherwise we do a normal filesystem mmap
         */
        fd = mkstemp(file_mask);
        if(fd == -1) {
            apc_eprint("apc_mmap: mkstemp on %s failed:", file_mask);
            goto error;
        }
        if (ftruncate(fd, size) < 0) {
            close(fd);
            unlink(file_mask);
            apc_eprint("apc_mmap: ftruncate failed:");
            goto error;
        }
        unlink(file_mask);
    }

    segment.shmaddr = (void *)mmap(NULL, size, PROT_READ | PROT_WRITE, flags, fd, 0);

#ifdef APC_MEMPROTECT
    if(remap) {
        segment.roaddr = (void *)mmap(NULL, size, PROT_READ, flags, fd, 0);
    } else {
        segment.roaddr = NULL;
    }
#endif

    if((long)segment.shmaddr == -1) {
        apc_eprint("apc_mmap: mmap failed:");
    }

    if(fd != -1) close(fd);
    
    return segment;

error:

    segment.shmaddr = (void*)-1;
#ifdef APC_MEMPROTECT
    segment.roaddr = NULL;
#endif
    return segment;
}
Esempio n. 4
0
void apc_fcntl_rdlock(int fd)
{
    if(lock_reg(fd, F_SETLKW, F_RDLCK, 0, SEEK_SET, 0) < 0) {
        apc_eprint("apc_fcntl_rdlock failed:");
    }
}
Esempio n. 5
0
/* {{{ apc_iterator_item */
static apc_iterator_item_t* apc_iterator_item_ctor(apc_iterator_t *iterator, slot_t **slot_pp) {
    zval *zvalue;
    char md5str[33];
    slot_t *slot = *slot_pp;
    apc_context_t ctxt = {0, };
    apc_iterator_item_t *item = ecalloc(1, sizeof(apc_iterator_item_t));

    if (slot->key.type == APC_CACHE_KEY_FILE) {
        /* keys should be unique and with stat=1 we could have multiple files with the same name, so use '<device> <inode>' instead */
#ifdef PHP_WIN32
        item->key_len = spprintf(&item->key, 0, "%I64d %I64d", slot->key.data.file.device, slot->key.data.file.inode);
#else
        item->key_len = spprintf(&item->key, 0, "%ld %ld", (ulong)slot->key.data.file.device, (ulong)slot->key.data.file.inode);
#endif
        item->filename_key = estrdup(slot->value->data.file.filename);
    } else if (slot->key.type == APC_CACHE_KEY_USER) {
        item->key = estrndup((char*)slot->key.data.user.identifier, slot->key.data.user.identifier_len);
        item->key_len = slot->key.data.user.identifier_len;
        item->filename_key = item->key; 
    } else if (slot->key.type == APC_CACHE_KEY_FPFILE) {
        item->key = estrndup((char*)slot->key.data.fpfile.fullpath, slot->key.data.fpfile.fullpath_len);
        item->key_len = slot->key.data.fpfile.fullpath_len;
    } else {
        apc_eprint("Internal error, invalid entry type.");
    }

    ALLOC_INIT_ZVAL(item->value);
    array_init(item->value);

    if (APC_ITER_TYPE & iterator->format) {
        if(slot->value->type == APC_CACHE_ENTRY_FILE) {
            add_assoc_string(item->value, "type", "file", 1);
        } else if(slot->value->type == APC_CACHE_ENTRY_USER) {
            add_assoc_string(item->value, "type", "user", 1);
        }
    }
    if (APC_ITER_FILENAME & iterator->format) {
        if(slot->value->type == APC_CACHE_ENTRY_FILE) {
            if (slot->key.type == APC_CACHE_KEY_FILE) {
              add_assoc_string(item->value, "filename", slot->value->data.file.filename, 1);
            } else {  /* APC_CACHE_FPFILE */
              add_assoc_string(item->value, "filename", (char*)slot->key.data.fpfile.fullpath, 1);
            }
        }
    }
    if (APC_ITER_DEVICE & iterator->format) {
        if(slot->key.type == APC_CACHE_KEY_FILE) {
#ifdef PHP_WIN32
			char buf[20];
			sprintf(buf, "%I64d", slot->key.data.file.device);
			add_assoc_string(item->value, "device", buf, 1);
#else
            add_assoc_long(item->value, "device", slot->key.data.file.device);
#endif
        }
    }
    if (APC_ITER_INODE & iterator->format) {
        if(slot->key.type == APC_CACHE_KEY_FILE) {
#ifdef PHP_WIN32
			char buf[20];
			sprintf(buf, "%I64d", slot->key.data.file.device);
			add_assoc_string(item->value, "device", buf, 1);
#else
            add_assoc_long(item->value, "inode", slot->key.data.file.inode);
#endif
        }
    }
    if (APC_ITER_KEY & iterator->format) {
        add_assoc_stringl(item->value, "key", item->key, item->key_len, 1);
    }
    if (APC_ITER_VALUE & iterator->format) {
        if(slot->value->type == APC_CACHE_ENTRY_USER) {

            ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free, NULL, NULL);
            ctxt.copy = APC_COPY_OUT_USER;

            MAKE_STD_ZVAL(zvalue);
            apc_cache_fetch_zval(zvalue, slot->value->data.user.val, &ctxt);
            apc_pool_destroy(ctxt.pool);
            add_assoc_zval(item->value, "value", zvalue);
        }
    }
    if (APC_ITER_MD5 & iterator->format) {
        if(slot->value->type == APC_CACHE_ENTRY_FILE) {
            if(slot->key.md5) {
                make_digest(md5str, slot->key.md5);
                add_assoc_string(item->value, "md5", md5str, 1);
            }
        }
    }
    if (APC_ITER_NUM_HITS & iterator->format) {
        add_assoc_long(item->value, "num_hits", slot->num_hits);
    }
    if (APC_ITER_MTIME & iterator->format) {
        add_assoc_long(item->value, "mtime", slot->key.mtime);
    }
    if (APC_ITER_CTIME & iterator->format) {
        add_assoc_long(item->value, "creation_time", slot->creation_time);
    }
    if (APC_ITER_DTIME & iterator->format) {
        add_assoc_long(item->value, "deletion_time", slot->deletion_time);
    }
    if (APC_ITER_ATIME & iterator->format) {
        add_assoc_long(item->value, "access_time", slot->access_time);
    }
    if (APC_ITER_REFCOUNT & iterator->format) {
        add_assoc_long(item->value, "ref_count", slot->value->ref_count);
    }
    if (APC_ITER_MEM_SIZE & iterator->format) {
        add_assoc_long(item->value, "mem_size", slot->value->mem_size);
    }
    if (APC_ITER_TTL & iterator->format) {
        if(slot->value->type == APC_CACHE_ENTRY_USER) {
            add_assoc_long(item->value, "ttl", slot->value->data.user.ttl);
        }
    }

    return item;
}