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