php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
posix.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: Kristian Koehntopp <kris@koehntopp.de> |
14 +----------------------------------------------------------------------+
15 */
16
17#ifdef HAVE_CONFIG_H
18#include <config.h>
19#endif
20
21#include "php.h"
22#include <unistd.h>
23#include "ext/standard/info.h"
24#include "php_posix.h"
25#include "main/php_network.h"
26
27#ifdef HAVE_POSIX
28
29#ifdef HAVE_SYS_TIME_H
30#include <sys/time.h>
31#endif
32
33#include <sys/resource.h>
34#include <sys/utsname.h>
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <signal.h>
38#include <sys/times.h>
39#include <errno.h>
40#include <grp.h>
41#include <pwd.h>
42#ifdef MAJOR_IN_MKDEV
43# include <sys/mkdev.h>
44#elif defined(MAJOR_IN_SYSMACROS)
45# include <sys/sysmacros.h>
46#endif
47
48#include "posix_arginfo.h"
49
51static PHP_MINFO_FUNCTION(posix);
52
53/* {{{ PHP_MINFO_FUNCTION */
54static PHP_MINFO_FUNCTION(posix)
55{
57 php_info_print_table_row(2, "POSIX support", "enabled");
59}
60/* }}} */
61
62static PHP_GINIT_FUNCTION(posix) /* {{{ */
63{
64#if defined(COMPILE_DL_POSIX) && defined(ZTS)
66#endif
67 posix_globals->last_error = 0;
68}
69/* }}} */
70
71/* {{{ PHP_MINIT_FUNCTION(posix) */
72static PHP_MINIT_FUNCTION(posix)
73{
74 register_posix_symbols(module_number);
75
76 return SUCCESS;
77}
78/* }}} */
79
80/* {{{ posix_module_entry */
81zend_module_entry posix_module_entry = {
83 "posix",
84 ext_functions,
85 PHP_MINIT(posix),
86 NULL,
87 NULL,
88 NULL,
89 PHP_MINFO(posix),
90 PHP_POSIX_VERSION,
91 PHP_MODULE_GLOBALS(posix),
92 PHP_GINIT(posix),
93 NULL,
94 NULL,
96};
97/* }}} */
98
99#ifdef COMPILE_DL_POSIX
100#ifdef ZTS
102#endif
103ZEND_GET_MODULE(posix)
104#endif
105
106#define PHP_POSIX_RETURN_LONG_FUNC(func_name) \
107 ZEND_PARSE_PARAMETERS_NONE(); \
108 RETURN_LONG(func_name());
109
110#define PHP_POSIX_SINGLE_ARG_FUNC(func_name) \
111 zend_long val; \
112 ZEND_PARSE_PARAMETERS_START(1, 1) \
113 Z_PARAM_LONG(val) \
114 ZEND_PARSE_PARAMETERS_END(); \
115 if (func_name(val) < 0) { \
116 POSIX_G(last_error) = errno; \
117 RETURN_FALSE; \
118 } \
119 RETURN_TRUE;
120
121/* {{{ Send a signal to a process (POSIX.1, 3.3.2) */
122
124{
125 zend_long pid, sig;
126
128 Z_PARAM_LONG(pid)
129 Z_PARAM_LONG(sig)
131
132 if (kill(pid, sig) < 0) {
133 POSIX_G(last_error) = errno;
135 }
136
138}
139/* }}} */
140
141/* {{{ Get the current process id (POSIX.1, 4.1.1) */
143{
144 PHP_POSIX_RETURN_LONG_FUNC(getpid);
145}
146/* }}} */
147
148/* {{{ Get the parent process id (POSIX.1, 4.1.1) */
150{
151 PHP_POSIX_RETURN_LONG_FUNC(getppid);
152}
153/* }}} */
154
155/* {{{ Get the current user id (POSIX.1, 4.2.1) */
157{
158 PHP_POSIX_RETURN_LONG_FUNC(getuid);
159}
160/* }}} */
161
162/* {{{ Get the current group id (POSIX.1, 4.2.1) */
164{
165 PHP_POSIX_RETURN_LONG_FUNC(getgid);
166}
167/* }}} */
168
169/* {{{ Get the current effective user id (POSIX.1, 4.2.1) */
171{
172 PHP_POSIX_RETURN_LONG_FUNC(geteuid);
173}
174/* }}} */
175
176/* {{{ Get the current effective group id (POSIX.1, 4.2.1) */
178{
179 PHP_POSIX_RETURN_LONG_FUNC(getegid);
180}
181/* }}} */
182
183/* {{{ Set user id (POSIX.1, 4.2.2) */
185{
186 PHP_POSIX_SINGLE_ARG_FUNC(setuid);
187}
188/* }}} */
189
190/* {{{ Set group id (POSIX.1, 4.2.2) */
192{
193 PHP_POSIX_SINGLE_ARG_FUNC(setgid);
194}
195/* }}} */
196
197/* {{{ Set effective user id */
198#ifdef HAVE_SETEUID
200{
201 PHP_POSIX_SINGLE_ARG_FUNC(seteuid);
202}
203#endif
204/* }}} */
205
206/* {{{ Set effective group id */
207#ifdef HAVE_SETEGID
209{
210 PHP_POSIX_SINGLE_ARG_FUNC(setegid);
211}
212#endif
213/* }}} */
214
215/* {{{ Get supplementary group id's (POSIX.1, 4.2.3) */
216#ifdef HAVE_GETGROUPS
218{
219 gid_t *gidlist;
220 int result;
221 int i;
222
224
225 /* MacOS may return more than NGROUPS_MAX groups.
226 * Fetch the actual number of groups and create an appropriate allocation. */
227 if ((result = getgroups(0, NULL)) < 0) {
228 POSIX_G(last_error) = errno;
230 }
231
232 gidlist = emalloc(sizeof(gid_t) * result);
233 if ((result = getgroups(result, gidlist)) < 0) {
234 POSIX_G(last_error) = errno;
235 efree(gidlist);
237 }
238
240
241 for (i=0; i<result; i++) {
243 }
244 efree(gidlist);
245}
246#endif
247/* }}} */
248
249/* {{{ Get user name (POSIX.1, 4.2.4) */
250#ifdef HAVE_GETLOGIN
252{
253 char *p;
254
256
257 if (NULL == (p = getlogin())) {
258 POSIX_G(last_error) = errno;
260 }
261
263}
264#endif
265/* }}} */
266
267/* {{{ Get current process group id (POSIX.1, 4.3.1) */
269{
270 PHP_POSIX_RETURN_LONG_FUNC(getpgrp);
271}
272/* }}} */
273
274/* {{{ Create session and set process group id (POSIX.1, 4.3.2) */
275#ifdef HAVE_SETSID
277{
278 PHP_POSIX_RETURN_LONG_FUNC(setsid);
279}
280#endif
281/* }}} */
282
283/* {{{ Set process group id for job control (POSIX.1, 4.3.3) */
285{
286 zend_long pid, pgid;
287
289 Z_PARAM_LONG(pid)
290 Z_PARAM_LONG(pgid)
292
293 if (setpgid(pid, pgid) < 0) {
294 POSIX_G(last_error) = errno;
296 }
297
299}
300/* }}} */
301
302/* {{{ Get the process group id of the specified process (This is not a POSIX function, but a SVR4ism, so we compile conditionally) */
303#ifdef HAVE_GETPGID
305{
307
311
312 if ((val = getpgid(val)) < 0) {
313 POSIX_G(last_error) = errno;
315 }
317}
318#endif
319/* }}} */
320
321/* {{{ Get process group id of session leader (This is not a POSIX function, but a SVR4ism, so be compile conditionally) */
322#ifdef HAVE_GETSID
324{
326
330
331 if ((val = getsid(val)) < 0) {
332 POSIX_G(last_error) = errno;
334 }
336}
337#endif
338/* }}} */
339
340/* {{{ Get system name (POSIX.1, 4.4.1) */
342{
343 struct utsname u;
344
346
347 if (uname(&u) < 0) {
348 POSIX_G(last_error) = errno;
350 }
351
353
354 add_assoc_string(return_value, "sysname", u.sysname);
355 add_assoc_string(return_value, "nodename", u.nodename);
356 add_assoc_string(return_value, "release", u.release);
357 add_assoc_string(return_value, "version", u.version);
358 add_assoc_string(return_value, "machine", u.machine);
359
360#if defined(_GNU_SOURCE) && defined(HAVE_STRUCT_UTSNAME_DOMAINNAME)
361 add_assoc_string(return_value, "domainname", u.domainname);
362#endif
363}
364/* }}} */
365
366/* POSIX.1, 4.5.1 time() - Get System Time
367 already covered by PHP
368 */
369
370/* {{{ Get process times (POSIX.1, 4.5.2) */
372{
373 struct tms t;
374 clock_t ticks;
375
377
378 if ((ticks = times(&t)) == -1) {
379 POSIX_G(last_error) = errno;
381 }
382
384
385 add_assoc_long(return_value, "ticks", ticks); /* clock ticks */
386 add_assoc_long(return_value, "utime", t.tms_utime); /* user time */
387 add_assoc_long(return_value, "stime", t.tms_stime); /* system time */
388 add_assoc_long(return_value, "cutime", t.tms_cutime); /* user time of children */
389 add_assoc_long(return_value, "cstime", t.tms_cstime); /* system time of children */
390}
391/* }}} */
392
393/* POSIX.1, 4.6.1 getenv() - Environment Access
394 already covered by PHP
395*/
396
397/* {{{ Generate terminal path name (POSIX.1, 4.7.1) */
398#ifdef HAVE_CTERMID
400{
401 char buffer[L_ctermid];
402
404
405 if (NULL == ctermid(buffer)) {
406 /* Found no documentation how the defined behaviour is when this
407 * function fails
408 */
409 POSIX_G(last_error) = errno;
411 }
412
414}
415#endif
416/* }}} */
417
418/* Checks if the provides resource is a stream and if it provides a file descriptor */
419static zend_result php_posix_stream_get_fd(zval *zfp, zend_long *ret) /* {{{ */
420{
421 php_stream *stream;
422
424
425 if (stream == NULL) {
426 return FAILURE;
427 }
428
429 /* get the fd. php_socket_t is used for FDs, and is shorter than zend_long.
430 * NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag when casting.
431 * It is only used here so that the buffered data warning is not displayed.
432 */
433 php_socket_t fd = -1;
438 } else {
439 php_error_docref(NULL, E_WARNING, "Could not use stream of type '%s'",
440 stream->ops->label);
441 return FAILURE;
442 }
443 *ret = fd;
444 return SUCCESS;
445}
446/* }}} */
447
448/* {{{ Determine terminal device name (POSIX.1, 4.7.2) */
450{
451 zval *z_fd;
452 char *p;
453 zend_long fd = 0;
454#if defined(ZTS) && defined(HAVE_TTYNAME_R) && defined(_SC_TTY_NAME_MAX)
455 zend_long buflen;
456 int err;
457#endif
458
460 Z_PARAM_ZVAL(z_fd)
462
463 if (Z_TYPE_P(z_fd) == IS_RESOURCE) {
464 if (php_posix_stream_get_fd(z_fd, &fd) == FAILURE) {
466 }
467 } else {
468 if (!zend_parse_arg_long(z_fd, &fd, /* is_null */ NULL, /* check_null */ false, /* arg_num */ 1)) {
469 php_error_docref(NULL, E_WARNING, "Argument #1 ($file_descriptor) must be of type int|resource, %s given",
471 fd = zval_get_long(z_fd);
472 }
473 /* fd must fit in an int and be positive */
475 php_error_docref(NULL, E_WARNING, "Argument #1 ($file_descriptor) must be between 0 and %d", INT_MAX);
477 }
478 }
479#if defined(ZTS) && defined(HAVE_TTYNAME_R) && defined(_SC_TTY_NAME_MAX)
480 buflen = sysconf(_SC_TTY_NAME_MAX);
481 if (buflen < 1) {
482 buflen = 32;
483 }
484#if ZEND_DEBUG
485 /* Test retry logic */
486 buflen = 1;
487#endif
488 p = emalloc(buflen);
489
490try_again:
491 err = ttyname_r(fd, p, buflen);
492 if (err) {
493 if (err == ERANGE) {
494 buflen *= 2;
495 p = erealloc(p, buflen);
496 goto try_again;
497 }
498 POSIX_G(last_error) = err;
499 efree(p);
501 }
503 efree(p);
504#else
505 if (NULL == (p = ttyname(fd))) {
506 POSIX_G(last_error) = errno;
508 }
510#endif
511}
512/* }}} */
513
514/* {{{ Determine if filedesc is a tty (POSIX.1, 4.7.1) */
516{
517 zval *z_fd;
518 zend_long fd = 0;
519
521 Z_PARAM_ZVAL(z_fd)
523
524 if (Z_TYPE_P(z_fd) == IS_RESOURCE) {
525 if (php_posix_stream_get_fd(z_fd, &fd) == FAILURE) {
527 }
528 } else {
529 if (!zend_parse_arg_long(z_fd, &fd, /* is_null */ NULL, /* check_null */ false, /* arg_num */ 1)) {
530 php_error_docref(NULL, E_WARNING, "Argument #1 ($file_descriptor) must be of type int|resource, %s given",
533 }
534 }
535
536 /* A valid file descriptor must fit in an int and be positive */
538 POSIX_G(last_error) = EBADF;
540 }
541 if (isatty(fd)) {
543 } else {
544 POSIX_G(last_error) = errno;
546 }
547}
548/* }}} */
549
550/*
551 POSIX.1, 4.8.1 sysconf()
552 POSIX.1, 5.7.1 pathconf(), fpathconf()
553
554 POSIX.1, 5.1.2 opendir(), readdir(), rewinddir(), closedir()
555 POSIX.1, 5.2.1 chdir()
556 already supported by PHP
557 */
558
559/* {{{ Get working directory pathname (POSIX.1, 5.2.2) */
561{
562 char buffer[MAXPATHLEN];
563 char *p;
564
566
568 if (!p) {
569 POSIX_G(last_error) = errno;
571 }
572
574}
575/* }}} */
576
577/*
578 POSIX.1, 5.3.x open(), creat(), umask()
579 POSIX.1, 5.4.1 link()
580 already supported by PHP.
581 */
582
583/* {{{ Make a FIFO special file (POSIX.1, 5.4.2) */
584#ifdef HAVE_MKFIFO
586{
587 zend_string *path;
589 int result;
590
592 Z_PARAM_PATH_STR(path)
595
598 }
599
600 result = mkfifo(ZSTR_VAL(path), mode);
601 if (result < 0) {
602 POSIX_G(last_error) = errno;
604 }
605
607}
608#endif
609/* }}} */
610
611/* {{{ Make a special or ordinary file (POSIX.1) */
612#ifdef HAVE_MKNOD
614{
615 zend_string *path;
617 zend_long major = 0, minor = 0;
618 int result;
619 dev_t php_dev = 0;
620
622 Z_PARAM_PATH_STR(path)
628
631 }
632
633 if ((mode & S_IFCHR) || (mode & S_IFBLK)) {
634 if (major == 0) {
635 zend_argument_value_error(3, "cannot be 0 for the POSIX_S_IFCHR and POSIX_S_IFBLK modes");
637 } else {
638#ifdef HAVE_MAKEDEV
639 php_dev = makedev(major, minor);
640#else
641 php_error_docref(NULL, E_WARNING, "Cannot create a block or character device, creating a normal file instead");
642#endif
643 }
644 }
645
646 result = mknod(ZSTR_VAL(path), mode, php_dev);
647 if (result < 0) {
648 POSIX_G(last_error) = errno;
650 }
651
653}
654#endif
655/* }}} */
656
657/* Takes a pointer to posix group and a pointer to an already initialized ZVAL
658 * array container and fills the array with the posix group member data. */
659int php_posix_group_to_array(struct group *g, zval *array_group) /* {{{ */
660{
661 zval array_members;
662 int count;
663
664 if (NULL == g)
665 return 0;
666
667 if (array_group == NULL || Z_TYPE_P(array_group) != IS_ARRAY)
668 return 0;
669
670 array_init(&array_members);
671
672 add_assoc_string(array_group, "name", g->gr_name);
673 if (g->gr_passwd) {
674 add_assoc_string(array_group, "passwd", g->gr_passwd);
675 } else {
676 add_assoc_null(array_group, "passwd");
677 }
678 for (count = 0;; count++) {
679 /* gr_mem entries may be misaligned on macos. */
680 char *gr_mem;
681 memcpy(&gr_mem, &g->gr_mem[count], sizeof(char *));
682 if (!gr_mem) {
683 break;
684 }
685
686 add_next_index_string(&array_members, gr_mem);
687 }
688 zend_hash_str_update(Z_ARRVAL_P(array_group), "members", sizeof("members")-1, &array_members);
689 add_assoc_long(array_group, "gid", g->gr_gid);
690 return 1;
691}
692/* }}} */
693
694/*
695 POSIX.1, 5.5.1 unlink()
696 POSIX.1, 5.5.2 rmdir()
697 POSIX.1, 5.5.3 rename()
698 POSIX.1, 5.6.x stat(), chmod(), utime() already supported by PHP.
699*/
700
701/* {{{ Determine accessibility of a file (POSIX.1 5.6.3) */
703{
704 zend_long mode = 0;
705 size_t filename_len, ret;
706 char *filename, *path;
707
709 Z_PARAM_PATH(filename, filename_len)
713
714 path = expand_filepath(filename, NULL);
715 if (!path) {
716 POSIX_G(last_error) = EIO;
718 }
719
720 if (php_check_open_basedir_ex(path, 0)) {
721 efree(path);
722 POSIX_G(last_error) = EPERM;
724 }
725
726 ret = access(path, mode);
727 efree(path);
728
729 if (ret) {
730 POSIX_G(last_error) = errno;
732 }
733
735}
736
737#ifdef HAVE_EACCESS
739{
740 zend_long mode = 0;
741 size_t filename_len, ret;
742 char *filename, *path;
743
745 Z_PARAM_PATH(filename, filename_len)
749
750 path = expand_filepath(filename, NULL);
751 if (!path) {
754 }
755
756 if (php_check_open_basedir_ex(path, 0)) {
757 efree(path);
758 POSIX_G(last_error) = EPERM;
760 }
761
762 ret = eaccess(path, mode);
763 efree(path);
764
765 if (ret) {
766 POSIX_G(last_error) = errno;
768 }
769
771}
772#endif
773
774/* }}} */
775
776/*
777 POSIX.1, 6.x most I/O functions already supported by PHP.
778 POSIX.1, 7.x tty functions, TODO
779 POSIX.1, 8.x interactions with other C language functions
780 POSIX.1, 9.x system database access
781*/
782
783/* {{{ Group database access (POSIX.1, 9.2.1) */
785{
786 char *name;
787 struct group *g;
788 size_t name_len;
789#if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
790 struct group gbuf;
791 long buflen;
792 char *buf;
793 int err;
794#endif
795
797 Z_PARAM_STRING(name, name_len)
799
800#if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
801 buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
802 if (buflen < 1) {
803 buflen = 1024;
804 }
805#if ZEND_DEBUG
806 /* Test retry logic */
807 buflen = 1;
808#endif
809 buf = emalloc(buflen);
810try_again:
811 g = &gbuf;
812
813 err = getgrnam_r(name, g, buf, buflen, &g);
814 if (err || g == NULL) {
815 if (err == ERANGE) {
816 buflen *= 2;
817 buf = erealloc(buf, buflen);
818 goto try_again;
819 }
820 POSIX_G(last_error) = err;
821 efree(buf);
823 }
824#else
825 if (NULL == (g = getgrnam(name))) {
826 POSIX_G(last_error) = errno;
828 }
829#endif
831
832 if (!php_posix_group_to_array(g, return_value)) {
834 php_error_docref(NULL, E_WARNING, "Unable to convert posix group to array");
836 }
837#if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
838 efree(buf);
839#endif
840}
841/* }}} */
842
843/* {{{ Group database access (POSIX.1, 9.2.1) */
845{
846 zend_long gid;
847#if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
848 int err;
849 struct group _g;
850 struct group *retgrptr = NULL;
851 long grbuflen;
852 char *grbuf;
853#endif
854 struct group *g;
855
857 Z_PARAM_LONG(gid)
859
860#if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
861
862 grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
863 if (grbuflen < 1) {
864 grbuflen = 1024;
865 }
866#if ZEND_DEBUG
867 /* Test retry logic */
868 grbuflen = 1;
869#endif
870
871 grbuf = emalloc(grbuflen);
872
873try_again:
874 err = getgrgid_r(gid, &_g, grbuf, grbuflen, &retgrptr);
875 if (err || retgrptr == NULL) {
876 if (err == ERANGE) {
877 grbuflen *= 2;
878 grbuf = erealloc(grbuf, grbuflen);
879 goto try_again;
880 }
881 POSIX_G(last_error) = err;
882 efree(grbuf);
884 }
885 g = &_g;
886#else
887 if (NULL == (g = getgrgid(gid))) {
888 POSIX_G(last_error) = errno;
890 }
891#endif
893
894 if (!php_posix_group_to_array(g, return_value)) {
896 php_error_docref(NULL, E_WARNING, "Unable to convert posix group struct to array");
898 }
899#if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
900 efree(grbuf);
901#endif
902}
903/* }}} */
904
905int php_posix_passwd_to_array(struct passwd *pw, zval *return_value) /* {{{ */
906{
907 if (NULL == pw)
908 return 0;
910 return 0;
911
912 add_assoc_string(return_value, "name", pw->pw_name);
913 add_assoc_string(return_value, "passwd", pw->pw_passwd);
914 add_assoc_long (return_value, "uid", pw->pw_uid);
915 add_assoc_long (return_value, "gid", pw->pw_gid);
916 add_assoc_string(return_value, "gecos", pw->pw_gecos);
917 add_assoc_string(return_value, "dir", pw->pw_dir);
918 add_assoc_string(return_value, "shell", pw->pw_shell);
919 return 1;
920}
921/* }}} */
922
923/* {{{ User database access (POSIX.1, 9.2.2) */
925{
926 struct passwd *pw;
927 char *name;
928 size_t name_len;
929#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
930 struct passwd pwbuf;
931 long buflen;
932 char *buf;
933 int err;
934#endif
935
937 Z_PARAM_STRING(name, name_len)
939
940#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
941 buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
942 if (buflen < 1) {
943 buflen = 1024;
944 }
945#if ZEND_DEBUG
946 /* Test retry logic */
947 buflen = 1;
948#endif
949 buf = emalloc(buflen);
950
951try_again:
952 pw = &pwbuf;
953 err = getpwnam_r(name, pw, buf, buflen, &pw);
954 if (err || pw == NULL) {
955 if (err == ERANGE) {
956 buflen *= 2;
957 buf = erealloc(buf, buflen);
958 goto try_again;
959 }
960 efree(buf);
961 POSIX_G(last_error) = err;
963 }
964#else
965 if (NULL == (pw = getpwnam(name))) {
966 POSIX_G(last_error) = errno;
968 }
969#endif
971
972 if (!php_posix_passwd_to_array(pw, return_value)) {
974 php_error_docref(NULL, E_WARNING, "Unable to convert posix passwd struct to array");
976 }
977#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
978 efree(buf);
979#endif
980}
981/* }}} */
982
983/* {{{ User database access (POSIX.1, 9.2.2) */
985{
986 zend_long uid;
987#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
988 struct passwd _pw;
989 struct passwd *retpwptr = NULL;
990 long pwbuflen;
991 char *pwbuf;
992 int err;
993#endif
994 struct passwd *pw;
995
997 Z_PARAM_LONG(uid)
999
1000#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
1001 pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
1002 if (pwbuflen < 1) {
1003 pwbuflen = 1024;
1004 }
1005#if ZEND_DEBUG
1006 /* Test retry logic */
1007 pwbuflen = 1;
1008#endif
1009 pwbuf = emalloc(pwbuflen);
1010
1011try_again:
1012 err = getpwuid_r(uid, &_pw, pwbuf, pwbuflen, &retpwptr);
1013 if (err || retpwptr == NULL) {
1014 if (err == ERANGE) {
1015 pwbuflen *= 2;
1016 pwbuf = erealloc(pwbuf, pwbuflen);
1017 goto try_again;
1018 }
1019 POSIX_G(last_error) = err;
1020 efree(pwbuf);
1022 }
1023 pw = &_pw;
1024#else
1025 if (NULL == (pw = getpwuid(uid))) {
1026 POSIX_G(last_error) = errno;
1028 }
1029#endif
1031
1032 if (!php_posix_passwd_to_array(pw, return_value)) {
1034 php_error_docref(NULL, E_WARNING, "Unable to convert posix passwd struct to array");
1036 }
1037#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
1038 efree(pwbuf);
1039#endif
1040}
1041/* }}} */
1042
1043
1044#ifdef HAVE_GETRLIMIT
1045
1046#define UNLIMITED_STRING "unlimited"
1047
1048/* {{{ posix_addlimit */
1049static zend_result posix_addlimit(int limit, const char *name, zval *return_value) {
1050 int result;
1051 struct rlimit rl;
1052 char hard[80];
1053 char soft[80];
1054
1055 snprintf(hard, 80, "hard %s", name);
1056 snprintf(soft, 80, "soft %s", name);
1057
1058 result = getrlimit(limit, &rl);
1059 if (result < 0) {
1060 POSIX_G(last_error) = errno;
1061 return FAILURE;
1062 }
1063
1064 if (rl.rlim_cur == RLIM_INFINITY) {
1065 add_assoc_stringl(return_value, soft, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1);
1066 } else {
1067 add_assoc_long(return_value, soft, rl.rlim_cur);
1068 }
1069
1070 if (rl.rlim_max == RLIM_INFINITY) {
1071 add_assoc_stringl(return_value, hard, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1);
1072 } else {
1073 add_assoc_long(return_value, hard, rl.rlim_max);
1074 }
1075
1076 return SUCCESS;
1077}
1078/* }}} */
1079
1080/* {{{ limits[] */
1081static const struct limitlist {
1082 int limit;
1083 const char *name;
1084} limits[] = {
1085#ifdef RLIMIT_CORE
1086 { RLIMIT_CORE, "core" },
1087#endif
1088
1089#ifdef RLIMIT_DATA
1090 { RLIMIT_DATA, "data" },
1091#endif
1092
1093#ifdef RLIMIT_STACK
1094 { RLIMIT_STACK, "stack" },
1095#endif
1096
1097#ifdef RLIMIT_VMEM
1098 { RLIMIT_VMEM, "virtualmem" },
1099#endif
1100
1101#ifdef RLIMIT_AS
1102 { RLIMIT_AS, "totalmem" },
1103#endif
1104
1105#ifdef RLIMIT_RSS
1106 { RLIMIT_RSS, "rss" },
1107#endif
1108
1109#ifdef RLIMIT_NPROC
1110 { RLIMIT_NPROC, "maxproc" },
1111#endif
1112
1113#ifdef RLIMIT_MEMLOCK
1114 { RLIMIT_MEMLOCK, "memlock" },
1115#endif
1116
1117#ifdef RLIMIT_CPU
1118 { RLIMIT_CPU, "cpu" },
1119#endif
1120
1121#ifdef RLIMIT_FSIZE
1122 { RLIMIT_FSIZE, "filesize" },
1123#endif
1124
1125#ifdef RLIMIT_NOFILE
1126 { RLIMIT_NOFILE, "openfiles" },
1127#endif
1128
1129#ifdef RLIMIT_OFILE
1130 { RLIMIT_OFILE, "openfiles" },
1131#endif
1132
1133#ifdef RLIMIT_KQUEUES
1134 { RLIMIT_KQUEUES, "kqueues" },
1135#endif
1136
1137#ifdef RLIMIT_NPTS
1138 { RLIMIT_NPTS, "npts" },
1139#endif
1140
1141 { 0, NULL }
1142};
1143/* }}} */
1144
1145
1146/* {{{ Get system resource consumption limits (This is not a POSIX function, but a BSDism and a SVR4ism. We compile conditionally) */
1148{
1149 const struct limitlist *l = NULL;
1150 zend_long res;
1151 bool res_is_null = true;
1152
1155 Z_PARAM_LONG_OR_NULL(res, res_is_null)
1157
1158 if (res_is_null) {
1160
1161 for (l=limits; l->name; l++) {
1162 if (posix_addlimit(l->limit, l->name, return_value) == FAILURE) {
1165 }
1166 }
1167 } else {
1168 struct rlimit rl;
1169 int result = getrlimit(res, &rl);
1170 if (result < 0) {
1171 POSIX_G(last_error) = errno;
1173 }
1174
1176 if (rl.rlim_cur == RLIM_INFINITY) {
1177 add_next_index_stringl(return_value, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1);
1178 } else {
1179 add_next_index_long(return_value, rl.rlim_cur);
1180 }
1181
1182 if (rl.rlim_max == RLIM_INFINITY) {
1183 add_next_index_stringl(return_value, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1);
1184 } else {
1185 add_next_index_long(return_value, rl.rlim_max);
1186 }
1187 }
1188}
1189/* }}} */
1190
1191#endif /* HAVE_GETRLIMIT */
1192
1193#ifdef HAVE_SETRLIMIT
1194/* {{{ Set system resource consumption limits (POSIX.1-2001) */
1196{
1197 struct rlimit rl;
1198 zend_long res, cur, max;
1199
1202 Z_PARAM_LONG(cur)
1205
1206 rl.rlim_cur = cur;
1207 rl.rlim_max = max;
1208
1209 if (setrlimit(res, &rl) == -1) {
1210 POSIX_G(last_error) = errno;
1212 }
1213
1215}
1216/* }}} */
1217
1218#endif /* HAVE_SETRLIMIT */
1219
1220
1221/* {{{ Retrieve the error number set by the last posix function which failed. */
1223{
1225
1226 RETURN_LONG(POSIX_G(last_error));
1227}
1228/* }}} */
1229
1230/* {{{ Retrieve the system error message associated with the given errno. */
1232{
1234
1238
1239 RETURN_STRING(strerror(error));
1240}
1241/* }}} */
1242
1243#endif
1244
1245#ifdef HAVE_INITGROUPS
1246/* {{{ Calculate the group access list for the user specified in name. */
1248{
1249 zend_long basegid;
1250 char *name;
1251 size_t name_len;
1252
1254 Z_PARAM_STRING(name, name_len)
1255 Z_PARAM_LONG(basegid)
1257
1258 if (name_len == 0) {
1260 }
1261
1262 RETURN_BOOL(!initgroups((const char *)name, basegid));
1263}
1264/* }}} */
1265#endif
1266
1268{
1269 zend_long conf_id;
1270
1272 Z_PARAM_LONG(conf_id)
1274
1275 RETURN_LONG(sysconf(conf_id));
1276}
1277
1278#ifdef HAVE_PATHCONF
1280{
1282 char *path;
1283 size_t path_len;
1284
1286 Z_PARAM_PATH(path, path_len)
1289
1290 if (path_len == 0) {
1292 RETURN_THROWS();
1293 } else if (php_check_open_basedir(path)) {
1294 php_error_docref(NULL, E_WARNING, "Invalid path supplied: %s", path);
1296 }
1297
1298 ret = pathconf(path, name);
1299
1300 if (ret < 0 && errno != 0) {
1301 POSIX_G(last_error) = errno;
1303 }
1304
1306}
1307#endif
1308
1309#ifdef HAVE_FPATHCONF
1311{
1312 zend_long name, ret, fd = 0;
1313 zval *z_fd;
1314
1316 Z_PARAM_ZVAL(z_fd)
1319
1320 if (Z_TYPE_P(z_fd) == IS_RESOURCE) {
1321 if (php_posix_stream_get_fd(z_fd, &fd) == FAILURE) {
1323 }
1324 } else {
1325 if (!zend_parse_arg_long(z_fd, &fd, /* is_null */ NULL, /* check_null */ false, /* arg_num */ 1)) {
1326 zend_argument_type_error(1, "must be of type int|resource, %s given",
1327 zend_zval_value_name(z_fd));
1328 RETURN_THROWS();
1329 }
1330 }
1331
1332 ret = fpathconf(fd, name);
1333
1334 if (ret < 0 && errno != 0) {
1335 POSIX_G(last_error) = errno;
1337 }
1338
1340}
1341#endif
count(Countable|array $value, int $mode=COUNT_NORMAL)
uint32_t u
Definition cdf.c:78
#define max(a, b)
Definition exif.c:60
error($message)
Definition ext_skel.php:22
zend_string * res
Definition ffi.c:4692
memcpy(ptr1, ptr2, size)
char * err
Definition ffi.c:3029
zval * val
Definition ffi.c:4262
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
PHPAPI int php_check_open_basedir(const char *path)
PHPAPI char * expand_filepath(const char *filepath, char *real_path)
PHPAPI int php_check_open_basedir_ex(const char *path, int warn)
#define minor(dev)
Definition fsmagic.c:66
#define major(dev)
Definition fsmagic.c:65
char * mode
size_t filename_len
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
Definition main.c:1173
php_info_print_table_start()
Definition info.c:1064
php_info_print_table_row(2, "PDO Driver for Firebird", "enabled")
php_info_print_table_end()
Definition info.c:1074
#define PHP_GINIT
Definition php.h:397
#define PHP_FUNCTION
Definition php.h:364
#define PHP_MINFO
Definition php.h:396
#define PHP_MINIT_FUNCTION
Definition php.h:400
#define PHP_MINFO_FUNCTION
Definition php.h:404
#define PHP_GINIT_FUNCTION
Definition php.h:405
#define INT_MAX
Definition php.h:237
#define PHP_MINIT
Definition php.h:392
#define PHP_MODULE_GLOBALS
Definition php.h:408
int php_socket_t
int last_error
Definition php_pcntl.h:48
#define php_stream_cast(stream, as, ret, show_err)
struct _php_stream php_stream
Definition php_streams.h:96
#define PHP_STREAM_AS_FD_FOR_SELECT
#define php_stream_can_cast(stream, as)
#define php_stream_from_zval_no_verify(xstr, pzval)
#define PHP_STREAM_AS_FD
#define PHP_STREAM_CAST_INTERNAL
int fd
Definition phpdbg.h:282
posix_setsid()
posix_getpid()
posix_pathconf(string $path, int $name)
posix_setrlimit(int $resource, int $soft_limit, int $hard_limit)
posix_getegid()
posix_strerror(int $error_code)
posix_getpgid(int $process_id)
posix_access(string $filename, int $flags=0)
posix_getgrnam(string $name)
posix_times()
posix_kill(int $process_id, int $signal)
posix_ctermid()
posix_getcwd()
posix_getgid()
posix_seteuid(int $user_id)
posix_getrlimit(?int $resource=null)
posix_sysconf(int $conf_id)
posix_get_last_error()
posix_setegid(int $group_id)
posix_getuid()
posix_getpwnam(string $username)
posix_getsid(int $process_id)
posix_setpgid(int $process_id, int $process_group_id)
posix_ttyname($file_descriptor)
posix_getgrgid(int $group_id)
posix_getppid()
posix_fpathconf($file_descriptor, int $name)
posix_setuid(int $user_id)
posix_mkfifo(string $filename, int $permissions)
posix_getpgrp()
posix_geteuid()
posix_initgroups(string $username, int $group_id)
posix_getgroups()
posix_setgid(int $group_id)
posix_mknod(string $filename, int $flags, int $major=0, int $minor=0)
posix_isatty($file_descriptor)
posix_eaccess(string $filename, int $flags=0)
posix_getpwuid(int $user_id)
posix_uname()
posix_getlogin()
p
Definition session.c:1105
const char * label
const php_stream_ops * ops
Definition file.h:177
#define errno
#define ZEND_TSRMLS_CACHE_UPDATE()
Definition zend.h:69
#define ZEND_TSRMLS_CACHE_DEFINE()
Definition zend.h:68
ZEND_API const char * zend_zval_value_name(const zval *arg)
Definition zend_API.c:148
ZEND_API zend_result add_next_index_stringl(zval *arg, const char *str, size_t length)
Definition zend_API.c:2195
ZEND_API zend_result add_next_index_long(zval *arg, zend_long n)
Definition zend_API.c:2132
ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num)
Definition zend_API.c:443
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:433
ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:423
ZEND_API zend_result add_next_index_string(zval *arg, const char *str)
Definition zend_API.c:2186
#define Z_PARAM_PATH_STR(dest)
Definition zend_API.h:2041
#define RETURN_STRING(s)
Definition zend_API.h:1043
#define ZEND_PARSE_PARAMETERS_END()
Definition zend_API.h:1641
#define RETURN_FALSE
Definition zend_API.h:1058
#define RETVAL_STRING(s)
Definition zend_API.h:1017
#define ZEND_PARSE_PARAMETERS_NONE()
Definition zend_API.h:1623
#define ZEND_DECLARE_MODULE_GLOBALS(module_name)
Definition zend_API.h:268
#define Z_PARAM_OPTIONAL
Definition zend_API.h:1667
#define ZEND_GET_MODULE(name)
Definition zend_API.h:241
#define Z_PARAM_STRING(dest, dest_len)
Definition zend_API.h:2071
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
Definition zend_API.h:1620
#define Z_PARAM_LONG(dest)
Definition zend_API.h:1896
#define RETURN_LONG(l)
Definition zend_API.h:1037
#define RETURN_BOOL(b)
Definition zend_API.h:1035
#define RETURN_THROWS()
Definition zend_API.h:1060
#define Z_PARAM_LONG_OR_NULL(dest, is_null)
Definition zend_API.h:1899
#define Z_PARAM_PATH(dest, dest_len)
Definition zend_API.h:2026
#define Z_PARAM_ZVAL(dest)
Definition zend_API.h:2100
#define RETVAL_FALSE
Definition zend_API.h:1032
#define RETURN_TRUE
Definition zend_API.h:1059
#define array_init(arg)
Definition zend_API.h:537
#define efree(ptr)
Definition zend_alloc.h:155
#define erealloc(ptr, size)
Definition zend_alloc.h:159
#define emalloc(size)
Definition zend_alloc.h:151
struct _zval_struct zval
#define snprintf
#define E_WARNING
Definition zend_errors.h:24
ZEND_API zval *ZEND_FASTCALL zend_hash_str_update(HashTable *ht, const char *str, size_t len, zval *pData)
Definition zend_hash.c:1031
ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
Definition zend_hash.c:1808
int32_t zend_long
Definition zend_long.h:42
struct _zend_string zend_string
#define STANDARD_MODULE_HEADER
struct _zend_module_entry zend_module_entry
#define STANDARD_MODULE_PROPERTIES_EX
ZEND_DLIMPORT int isatty(int fd)
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
#define Z_ARRVAL_P(zval_p)
Definition zend_types.h:987
#define IS_RESOURCE
Definition zend_types.h:609
#define IS_ARRAY
Definition zend_types.h:607
@ FAILURE
Definition zend_types.h:61
ZEND_RESULT_CODE zend_result
Definition zend_types.h:64
#define Z_ARR_P(zval_p)
Definition zend_types.h:984
#define S_IFBLK
#define VCWD_GETCWD(buff, size)
#define MAXPATHLEN
zval * return_value
zend_string * name
bool result
zval * ret