xref: /PHP-8.2/ext/opcache/shared_alloc_posix.c (revision 01b3fc03)
1 /*
2    +----------------------------------------------------------------------+
3    | Zend OPcache                                                         |
4    +----------------------------------------------------------------------+
5    | Copyright (c) The PHP Group                                          |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 3.01 of the PHP license,      |
8    | that is bundled with this package in the file LICENSE, and is        |
9    | available through the world-wide-web at the following url:           |
10    | https://www.php.net/license/3_01.txt                                 |
11    | If you did not receive a copy of the PHP license and are unable to   |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@php.net so we can mail you a copy immediately.               |
14    +----------------------------------------------------------------------+
15    | Authors: Andi Gutmans <andi@php.net>                                 |
16    |          Zeev Suraski <zeev@php.net>                                 |
17    |          Stanislav Malyshev <stas@zend.com>                          |
18    |          Dmitry Stogov <dmitry@php.net>                              |
19    +----------------------------------------------------------------------+
20 */
21 
22 #include "zend_shared_alloc.h"
23 
24 #ifdef USE_SHM_OPEN
25 
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <stdio.h>
29 #include <fcntl.h>
30 #include <sys/mman.h>
31 #include <unistd.h>
32 #include <stdlib.h>
33 
34 typedef struct  {
35     zend_shared_segment common;
36     int shm_fd;
37 } zend_shared_segment_posix;
38 
create_segments(size_t requested_size,zend_shared_segment_posix *** shared_segments_p,int * shared_segments_count,char ** error_in)39 static int create_segments(size_t requested_size, zend_shared_segment_posix ***shared_segments_p, int *shared_segments_count, char **error_in)
40 {
41 	zend_shared_segment_posix *shared_segment;
42 	char shared_segment_name[sizeof("/ZendAccelerator.") + 20];
43 
44 	*shared_segments_count = 1;
45 	*shared_segments_p = (zend_shared_segment_posix **) calloc(1, sizeof(zend_shared_segment_posix) + sizeof(void *));
46 	if (!*shared_segments_p) {
47 		*error_in = "calloc";
48 		return ALLOC_FAILURE;
49 	}
50 	shared_segment = (zend_shared_segment_posix *)((char *)(*shared_segments_p) + sizeof(void *));
51 	(*shared_segments_p)[0] = shared_segment;
52 
53 	sprintf(shared_segment_name, "/ZendAccelerator.%d", getpid());
54 	shared_segment->shm_fd = shm_open(shared_segment_name, O_RDWR|O_CREAT|O_TRUNC, 0600);
55 	if (shared_segment->shm_fd == -1) {
56 		*error_in = "shm_open";
57 		return ALLOC_FAILURE;
58 	}
59 
60 	if (ftruncate(shared_segment->shm_fd, requested_size) != 0) {
61 		*error_in = "ftruncate";
62 		shm_unlink(shared_segment_name);
63 		return ALLOC_FAILURE;
64 	}
65 
66 	shared_segment->common.p = mmap(0, requested_size, PROT_READ | PROT_WRITE, MAP_SHARED, shared_segment->shm_fd, 0);
67 	if (shared_segment->common.p == MAP_FAILED) {
68 		*error_in = "mmap";
69 		shm_unlink(shared_segment_name);
70 		return ALLOC_FAILURE;
71 	}
72 	shm_unlink(shared_segment_name);
73 
74 	shared_segment->common.pos = 0;
75 	shared_segment->common.size = requested_size;
76 
77 	return ALLOC_SUCCESS;
78 }
79 
detach_segment(zend_shared_segment_posix * shared_segment)80 static int detach_segment(zend_shared_segment_posix *shared_segment)
81 {
82 	munmap(shared_segment->common.p, shared_segment->common.size);
83 	close(shared_segment->shm_fd);
84 	return 0;
85 }
86 
segment_type_size(void)87 static size_t segment_type_size(void)
88 {
89 	return sizeof(zend_shared_segment_posix);
90 }
91 
92 zend_shared_memory_handlers zend_alloc_posix_handlers = {
93 	(create_segments_t)create_segments,
94 	(detach_segment_t)detach_segment,
95 	segment_type_size
96 };
97 
98 #endif /* USE_SHM_OPEN */
99