1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
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 288943 2009-09-29 14:02:50Z 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 42 : {
312 42 : php_info_print_table_start();
313 42 : php_info_print_table_row(2, "Revision", "$Revision: 288943 $");
314 42 : php_info_print_table_end();
315 42 : }
316 : /* }}} */
317 :
318 : static PHP_GINIT_FUNCTION(posix) /* {{{ */
319 17633 : {
320 17633 : posix_globals->last_error = 0;
321 17633 : }
322 : /* }}} */
323 :
324 : /* {{{ PHP_MINIT_FUNCTION(posix)
325 : */
326 : static PHP_MINIT_FUNCTION(posix)
327 17633 : {
328 17633 : REGISTER_LONG_CONSTANT("POSIX_F_OK", F_OK, CONST_CS | CONST_PERSISTENT);
329 17633 : REGISTER_LONG_CONSTANT("POSIX_X_OK", X_OK, CONST_CS | CONST_PERSISTENT);
330 17633 : REGISTER_LONG_CONSTANT("POSIX_W_OK", W_OK, CONST_CS | CONST_PERSISTENT);
331 17633 : REGISTER_LONG_CONSTANT("POSIX_R_OK", R_OK, CONST_CS | CONST_PERSISTENT);
332 : #ifdef S_IFREG
333 17633 : REGISTER_LONG_CONSTANT("POSIX_S_IFREG", S_IFREG, CONST_CS | CONST_PERSISTENT);
334 : #endif
335 : #ifdef S_IFCHR
336 17633 : REGISTER_LONG_CONSTANT("POSIX_S_IFCHR", S_IFCHR, CONST_CS | CONST_PERSISTENT);
337 : #endif
338 : #ifdef S_IFBLK
339 17633 : REGISTER_LONG_CONSTANT("POSIX_S_IFBLK", S_IFBLK, CONST_CS | CONST_PERSISTENT);
340 : #endif
341 : #ifdef S_IFIFO
342 17633 : REGISTER_LONG_CONSTANT("POSIX_S_IFIFO", S_IFIFO, CONST_CS | CONST_PERSISTENT);
343 : #endif
344 : #ifdef S_IFSOCK
345 17633 : REGISTER_LONG_CONSTANT("POSIX_S_IFSOCK", S_IFSOCK, CONST_CS | CONST_PERSISTENT);
346 : #endif
347 :
348 17633 : return SUCCESS;
349 : }
350 : /* }}} */
351 :
352 : /* {{{ posix_module_entry
353 : */
354 : zend_module_entry posix_module_entry = {
355 : STANDARD_MODULE_HEADER,
356 : "posix",
357 : posix_functions,
358 : PHP_MINIT(posix),
359 : NULL,
360 : NULL,
361 : NULL,
362 : PHP_MINFO(posix),
363 : NO_VERSION_YET,
364 : PHP_MODULE_GLOBALS(posix),
365 : PHP_GINIT(posix),
366 : NULL,
367 : NULL,
368 : STANDARD_MODULE_PROPERTIES_EX
369 : };
370 : /* }}} */
371 :
372 : #ifdef COMPILE_DL_POSIX
373 : ZEND_GET_MODULE(posix)
374 : #endif
375 :
376 : #define PHP_POSIX_NO_ARGS if (zend_parse_parameters_none() == FAILURE) return;
377 :
378 : #define PHP_POSIX_RETURN_LONG_FUNC(func_name) \
379 : PHP_POSIX_NO_ARGS \
380 : RETURN_LONG(func_name());
381 :
382 : #define PHP_POSIX_SINGLE_ARG_FUNC(func_name) \
383 : long val; \
384 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &val) == FAILURE) RETURN_FALSE; \
385 : if (func_name(val) < 0) { \
386 : POSIX_G(last_error) = errno; \
387 : RETURN_FALSE; \
388 : } \
389 : RETURN_TRUE;
390 :
391 : /* {{{ proto bool posix_kill(int pid, int sig)
392 : Send a signal to a process (POSIX.1, 3.3.2) */
393 :
394 : PHP_FUNCTION(posix_kill)
395 74 : {
396 : long pid, sig;
397 :
398 74 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &pid, &sig) == FAILURE) {
399 20 : RETURN_FALSE;
400 : }
401 :
402 54 : if (kill(pid, sig) < 0) {
403 30 : POSIX_G(last_error) = errno;
404 30 : RETURN_FALSE;
405 : }
406 :
407 24 : RETURN_TRUE;
408 : }
409 : /* }}} */
410 :
411 : /* {{{ proto int posix_getpid(void)
412 : Get the current process id (POSIX.1, 4.1.1) */
413 : PHP_FUNCTION(posix_getpid)
414 16 : {
415 16 : PHP_POSIX_RETURN_LONG_FUNC(getpid);
416 : }
417 : /* }}} */
418 :
419 : /* {{{ proto int posix_getppid(void)
420 : Get the parent process id (POSIX.1, 4.1.1) */
421 : PHP_FUNCTION(posix_getppid)
422 3 : {
423 3 : PHP_POSIX_RETURN_LONG_FUNC(getppid);
424 : }
425 : /* }}} */
426 :
427 : /* {{{ proto int posix_getuid(void)
428 : Get the current user id (POSIX.1, 4.2.1) */
429 : PHP_FUNCTION(posix_getuid)
430 9 : {
431 9 : PHP_POSIX_RETURN_LONG_FUNC(getuid);
432 : }
433 : /* }}} */
434 :
435 : /* {{{ proto int posix_getgid(void)
436 : Get the current group id (POSIX.1, 4.2.1) */
437 : PHP_FUNCTION(posix_getgid)
438 5 : {
439 5 : PHP_POSIX_RETURN_LONG_FUNC(getgid);
440 : }
441 : /* }}} */
442 :
443 : /* {{{ proto int posix_geteuid(void)
444 : Get the current effective user id (POSIX.1, 4.2.1) */
445 : PHP_FUNCTION(posix_geteuid)
446 11 : {
447 11 : PHP_POSIX_RETURN_LONG_FUNC(geteuid);
448 : }
449 : /* }}} */
450 :
451 : /* {{{ proto int posix_getegid(void)
452 : Get the current effective group id (POSIX.1, 4.2.1) */
453 : PHP_FUNCTION(posix_getegid)
454 0 : {
455 0 : PHP_POSIX_RETURN_LONG_FUNC(getegid);
456 : }
457 : /* }}} */
458 :
459 : /* {{{ proto bool posix_setuid(long uid)
460 : Set user id (POSIX.1, 4.2.2) */
461 : PHP_FUNCTION(posix_setuid)
462 32 : {
463 32 : PHP_POSIX_SINGLE_ARG_FUNC(setuid);
464 : }
465 : /* }}} */
466 :
467 : /* {{{ proto bool posix_setgid(int uid)
468 : Set group id (POSIX.1, 4.2.2) */
469 : PHP_FUNCTION(posix_setgid)
470 31 : {
471 31 : PHP_POSIX_SINGLE_ARG_FUNC(setgid);
472 : }
473 : /* }}} */
474 :
475 : /* {{{ proto bool posix_seteuid(long uid)
476 : Set effective user id */
477 : #ifdef HAVE_SETEUID
478 : PHP_FUNCTION(posix_seteuid)
479 31 : {
480 31 : PHP_POSIX_SINGLE_ARG_FUNC(seteuid);
481 : }
482 : #endif
483 : /* }}} */
484 :
485 : /* {{{ proto bool posix_setegid(long uid)
486 : Set effective group id */
487 : #ifdef HAVE_SETEGID
488 : PHP_FUNCTION(posix_setegid)
489 0 : {
490 0 : PHP_POSIX_SINGLE_ARG_FUNC(setegid);
491 : }
492 : #endif
493 : /* }}} */
494 :
495 : /* {{{ proto array posix_getgroups(void)
496 : Get supplementary group id's (POSIX.1, 4.2.3) */
497 : #ifdef HAVE_GETGROUPS
498 : PHP_FUNCTION(posix_getgroups)
499 1 : {
500 : gid_t gidlist[NGROUPS_MAX];
501 : int result;
502 : int i;
503 :
504 1 : PHP_POSIX_NO_ARGS;
505 :
506 1 : if ((result = getgroups(NGROUPS_MAX, gidlist)) < 0) {
507 0 : POSIX_G(last_error) = errno;
508 0 : RETURN_FALSE;
509 : }
510 :
511 1 : array_init(return_value);
512 :
513 3 : for (i=0; i<result; i++) {
514 2 : add_next_index_long(return_value, gidlist[i]);
515 : }
516 : }
517 : #endif
518 : /* }}} */
519 :
520 : /* {{{ proto string posix_getlogin(void)
521 : Get user name (POSIX.1, 4.2.4) */
522 : #ifdef HAVE_GETLOGIN
523 : PHP_FUNCTION(posix_getlogin)
524 0 : {
525 : char *p;
526 :
527 0 : PHP_POSIX_NO_ARGS;
528 :
529 0 : if (NULL == (p = getlogin())) {
530 0 : POSIX_G(last_error) = errno;
531 0 : RETURN_FALSE;
532 : }
533 :
534 0 : RETURN_STRING(p, 1);
535 : }
536 : #endif
537 : /* }}} */
538 :
539 : /* {{{ proto int posix_getpgrp(void)
540 : Get current process group id (POSIX.1, 4.3.1) */
541 : PHP_FUNCTION(posix_getpgrp)
542 2 : {
543 2 : PHP_POSIX_RETURN_LONG_FUNC(getpgrp);
544 : }
545 : /* }}} */
546 :
547 : /* {{{ proto int posix_setsid(void)
548 : Create session and set process group id (POSIX.1, 4.3.2) */
549 : #ifdef HAVE_SETSID
550 : PHP_FUNCTION(posix_setsid)
551 0 : {
552 0 : PHP_POSIX_RETURN_LONG_FUNC(setsid);
553 : }
554 : #endif
555 : /* }}} */
556 :
557 : /* {{{ proto bool posix_setpgid(int pid, int pgid)
558 : Set process group id for job control (POSIX.1, 4.3.3) */
559 : PHP_FUNCTION(posix_setpgid)
560 0 : {
561 : long pid, pgid;
562 :
563 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &pid, &pgid) == FAILURE) {
564 0 : RETURN_FALSE;
565 : }
566 :
567 0 : if (setpgid(pid, pgid) < 0) {
568 0 : POSIX_G(last_error) = errno;
569 0 : RETURN_FALSE;
570 : }
571 :
572 0 : RETURN_TRUE;
573 : }
574 : /* }}} */
575 :
576 : /* {{{ proto int posix_getpgid(void)
577 : Get the process group id of the specified process (This is not a POSIX function, but a SVR4ism, so we compile conditionally) */
578 : #ifdef HAVE_GETPGID
579 : PHP_FUNCTION(posix_getpgid)
580 26 : {
581 : long val;
582 26 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &val) == FAILURE) {
583 11 : RETURN_FALSE;
584 : }
585 :
586 15 : if ((val = getpgid(val)) < 0) {
587 3 : POSIX_G(last_error) = errno;
588 3 : RETURN_FALSE;
589 : }
590 12 : RETURN_LONG(val);
591 : }
592 : #endif
593 : /* }}} */
594 :
595 : /* {{{ proto int posix_getsid(void)
596 : Get process group id of session leader (This is not a POSIX function, but a SVR4ism, so be compile conditionally) */
597 : #ifdef HAVE_GETSID
598 : PHP_FUNCTION(posix_getsid)
599 5 : {
600 : long val;
601 5 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &val) == FAILURE) {
602 2 : RETURN_FALSE;
603 : }
604 :
605 3 : if ((val = getsid(val)) < 0) {
606 1 : POSIX_G(last_error) = errno;
607 1 : RETURN_FALSE;
608 : }
609 2 : RETURN_LONG(val);
610 : }
611 : #endif
612 : /* }}} */
613 :
614 : /* {{{ proto array posix_uname(void)
615 : Get system name (POSIX.1, 4.4.1) */
616 : PHP_FUNCTION(posix_uname)
617 3 : {
618 : struct utsname u;
619 :
620 3 : PHP_POSIX_NO_ARGS;
621 :
622 2 : if (uname(&u) < 0) {
623 0 : POSIX_G(last_error) = errno;
624 0 : RETURN_FALSE;
625 : }
626 :
627 2 : array_init(return_value);
628 :
629 2 : add_assoc_string(return_value, "sysname", u.sysname, 1);
630 2 : add_assoc_string(return_value, "nodename", u.nodename, 1);
631 2 : add_assoc_string(return_value, "release", u.release, 1);
632 2 : add_assoc_string(return_value, "version", u.version, 1);
633 2 : add_assoc_string(return_value, "machine", u.machine, 1);
634 :
635 : #if defined(_GNU_SOURCE) && !defined(DARWIN) && defined(HAVE_UTSNAME_DOMAINNAME)
636 : add_assoc_string(return_value, "domainname", u.domainname, 1);
637 : #endif
638 : }
639 : /* }}} */
640 :
641 : /* POSIX.1, 4.5.1 time() - Get System Time
642 : already covered by PHP
643 : */
644 :
645 : /* {{{ proto array posix_times(void)
646 : Get process times (POSIX.1, 4.5.2) */
647 : PHP_FUNCTION(posix_times)
648 3 : {
649 : struct tms t;
650 : clock_t ticks;
651 :
652 3 : PHP_POSIX_NO_ARGS;
653 :
654 2 : if ((ticks = times(&t)) == -1) {
655 0 : POSIX_G(last_error) = errno;
656 0 : RETURN_FALSE;
657 : }
658 :
659 2 : array_init(return_value);
660 :
661 2 : add_assoc_long(return_value, "ticks", ticks); /* clock ticks */
662 2 : add_assoc_long(return_value, "utime", t.tms_utime); /* user time */
663 2 : add_assoc_long(return_value, "stime", t.tms_stime); /* system time */
664 2 : add_assoc_long(return_value, "cutime", t.tms_cutime); /* user time of children */
665 2 : add_assoc_long(return_value, "cstime", t.tms_cstime); /* system time of children */
666 : }
667 : /* }}} */
668 :
669 : /* POSIX.1, 4.6.1 getenv() - Environment Access
670 : already covered by PHP
671 : */
672 :
673 : /* {{{ proto string posix_ctermid(void)
674 : Generate terminal path name (POSIX.1, 4.7.1) */
675 : #ifdef HAVE_CTERMID
676 : PHP_FUNCTION(posix_ctermid)
677 3 : {
678 : char buffer[L_ctermid];
679 :
680 3 : PHP_POSIX_NO_ARGS;
681 :
682 2 : if (NULL == ctermid(buffer)) {
683 : /* Found no documentation how the defined behaviour is when this
684 : * function fails
685 : */
686 0 : POSIX_G(last_error) = errno;
687 0 : RETURN_FALSE;
688 : }
689 :
690 2 : RETURN_STRING(buffer, 1);
691 : }
692 : #endif
693 : /* }}} */
694 :
695 : /* Checks if the provides resource is a stream and if it provides a file descriptor */
696 : static int php_posix_stream_get_fd(zval *zfp, int *fd TSRMLS_DC) /* {{{ */
697 4 : {
698 : php_stream *stream;
699 :
700 4 : php_stream_from_zval_no_verify(stream, &zfp);
701 :
702 4 : if (stream == NULL) {
703 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "expects argument 1 to be a valid stream resource");
704 1 : return 0;
705 : }
706 3 : if (php_stream_can_cast(stream, PHP_STREAM_AS_FD) == SUCCESS) {
707 3 : php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)fd, 0);
708 : } else {
709 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not use stream of type '%s'",
710 : stream->ops->label);
711 0 : return 0;
712 : }
713 3 : return 1;
714 : }
715 : /* }}} */
716 :
717 : /* {{{ proto string posix_ttyname(int fd)
718 : Determine terminal device name (POSIX.1, 4.7.2) */
719 : PHP_FUNCTION(posix_ttyname)
720 35 : {
721 : zval **z_fd;
722 : char *p;
723 : int fd;
724 : #if defined(ZTS) && defined(HAVE_TTYNAME_R) && defined(_SC_TTY_NAME_MAX)
725 : long buflen;
726 : #endif
727 :
728 35 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &z_fd) == FAILURE) {
729 3 : RETURN_FALSE;
730 : }
731 :
732 32 : switch (Z_TYPE_PP(z_fd)) {
733 : case IS_RESOURCE:
734 4 : if (!php_posix_stream_get_fd(*z_fd, &fd TSRMLS_CC)) {
735 1 : RETURN_FALSE;
736 : }
737 3 : break;
738 : default:
739 28 : convert_to_long_ex(z_fd);
740 28 : fd = Z_LVAL_PP(z_fd);
741 : }
742 : #if defined(ZTS) && defined(HAVE_TTYNAME_R) && defined(_SC_TTY_NAME_MAX)
743 : buflen = sysconf(_SC_TTY_NAME_MAX);
744 : if (buflen < 1) {
745 : RETURN_FALSE;
746 : }
747 : p = emalloc(buflen);
748 :
749 : if (ttyname_r(fd, p, buflen)) {
750 : POSIX_G(last_error) = errno;
751 : efree(p);
752 : RETURN_FALSE;
753 : }
754 : RETURN_STRING(p, 0);
755 : #else
756 31 : if (NULL == (p = ttyname(fd))) {
757 31 : POSIX_G(last_error) = errno;
758 31 : RETURN_FALSE;
759 : }
760 : #endif
761 0 : RETURN_STRING(p, 1);
762 : }
763 : /* }}} */
764 :
765 : /* {{{ proto bool posix_isatty(int fd)
766 : Determine if filedesc is a tty (POSIX.1, 4.7.1) */
767 : PHP_FUNCTION(posix_isatty)
768 1 : {
769 : zval **z_fd;
770 : int fd;
771 :
772 1 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &z_fd) == FAILURE) {
773 0 : RETURN_FALSE;
774 : }
775 :
776 1 : switch (Z_TYPE_PP(z_fd)) {
777 : case IS_RESOURCE:
778 0 : if (!php_posix_stream_get_fd(*z_fd, &fd TSRMLS_CC)) {
779 0 : RETURN_FALSE;
780 : }
781 0 : break;
782 : default:
783 1 : convert_to_long_ex(z_fd);
784 1 : fd = Z_LVAL_PP(z_fd);
785 : }
786 :
787 1 : if (isatty(fd)) {
788 0 : RETURN_TRUE;
789 : } else {
790 1 : RETURN_FALSE;
791 : }
792 : }
793 : /* }}} */
794 :
795 : /*
796 : POSIX.1, 4.8.1 sysconf() - TODO
797 : POSIX.1, 5.7.1 pathconf(), fpathconf() - TODO
798 :
799 : POSIX.1, 5.1.2 opendir(), readdir(), rewinddir(), closedir()
800 : POSIX.1, 5.2.1 chdir()
801 : already supported by PHP
802 : */
803 :
804 : /* {{{ proto string posix_getcwd(void)
805 : Get working directory pathname (POSIX.1, 5.2.2) */
806 : PHP_FUNCTION(posix_getcwd)
807 4 : {
808 : char buffer[MAXPATHLEN];
809 : char *p;
810 :
811 4 : PHP_POSIX_NO_ARGS;
812 :
813 2 : p = VCWD_GETCWD(buffer, MAXPATHLEN);
814 2 : if (!p) {
815 0 : POSIX_G(last_error) = errno;
816 0 : RETURN_FALSE;
817 : }
818 :
819 2 : RETURN_STRING(buffer, 1);
820 : }
821 : /* }}} */
822 :
823 : /*
824 : POSIX.1, 5.3.x open(), creat(), umask()
825 : POSIX.1, 5.4.1 link()
826 : already supported by PHP.
827 : */
828 :
829 : /* {{{ proto bool posix_mkfifo(string pathname, int mode)
830 : Make a FIFO special file (POSIX.1, 5.4.2) */
831 : #ifdef HAVE_MKFIFO
832 : PHP_FUNCTION(posix_mkfifo)
833 5 : {
834 : char *path;
835 : int path_len;
836 : long mode;
837 : int result;
838 :
839 5 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &path, &path_len, &mode) == FAILURE) {
840 1 : RETURN_FALSE;
841 : }
842 :
843 4 : if (php_check_open_basedir_ex(path, 0 TSRMLS_CC) ||
844 : (PG(safe_mode) && (!php_checkuid(path, NULL, CHECKUID_ALLOW_ONLY_DIR)))) {
845 1 : RETURN_FALSE;
846 : }
847 :
848 3 : result = mkfifo(path, mode);
849 3 : if (result < 0) {
850 1 : POSIX_G(last_error) = errno;
851 1 : RETURN_FALSE;
852 : }
853 :
854 2 : RETURN_TRUE;
855 : }
856 : #endif
857 : /* }}} */
858 :
859 : /* {{{ proto bool posix_mknod(string pathname, int mode [, int major [, int minor]])
860 : Make a special or ordinary file (POSIX.1) */
861 : #ifdef HAVE_MKNOD
862 : PHP_FUNCTION(posix_mknod)
863 2 : {
864 : char *path;
865 : int path_len;
866 : long mode;
867 2 : long major = 0, minor = 0;
868 : int result;
869 : dev_t php_dev;
870 :
871 2 : php_dev = 0;
872 :
873 2 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|ll", &path, &path_len,
874 : &mode, &major, &minor) == FAILURE) {
875 0 : RETURN_FALSE;
876 : }
877 :
878 2 : if (php_check_open_basedir_ex(path, 0 TSRMLS_CC) ||
879 : (PG(safe_mode) && (!php_checkuid(path, NULL, CHECKUID_ALLOW_ONLY_DIR)))) {
880 0 : RETURN_FALSE;
881 : }
882 :
883 2 : if ((mode & S_IFCHR) || (mode & S_IFBLK)) {
884 0 : if (ZEND_NUM_ARGS() == 2) {
885 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "For S_IFCHR and S_IFBLK you need to pass a major device kernel identifier");
886 0 : RETURN_FALSE;
887 : }
888 0 : if (major == 0) {
889 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING,
890 : "Expects argument 3 to be non-zero for POSIX_S_IFCHR and POSIX_S_IFBLK");
891 0 : RETURN_FALSE;
892 : } else {
893 : #if defined(HAVE_MAKEDEV) || defined(makedev)
894 0 : php_dev = makedev(major, minor);
895 : #else
896 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create a block or character device, creating a normal file instead");
897 : #endif
898 : }
899 : }
900 :
901 2 : result = mknod(path, mode, php_dev);
902 2 : if (result < 0) {
903 2 : POSIX_G(last_error) = errno;
904 2 : RETURN_FALSE;
905 : }
906 :
907 0 : RETURN_TRUE;
908 : }
909 : #endif
910 : /* }}} */
911 :
912 : /* Takes a pointer to posix group and a pointer to an already initialized ZVAL
913 : * array container and fills the array with the posix group member data. */
914 : int php_posix_group_to_array(struct group *g, zval *array_group) /* {{{ */
915 13 : {
916 : zval *array_members;
917 : int count;
918 :
919 13 : if (NULL == g)
920 0 : return 0;
921 :
922 13 : if (array_group == NULL || Z_TYPE_P(array_group) != IS_ARRAY)
923 0 : return 0;
924 :
925 13 : MAKE_STD_ZVAL(array_members);
926 13 : array_init(array_members);
927 :
928 13 : add_assoc_string(array_group, "name", g->gr_name, 1);
929 13 : add_assoc_string(array_group, "passwd", g->gr_passwd, 1);
930 30 : for (count=0; g->gr_mem[count] != NULL; count++) {
931 17 : add_next_index_string(array_members, g->gr_mem[count], 1);
932 : }
933 13 : zend_hash_update(Z_ARRVAL_P(array_group), "members", sizeof("members"), (void*)&array_members, sizeof(zval*), NULL);
934 13 : add_assoc_long(array_group, "gid", g->gr_gid);
935 13 : return 1;
936 : }
937 : /* }}} */
938 :
939 : /*
940 : POSIX.1, 5.5.1 unlink()
941 : POSIX.1, 5.5.2 rmdir()
942 : POSIX.1, 5.5.3 rename()
943 : POSIX.1, 5.6.x stat(), chmod(), utime() already supported by PHP.
944 : */
945 :
946 : /* {{{ proto bool posix_access(string file [, int mode])
947 : Determine accessibility of a file (POSIX.1 5.6.3) */
948 : PHP_FUNCTION(posix_access)
949 15 : {
950 15 : long mode = 0;
951 : int filename_len, ret;
952 : char *filename, *path;
953 :
954 15 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &filename, &filename_len, &mode) == FAILURE) {
955 3 : RETURN_FALSE;
956 : }
957 :
958 12 : path = expand_filepath(filename, NULL TSRMLS_CC);
959 12 : if (!path) {
960 2 : POSIX_G(last_error) = EIO;
961 2 : RETURN_FALSE;
962 : }
963 :
964 10 : if (php_check_open_basedir_ex(path, 0 TSRMLS_CC) ||
965 : (PG(safe_mode) && (!php_checkuid_ex(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR, CHECKUID_NO_ERRORS)))) {
966 1 : efree(path);
967 1 : POSIX_G(last_error) = EPERM;
968 1 : RETURN_FALSE;
969 : }
970 :
971 9 : ret = access(path, mode);
972 9 : efree(path);
973 :
974 9 : if (ret) {
975 5 : POSIX_G(last_error) = errno;
976 5 : RETURN_FALSE;
977 : }
978 :
979 4 : RETURN_TRUE;
980 : }
981 : /* }}} */
982 :
983 : /*
984 : POSIX.1, 6.x most I/O functions already supported by PHP.
985 : POSIX.1, 7.x tty functions, TODO
986 : POSIX.1, 8.x interactions with other C language functions
987 : POSIX.1, 9.x system database access
988 : */
989 :
990 : /* {{{ proto array posix_getgrnam(string groupname)
991 : Group database access (POSIX.1, 9.2.1) */
992 : PHP_FUNCTION(posix_getgrnam)
993 6 : {
994 : char *name;
995 : struct group *g;
996 : int name_len;
997 : #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
998 : struct group gbuf;
999 : long buflen;
1000 : char *buf;
1001 : #endif
1002 :
1003 6 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
1004 0 : RETURN_FALSE;
1005 : }
1006 :
1007 : #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
1008 : buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
1009 : if (buflen < 1) {
1010 : RETURN_FALSE;
1011 : }
1012 : buf = emalloc(buflen);
1013 : g = &gbuf;
1014 :
1015 : if (getgrnam_r(name, g, buf, buflen, &g) || g == NULL) {
1016 : POSIX_G(last_error) = errno;
1017 : efree(buf);
1018 : RETURN_FALSE;
1019 : }
1020 : #else
1021 6 : if (NULL == (g = getgrnam(name))) {
1022 6 : POSIX_G(last_error) = errno;
1023 6 : RETURN_FALSE;
1024 : }
1025 : #endif
1026 0 : array_init(return_value);
1027 :
1028 0 : if (!php_posix_group_to_array(g, return_value)) {
1029 0 : zval_dtor(return_value);
1030 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix group to array");
1031 0 : RETVAL_FALSE;
1032 : }
1033 : #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
1034 : efree(buf);
1035 : #endif
1036 : }
1037 : /* }}} */
1038 :
1039 : /* {{{ proto array posix_getgrgid(long gid)
1040 : Group database access (POSIX.1, 9.2.1) */
1041 : PHP_FUNCTION(posix_getgrgid)
1042 30 : {
1043 : long gid;
1044 : #if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
1045 : int ret;
1046 : struct group _g;
1047 : struct group *retgrptr = NULL;
1048 : long grbuflen;
1049 : char *grbuf;
1050 : #endif
1051 : struct group *g;
1052 :
1053 30 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &gid) == FAILURE) {
1054 12 : RETURN_FALSE;
1055 : }
1056 : #if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
1057 :
1058 : grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
1059 : if (grbuflen < 1) {
1060 : RETURN_FALSE;
1061 : }
1062 :
1063 : grbuf = emalloc(grbuflen);
1064 :
1065 : ret = getgrgid_r(gid, &_g, grbuf, grbuflen, &retgrptr);
1066 : if (ret || retgrptr == NULL) {
1067 : POSIX_G(last_error) = ret;
1068 : efree(grbuf);
1069 : RETURN_FALSE;
1070 : }
1071 : g = &_g;
1072 : #else
1073 18 : if (NULL == (g = getgrgid(gid))) {
1074 5 : POSIX_G(last_error) = errno;
1075 5 : RETURN_FALSE;
1076 : }
1077 : #endif
1078 13 : array_init(return_value);
1079 :
1080 13 : if (!php_posix_group_to_array(g, return_value)) {
1081 0 : zval_dtor(return_value);
1082 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix group struct to array");
1083 0 : RETVAL_FALSE;
1084 : }
1085 : #if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
1086 : efree(grbuf);
1087 : #endif
1088 : }
1089 : /* }}} */
1090 :
1091 : int php_posix_passwd_to_array(struct passwd *pw, zval *return_value) /* {{{ */
1092 12 : {
1093 12 : if (NULL == pw)
1094 0 : return 0;
1095 12 : if (NULL == return_value || Z_TYPE_P(return_value) != IS_ARRAY)
1096 0 : return 0;
1097 :
1098 12 : add_assoc_string(return_value, "name", pw->pw_name, 1);
1099 12 : add_assoc_string(return_value, "passwd", pw->pw_passwd, 1);
1100 12 : add_assoc_long (return_value, "uid", pw->pw_uid);
1101 12 : add_assoc_long (return_value, "gid", pw->pw_gid);
1102 12 : add_assoc_string(return_value, "gecos", pw->pw_gecos, 1);
1103 12 : add_assoc_string(return_value, "dir", pw->pw_dir, 1);
1104 12 : add_assoc_string(return_value, "shell", pw->pw_shell, 1);
1105 12 : return 1;
1106 : }
1107 : /* }}} */
1108 :
1109 : /* {{{ proto array posix_getpwnam(string groupname)
1110 : User database access (POSIX.1, 9.2.2) */
1111 : PHP_FUNCTION(posix_getpwnam)
1112 6 : {
1113 : struct passwd *pw;
1114 : char *name;
1115 : int name_len;
1116 : #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
1117 : struct passwd pwbuf;
1118 : long buflen;
1119 : char *buf;
1120 : #endif
1121 :
1122 6 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
1123 0 : RETURN_FALSE;
1124 : }
1125 :
1126 : #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
1127 : buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
1128 : if (buflen < 1) {
1129 : RETURN_FALSE;
1130 : }
1131 : buf = emalloc(buflen);
1132 : pw = &pwbuf;
1133 :
1134 : if (getpwnam_r(name, pw, buf, buflen, &pw) || pw == NULL) {
1135 : efree(buf);
1136 : POSIX_G(last_error) = errno;
1137 : RETURN_FALSE;
1138 : }
1139 : #else
1140 6 : if (NULL == (pw = getpwnam(name))) {
1141 6 : POSIX_G(last_error) = errno;
1142 6 : RETURN_FALSE;
1143 : }
1144 : #endif
1145 0 : array_init(return_value);
1146 :
1147 0 : if (!php_posix_passwd_to_array(pw, return_value)) {
1148 0 : zval_dtor(return_value);
1149 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix passwd struct to array");
1150 0 : RETVAL_FALSE;
1151 : }
1152 : #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
1153 : efree(buf);
1154 : #endif
1155 : }
1156 : /* }}} */
1157 :
1158 : /* {{{ proto array posix_getpwuid(long uid)
1159 : User database access (POSIX.1, 9.2.2) */
1160 : PHP_FUNCTION(posix_getpwuid)
1161 26 : {
1162 : long uid;
1163 : #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
1164 : struct passwd _pw;
1165 : struct passwd *retpwptr = NULL;
1166 : long pwbuflen;
1167 : char *pwbuf;
1168 : int ret;
1169 : #endif
1170 : struct passwd *pw;
1171 :
1172 26 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &uid) == FAILURE) {
1173 11 : RETURN_FALSE;
1174 : }
1175 : #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
1176 : pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
1177 : if (pwbuflen < 1) {
1178 : RETURN_FALSE;
1179 : }
1180 : pwbuf = emalloc(pwbuflen);
1181 :
1182 : ret = getpwuid_r(uid, &_pw, pwbuf, pwbuflen, &retpwptr);
1183 : if (ret || retpwptr == NULL) {
1184 : POSIX_G(last_error) = ret;
1185 : efree(pwbuf);
1186 : RETURN_FALSE;
1187 : }
1188 : pw = &_pw;
1189 : #else
1190 15 : if (NULL == (pw = getpwuid(uid))) {
1191 3 : POSIX_G(last_error) = errno;
1192 3 : RETURN_FALSE;
1193 : }
1194 : #endif
1195 12 : array_init(return_value);
1196 :
1197 12 : if (!php_posix_passwd_to_array(pw, return_value)) {
1198 0 : zval_dtor(return_value);
1199 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix passwd struct to array");
1200 0 : RETVAL_FALSE;
1201 : }
1202 : #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
1203 : efree(pwbuf);
1204 : #endif
1205 : }
1206 : /* }}} */
1207 :
1208 :
1209 : #ifdef HAVE_GETRLIMIT
1210 :
1211 : #define UNLIMITED_STRING "unlimited"
1212 :
1213 : /* {{{ posix_addlimit
1214 : */
1215 22 : static int posix_addlimit(int limit, char *name, zval *return_value TSRMLS_DC) {
1216 : int result;
1217 : struct rlimit rl;
1218 : char hard[80];
1219 : char soft[80];
1220 :
1221 22 : snprintf(hard, 80, "hard %s", name);
1222 22 : snprintf(soft, 80, "soft %s", name);
1223 :
1224 22 : result = getrlimit(limit, &rl);
1225 22 : if (result < 0) {
1226 0 : POSIX_G(last_error) = errno;
1227 0 : return FAILURE;
1228 : }
1229 :
1230 22 : if (rl.rlim_cur == RLIM_INFINITY) {
1231 10 : add_assoc_stringl(return_value, soft, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1, 1);
1232 : } else {
1233 12 : add_assoc_long(return_value, soft, rl.rlim_cur);
1234 : }
1235 :
1236 22 : if (rl.rlim_max == RLIM_INFINITY) {
1237 14 : add_assoc_stringl(return_value, hard, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1, 1);
1238 : } else {
1239 8 : add_assoc_long(return_value, hard, rl.rlim_max);
1240 : }
1241 :
1242 22 : return SUCCESS;
1243 : }
1244 : /* }}} */
1245 :
1246 : /* {{{ limits[]
1247 : */
1248 : struct limitlist {
1249 : int limit;
1250 : char *name;
1251 : } limits[] = {
1252 : #ifdef RLIMIT_CORE
1253 : { RLIMIT_CORE, "core" },
1254 : #endif
1255 :
1256 : #ifdef RLIMIT_DATA
1257 : { RLIMIT_DATA, "data" },
1258 : #endif
1259 :
1260 : #ifdef RLIMIT_STACK
1261 : { RLIMIT_STACK, "stack" },
1262 : #endif
1263 :
1264 : #ifdef RLIMIT_VMEM
1265 : { RLIMIT_VMEM, "virtualmem" },
1266 : #endif
1267 :
1268 : #ifdef RLIMIT_AS
1269 : { RLIMIT_AS, "totalmem" },
1270 : #endif
1271 :
1272 : #ifdef RLIMIT_RSS
1273 : { RLIMIT_RSS, "rss" },
1274 : #endif
1275 :
1276 : #ifdef RLIMIT_NPROC
1277 : { RLIMIT_NPROC, "maxproc" },
1278 : #endif
1279 :
1280 : #ifdef RLIMIT_MEMLOCK
1281 : { RLIMIT_MEMLOCK, "memlock" },
1282 : #endif
1283 :
1284 : #ifdef RLIMIT_CPU
1285 : { RLIMIT_CPU, "cpu" },
1286 : #endif
1287 :
1288 : #ifdef RLIMIT_FSIZE
1289 : { RLIMIT_FSIZE, "filesize" },
1290 : #endif
1291 :
1292 : #ifdef RLIMIT_NOFILE
1293 : { RLIMIT_NOFILE, "openfiles" },
1294 : #endif
1295 :
1296 : #ifdef RLIMIT_OFILE
1297 : { RLIMIT_OFILE, "openfiles" },
1298 : #endif
1299 :
1300 : { 0, NULL }
1301 : };
1302 : /* }}} */
1303 :
1304 :
1305 : /* {{{ proto array posix_getrlimit(void)
1306 : Get system resource consumption limits (This is not a POSIX function, but a BSDism and a SVR4ism. We compile conditionally) */
1307 : PHP_FUNCTION(posix_getrlimit)
1308 2 : {
1309 2 : struct limitlist *l = NULL;
1310 :
1311 2 : PHP_POSIX_NO_ARGS;
1312 :
1313 2 : array_init(return_value);
1314 :
1315 24 : for (l=limits; l->name; l++) {
1316 22 : if (posix_addlimit(l->limit, l->name, return_value TSRMLS_CC) == FAILURE) {
1317 0 : zval_dtor(return_value);
1318 0 : RETURN_FALSE;
1319 : }
1320 : }
1321 : }
1322 : /* }}} */
1323 :
1324 : #endif /* HAVE_GETRLIMIT */
1325 :
1326 : /* {{{ proto int posix_get_last_error(void)
1327 : Retrieve the error number set by the last posix function which failed. */
1328 : PHP_FUNCTION(posix_get_last_error)
1329 7 : {
1330 7 : PHP_POSIX_NO_ARGS;
1331 :
1332 5 : RETURN_LONG(POSIX_G(last_error));
1333 : }
1334 : /* }}} */
1335 :
1336 : /* {{{ proto string posix_strerror(int errno)
1337 : Retrieve the system error message associated with the given errno. */
1338 : PHP_FUNCTION(posix_strerror)
1339 26 : {
1340 : long error;
1341 :
1342 26 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &error) == FAILURE) {
1343 11 : RETURN_FALSE;
1344 : }
1345 :
1346 15 : RETURN_STRING(strerror(error), 1);
1347 : }
1348 : /* }}} */
1349 :
1350 : #endif
1351 :
1352 : #ifdef HAVE_INITGROUPS
1353 : /* {{{ proto bool posix_initgroups(string name, int base_group_id)
1354 : Calculate the group access list for the user specified in name. */
1355 : PHP_FUNCTION(posix_initgroups)
1356 4 : {
1357 : long basegid;
1358 : char *name;
1359 : int name_len;
1360 :
1361 4 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &name, &name_len, &basegid) == FAILURE) {
1362 2 : RETURN_FALSE;
1363 : }
1364 :
1365 2 : if (name_len == 0) {
1366 2 : RETURN_FALSE;
1367 : }
1368 :
1369 0 : RETURN_BOOL(!initgroups((const char *)name, basegid));
1370 : }
1371 : /* }}} */
1372 : #endif
1373 :
1374 : /*
1375 : * Local variables:
1376 : * tab-width: 4
1377 : * c-basic-offset: 4
1378 : * End:
1379 : * vim600: sw=4 ts=4 fdm=marker
1380 : * vim<600: sw=4 ts=4
1381 : */
|