xref: /PHP-8.1/ext/standard/flock_compat.c (revision a3abcc06)
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