xref: /PHP-5.5/ext/standard/flock_compat.c (revision 6751f8b3)
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
flock(int fd,int operation)41 PHPAPI int flock(int fd, int operation)
42 {
43 	return php_flock(fd, operation);
44 }
45 #endif /* !defined(HAVE_FLOCK) */
46 
php_flock(int fd,int operation)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  */
inet_aton(const char * cp,struct in_addr * ap)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