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