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