1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 6 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 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: Kristian Koehntopp <kris@koehntopp.de> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : /* $Id: posix.c 288944 2009-09-29 14:03:49Z rasmus $ */
20 :
21 : #ifdef HAVE_CONFIG_H
22 : #include "config.h"
23 : #endif
24 :
25 : #include "php.h"
26 : #include <unistd.h>
27 : #include "ext/standard/info.h"
28 : #include "ext/standard/php_string.h"
29 : #include "php_posix.h"
30 :
31 :
32 : #if HAVE_POSIX
33 :
34 : #ifdef HAVE_SYS_TIME_H
35 : #include <sys/time.h>
36 : #endif
37 :
38 : #include <sys/resource.h>
39 :
40 : #if defined(_GNU_SOURCE) && !defined(__USE_GNU)
41 : # define __USE_GNU
42 : #endif
43 :
44 : #include <sys/utsname.h>
45 : #include <sys/types.h>
46 : #include <sys/stat.h>
47 : #include <signal.h>
48 : #include <sys/times.h>
49 : #include <errno.h>
50 : #include <grp.h>
51 : #include <pwd.h>
52 : #if HAVE_SYS_MKDEV_H
53 : # include <sys/mkdev.h>
54 : #endif
55 :
56 : ZEND_DECLARE_MODULE_GLOBALS(posix)
57 : static PHP_MINFO_FUNCTION(posix);
58 :
59 : /* {{{ arginfo */
60 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_kill, 0, 0, 2)
61 : ZEND_ARG_INFO(0, pid)
62 : ZEND_ARG_INFO(0, sig)
63 : ZEND_END_ARG_INFO()
64 :
65 : ZEND_BEGIN_ARG_INFO(arginfo_posix_getpid, 0)
66 : ZEND_END_ARG_INFO()
67 :
68 : ZEND_BEGIN_ARG_INFO(arginfo_posix_getppid, 0)
69 : ZEND_END_ARG_INFO()
70 :
71 : ZEND_BEGIN_ARG_INFO(arginfo_posix_getuid, 0)
72 : ZEND_END_ARG_INFO()
73 :
74 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_setuid, 0, 0, 1)
75 : ZEND_ARG_INFO(0, uid)
76 : ZEND_END_ARG_INFO()
77 :
78 : ZEND_BEGIN_ARG_INFO(arginfo_posix_geteuid, 0)
79 : ZEND_END_ARG_INFO()
80 :
81 : #ifdef HAVE_SETEUID
82 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_seteuid, 0, 0, 1)
83 : ZEND_ARG_INFO(0, uid)
84 : ZEND_END_ARG_INFO()
85 : #endif
86 :
87 : ZEND_BEGIN_ARG_INFO(arginfo_posix_getgid, 0)
88 : ZEND_END_ARG_INFO()
89 :
90 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_setgid, 0, 0, 1)
91 : ZEND_ARG_INFO(0, gid)
92 : ZEND_END_ARG_INFO()
93 :
94 : ZEND_BEGIN_ARG_INFO(arginfo_posix_getegid, 0)
95 : ZEND_END_ARG_INFO()
96 :
97 : #ifdef HAVE_SETEGID
98 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_setegid, 0, 0, 1)
99 : ZEND_ARG_INFO(0, gid)
100 : ZEND_END_ARG_INFO()
101 : #endif
102 :
103 : #ifdef HAVE_GETGROUPS
104 : ZEND_BEGIN_ARG_INFO(arginfo_posix_getgroups, 0)
105 : ZEND_END_ARG_INFO()
106 : #endif
107 :
108 : #ifdef HAVE_GETLOGIN
109 : ZEND_BEGIN_ARG_INFO(arginfo_posix_getlogin, 0)
110 : ZEND_END_ARG_INFO()
111 : #endif
112 :
113 : ZEND_BEGIN_ARG_INFO(arginfo_posix_getpgrp, 0)
114 : ZEND_END_ARG_INFO()
115 :
116 : #ifdef HAVE_SETSID
117 : ZEND_BEGIN_ARG_INFO(arginfo_posix_setsid, 0)
118 : ZEND_END_ARG_INFO()
119 : #endif
120 :
121 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_setpgid, 0, 0, 2)
122 : ZEND_ARG_INFO(0, pid)
123 : ZEND_ARG_INFO(0, pgid)
124 : ZEND_END_ARG_INFO()
125 :
126 : #ifdef HAVE_GETPGID
127 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_getpgid, 0, 0, 1)
128 : ZEND_ARG_INFO(0, pid)
129 : ZEND_END_ARG_INFO()
130 : #endif
131 :
132 : #ifdef HAVE_GETSID
133 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_getsid, 0, 0, 1)
134 : ZEND_ARG_INFO(0, pid)
135 : ZEND_END_ARG_INFO()
136 : #endif
137 :
138 : ZEND_BEGIN_ARG_INFO(arginfo_posix_uname, 0)
139 : ZEND_END_ARG_INFO()
140 :
141 : ZEND_BEGIN_ARG_INFO(arginfo_posix_times, 0)
142 : ZEND_END_ARG_INFO()
143 :
144 : #ifdef HAVE_CTERMID
145 : ZEND_BEGIN_ARG_INFO(arginfo_posix_ctermid, 0)
146 : ZEND_END_ARG_INFO()
147 : #endif
148 :
149 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_ttyname, 0, 0, 1)
150 : ZEND_ARG_INFO(0, fd)
151 : ZEND_END_ARG_INFO()
152 :
153 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_isatty, 0, 0, 1)
154 : ZEND_ARG_INFO(0, fd)
155 : ZEND_END_ARG_INFO()
156 :
157 : ZEND_BEGIN_ARG_INFO(arginfo_posix_getcwd, 0)
158 : ZEND_END_ARG_INFO()
159 :
160 : #ifdef HAVE_MKFIFO
161 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_mkfifo, 0, 0, 2)
162 : ZEND_ARG_INFO(0, pathname)
163 : ZEND_ARG_INFO(0, mode)
164 : ZEND_END_ARG_INFO()
165 : #endif
166 :
167 : #ifdef HAVE_MKNOD
168 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_mknod, 0, 0, 2)
169 : ZEND_ARG_INFO(0, pathname)
170 : ZEND_ARG_INFO(0, mode)
171 : ZEND_ARG_INFO(0, major)
172 : ZEND_ARG_INFO(0, minor)
173 : ZEND_END_ARG_INFO()
174 : #endif
175 :
176 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_access, 0, 0, 1)
177 : ZEND_ARG_INFO(0, file)
178 : ZEND_ARG_INFO(0, mode)
179 : ZEND_END_ARG_INFO()
180 :
181 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_getgrnam, 0, 0, 1)
182 : ZEND_ARG_INFO(0, name)
183 : ZEND_END_ARG_INFO()
184 :
185 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_getgrgid, 0, 0, 1)
186 : ZEND_ARG_INFO(0, gid)
187 : ZEND_END_ARG_INFO()
188 :
189 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_getpwnam, 0, 0, 1)
190 : ZEND_ARG_INFO(0, username)
191 : ZEND_END_ARG_INFO()
192 :
193 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_getpwuid, 0, 0, 1)
194 : ZEND_ARG_INFO(0, uid)
195 : ZEND_END_ARG_INFO()
196 :
197 : #ifdef HAVE_GETRLIMIT
198 : ZEND_BEGIN_ARG_INFO(arginfo_posix_getrlimit, 0)
199 : ZEND_END_ARG_INFO()
200 : #endif
201 :
202 : ZEND_BEGIN_ARG_INFO(arginfo_posix_get_last_error, 0)
203 : ZEND_END_ARG_INFO()
204 :
205 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_strerror, 0, 0, 1)
206 : ZEND_ARG_INFO(0, errno)
207 : ZEND_END_ARG_INFO()
208 :
209 : #ifdef HAVE_INITGROUPS
210 : ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_initgroups, 0, 0, 2)
211 : ZEND_ARG_INFO(0, name)
212 : ZEND_ARG_INFO(0, base_group_id)
213 : ZEND_END_ARG_INFO()
214 : #endif
215 : /* }}} */
216 :
217 : /* {{{ posix_functions[]
218 : */
219 : const zend_function_entry posix_functions[] = {
220 : /* POSIX.1, 3.3 */
221 : PHP_FE(posix_kill, arginfo_posix_kill)
222 :
223 : /* POSIX.1, 4.1 */
224 : PHP_FE(posix_getpid, arginfo_posix_getpid)
225 : PHP_FE(posix_getppid, arginfo_posix_getppid)
226 :
227 : /* POSIX.1, 4.2 */
228 : PHP_FE(posix_getuid, arginfo_posix_getuid)
229 : PHP_FE(posix_setuid, arginfo_posix_setuid)
230 : PHP_FE(posix_geteuid, arginfo_posix_geteuid)
231 : #ifdef HAVE_SETEUID
232 : PHP_FE(posix_seteuid, arginfo_posix_seteuid)
233 : #endif
234 : PHP_FE(posix_getgid, arginfo_posix_getgid)
235 : PHP_FE(posix_setgid, arginfo_posix_setgid)
236 : PHP_FE(posix_getegid, arginfo_posix_getegid)
237 : #ifdef HAVE_SETEGID
238 : PHP_FE(posix_setegid, arginfo_posix_setegid)
239 : #endif
240 : #ifdef HAVE_GETGROUPS
241 : PHP_FE(posix_getgroups, arginfo_posix_getgroups)
242 : #endif
243 : #ifdef HAVE_GETLOGIN
244 : PHP_FE(posix_getlogin, arginfo_posix_getlogin)
245 : #endif
246 :
247 : /* POSIX.1, 4.3 */
248 : PHP_FE(posix_getpgrp, arginfo_posix_getpgrp)
249 : #ifdef HAVE_SETSID
250 : PHP_FE(posix_setsid, arginfo_posix_setsid)
251 : #endif
252 : PHP_FE(posix_setpgid, arginfo_posix_setpgid)
253 : /* Non-Posix functions which are common */
254 : #ifdef HAVE_GETPGID
255 : PHP_FE(posix_getpgid, arginfo_posix_getpgid)
256 : #endif /* HAVE_GETPGID */
257 : #ifdef HAVE_GETSID
258 : PHP_FE(posix_getsid, arginfo_posix_getsid)
259 : #endif /* HAVE_GETSID */
260 :
261 : /* POSIX.1, 4.4 */
262 : PHP_FE(posix_uname, arginfo_posix_uname)
263 :
264 : /* POSIX.1, 4.5 */
265 : PHP_FE(posix_times, arginfo_posix_times)
266 :
267 : /* POSIX.1, 4.7 */
268 : #ifdef HAVE_CTERMID
269 : PHP_FE(posix_ctermid, arginfo_posix_ctermid)
270 : #endif
271 : PHP_FE(posix_ttyname, arginfo_posix_ttyname)
272 : PHP_FE(posix_isatty, arginfo_posix_isatty)
273 :
274 : /* POSIX.1, 5.2 */
275 : PHP_FE(posix_getcwd, arginfo_posix_getcwd)
276 :
277 : /* POSIX.1, 5.4 */
278 : #ifdef HAVE_MKFIFO
279 : PHP_FE(posix_mkfifo, arginfo_posix_mkfifo)
280 : #endif
281 : #ifdef HAVE_MKNOD
282 : PHP_FE(posix_mknod, arginfo_posix_mknod)
283 : #endif
284 :
285 : /* POSIX.1, 5.6 */
286 : PHP_FE(posix_access, arginfo_posix_access)
287 : /* POSIX.1, 9.2 */
288 : PHP_FE(posix_getgrnam, arginfo_posix_getgrnam)
289 : PHP_FE(posix_getgrgid, arginfo_posix_getgrgid)
290 : PHP_FE(posix_getpwnam, arginfo_posix_getpwnam)
291 : PHP_FE(posix_getpwuid, arginfo_posix_getpwuid)
292 :
293 : #ifdef HAVE_GETRLIMIT
294 : PHP_FE(posix_getrlimit, arginfo_posix_getrlimit)
295 : #endif
296 :
297 : PHP_FE(posix_get_last_error, arginfo_posix_get_last_error)
298 : PHP_FALIAS(posix_errno, posix_get_last_error, NULL)
299 : PHP_FE(posix_strerror, arginfo_posix_strerror)
300 : #ifdef HAVE_INITGROUPS
301 : PHP_FE(posix_initgroups, arginfo_posix_initgroups)
302 : #endif
303 :
304 : {NULL, NULL, NULL}
305 : };
306 : /* }}} */
307 :
308 : /* {{{ PHP_MINFO_FUNCTION
309 : */
310 : static PHP_MINFO_FUNCTION(posix)
311 43 : {
312 43 : php_info_print_table_start();
313 43 : php_info_print_table_row(2, "Revision", "$Revision: 288944 $");
314 43 : php_info_print_table_end();
315 43 : }
316 : /* }}} */
317 :
318 : static PHP_GINIT_FUNCTION(posix) /* {{{ */
319 17007 : {
320 17007 : posix_globals->last_error = 0;
321 17007 : }
322 : /* }}} */
323 :
324 : /* {{{ PHP_MINIT_FUNCTION(posix)
325 : */
326 : static PHP_MINIT_FUNCTION(posix)
327 17007 : {
328 17007 : REGISTER_LONG_CONSTANT("POSIX_F_OK", F_OK, CONST_CS | CONST_PERSISTENT);
329 17007 : REGISTER_LONG_CONSTANT("POSIX_X_OK", X_OK, CONST_CS | CONST_PERSISTENT);
330 17007 : REGISTER_LONG_CONSTANT("POSIX_W_OK", W_OK, CONST_CS | CONST_PERSISTENT);
331 17007 : REGISTER_LONG_CONSTANT("POSIX_R_OK", R_OK, CONST_CS | CONST_PERSISTENT);
332 : #ifdef S_IFREG
333 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IFREG", S_IFREG, CONST_CS | CONST_PERSISTENT);
334 : #endif
335 : #ifdef S_IFDIR
336 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IFDIR", S_IFDIR, CONST_CS | CONST_PERSISTENT);
337 : #endif
338 : #ifdef S_IFLNK
339 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IFLNK", S_IFLNK, CONST_CS | CONST_PERSISTENT);
340 : #endif
341 : #ifdef S_IFCHR
342 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IFCHR", S_IFCHR, CONST_CS | CONST_PERSISTENT);
343 : #endif
344 : #ifdef S_IFBLK
345 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IFBLK", S_IFBLK, CONST_CS | CONST_PERSISTENT);
346 : #endif
347 : #ifdef S_IFIFO
348 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IFIFO", S_IFIFO, CONST_CS | CONST_PERSISTENT);
349 : #endif
350 : #ifdef S_IFSOCK
351 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IFSOCK", S_IFSOCK, CONST_CS | CONST_PERSISTENT);
352 : #endif
353 : #ifdef S_IFWHT
354 : REGISTER_LONG_CONSTANT("POSIX_S_IFWHT", S_IFWHT, CONST_CS | CONST_PERSISTENT);
355 : #endif
356 : #ifdef S_IRWXU
357 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IRWXU", S_IRWXU, CONST_CS | CONST_PERSISTENT);
358 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IRUSR", S_IRUSR, CONST_CS | CONST_PERSISTENT);
359 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IWUSR", S_IWUSR, CONST_CS | CONST_PERSISTENT);
360 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IXUSR", S_IXUSR, CONST_CS | CONST_PERSISTENT);
361 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IRWXG", S_IRWXG, CONST_CS | CONST_PERSISTENT);
362 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IRGRP", S_IRGRP, CONST_CS | CONST_PERSISTENT);
363 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IWGRP", S_IWGRP, CONST_CS | CONST_PERSISTENT);
364 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IXGRP", S_IXGRP, CONST_CS | CONST_PERSISTENT);
365 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IRWXO", S_IRWXO, CONST_CS | CONST_PERSISTENT);
366 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IROTH", S_IROTH, CONST_CS | CONST_PERSISTENT);
367 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IWOTH", S_IWOTH, CONST_CS | CONST_PERSISTENT);
368 17007 : REGISTER_LONG_CONSTANT("POSIX_S_IXOTH", S_IXOTH, CONST_CS | CONST_PERSISTENT);
369 : #endif
370 : #ifdef S_ISUID
371 17007 : REGISTER_LONG_CONSTANT("POSIX_S_ISUID", S_ISUID, CONST_CS | CONST_PERSISTENT);
372 : #endif
373 : #ifdef S_ISGID
374 17007 : REGISTER_LONG_CONSTANT("POSIX_S_ISGID", S_ISGID, CONST_CS | CONST_PERSISTENT);
375 : #endif
376 : #ifdef S_ISVTX
377 17007 : REGISTER_LONG_CONSTANT("POSIX_S_ISVTX", S_ISVTX, CONST_CS | CONST_PERSISTENT);
378 : #endif
379 : #ifdef S_ISTXT
380 : REGISTER_LONG_CONSTANT("POSIX_S_ISTXT", S_ISTXT, CONST_CS | CONST_PERSISTENT);
381 : #endif
382 17007 : return SUCCESS;
383 : }
384 : /* }}} */
385 :
386 : /* {{{ posix_module_entry
387 : */
388 : zend_module_entry posix_module_entry = {
389 : STANDARD_MODULE_HEADER,
390 : "posix",
391 : posix_functions,
392 : PHP_MINIT(posix),
393 : NULL,
394 : NULL,
395 : NULL,
396 : PHP_MINFO(posix),
397 : NO_VERSION_YET,
398 : PHP_MODULE_GLOBALS(posix),
399 : PHP_GINIT(posix),
400 : NULL,
401 : NULL,
402 : STANDARD_MODULE_PROPERTIES_EX
403 : };
404 : /* }}} */
405 :
406 : #ifdef COMPILE_DL_POSIX
407 : ZEND_GET_MODULE(posix)
408 : #endif
409 :
410 : #define PHP_POSIX_NO_ARGS if (zend_parse_parameters_none() == FAILURE) return;
411 :
412 : #define PHP_POSIX_RETURN_LONG_FUNC(func_name) \
413 : PHP_POSIX_NO_ARGS \
414 : RETURN_LONG(func_name());
415 :
416 : #define PHP_POSIX_SINGLE_ARG_FUNC(func_name) \
417 : long val; \
418 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &val) == FAILURE) RETURN_FALSE; \
419 : if (func_name(val) < 0) { \
420 : POSIX_G(last_error) = errno; \
421 : RETURN_FALSE; \
422 : } \
423 : RETURN_TRUE;
424 :
425 : /* {{{ proto bool posix_kill(int pid, int sig) U
426 : Send a signal to a process (POSIX.1, 3.3.2) */
427 :
428 : PHP_FUNCTION(posix_kill)
429 74 : {
430 : long pid, sig;
431 :
432 74 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &pid, &sig) == FAILURE) {
433 20 : RETURN_FALSE;
434 : }
435 :
436 54 : if (kill(pid, sig) < 0) {
437 30 : POSIX_G(last_error) = errno;
438 30 : RETURN_FALSE;
439 : }
440 :
441 24 : RETURN_TRUE;
442 : }
443 : /* }}} */
444 :
445 : /* {{{ proto int posix_getpid(void) U
446 : Get the current process id (POSIX.1, 4.1.1) */
447 : PHP_FUNCTION(posix_getpid)
448 16 : {
449 16 : PHP_POSIX_RETURN_LONG_FUNC(getpid);
450 : }
451 : /* }}} */
452 :
453 : /* {{{ proto int posix_getppid(void) U
454 : Get the parent process id (POSIX.1, 4.1.1) */
455 : PHP_FUNCTION(posix_getppid)
456 3 : {
457 3 : PHP_POSIX_RETURN_LONG_FUNC(getppid);
458 : }
459 : /* }}} */
460 :
461 : /* {{{ proto int posix_getuid(void) U
462 : Get the current user id (POSIX.1, 4.2.1) */
463 : PHP_FUNCTION(posix_getuid)
464 9 : {
465 9 : PHP_POSIX_RETURN_LONG_FUNC(getuid);
466 : }
467 : /* }}} */
468 :
469 : /* {{{ proto int posix_getgid(void) U
470 : Get the current group id (POSIX.1, 4.2.1) */
471 : PHP_FUNCTION(posix_getgid)
472 5 : {
473 5 : PHP_POSIX_RETURN_LONG_FUNC(getgid);
474 : }
475 : /* }}} */
476 :
477 : /* {{{ proto int posix_geteuid(void) U
478 : Get the current effective user id (POSIX.1, 4.2.1) */
479 : PHP_FUNCTION(posix_geteuid)
480 9 : {
481 9 : PHP_POSIX_RETURN_LONG_FUNC(geteuid);
482 : }
483 : /* }}} */
484 :
485 : /* {{{ proto int posix_getegid(void) U
486 : Get the current effective group id (POSIX.1, 4.2.1) */
487 : PHP_FUNCTION(posix_getegid)
488 0 : {
489 0 : PHP_POSIX_RETURN_LONG_FUNC(getegid);
490 : }
491 : /* }}} */
492 :
493 : /* {{{ proto bool posix_setuid(int uid) U
494 : Set user id (POSIX.1, 4.2.2) */
495 : PHP_FUNCTION(posix_setuid)
496 32 : {
497 32 : PHP_POSIX_SINGLE_ARG_FUNC(setuid);
498 : }
499 : /* }}} */
500 :
501 : /* {{{ proto bool posix_setgid(int uid) U
502 : Set group id (POSIX.1, 4.2.2) */
503 : PHP_FUNCTION(posix_setgid)
504 31 : {
505 31 : PHP_POSIX_SINGLE_ARG_FUNC(setgid);
506 : }
507 : /* }}} */
508 :
509 : /* {{{ proto bool posix_seteuid(int uid) U
510 : Set effective user id */
511 : #ifdef HAVE_SETEUID
512 : PHP_FUNCTION(posix_seteuid)
513 31 : {
514 31 : PHP_POSIX_SINGLE_ARG_FUNC(seteuid);
515 : }
516 : #endif
517 : /* }}} */
518 :
519 : /* {{{ proto bool posix_setegid(int uid) U
520 : Set effective group id */
521 : #ifdef HAVE_SETEGID
522 : PHP_FUNCTION(posix_setegid)
523 0 : {
524 0 : PHP_POSIX_SINGLE_ARG_FUNC(setegid);
525 : }
526 : #endif
527 : /* }}} */
528 :
529 : /* {{{ proto array posix_getgroups(void) U
530 : Get supplementary group id's (POSIX.1, 4.2.3) */
531 : #ifdef HAVE_GETGROUPS
532 : PHP_FUNCTION(posix_getgroups)
533 1 : {
534 : gid_t gidlist[NGROUPS_MAX];
535 : int result;
536 : int i;
537 :
538 1 : PHP_POSIX_NO_ARGS;
539 :
540 1 : if ((result = getgroups(NGROUPS_MAX, gidlist)) < 0) {
541 0 : POSIX_G(last_error) = errno;
542 0 : RETURN_FALSE;
543 : }
544 :
545 1 : array_init(return_value);
546 :
547 3 : for (i=0; i<result; i++) {
548 2 : add_next_index_long(return_value, gidlist[i]);
549 : }
550 : }
551 : #endif
552 : /* }}} */
553 :
554 : /* {{{ proto string posix_getlogin(void)
555 : Get user name (POSIX.1, 4.2.4) */
556 : #ifdef HAVE_GETLOGIN
557 : PHP_FUNCTION(posix_getlogin)
558 0 : {
559 : char *p;
560 :
561 0 : PHP_POSIX_NO_ARGS;
562 :
563 0 : if (NULL == (p = getlogin())) {
564 0 : POSIX_G(last_error) = errno;
565 0 : RETURN_FALSE;
566 : }
567 :
568 0 : RETURN_STRING(p, 1);
569 : }
570 : #endif
571 : /* }}} */
572 :
573 : /* {{{ proto int posix_getpgrp(void) U
574 : Get current process group id (POSIX.1, 4.3.1) */
575 : PHP_FUNCTION(posix_getpgrp)
576 2 : {
577 2 : PHP_POSIX_RETURN_LONG_FUNC(getpgrp);
578 : }
579 : /* }}} */
580 :
581 : /* {{{ proto int posix_setsid(void) U
582 : Create session and set process group id (POSIX.1, 4.3.2) */
583 : #ifdef HAVE_SETSID
584 : PHP_FUNCTION(posix_setsid)
585 0 : {
586 0 : PHP_POSIX_RETURN_LONG_FUNC(setsid);
587 : }
588 : #endif
589 : /* }}} */
590 :
591 : /* {{{ proto bool posix_setpgid(int pid, int pgid) U
592 : Set process group id for job control (POSIX.1, 4.3.3) */
593 : PHP_FUNCTION(posix_setpgid)
594 0 : {
595 : long pid, pgid;
596 :
597 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &pid, &pgid) == FAILURE) {
598 0 : RETURN_FALSE;
599 : }
600 :
601 0 : if (setpgid(pid, pgid) < 0) {
602 0 : POSIX_G(last_error) = errno;
603 0 : RETURN_FALSE;
604 : }
605 :
606 0 : RETURN_TRUE;
607 : }
608 : /* }}} */
609 :
610 : /* {{{ proto int posix_getpgid(void) U
611 : Get the process group id of the specified process (This is not a POSIX function, but a SVR4ism, so we compile conditionally) */
612 : #ifdef HAVE_GETPGID
613 : PHP_FUNCTION(posix_getpgid)
614 26 : {
615 : long val;
616 26 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &val) == FAILURE) {
617 11 : RETURN_FALSE;
618 : }
619 :
620 15 : if ((val = getpgid(val)) < 0) {
621 3 : POSIX_G(last_error) = errno;
622 3 : RETURN_FALSE;
623 : }
624 12 : RETURN_LONG(val);
625 : }
626 : #endif
627 : /* }}} */
628 :
629 : /* {{{ proto int posix_getsid(void) U
630 : Get process group id of session leader (This is not a POSIX function, but a SVR4ism, so be compile conditionally) */
631 : #ifdef HAVE_GETSID
632 : PHP_FUNCTION(posix_getsid)
633 5 : {
634 : long val;
635 5 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &val) == FAILURE) {
636 2 : RETURN_FALSE;
637 : }
638 :
639 3 : if ((val = getsid(val)) < 0) {
640 1 : POSIX_G(last_error) = errno;
641 1 : RETURN_FALSE;
642 : }
643 2 : RETURN_LONG(val);
644 : }
645 : #endif
646 : /* }}} */
647 :
648 : /* {{{ proto array posix_uname(void)
649 : Get system name (POSIX.1, 4.4.1) */
650 : PHP_FUNCTION(posix_uname)
651 3 : {
652 : struct utsname u;
653 :
654 3 : PHP_POSIX_NO_ARGS;
655 :
656 2 : if (uname(&u) < 0) {
657 0 : POSIX_G(last_error) = errno;
658 0 : RETURN_FALSE;
659 : }
660 :
661 2 : array_init(return_value);
662 :
663 2 : add_ascii_assoc_string(return_value, "sysname", u.sysname, 1);
664 2 : add_ascii_assoc_string(return_value, "nodename", u.nodename, 1);
665 2 : add_ascii_assoc_string(return_value, "release", u.release, 1);
666 2 : add_ascii_assoc_string(return_value, "version", u.version, 1);
667 2 : add_ascii_assoc_string(return_value, "machine", u.machine, 1);
668 : #if defined(_GNU_SOURCE) && !defined(DARWIN) && defined(HAVE_UTSNAME_DOMAINNAME)
669 : add_ascii_assoc_string(return_value, "domainname", u.domainname, 1);
670 : #endif
671 : }
672 : /* }}} */
673 :
674 : /* POSIX.1, 4.5.1 time() - Get System Time
675 : already covered by PHP
676 : */
677 :
678 : /* {{{ proto array posix_times(void)
679 : Get process times (POSIX.1, 4.5.2) */
680 : PHP_FUNCTION(posix_times)
681 3 : {
682 : struct tms t;
683 : clock_t ticks;
684 :
685 3 : PHP_POSIX_NO_ARGS;
686 :
687 2 : if ((ticks = times(&t)) == -1) {
688 0 : POSIX_G(last_error) = errno;
689 0 : RETURN_FALSE;
690 : }
691 :
692 2 : array_init(return_value);
693 :
694 2 : add_ascii_assoc_long(return_value, "ticks", ticks); /* clock ticks */
695 2 : add_ascii_assoc_long(return_value, "utime", t.tms_utime); /* user time */
696 2 : add_ascii_assoc_long(return_value, "stime", t.tms_stime); /* system time */
697 2 : add_ascii_assoc_long(return_value, "cutime", t.tms_cutime); /* user time of children */
698 2 : add_ascii_assoc_long(return_value, "cstime", t.tms_cstime); /* system time of children */
699 : }
700 : /* }}} */
701 :
702 : /* POSIX.1, 4.6.1 getenv() - Environment Access
703 : already covered by PHP
704 : */
705 :
706 : /* {{{ proto string posix_ctermid(void)
707 : Generate terminal path name (POSIX.1, 4.7.1) */
708 : #ifdef HAVE_CTERMID
709 : PHP_FUNCTION(posix_ctermid)
710 3 : {
711 : char buffer[L_ctermid];
712 :
713 3 : PHP_POSIX_NO_ARGS;
714 :
715 2 : if (NULL == ctermid(buffer)) {
716 : /* Found no documentation how the defined behaviour is when this
717 : * function fails
718 : */
719 0 : POSIX_G(last_error) = errno;
720 0 : RETURN_FALSE;
721 : }
722 :
723 2 : RETURN_STRING(buffer, 1);
724 : }
725 : #endif
726 : /* }}} */
727 :
728 : /* Checks if the provides resource is a stream and if it provides a file descriptor */
729 : static int php_posix_stream_get_fd(zval *zfp, int *fd TSRMLS_DC) /* {{{ */
730 4 : {
731 : php_stream *stream;
732 :
733 4 : php_stream_from_zval_no_verify(stream, &zfp);
734 :
735 4 : if (stream == NULL) {
736 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "expects argument 1 to be a valid stream resource");
737 1 : return 0;
738 : }
739 3 : if (php_stream_can_cast(stream, PHP_STREAM_AS_FD) == SUCCESS) {
740 3 : php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)fd, 0);
741 : } else {
742 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not use stream of type '%s'",
743 : stream->ops->label);
744 0 : return 0;
745 : }
746 3 : return 1;
747 : }
748 : /* }}} */
749 :
750 : /* {{{ proto string posix_ttyname(int fd)
751 : Determine terminal device name (POSIX.1, 4.7.2) */
752 : PHP_FUNCTION(posix_ttyname)
753 35 : {
754 : zval **z_fd;
755 : char *p;
756 : int fd;
757 : #if defined(ZTS) && defined(HAVE_TTYNAME_R) && defined(_SC_TTY_NAME_MAX)
758 : long buflen;
759 : #endif
760 :
761 35 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &z_fd) == FAILURE) {
762 3 : RETURN_FALSE;
763 : }
764 :
765 32 : switch (Z_TYPE_PP(z_fd)) {
766 : case IS_RESOURCE:
767 4 : if (!php_posix_stream_get_fd(*z_fd, &fd TSRMLS_CC)) {
768 1 : RETURN_FALSE;
769 : }
770 3 : break;
771 : default:
772 28 : convert_to_long_ex(z_fd);
773 28 : fd = Z_LVAL_PP(z_fd);
774 : }
775 : #if defined(ZTS) && defined(HAVE_TTYNAME_R) && defined(_SC_TTY_NAME_MAX)
776 : buflen = sysconf(_SC_TTY_NAME_MAX);
777 : if (buflen < 1) {
778 : RETURN_FALSE;
779 : }
780 : p = emalloc(buflen);
781 :
782 : if (ttyname_r(fd, p, buflen)) {
783 : POSIX_G(last_error) = errno;
784 : efree(p);
785 : RETURN_FALSE;
786 : }
787 : RETURN_STRING(p, 0);
788 : #else
789 31 : if (NULL == (p = ttyname(fd))) {
790 31 : POSIX_G(last_error) = errno;
791 31 : RETURN_FALSE;
792 : }
793 : #endif
794 0 : RETURN_STRING(p, 1);
795 : }
796 : /* }}} */
797 :
798 : /* {{{ proto bool posix_isatty(int fd) U
799 : Determine if filedesc is a tty (POSIX.1, 4.7.1) */
800 : PHP_FUNCTION(posix_isatty)
801 1 : {
802 : zval **z_fd;
803 : int fd;
804 :
805 1 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &z_fd) == FAILURE) {
806 0 : RETURN_FALSE;
807 : }
808 :
809 1 : switch (Z_TYPE_PP(z_fd)) {
810 : case IS_RESOURCE:
811 0 : if (!php_posix_stream_get_fd(*z_fd, &fd TSRMLS_CC)) {
812 0 : RETURN_FALSE;
813 : }
814 0 : break;
815 : default:
816 1 : convert_to_long_ex(z_fd);
817 1 : fd = Z_LVAL_PP(z_fd);
818 : }
819 :
820 1 : if (isatty(fd)) {
821 0 : RETURN_TRUE;
822 : } else {
823 1 : RETURN_FALSE;
824 : }
825 : }
826 : /* }}} */
827 :
828 : /*
829 : POSIX.1, 4.8.1 sysconf() - TODO
830 : POSIX.1, 5.7.1 pathconf(), fpathconf() - TODO
831 :
832 : POSIX.1, 5.1.2 opendir(), readdir(), rewinddir(), closedir()
833 : POSIX.1, 5.2.1 chdir()
834 : already supported by PHP
835 : */
836 :
837 : /* {{{ proto string posix_getcwd(void)
838 : Get working directory pathname (POSIX.1, 5.2.2) */
839 : PHP_FUNCTION(posix_getcwd)
840 4 : {
841 : char buffer[MAXPATHLEN];
842 : char *p;
843 :
844 4 : PHP_POSIX_NO_ARGS;
845 :
846 2 : p = VCWD_GETCWD(buffer, MAXPATHLEN);
847 2 : if (!p) {
848 0 : POSIX_G(last_error) = errno;
849 0 : RETURN_FALSE;
850 : }
851 :
852 2 : RETURN_STRING(buffer, 1);
853 : }
854 : /* }}} */
855 :
856 : /*
857 : POSIX.1, 5.3.x open(), creat(), umask()
858 : POSIX.1, 5.4.1 link()
859 : already supported by PHP.
860 : */
861 :
862 : /* {{{ proto bool posix_mkfifo(string pathname, int mode)
863 : Make a FIFO special file (POSIX.1, 5.4.2) */
864 : #ifdef HAVE_MKFIFO
865 : PHP_FUNCTION(posix_mkfifo)
866 3 : {
867 : char *path;
868 : int path_len;
869 : long mode;
870 : int result;
871 :
872 3 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &path, &path_len, &mode) == FAILURE) {
873 1 : RETURN_FALSE;
874 : }
875 :
876 2 : if (php_check_open_basedir_ex(path, 0 TSRMLS_CC)) {
877 0 : RETURN_FALSE;
878 : }
879 :
880 2 : result = mkfifo(path, mode);
881 2 : if (result < 0) {
882 1 : POSIX_G(last_error) = errno;
883 1 : RETURN_FALSE;
884 : }
885 :
886 1 : RETURN_TRUE;
887 : }
888 : #endif
889 : /* }}} */
890 :
891 : /* {{{ proto bool posix_mknod(string pathname, int mode [, int major [, int minor]])
892 : Make a special or ordinary file (POSIX.1) */
893 : #ifdef HAVE_MKNOD
894 : PHP_FUNCTION(posix_mknod)
895 2 : {
896 : char *path;
897 : int path_len;
898 : long mode;
899 2 : long major = 0, minor = 0;
900 : int result;
901 : dev_t php_dev;
902 :
903 2 : php_dev = 0;
904 :
905 2 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|ll", &path, &path_len,
906 : &mode, &major, &minor) == FAILURE) {
907 0 : RETURN_FALSE;
908 : }
909 :
910 2 : if (php_check_open_basedir_ex(path, 0 TSRMLS_CC)) {
911 0 : RETURN_FALSE;
912 : }
913 :
914 2 : if ((mode & S_IFCHR) || (mode & S_IFBLK)) {
915 0 : if (ZEND_NUM_ARGS() == 2) {
916 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "For S_IFCHR and S_IFBLK you need to pass a major device kernel identifier");
917 0 : RETURN_FALSE;
918 : }
919 0 : if (major == 0) {
920 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING,
921 : "Expects argument 3 to be non-zero for POSIX_S_IFCHR and POSIX_S_IFBLK");
922 0 : RETURN_FALSE;
923 : } else {
924 : #if defined(HAVE_MAKEDEV) || defined(makedev)
925 0 : php_dev = makedev(major, minor);
926 : #else
927 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create a block or character device, creating a normal file instead");
928 : #endif
929 : }
930 : }
931 :
932 2 : result = mknod(path, mode, php_dev);
933 2 : if (result < 0) {
934 2 : POSIX_G(last_error) = errno;
935 2 : RETURN_FALSE;
936 : }
937 :
938 0 : RETURN_TRUE;
939 : }
940 : #endif
941 : /* }}} */
942 :
943 : /* Takes a pointer to posix group and a pointer to an already initialized ZVAL
944 : * array container and fills the array with the posix group member data. */
945 :
946 : int php_posix_group_to_array(struct group *g, zval *array_group) /* {{{ */
947 13 : {
948 : zval *array_members;
949 : int count;
950 :
951 13 : if (NULL == g)
952 0 : return 0;
953 :
954 13 : if (array_group == NULL || Z_TYPE_P(array_group) != IS_ARRAY)
955 0 : return 0;
956 :
957 13 : MAKE_STD_ZVAL(array_members);
958 13 : array_init(array_members);
959 :
960 13 : add_ascii_assoc_string(array_group, "name", g->gr_name, 1);
961 13 : add_ascii_assoc_string(array_group, "passwd", g->gr_passwd, 1);
962 30 : for (count=0; g->gr_mem[count] != NULL; count++) {
963 17 : add_next_index_string(array_members, g->gr_mem[count], 1);
964 : }
965 13 : zend_ascii_hash_update(Z_ARRVAL_P(array_group), "members", sizeof("members"), (void*)&array_members, sizeof(zval*), NULL);
966 13 : add_ascii_assoc_long(array_group, "gid", g->gr_gid);
967 13 : return 1;
968 : }
969 : /* }}} */
970 :
971 : /*
972 : POSIX.1, 5.5.1 unlink()
973 : POSIX.1, 5.5.2 rmdir()
974 : POSIX.1, 5.5.3 rename()
975 : POSIX.1, 5.6.x stat(), chmod(), utime() already supported by PHP.
976 : */
977 :
978 : /* {{{ proto bool posix_access(string file [, int mode])
979 : Determine accessibility of a file (POSIX.1 5.6.3) */
980 : PHP_FUNCTION(posix_access)
981 14 : {
982 14 : long mode = 0;
983 : int filename_len, ret;
984 : char *filename, *path;
985 :
986 14 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &filename, &filename_len, &mode) == FAILURE) {
987 3 : RETURN_FALSE;
988 : }
989 :
990 11 : path = expand_filepath(filename, NULL TSRMLS_CC);
991 11 : if (!path) {
992 2 : POSIX_G(last_error) = EIO;
993 2 : RETURN_FALSE;
994 : }
995 :
996 9 : if (php_check_open_basedir_ex(path, 0 TSRMLS_CC)) {
997 0 : efree(path);
998 0 : POSIX_G(last_error) = EPERM;
999 0 : RETURN_FALSE;
1000 : }
1001 :
1002 9 : ret = access(path, mode);
1003 9 : efree(path);
1004 :
1005 9 : if (ret) {
1006 5 : POSIX_G(last_error) = errno;
1007 5 : RETURN_FALSE;
1008 : }
1009 :
1010 4 : RETURN_TRUE;
1011 : }
1012 : /* }}} */
1013 :
1014 : /*
1015 : POSIX.1, 6.x most I/O functions already supported by PHP.
1016 : POSIX.1, 7.x tty functions, TODO
1017 : POSIX.1, 8.x interactions with other C language functions
1018 : POSIX.1, 9.x system database access
1019 : */
1020 :
1021 : /* {{{ proto array posix_getgrnam(string groupname)
1022 : Group database access (POSIX.1, 9.2.1) */
1023 : PHP_FUNCTION(posix_getgrnam)
1024 6 : {
1025 : char *name;
1026 : struct group *g;
1027 : int name_len;
1028 : #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
1029 : struct group gbuf;
1030 : long buflen;
1031 : char *buf;
1032 : #endif
1033 :
1034 6 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
1035 0 : RETURN_FALSE;
1036 : }
1037 :
1038 : #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
1039 : buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
1040 : if (buflen < 1) {
1041 : RETURN_FALSE;
1042 : }
1043 : buf = emalloc(buflen);
1044 : g = &gbuf;
1045 :
1046 : if (getgrnam_r(name, g, buf, buflen, &g) || g == NULL) {
1047 : POSIX_G(last_error) = errno;
1048 : efree(buf);
1049 : RETURN_FALSE;
1050 : }
1051 : #else
1052 6 : if (NULL == (g = getgrnam(name))) {
1053 6 : POSIX_G(last_error) = errno;
1054 6 : RETURN_FALSE;
1055 : }
1056 : #endif
1057 0 : array_init(return_value);
1058 :
1059 0 : if (!php_posix_group_to_array(g, return_value)) {
1060 0 : zval_dtor(return_value);
1061 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix group to array");
1062 0 : RETVAL_FALSE;
1063 : }
1064 : #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
1065 : efree(buf);
1066 : #endif
1067 : }
1068 : /* }}} */
1069 :
1070 : /* {{{ proto array posix_getgrgid(long gid)
1071 : Group database access (POSIX.1, 9.2.1) */
1072 : PHP_FUNCTION(posix_getgrgid)
1073 30 : {
1074 : long gid;
1075 : #if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
1076 : int ret;
1077 : struct group _g;
1078 : struct group *retgrptr = NULL;
1079 : long grbuflen;
1080 : char *grbuf;
1081 : #endif
1082 : struct group *g;
1083 :
1084 30 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &gid) == FAILURE) {
1085 12 : RETURN_FALSE;
1086 : }
1087 : #if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
1088 :
1089 : grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
1090 : if (grbuflen < 1) {
1091 : RETURN_FALSE;
1092 : }
1093 :
1094 : grbuf = emalloc(grbuflen);
1095 :
1096 : ret = getgrgid_r(gid, &_g, grbuf, grbuflen, &retgrptr);
1097 : if (ret || retgrptr == NULL) {
1098 : POSIX_G(last_error) = ret;
1099 : efree(grbuf);
1100 : RETURN_FALSE;
1101 : }
1102 : g = &_g;
1103 : #else
1104 18 : if (NULL == (g = getgrgid(gid))) {
1105 5 : POSIX_G(last_error) = errno;
1106 5 : RETURN_FALSE;
1107 : }
1108 : #endif
1109 13 : array_init(return_value);
1110 :
1111 13 : if (!php_posix_group_to_array(g, return_value)) {
1112 0 : zval_dtor(return_value);
1113 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix group struct to array");
1114 0 : RETVAL_FALSE;
1115 : }
1116 : #if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
1117 : efree(grbuf);
1118 : #endif
1119 : }
1120 : /* }}} */
1121 :
1122 : int php_posix_passwd_to_array(struct passwd *pw, zval *return_value) /* {{{ */
1123 12 : {
1124 12 : if (NULL == pw)
1125 0 : return 0;
1126 12 : if (NULL == return_value || Z_TYPE_P(return_value) != IS_ARRAY)
1127 0 : return 0;
1128 :
1129 12 : add_ascii_assoc_string(return_value, "name", pw->pw_name, 1);
1130 12 : add_ascii_assoc_string(return_value, "passwd", pw->pw_passwd, 1);
1131 12 : add_ascii_assoc_long (return_value, "uid", pw->pw_uid);
1132 12 : add_ascii_assoc_long (return_value, "gid", pw->pw_gid);
1133 12 : add_ascii_assoc_string(return_value, "gecos", pw->pw_gecos, 1);
1134 12 : add_ascii_assoc_string(return_value, "dir", pw->pw_dir, 1);
1135 12 : add_ascii_assoc_string(return_value, "shell", pw->pw_shell, 1);
1136 12 : return 1;
1137 : }
1138 : /* }}} */
1139 :
1140 : /* {{{ proto array posix_getpwnam(string groupname)
1141 : User database access (POSIX.1, 9.2.2) */
1142 : PHP_FUNCTION(posix_getpwnam)
1143 6 : {
1144 : struct passwd *pw;
1145 : char *name;
1146 : int name_len;
1147 : #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
1148 : struct passwd pwbuf;
1149 : long buflen;
1150 : char *buf;
1151 : #endif
1152 :
1153 6 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
1154 0 : RETURN_FALSE;
1155 : }
1156 :
1157 : #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
1158 : buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
1159 : if (buflen < 1) {
1160 : RETURN_FALSE;
1161 : }
1162 : buf = emalloc(buflen);
1163 : pw = &pwbuf;
1164 :
1165 : if (getpwnam_r(name, pw, buf, buflen, &pw) || pw == NULL) {
1166 : efree(buf);
1167 : POSIX_G(last_error) = errno;
1168 : RETURN_FALSE;
1169 : }
1170 : #else
1171 6 : if (NULL == (pw = getpwnam(name))) {
1172 6 : POSIX_G(last_error) = errno;
1173 6 : RETURN_FALSE;
1174 : }
1175 : #endif
1176 0 : array_init(return_value);
1177 :
1178 0 : if (!php_posix_passwd_to_array(pw, return_value)) {
1179 0 : zval_dtor(return_value);
1180 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix passwd struct to array");
1181 0 : RETVAL_FALSE;
1182 : }
1183 : #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
1184 : efree(buf);
1185 : #endif
1186 : }
1187 : /* }}} */
1188 :
1189 : /* {{{ proto array posix_getpwuid(long uid)
1190 : User database access (POSIX.1, 9.2.2) */
1191 : PHP_FUNCTION(posix_getpwuid)
1192 26 : {
1193 : long uid;
1194 : #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
1195 : struct passwd _pw;
1196 : struct passwd *retpwptr = NULL;
1197 : long pwbuflen;
1198 : char *pwbuf;
1199 : int ret;
1200 : #endif
1201 : struct passwd *pw;
1202 :
1203 26 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &uid) == FAILURE) {
1204 11 : RETURN_FALSE;
1205 : }
1206 : #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
1207 : pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
1208 : if (pwbuflen < 1) {
1209 : RETURN_FALSE;
1210 : }
1211 : pwbuf = emalloc(pwbuflen);
1212 :
1213 : ret = getpwuid_r(uid, &_pw, pwbuf, pwbuflen, &retpwptr);
1214 : if (ret || retpwptr == NULL) {
1215 : POSIX_G(last_error) = ret;
1216 : efree(pwbuf);
1217 : RETURN_FALSE;
1218 : }
1219 : pw = &_pw;
1220 : #else
1221 15 : if (NULL == (pw = getpwuid(uid))) {
1222 3 : POSIX_G(last_error) = errno;
1223 3 : RETURN_FALSE;
1224 : }
1225 : #endif
1226 12 : array_init(return_value);
1227 :
1228 12 : if (!php_posix_passwd_to_array(pw, return_value)) {
1229 0 : zval_dtor(return_value);
1230 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix passwd struct to array");
1231 0 : RETVAL_FALSE;
1232 : }
1233 : #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
1234 : efree(pwbuf);
1235 : #endif
1236 : }
1237 : /* }}} */
1238 :
1239 :
1240 : #ifdef HAVE_GETRLIMIT
1241 :
1242 : #define UNLIMITED_STRING "unlimited"
1243 :
1244 : /* {{{ posix_addlimit
1245 : */
1246 : static int posix_addlimit(int limit, char *name, zval *return_value TSRMLS_DC)
1247 22 : {
1248 : int result;
1249 : struct rlimit rl;
1250 : char hard[80];
1251 : char soft[80];
1252 :
1253 22 : snprintf(hard, 80, "hard %s", name);
1254 22 : snprintf(soft, 80, "soft %s", name);
1255 :
1256 22 : result = getrlimit(limit, &rl);
1257 22 : if (result < 0) {
1258 0 : POSIX_G(last_error) = errno;
1259 0 : return FAILURE;
1260 : }
1261 :
1262 22 : if (rl.rlim_cur == RLIM_INFINITY) {
1263 10 : add_ascii_assoc_stringl(return_value, soft, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1, 1);
1264 : } else {
1265 12 : add_ascii_assoc_long(return_value, soft, rl.rlim_cur);
1266 : }
1267 :
1268 22 : if (rl.rlim_max == RLIM_INFINITY) {
1269 14 : add_ascii_assoc_stringl(return_value, hard, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1, 1);
1270 : } else {
1271 8 : add_ascii_assoc_long(return_value, hard, rl.rlim_max);
1272 : }
1273 :
1274 22 : return SUCCESS;
1275 : }
1276 : /* }}} */
1277 :
1278 : /* {{{ limits[]
1279 : */
1280 : struct limitlist {
1281 : int limit;
1282 : char *name;
1283 : } limits[] = {
1284 : #ifdef RLIMIT_CORE
1285 : { RLIMIT_CORE, "core" },
1286 : #endif
1287 :
1288 : #ifdef RLIMIT_DATA
1289 : { RLIMIT_DATA, "data" },
1290 : #endif
1291 :
1292 : #ifdef RLIMIT_STACK
1293 : { RLIMIT_STACK, "stack" },
1294 : #endif
1295 :
1296 : #ifdef RLIMIT_VMEM
1297 : { RLIMIT_VMEM, "virtualmem" },
1298 : #endif
1299 :
1300 : #ifdef RLIMIT_AS
1301 : { RLIMIT_AS, "totalmem" },
1302 : #endif
1303 :
1304 : #ifdef RLIMIT_RSS
1305 : { RLIMIT_RSS, "rss" },
1306 : #endif
1307 :
1308 : #ifdef RLIMIT_NPROC
1309 : { RLIMIT_NPROC, "maxproc" },
1310 : #endif
1311 :
1312 : #ifdef RLIMIT_MEMLOCK
1313 : { RLIMIT_MEMLOCK, "memlock" },
1314 : #endif
1315 :
1316 : #ifdef RLIMIT_CPU
1317 : { RLIMIT_CPU, "cpu" },
1318 : #endif
1319 :
1320 : #ifdef RLIMIT_FSIZE
1321 : { RLIMIT_FSIZE, "filesize" },
1322 : #endif
1323 :
1324 : #ifdef RLIMIT_NOFILE
1325 : { RLIMIT_NOFILE, "openfiles" },
1326 : #endif
1327 :
1328 : #ifdef RLIMIT_OFILE
1329 : { RLIMIT_OFILE, "openfiles" },
1330 : #endif
1331 :
1332 : { 0, NULL }
1333 : };
1334 : /* }}} */
1335 :
1336 :
1337 : /* {{{ proto array posix_getrlimit(void)
1338 : Get system resource consumption limits (This is not a POSIX function, but a BSDism and a SVR4ism. We compile conditionally) */
1339 : PHP_FUNCTION(posix_getrlimit)
1340 2 : {
1341 2 : struct limitlist *l = NULL;
1342 :
1343 2 : PHP_POSIX_NO_ARGS;
1344 :
1345 2 : array_init(return_value);
1346 :
1347 24 : for (l=limits; l->name; l++) {
1348 22 : if (posix_addlimit(l->limit, l->name, return_value TSRMLS_CC) == FAILURE) {
1349 0 : zval_dtor(return_value);
1350 0 : RETURN_FALSE;
1351 : }
1352 : }
1353 : }
1354 : /* }}} */
1355 :
1356 : #endif /* HAVE_GETRLIMIT */
1357 :
1358 : /* {{{ proto int posix_get_last_error(void) U
1359 : Retrieve the error number set by the last posix function which failed. */
1360 : PHP_FUNCTION(posix_get_last_error)
1361 7 : {
1362 7 : PHP_POSIX_NO_ARGS;
1363 :
1364 5 : RETURN_LONG(POSIX_G(last_error));
1365 : }
1366 : /* }}} */
1367 :
1368 : /* {{{ proto string posix_strerror(int errno)
1369 : Retrieve the system error message associated with the given errno. */
1370 : PHP_FUNCTION(posix_strerror)
1371 26 : {
1372 : long error;
1373 :
1374 26 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &error) == FAILURE) {
1375 11 : RETURN_FALSE;
1376 : }
1377 :
1378 15 : RETURN_STRING(strerror(error), 1);
1379 : }
1380 : /* }}} */
1381 :
1382 : #endif
1383 :
1384 : #ifdef HAVE_INITGROUPS
1385 : /* {{{ proto bool posix_initgroups(string name, int base_group_id)
1386 : Calculate the group access list for the user specified in name. */
1387 : PHP_FUNCTION(posix_initgroups)
1388 4 : {
1389 : long basegid;
1390 : char *name;
1391 : int name_len;
1392 :
1393 4 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &name, &name_len, &basegid) == FAILURE) {
1394 2 : RETURN_FALSE;
1395 : }
1396 :
1397 2 : if (name_len == 0) {
1398 2 : RETURN_FALSE;
1399 : }
1400 :
1401 0 : RETURN_BOOL(!initgroups((const char *)name, basegid));
1402 : }
1403 : /* }}} */
1404 : #endif
1405 :
1406 : /*
1407 : * Local variables:
1408 : * tab-width: 4
1409 : * c-basic-offset: 4
1410 : * End:
1411 : * vim600: sw=4 ts=4 fdm=marker
1412 : * vim<600: sw=4 ts=4
1413 : */
|