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