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