1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2018 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 | http://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 | Author: Sascha Schumann <sascha@schumann.cx> |
16 +----------------------------------------------------------------------+
17 */
18
19 #include "php.h"
20 #include <errno.h>
21 #include "ext/standard/flock_compat.h"
22
23 #if HAVE_STRUCT_FLOCK
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <sys/file.h>
27 #endif
28
29 #ifdef PHP_WIN32
30 #include <io.h>
31 #include "config.w32.h"
32 #endif
33
34 #ifndef HAVE_FLOCK
flock(int fd,int operation)35 PHPAPI int flock(int fd, int operation)
36 {
37 return php_flock(fd, operation);
38 }
39 #endif /* !defined(HAVE_FLOCK) */
40
php_flock(int fd,int operation)41 PHPAPI int php_flock(int fd, int operation)
42 #if HAVE_STRUCT_FLOCK /* {{{ */
43 {
44 struct flock flck;
45 int ret;
46
47 flck.l_start = flck.l_len = 0;
48 flck.l_whence = SEEK_SET;
49
50 if (operation & LOCK_SH)
51 flck.l_type = F_RDLCK;
52 else if (operation & LOCK_EX)
53 flck.l_type = F_WRLCK;
54 else if (operation & LOCK_UN)
55 flck.l_type = F_UNLCK;
56 else {
57 errno = EINVAL;
58 return -1;
59 }
60
61 ret = fcntl(fd, operation & LOCK_NB ? F_SETLK : F_SETLKW, &flck);
62
63 if (operation & LOCK_NB && ret == -1 &&
64 (errno == EACCES || errno == EAGAIN))
65 errno = EWOULDBLOCK;
66
67 if (ret != -1) ret = 0;
68
69 return ret;
70 }
71 /* }}} */
72 #elif defined(PHP_WIN32) /* {{{ */
73 /*
74 * Program: Unix compatibility routines
75 *
76 * Author: Mark Crispin
77 * Networks and Distributed Computing
78 * Computing & Communications
79 * University of Washington
80 * Administration Building, AG-44
81 * Seattle, WA 98195
82 * Internet: MRC@CAC.Washington.EDU
83 *
84 * Date: 14 September 1996
85 * Last Edited: 14 August 1997
86 *
87 * Copyright 1997 by the University of Washington
88 *
89 * Permission to use, copy, modify, and distribute this software and its
90 * documentation for any purpose and without fee is hereby granted, provided
91 * that the above copyright notice appears in all copies and that both the
92 * above copyright notice and this permission notice appear in supporting
93 * documentation, and that the name of the University of Washington not be
94 * used in advertising or publicity pertaining to distribution of the software
95 * without specific, written prior permission. This software is made available
96 * "as is", and
97 * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
98 * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
99 * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
100 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
101 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
102 * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
103 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
104 *
105 */
106 /* DEDICATION
107
108 * This file is dedicated to my dog, Unix, also known as Yun-chan and
109 * Unix J. Terwilliker Jehosophat Aloysius Monstrosity Animal Beast. Unix
110 * passed away at the age of 11 1/2 on September 14, 1996, 12:18 PM PDT, after
111 * a two-month bout with cirrhosis of the liver.
112 *
113 * He was a dear friend, and I miss him terribly.
114 *
115 * Lift a leg, Yunie. Luv ya forever!!!!
116 */
117 {
118 HANDLE hdl = (HANDLE) _get_osfhandle(fd);
119 DWORD low = 1, high = 0;
120 OVERLAPPED offset =
121 {0, 0, 0, 0, NULL};
122 DWORD err;
123
124 if (INVALID_HANDLE_VALUE == hdl) {
125 _set_errno(EBADF);
126 return -1; /* error in file descriptor */
127 }
128 /* bug for bug compatible with Unix */
129 UnlockFileEx(hdl, 0, low, high, &offset);
130 switch (operation & ~LOCK_NB) { /* translate to LockFileEx() op */
131 case LOCK_EX: /* exclusive */
132 if (LockFileEx(hdl, LOCKFILE_EXCLUSIVE_LOCK +
133 ((operation & LOCK_NB) ? LOCKFILE_FAIL_IMMEDIATELY : 0),
134 0, low, high, &offset))
135 return 0;
136 break;
137 case LOCK_SH: /* shared */
138 if (LockFileEx(hdl, ((operation & LOCK_NB) ? LOCKFILE_FAIL_IMMEDIATELY : 0),
139 0, low, high, &offset))
140 return 0;
141 break;
142 case LOCK_UN: /* unlock */
143 return 0; /* always succeeds */
144 default: /* default */
145 break;
146 }
147
148 err = GetLastError();
149 if (ERROR_LOCK_VIOLATION == err || ERROR_SHARING_VIOLATION == err) {
150 _set_errno(EWOULDBLOCK);
151 } else {
152 _set_errno(EINVAL); /* bad call */
153 }
154
155 return -1;
156 }
157 /* }}} */
158 #else
159 #warning no proper flock support for your site
160 {
161 errno = 0;
162 return 0;
163 }
164 #endif
165
166 #ifndef PHP_WIN32
167 #if !(HAVE_INET_ATON)
168 /* {{{ inet_aton
169 * Check whether "cp" is a valid ascii representation
170 * of an Internet address and convert to a binary address.
171 * Returns 1 if the address is valid, 0 if not.
172 * This replaces inet_addr, the return value from which
173 * cannot distinguish between failure and a local broadcast address.
174 */
inet_aton(const char * cp,struct in_addr * ap)175 int inet_aton(const char *cp, struct in_addr *ap)
176 {
177 int dots = 0;
178 register unsigned long acc = 0, addr = 0;
179
180 do {
181 register char cc = *cp;
182
183 switch (cc) {
184 case '0':
185 case '1':
186 case '2':
187 case '3':
188 case '4':
189 case '5':
190 case '6':
191 case '7':
192 case '8':
193 case '9':
194 acc = acc * 10 + (cc - '0');
195 break;
196
197 case '.':
198 if (++dots > 3) {
199 return 0;
200 }
201 /* Fall through */
202
203 case '\0':
204 if (acc > 255) {
205 return 0;
206 }
207 addr = addr << 8 | acc;
208 acc = 0;
209 break;
210
211 default:
212 return 0;
213 }
214 } while (*cp++) ;
215
216 /* Normalize the address */
217 if (dots < 3) {
218 addr <<= 8 * (3 - dots) ;
219 }
220
221 /* Store it if requested */
222 if (ap) {
223 ap->s_addr = htonl(addr);
224 }
225
226 return 1;
227 }
228 /* }}} */
229 #endif /* !HAVE_INET_ATON */
230 #endif
231
232 /*
233 * Local variables:
234 * tab-width: 4
235 * c-basic-offset: 4
236 * End:
237 * vim600: sw=4 ts=4 fdm=marker
238 * vim<600: sw=4 ts=4
239 */
240