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