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