1 /*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Chris Vandomelen <chrisv@b0rked.dhs.org> |
14 | Sterling Hughes <sterling@php.net> |
15 | |
16 | WinSock: Daniel Beulshausen <daniel@php4win.de> |
17 +----------------------------------------------------------------------+
18 */
19
20 #ifndef PHP_SOCKETS_H
21 #define PHP_SOCKETS_H
22
23 #if HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 #if HAVE_SOCKETS
28
29 #include <php.h>
30 #ifdef PHP_WIN32
31 # include "windows_common.h"
32 #else
33 # define IS_INVALID_SOCKET(a) (a->bsd_socket < 0)
34 #endif
35
36 #define PHP_SOCKETS_VERSION PHP_VERSION
37
38 extern zend_module_entry sockets_module_entry;
39 #define phpext_sockets_ptr &sockets_module_entry
40
41 #ifdef PHP_WIN32
42 #include <Winsock2.h>
43 #else
44 #if HAVE_SYS_SOCKET_H
45 #include <sys/socket.h>
46 #endif
47 #endif
48
49 #ifndef PHP_WIN32
50 typedef int PHP_SOCKET;
51 #else
52 typedef SOCKET PHP_SOCKET;
53 #endif
54
55 #ifdef PHP_WIN32
56 # ifdef PHP_SOCKETS_EXPORTS
57 # define PHP_SOCKETS_API __declspec(dllexport)
58 # else
59 # define PHP_SOCKETS_API __declspec(dllimport)
60 # endif
61 #elif defined(__GNUC__) && __GNUC__ >= 4
62 # define PHP_SOCKETS_API __attribute__ ((visibility("default")))
63 #else
64 # define PHP_SOCKETS_API
65 #endif
66
67 /* Socket class */
68
69 typedef struct {
70 PHP_SOCKET bsd_socket;
71 int type;
72 int error;
73 int blocking;
74 zval zstream;
75 zend_object std;
76 } php_socket;
77
78 extern PHP_SOCKETS_API zend_class_entry *socket_ce;
79
socket_from_obj(zend_object * obj)80 static inline php_socket *socket_from_obj(zend_object *obj) {
81 return (php_socket *)((char *)(obj) - XtOffsetOf(php_socket, std));
82 }
83
84 #define Z_SOCKET_P(zv) socket_from_obj(Z_OBJ_P(zv))
85
86 #define ENSURE_SOCKET_VALID(php_sock) do { \
87 if (IS_INVALID_SOCKET(php_sock)) { \
88 zend_argument_error(NULL, 1, "has already been closed"); \
89 RETURN_THROWS(); \
90 } \
91 } while (0)
92
93 #ifdef PHP_WIN32
94 struct sockaddr_un {
95 short sun_family;
96 char sun_path[108];
97 };
98 #endif
99
100 #define PHP_SOCKET_ERROR(socket, msg, errn) \
101 do { \
102 int _err = (errn); /* save value to avoid repeated calls to WSAGetLastError() on Windows */ \
103 (socket)->error = _err; \
104 SOCKETS_G(last_error) = _err; \
105 if (_err != EAGAIN && _err != EWOULDBLOCK && _err != EINPROGRESS) { \
106 php_error_docref(NULL, E_WARNING, "%s [%d]: %s", msg, _err, sockets_strerror(_err)); \
107 } \
108 } while (0)
109
110 ZEND_BEGIN_MODULE_GLOBALS(sockets)
111 int last_error;
112 char *strerror_buf;
113 #ifdef PHP_WIN32
114 uint32_t wsa_child_count;
115 HashTable wsa_info;
116 #endif
117 ZEND_END_MODULE_GLOBALS(sockets)
118
119 PHP_SOCKETS_API ZEND_EXTERN_MODULE_GLOBALS(sockets)
120 #define SOCKETS_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(sockets, v)
121
122 enum sockopt_return {
123 SOCKOPT_ERROR,
124 SOCKOPT_CONTINUE,
125 SOCKOPT_SUCCESS
126 };
127
128 PHP_SOCKETS_API char *sockets_strerror(int error);
129 PHP_SOCKETS_API int socket_import_file_descriptor(PHP_SOCKET socket, php_socket *retsock);
130
131 #else
132 #define phpext_sockets_ptr NULL
133 #endif
134
135 #if defined(_AIX) && !defined(HAVE_SA_SS_FAMILY)
136 # define ss_family __ss_family
137 #endif
138
139 #endif
140