Back to index

php5  5.3.10
posix.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author: Kristian Koehntopp <kris@koehntopp.de>                       |
00016    +----------------------------------------------------------------------+
00017  */
00018 
00019 /* $Id: posix.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 #ifdef HAVE_CONFIG_H
00022 #include "config.h"
00023 #endif
00024 
00025 #include "php.h"
00026 #include <unistd.h>
00027 #include "ext/standard/info.h"
00028 #include "ext/standard/php_string.h"
00029 #include "php_posix.h"
00030 
00031 
00032 #if HAVE_POSIX
00033 
00034 #ifdef HAVE_SYS_TIME_H
00035 #include <sys/time.h>
00036 #endif
00037 
00038 #include <sys/resource.h>
00039 
00040 #if defined(_GNU_SOURCE) && !defined(__USE_GNU)
00041 # define __USE_GNU
00042 #endif
00043 
00044 #include <sys/utsname.h>
00045 #include <sys/types.h>
00046 #include <sys/stat.h>
00047 #include <signal.h>
00048 #include <sys/times.h>
00049 #include <errno.h>
00050 #include <grp.h>
00051 #include <pwd.h>
00052 #if HAVE_SYS_MKDEV_H
00053 # include <sys/mkdev.h>
00054 #endif
00055 
00056 ZEND_DECLARE_MODULE_GLOBALS(posix)
00057 static PHP_MINFO_FUNCTION(posix);
00058 
00059 /* {{{ arginfo */
00060 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_kill, 0, 0, 2)
00061        ZEND_ARG_INFO(0, pid)
00062        ZEND_ARG_INFO(0, sig)
00063 ZEND_END_ARG_INFO()
00064 
00065 ZEND_BEGIN_ARG_INFO(arginfo_posix_getpid, 0)
00066 ZEND_END_ARG_INFO()
00067 
00068 ZEND_BEGIN_ARG_INFO(arginfo_posix_getppid, 0)
00069 ZEND_END_ARG_INFO()
00070 
00071 ZEND_BEGIN_ARG_INFO(arginfo_posix_getuid, 0)
00072 ZEND_END_ARG_INFO()
00073 
00074 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_setuid, 0, 0, 1)
00075        ZEND_ARG_INFO(0, uid)
00076 ZEND_END_ARG_INFO()
00077 
00078 ZEND_BEGIN_ARG_INFO(arginfo_posix_geteuid, 0)
00079 ZEND_END_ARG_INFO()
00080 
00081 #ifdef HAVE_SETEUID
00082 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_seteuid, 0, 0, 1)
00083        ZEND_ARG_INFO(0, uid)
00084 ZEND_END_ARG_INFO()
00085 #endif
00086 
00087 ZEND_BEGIN_ARG_INFO(arginfo_posix_getgid, 0)
00088 ZEND_END_ARG_INFO()
00089 
00090 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_setgid, 0, 0, 1)
00091        ZEND_ARG_INFO(0, gid)
00092 ZEND_END_ARG_INFO()
00093 
00094 ZEND_BEGIN_ARG_INFO(arginfo_posix_getegid, 0)
00095 ZEND_END_ARG_INFO()
00096 
00097 #ifdef HAVE_SETEGID
00098 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_setegid, 0, 0, 1)
00099        ZEND_ARG_INFO(0, gid)
00100 ZEND_END_ARG_INFO()
00101 #endif
00102 
00103 #ifdef HAVE_GETGROUPS
00104 ZEND_BEGIN_ARG_INFO(arginfo_posix_getgroups, 0)
00105 ZEND_END_ARG_INFO()
00106 #endif
00107 
00108 #ifdef HAVE_GETLOGIN
00109 ZEND_BEGIN_ARG_INFO(arginfo_posix_getlogin, 0)
00110 ZEND_END_ARG_INFO()
00111 #endif
00112 
00113 ZEND_BEGIN_ARG_INFO(arginfo_posix_getpgrp, 0)
00114 ZEND_END_ARG_INFO()
00115 
00116 #ifdef HAVE_SETSID
00117 ZEND_BEGIN_ARG_INFO(arginfo_posix_setsid, 0)
00118 ZEND_END_ARG_INFO()
00119 #endif
00120 
00121 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_setpgid, 0, 0, 2)
00122        ZEND_ARG_INFO(0, pid)
00123        ZEND_ARG_INFO(0, pgid)
00124 ZEND_END_ARG_INFO()
00125 
00126 #ifdef HAVE_GETPGID
00127 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_getpgid, 0, 0, 1)
00128        ZEND_ARG_INFO(0, pid)
00129 ZEND_END_ARG_INFO()
00130 #endif
00131 
00132 #ifdef HAVE_GETSID
00133 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_getsid, 0, 0, 1)
00134        ZEND_ARG_INFO(0, pid)
00135 ZEND_END_ARG_INFO()
00136 #endif
00137 
00138 ZEND_BEGIN_ARG_INFO(arginfo_posix_uname, 0)
00139 ZEND_END_ARG_INFO()
00140 
00141 ZEND_BEGIN_ARG_INFO(arginfo_posix_times, 0)
00142 ZEND_END_ARG_INFO()
00143 
00144 #ifdef HAVE_CTERMID
00145 ZEND_BEGIN_ARG_INFO(arginfo_posix_ctermid, 0)
00146 ZEND_END_ARG_INFO()
00147 #endif
00148 
00149 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_ttyname, 0, 0, 1)
00150        ZEND_ARG_INFO(0, fd)
00151 ZEND_END_ARG_INFO()
00152 
00153 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_isatty, 0, 0, 1)
00154        ZEND_ARG_INFO(0, fd)
00155 ZEND_END_ARG_INFO()
00156 
00157 ZEND_BEGIN_ARG_INFO(arginfo_posix_getcwd, 0)
00158 ZEND_END_ARG_INFO()
00159 
00160 #ifdef HAVE_MKFIFO
00161 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_mkfifo, 0, 0, 2)
00162        ZEND_ARG_INFO(0, pathname)
00163        ZEND_ARG_INFO(0, mode)
00164 ZEND_END_ARG_INFO()
00165 #endif
00166 
00167 #ifdef HAVE_MKNOD
00168 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_mknod, 0, 0, 2)
00169        ZEND_ARG_INFO(0, pathname)
00170        ZEND_ARG_INFO(0, mode)
00171        ZEND_ARG_INFO(0, major)
00172        ZEND_ARG_INFO(0, minor)
00173 ZEND_END_ARG_INFO()
00174 #endif
00175 
00176 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_access, 0, 0, 1)
00177        ZEND_ARG_INFO(0, file)
00178        ZEND_ARG_INFO(0, mode)
00179 ZEND_END_ARG_INFO()
00180 
00181 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_getgrnam, 0, 0, 1)
00182        ZEND_ARG_INFO(0, name)
00183 ZEND_END_ARG_INFO()
00184 
00185 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_getgrgid, 0, 0, 1)
00186        ZEND_ARG_INFO(0, gid)
00187 ZEND_END_ARG_INFO()
00188 
00189 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_getpwnam, 0, 0, 1)
00190        ZEND_ARG_INFO(0, username)
00191 ZEND_END_ARG_INFO()
00192 
00193 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_getpwuid, 0, 0, 1)
00194        ZEND_ARG_INFO(0, uid)
00195 ZEND_END_ARG_INFO()
00196 
00197 #ifdef HAVE_GETRLIMIT
00198 ZEND_BEGIN_ARG_INFO(arginfo_posix_getrlimit, 0)
00199 ZEND_END_ARG_INFO()
00200 #endif
00201 
00202 ZEND_BEGIN_ARG_INFO(arginfo_posix_get_last_error, 0)
00203 ZEND_END_ARG_INFO()
00204 
00205 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_strerror, 0, 0, 1)
00206        ZEND_ARG_INFO(0, errno)
00207 ZEND_END_ARG_INFO()
00208 
00209 #ifdef HAVE_INITGROUPS
00210 ZEND_BEGIN_ARG_INFO_EX(arginfo_posix_initgroups, 0, 0, 2)
00211        ZEND_ARG_INFO(0, name)
00212        ZEND_ARG_INFO(0, base_group_id)
00213 ZEND_END_ARG_INFO()
00214 #endif
00215 /* }}} */
00216 
00217 /* {{{ posix_functions[]
00218  */
00219 const zend_function_entry posix_functions[] = {
00220     /* POSIX.1, 3.3 */
00221        PHP_FE(posix_kill,          arginfo_posix_kill)
00222 
00223        /* POSIX.1, 4.1 */
00224        PHP_FE(posix_getpid, arginfo_posix_getpid)
00225        PHP_FE(posix_getppid,       arginfo_posix_getppid)
00226 
00227        /* POSIX.1,  4.2 */
00228        PHP_FE(posix_getuid, arginfo_posix_getuid)
00229        PHP_FE(posix_setuid, arginfo_posix_setuid)
00230        PHP_FE(posix_geteuid,       arginfo_posix_geteuid)
00231 #ifdef HAVE_SETEUID
00232        PHP_FE(posix_seteuid,       arginfo_posix_seteuid)
00233 #endif
00234        PHP_FE(posix_getgid, arginfo_posix_getgid)
00235        PHP_FE(posix_setgid, arginfo_posix_setgid)
00236        PHP_FE(posix_getegid,       arginfo_posix_getegid)
00237 #ifdef HAVE_SETEGID
00238        PHP_FE(posix_setegid,       arginfo_posix_setegid)
00239 #endif
00240 #ifdef HAVE_GETGROUPS
00241        PHP_FE(posix_getgroups,     arginfo_posix_getgroups)
00242 #endif
00243 #ifdef HAVE_GETLOGIN
00244        PHP_FE(posix_getlogin,      arginfo_posix_getlogin)
00245 #endif
00246 
00247        /* POSIX.1, 4.3 */
00248        PHP_FE(posix_getpgrp,       arginfo_posix_getpgrp)
00249 #ifdef HAVE_SETSID
00250        PHP_FE(posix_setsid, arginfo_posix_setsid)
00251 #endif
00252        PHP_FE(posix_setpgid,       arginfo_posix_setpgid)
00253        /* Non-Posix functions which are common */
00254 #ifdef HAVE_GETPGID
00255        PHP_FE(posix_getpgid,       arginfo_posix_getpgid)
00256 #endif /* HAVE_GETPGID */
00257 #ifdef HAVE_GETSID
00258        PHP_FE(posix_getsid, arginfo_posix_getsid)
00259 #endif /* HAVE_GETSID */
00260 
00261        /* POSIX.1, 4.4 */
00262        PHP_FE(posix_uname,         arginfo_posix_uname)
00263 
00264        /* POSIX.1, 4.5 */
00265        PHP_FE(posix_times,         arginfo_posix_times)
00266 
00267        /* POSIX.1, 4.7 */
00268 #ifdef HAVE_CTERMID
00269        PHP_FE(posix_ctermid,       arginfo_posix_ctermid)
00270 #endif
00271        PHP_FE(posix_ttyname,       arginfo_posix_ttyname)
00272        PHP_FE(posix_isatty, arginfo_posix_isatty)
00273 
00274     /* POSIX.1, 5.2 */
00275        PHP_FE(posix_getcwd, arginfo_posix_getcwd)
00276 
00277        /* POSIX.1, 5.4 */
00278 #ifdef HAVE_MKFIFO
00279        PHP_FE(posix_mkfifo, arginfo_posix_mkfifo)
00280 #endif
00281 #ifdef HAVE_MKNOD
00282        PHP_FE(posix_mknod,         arginfo_posix_mknod)
00283 #endif
00284 
00285        /* POSIX.1, 5.6 */
00286        PHP_FE(posix_access, arginfo_posix_access)
00287        /* POSIX.1, 9.2 */
00288        PHP_FE(posix_getgrnam,      arginfo_posix_getgrnam)
00289        PHP_FE(posix_getgrgid,      arginfo_posix_getgrgid)
00290        PHP_FE(posix_getpwnam,      arginfo_posix_getpwnam)
00291        PHP_FE(posix_getpwuid,      arginfo_posix_getpwuid)
00292 
00293 #ifdef HAVE_GETRLIMIT
00294        PHP_FE(posix_getrlimit,     arginfo_posix_getrlimit)
00295 #endif
00296 
00297        PHP_FE(posix_get_last_error,                                   arginfo_posix_get_last_error)
00298        PHP_FALIAS(posix_errno, posix_get_last_error,    arginfo_posix_get_last_error)
00299        PHP_FE(posix_strerror,                                                arginfo_posix_strerror)
00300 #ifdef HAVE_INITGROUPS
00301        PHP_FE(posix_initgroups,    arginfo_posix_initgroups)
00302 #endif
00303 
00304        PHP_FE_END
00305 };
00306 /* }}} */
00307 
00308 /* {{{ PHP_MINFO_FUNCTION
00309  */
00310 static PHP_MINFO_FUNCTION(posix)
00311 {
00312        php_info_print_table_start();
00313        php_info_print_table_row(2, "Revision", "$Revision: 321634 $");
00314        php_info_print_table_end();
00315 }
00316 /* }}} */
00317 
00318 static PHP_GINIT_FUNCTION(posix) /* {{{ */
00319 {
00320        posix_globals->last_error = 0;
00321 }
00322 /* }}} */
00323 
00324 /* {{{ PHP_MINIT_FUNCTION(posix)
00325  */
00326 static PHP_MINIT_FUNCTION(posix)
00327 {
00328        REGISTER_LONG_CONSTANT("POSIX_F_OK", F_OK, CONST_CS | CONST_PERSISTENT);
00329        REGISTER_LONG_CONSTANT("POSIX_X_OK", X_OK, CONST_CS | CONST_PERSISTENT);
00330        REGISTER_LONG_CONSTANT("POSIX_W_OK", W_OK, CONST_CS | CONST_PERSISTENT);
00331        REGISTER_LONG_CONSTANT("POSIX_R_OK", R_OK, CONST_CS | CONST_PERSISTENT);
00332 #ifdef S_IFREG
00333        REGISTER_LONG_CONSTANT("POSIX_S_IFREG", S_IFREG, CONST_CS | CONST_PERSISTENT);
00334 #endif
00335 #ifdef S_IFCHR
00336        REGISTER_LONG_CONSTANT("POSIX_S_IFCHR", S_IFCHR, CONST_CS | CONST_PERSISTENT);
00337 #endif
00338 #ifdef S_IFBLK
00339        REGISTER_LONG_CONSTANT("POSIX_S_IFBLK", S_IFBLK, CONST_CS | CONST_PERSISTENT);
00340 #endif
00341 #ifdef S_IFIFO
00342        REGISTER_LONG_CONSTANT("POSIX_S_IFIFO", S_IFIFO, CONST_CS | CONST_PERSISTENT);
00343 #endif
00344 #ifdef S_IFSOCK
00345        REGISTER_LONG_CONSTANT("POSIX_S_IFSOCK", S_IFSOCK, CONST_CS | CONST_PERSISTENT);
00346 #endif
00347 
00348        return SUCCESS;
00349 }
00350 /* }}} */
00351 
00352 /* {{{ posix_module_entry
00353  */
00354 zend_module_entry posix_module_entry = {
00355        STANDARD_MODULE_HEADER,
00356        "posix", 
00357        posix_functions, 
00358        PHP_MINIT(posix),
00359        NULL,
00360        NULL,
00361        NULL, 
00362        PHP_MINFO(posix),
00363        NO_VERSION_YET,
00364        PHP_MODULE_GLOBALS(posix),
00365        PHP_GINIT(posix),
00366        NULL,
00367        NULL,
00368        STANDARD_MODULE_PROPERTIES_EX
00369 };
00370 /* }}} */
00371 
00372 #ifdef COMPILE_DL_POSIX
00373 ZEND_GET_MODULE(posix)
00374 #endif
00375 
00376 #define PHP_POSIX_NO_ARGS   if (zend_parse_parameters_none() == FAILURE) return;
00377 
00378 #define PHP_POSIX_RETURN_LONG_FUNC(func_name)    \
00379        PHP_POSIX_NO_ARGS    \
00380        RETURN_LONG(func_name());
00381 
00382 #define PHP_POSIX_SINGLE_ARG_FUNC(func_name)     \
00383        long val;     \
00384        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &val) == FAILURE) RETURN_FALSE;  \
00385        if (func_name(val) < 0) {   \
00386               POSIX_G(last_error) = errno;       \
00387               RETURN_FALSE; \
00388        }      \
00389        RETURN_TRUE;
00390 
00391 /* {{{ proto bool posix_kill(int pid, int sig)
00392    Send a signal to a process (POSIX.1, 3.3.2) */
00393 
00394 PHP_FUNCTION(posix_kill)
00395 {
00396        long pid, sig;
00397 
00398        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &pid, &sig) == FAILURE) {
00399               RETURN_FALSE;
00400        }
00401               
00402        if (kill(pid, sig) < 0) {
00403               POSIX_G(last_error) = errno;
00404               RETURN_FALSE;
00405        }
00406        
00407        RETURN_TRUE;
00408 }
00409 /* }}} */
00410 
00411 /* {{{ proto int posix_getpid(void)
00412    Get the current process id (POSIX.1, 4.1.1) */
00413 PHP_FUNCTION(posix_getpid)
00414 {
00415        PHP_POSIX_RETURN_LONG_FUNC(getpid);
00416 }
00417 /* }}} */
00418 
00419 /* {{{ proto int posix_getppid(void)
00420    Get the parent process id (POSIX.1, 4.1.1) */
00421 PHP_FUNCTION(posix_getppid)
00422 {
00423        PHP_POSIX_RETURN_LONG_FUNC(getppid);
00424 }
00425 /* }}} */
00426 
00427 /* {{{ proto int posix_getuid(void)
00428    Get the current user id (POSIX.1, 4.2.1) */
00429 PHP_FUNCTION(posix_getuid)
00430 {
00431        PHP_POSIX_RETURN_LONG_FUNC(getuid);
00432 }
00433 /* }}} */
00434 
00435 /* {{{ proto int posix_getgid(void)
00436    Get the current group id (POSIX.1, 4.2.1) */
00437 PHP_FUNCTION(posix_getgid)
00438 {
00439        PHP_POSIX_RETURN_LONG_FUNC(getgid);
00440 }
00441 /* }}} */
00442 
00443 /* {{{ proto int posix_geteuid(void)
00444    Get the current effective user id (POSIX.1, 4.2.1) */
00445 PHP_FUNCTION(posix_geteuid)
00446 {
00447        PHP_POSIX_RETURN_LONG_FUNC(geteuid);
00448 }
00449 /* }}} */
00450 
00451 /* {{{ proto int posix_getegid(void)
00452    Get the current effective group id (POSIX.1, 4.2.1) */
00453 PHP_FUNCTION(posix_getegid)
00454 {
00455        PHP_POSIX_RETURN_LONG_FUNC(getegid);
00456 }
00457 /* }}} */
00458 
00459 /* {{{ proto bool posix_setuid(long uid)
00460    Set user id (POSIX.1, 4.2.2) */
00461 PHP_FUNCTION(posix_setuid)
00462 {
00463        PHP_POSIX_SINGLE_ARG_FUNC(setuid);
00464 }
00465 /* }}} */
00466 
00467 /* {{{ proto bool posix_setgid(int uid)
00468    Set group id (POSIX.1, 4.2.2) */
00469 PHP_FUNCTION(posix_setgid)
00470 {
00471        PHP_POSIX_SINGLE_ARG_FUNC(setgid);
00472 }
00473 /* }}} */
00474 
00475 /* {{{ proto bool posix_seteuid(long uid)
00476    Set effective user id */
00477 #ifdef HAVE_SETEUID
00478 PHP_FUNCTION(posix_seteuid)
00479 {
00480        PHP_POSIX_SINGLE_ARG_FUNC(seteuid);
00481 }
00482 #endif
00483 /* }}} */
00484 
00485 /* {{{ proto bool posix_setegid(long uid)
00486    Set effective group id */
00487 #ifdef HAVE_SETEGID
00488 PHP_FUNCTION(posix_setegid)
00489 {
00490        PHP_POSIX_SINGLE_ARG_FUNC(setegid);
00491 }
00492 #endif
00493 /* }}} */
00494 
00495 /* {{{ proto array posix_getgroups(void)
00496    Get supplementary group id's (POSIX.1, 4.2.3) */
00497 #ifdef HAVE_GETGROUPS
00498 PHP_FUNCTION(posix_getgroups)
00499 {
00500        gid_t  gidlist[NGROUPS_MAX];
00501        int    result;
00502        int    i;
00503 
00504        PHP_POSIX_NO_ARGS;
00505        
00506        if ((result = getgroups(NGROUPS_MAX, gidlist)) < 0) {
00507               POSIX_G(last_error) = errno;
00508               RETURN_FALSE;
00509        }
00510 
00511        array_init(return_value);
00512 
00513        for (i=0; i<result; i++) {
00514               add_next_index_long(return_value, gidlist[i]);
00515        }
00516 }
00517 #endif
00518 /* }}} */
00519 
00520 /* {{{ proto string posix_getlogin(void) 
00521    Get user name (POSIX.1, 4.2.4) */
00522 #ifdef HAVE_GETLOGIN
00523 PHP_FUNCTION(posix_getlogin)
00524 {
00525        char *p;
00526        
00527        PHP_POSIX_NO_ARGS;
00528        
00529        if (NULL == (p = getlogin())) {
00530               POSIX_G(last_error) = errno;
00531               RETURN_FALSE;
00532        }
00533        
00534        RETURN_STRING(p, 1);
00535 }
00536 #endif
00537 /* }}} */
00538 
00539 /* {{{ proto int posix_getpgrp(void)
00540    Get current process group id (POSIX.1, 4.3.1) */
00541 PHP_FUNCTION(posix_getpgrp)
00542 {
00543        PHP_POSIX_RETURN_LONG_FUNC(getpgrp);
00544 }
00545 /* }}} */
00546 
00547 /* {{{ proto int posix_setsid(void)
00548    Create session and set process group id (POSIX.1, 4.3.2) */
00549 #ifdef HAVE_SETSID
00550 PHP_FUNCTION(posix_setsid)
00551 {
00552        PHP_POSIX_RETURN_LONG_FUNC(setsid);
00553 }
00554 #endif
00555 /* }}} */
00556 
00557 /* {{{ proto bool posix_setpgid(int pid, int pgid)
00558    Set process group id for job control (POSIX.1, 4.3.3) */
00559 PHP_FUNCTION(posix_setpgid)
00560 {
00561        long pid, pgid;
00562 
00563        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &pid, &pgid) == FAILURE) {
00564               RETURN_FALSE;
00565        }
00566        
00567        if (setpgid(pid, pgid) < 0) {
00568               POSIX_G(last_error) = errno;
00569               RETURN_FALSE;
00570        }
00571        
00572        RETURN_TRUE;
00573 }
00574 /* }}} */
00575 
00576 /* {{{ proto int posix_getpgid(void)
00577    Get the process group id of the specified process (This is not a POSIX function, but a SVR4ism, so we compile conditionally) */
00578 #ifdef HAVE_GETPGID
00579 PHP_FUNCTION(posix_getpgid)
00580 {
00581        long val;
00582        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &val) == FAILURE) {
00583               RETURN_FALSE;
00584        }
00585        
00586        if ((val = getpgid(val)) < 0) {
00587               POSIX_G(last_error) = errno;
00588               RETURN_FALSE;
00589        }
00590        RETURN_LONG(val);
00591 }
00592 #endif
00593 /* }}} */
00594 
00595 /* {{{ proto int posix_getsid(void)
00596    Get process group id of session leader (This is not a POSIX function, but a SVR4ism, so be compile conditionally) */
00597 #ifdef HAVE_GETSID
00598 PHP_FUNCTION(posix_getsid)
00599 {
00600        long val;
00601        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &val) == FAILURE) {
00602               RETURN_FALSE;
00603        }
00604        
00605        if ((val = getsid(val)) < 0) {
00606               POSIX_G(last_error) = errno;
00607               RETURN_FALSE;
00608        }
00609        RETURN_LONG(val);
00610 }
00611 #endif
00612 /* }}} */
00613 
00614 /* {{{ proto array posix_uname(void)
00615    Get system name (POSIX.1, 4.4.1) */
00616 PHP_FUNCTION(posix_uname)
00617 {
00618        struct utsname u;
00619 
00620        PHP_POSIX_NO_ARGS;
00621 
00622        if (uname(&u) < 0) {
00623               POSIX_G(last_error) = errno;
00624               RETURN_FALSE;
00625        }
00626 
00627        array_init(return_value);
00628 
00629        add_assoc_string(return_value, "sysname",  u.sysname,  1);
00630        add_assoc_string(return_value, "nodename", u.nodename, 1);
00631        add_assoc_string(return_value, "release",  u.release,  1);
00632        add_assoc_string(return_value, "version",  u.version,  1);
00633        add_assoc_string(return_value, "machine",  u.machine,  1);
00634 
00635 #if defined(_GNU_SOURCE) && !defined(DARWIN) && defined(HAVE_UTSNAME_DOMAINNAME)
00636        add_assoc_string(return_value, "domainname", u.domainname, 1);
00637 #endif
00638 }
00639 /* }}} */
00640 
00641 /* POSIX.1, 4.5.1 time() - Get System Time
00642                                                  already covered by PHP
00643  */
00644 
00645 /* {{{ proto array posix_times(void)
00646    Get process times (POSIX.1, 4.5.2) */
00647 PHP_FUNCTION(posix_times)
00648 {
00649        struct tms t;
00650        clock_t    ticks;
00651 
00652        PHP_POSIX_NO_ARGS;
00653 
00654        if ((ticks = times(&t)) == -1) {
00655               POSIX_G(last_error) = errno;
00656               RETURN_FALSE;
00657        }
00658 
00659        array_init(return_value);
00660 
00661        add_assoc_long(return_value, "ticks",     ticks);                     /* clock ticks */
00662        add_assoc_long(return_value, "utime",     t.tms_utime); /* user time */
00663        add_assoc_long(return_value, "stime",     t.tms_stime); /* system time */
00664        add_assoc_long(return_value, "cutime",    t.tms_cutime);       /* user time of children */
00665        add_assoc_long(return_value, "cstime",    t.tms_cstime);       /* system time of children */
00666 }
00667 /* }}} */
00668 
00669 /* POSIX.1, 4.6.1 getenv() - Environment Access
00670                                                  already covered by PHP
00671 */
00672 
00673 /* {{{ proto string posix_ctermid(void)
00674    Generate terminal path name (POSIX.1, 4.7.1) */
00675 #ifdef HAVE_CTERMID
00676 PHP_FUNCTION(posix_ctermid)
00677 {
00678        char  buffer[L_ctermid];
00679        
00680        PHP_POSIX_NO_ARGS;
00681 
00682        if (NULL == ctermid(buffer)) {
00683               /* Found no documentation how the defined behaviour is when this
00684                * function fails
00685                */
00686               POSIX_G(last_error) = errno;
00687               RETURN_FALSE;
00688        }
00689        
00690        RETURN_STRING(buffer, 1);
00691 }
00692 #endif
00693 /* }}} */
00694 
00695 /* Checks if the provides resource is a stream and if it provides a file descriptor */
00696 static int php_posix_stream_get_fd(zval *zfp, int *fd TSRMLS_DC) /* {{{ */
00697 {
00698        php_stream *stream;
00699 
00700        php_stream_from_zval_no_verify(stream, &zfp);
00701 
00702        if (stream == NULL) {
00703               php_error_docref(NULL TSRMLS_CC, E_WARNING, "expects argument 1 to be a valid stream resource");
00704               return 0;
00705        }
00706        if (php_stream_can_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT) == SUCCESS) {
00707               php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT, (void*)fd, 0);
00708        } else if (php_stream_can_cast(stream, PHP_STREAM_AS_FD) == SUCCESS) {
00709               php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)fd, 0);
00710        } else {
00711               php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not use stream of type '%s'", 
00712                             stream->ops->label);
00713               return 0;
00714        }
00715        return 1;
00716 }
00717 /* }}} */
00718 
00719 /* {{{ proto string posix_ttyname(int fd)
00720    Determine terminal device name (POSIX.1, 4.7.2) */
00721 PHP_FUNCTION(posix_ttyname)
00722 {
00723        zval **z_fd;
00724        char *p;
00725        int fd;
00726 #if defined(ZTS) && defined(HAVE_TTYNAME_R) && defined(_SC_TTY_NAME_MAX)
00727        long buflen;
00728 #endif
00729 
00730        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &z_fd) == FAILURE) {
00731               RETURN_FALSE;
00732        }
00733 
00734        switch (Z_TYPE_PP(z_fd)) {
00735               case IS_RESOURCE:
00736                      if (!php_posix_stream_get_fd(*z_fd, &fd TSRMLS_CC)) {
00737                             RETURN_FALSE;
00738                      }
00739                      break;
00740               default:
00741                      convert_to_long_ex(z_fd);
00742                      fd = Z_LVAL_PP(z_fd);
00743        }
00744 #if defined(ZTS) && defined(HAVE_TTYNAME_R) && defined(_SC_TTY_NAME_MAX)
00745        buflen = sysconf(_SC_TTY_NAME_MAX);
00746        if (buflen < 1) {
00747               RETURN_FALSE;
00748        }
00749        p = emalloc(buflen);
00750 
00751        if (ttyname_r(fd, p, buflen)) {
00752               POSIX_G(last_error) = errno;
00753               efree(p);
00754               RETURN_FALSE;
00755        }
00756        RETURN_STRING(p, 0);
00757 #else
00758        if (NULL == (p = ttyname(fd))) {
00759               POSIX_G(last_error) = errno;
00760               RETURN_FALSE;
00761        }
00762 #endif 
00763        RETURN_STRING(p, 1);
00764 }
00765 /* }}} */
00766 
00767 /* {{{ proto bool posix_isatty(int fd)
00768    Determine if filedesc is a tty (POSIX.1, 4.7.1) */
00769 PHP_FUNCTION(posix_isatty)
00770 {
00771        zval **z_fd;
00772        int fd;
00773        
00774        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &z_fd) == FAILURE) {
00775               RETURN_FALSE;
00776        }
00777        
00778        switch (Z_TYPE_PP(z_fd)) {
00779               case IS_RESOURCE:
00780                      if (!php_posix_stream_get_fd(*z_fd, &fd TSRMLS_CC)) {
00781                             RETURN_FALSE;
00782                      }
00783                      break;
00784               default:
00785                      convert_to_long_ex(z_fd);
00786                      fd = Z_LVAL_PP(z_fd);
00787        }
00788 
00789        if (isatty(fd)) {
00790               RETURN_TRUE;
00791        } else {
00792               RETURN_FALSE;
00793        }
00794 }
00795 /* }}} */
00796 
00797 /*
00798        POSIX.1, 4.8.1 sysconf() - TODO
00799        POSIX.1, 5.7.1 pathconf(), fpathconf() - TODO
00800 
00801        POSIX.1, 5.1.2 opendir(), readdir(), rewinddir(), closedir()
00802        POSIX.1, 5.2.1 chdir()
00803                             already supported by PHP
00804  */
00805 
00806 /* {{{ proto string posix_getcwd(void)
00807    Get working directory pathname (POSIX.1, 5.2.2) */
00808 PHP_FUNCTION(posix_getcwd)
00809 {
00810        char  buffer[MAXPATHLEN];
00811        char *p;
00812 
00813        PHP_POSIX_NO_ARGS;
00814 
00815        p = VCWD_GETCWD(buffer, MAXPATHLEN);
00816        if (!p) {
00817               POSIX_G(last_error) = errno;
00818               RETURN_FALSE;
00819        }
00820 
00821        RETURN_STRING(buffer, 1);
00822 }
00823 /* }}} */
00824 
00825 /*
00826        POSIX.1, 5.3.x open(), creat(), umask()
00827        POSIX.1, 5.4.1 link()
00828               already supported by PHP.
00829  */
00830 
00831 /* {{{ proto bool posix_mkfifo(string pathname, int mode)
00832    Make a FIFO special file (POSIX.1, 5.4.2) */
00833 #ifdef HAVE_MKFIFO
00834 PHP_FUNCTION(posix_mkfifo)
00835 {
00836        char *path;
00837        int path_len;
00838        long mode;
00839        int     result;
00840        
00841        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &path, &path_len, &mode) == FAILURE) {
00842               RETURN_FALSE;
00843        }
00844 
00845        if (strlen(path) != path_len) {
00846               RETURN_FALSE;
00847        }
00848 
00849        if (php_check_open_basedir_ex(path, 0 TSRMLS_CC) ||
00850                      (PG(safe_mode) && (!php_checkuid(path, NULL, CHECKUID_ALLOW_ONLY_DIR)))) {
00851               RETURN_FALSE;
00852        }
00853 
00854        result = mkfifo(path, mode);
00855        if (result < 0) {
00856               POSIX_G(last_error) = errno;
00857               RETURN_FALSE;
00858        }
00859 
00860        RETURN_TRUE;
00861 }
00862 #endif
00863 /* }}} */
00864 
00865 /* {{{ proto bool posix_mknod(string pathname, int mode [, int major [, int minor]])
00866    Make a special or ordinary file (POSIX.1) */
00867 #ifdef HAVE_MKNOD
00868 PHP_FUNCTION(posix_mknod)
00869 {
00870        char *path;
00871        int path_len;
00872        long mode;
00873        long major = 0, minor = 0;
00874        int result;
00875        dev_t php_dev;
00876 
00877        php_dev = 0;
00878 
00879        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|ll", &path, &path_len,
00880                      &mode, &major, &minor) == FAILURE) {
00881               RETURN_FALSE;
00882        }
00883 
00884        if (strlen(path) != path_len) {
00885               RETURN_FALSE;
00886        }
00887 
00888        if (php_check_open_basedir_ex(path, 0 TSRMLS_CC) ||
00889                      (PG(safe_mode) && (!php_checkuid(path, NULL, CHECKUID_ALLOW_ONLY_DIR)))) {
00890               RETURN_FALSE;
00891        }
00892 
00893        if ((mode & S_IFCHR) || (mode & S_IFBLK)) {
00894               if (ZEND_NUM_ARGS() == 2) {
00895                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "For S_IFCHR and S_IFBLK you need to pass a major device kernel identifier");
00896                      RETURN_FALSE;
00897               }
00898               if (major == 0) {
00899                      php_error_docref(NULL TSRMLS_CC, E_WARNING,
00900                             "Expects argument 3 to be non-zero for POSIX_S_IFCHR and POSIX_S_IFBLK");
00901                      RETURN_FALSE;
00902               } else {
00903 #if defined(HAVE_MAKEDEV) || defined(makedev)
00904                      php_dev = makedev(major, minor);
00905 #else
00906                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create a block or character device, creating a normal file instead");
00907 #endif
00908               }
00909        }
00910 
00911        result = mknod(path, mode, php_dev);
00912        if (result < 0) {
00913               POSIX_G(last_error) = errno;
00914               RETURN_FALSE;
00915        }
00916 
00917        RETURN_TRUE;
00918 }
00919 #endif
00920 /* }}} */
00921 
00922 /* Takes a pointer to posix group and a pointer to an already initialized ZVAL
00923  * array container and fills the array with the posix group member data. */
00924 int php_posix_group_to_array(struct group *g, zval *array_group) /* {{{ */
00925 {
00926        zval *array_members;
00927        int count;
00928 
00929        if (NULL == g)
00930               return 0;
00931 
00932        if (array_group == NULL || Z_TYPE_P(array_group) != IS_ARRAY)
00933               return 0;
00934 
00935        MAKE_STD_ZVAL(array_members);
00936        array_init(array_members);
00937        
00938        add_assoc_string(array_group, "name", g->gr_name, 1);
00939        add_assoc_string(array_group, "passwd", g->gr_passwd, 1);
00940        for (count=0; g->gr_mem[count] != NULL; count++) {
00941               add_next_index_string(array_members, g->gr_mem[count], 1);
00942        }
00943        zend_hash_update(Z_ARRVAL_P(array_group), "members", sizeof("members"), (void*)&array_members, sizeof(zval*), NULL);
00944        add_assoc_long(array_group, "gid", g->gr_gid);
00945        return 1;
00946 }
00947 /* }}} */
00948 
00949 /*
00950        POSIX.1, 5.5.1 unlink()
00951        POSIX.1, 5.5.2 rmdir()
00952        POSIX.1, 5.5.3 rename()
00953        POSIX.1, 5.6.x stat(), chmod(), utime() already supported by PHP.
00954 */
00955 
00956 /* {{{ proto bool posix_access(string file [, int mode])
00957    Determine accessibility of a file (POSIX.1 5.6.3) */
00958 PHP_FUNCTION(posix_access)
00959 {
00960        long mode = 0;
00961        int filename_len, ret;
00962        char *filename, *path;
00963 
00964        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &filename, &filename_len, &mode) == FAILURE) {
00965               RETURN_FALSE;
00966        }
00967 
00968        if (strlen(filename) != filename_len) {
00969               RETURN_FALSE;
00970        }
00971 
00972        path = expand_filepath(filename, NULL TSRMLS_CC);
00973        if (!path) {
00974               POSIX_G(last_error) = EIO;
00975               RETURN_FALSE;
00976        }
00977 
00978        if (php_check_open_basedir_ex(path, 0 TSRMLS_CC) ||
00979                      (PG(safe_mode) && (!php_checkuid_ex(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR, CHECKUID_NO_ERRORS)))) {
00980               efree(path);
00981               POSIX_G(last_error) = EPERM;
00982               RETURN_FALSE;
00983        }
00984 
00985        ret = access(path, mode);
00986        efree(path);
00987 
00988        if (ret) {
00989               POSIX_G(last_error) = errno;
00990               RETURN_FALSE;
00991        }
00992 
00993        RETURN_TRUE;
00994 }
00995 /* }}} */
00996 
00997 /*
00998        POSIX.1, 6.x most I/O functions already supported by PHP.
00999        POSIX.1, 7.x tty functions, TODO
01000        POSIX.1, 8.x interactions with other C language functions
01001        POSIX.1, 9.x system database access
01002 */
01003 
01004 /* {{{ proto array posix_getgrnam(string groupname)
01005    Group database access (POSIX.1, 9.2.1) */
01006 PHP_FUNCTION(posix_getgrnam)
01007 {
01008        char *name;
01009        struct group *g;
01010        int name_len;
01011 #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
01012        struct group gbuf;
01013        long buflen;
01014        char *buf;
01015 #endif
01016        
01017        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
01018               RETURN_FALSE;
01019        }
01020 
01021 #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
01022        buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
01023        if (buflen < 1) {
01024               RETURN_FALSE;
01025        }
01026        buf = emalloc(buflen);
01027        g = &gbuf;
01028 
01029        if (getgrnam_r(name, g, buf, buflen, &g) || g == NULL) {
01030               POSIX_G(last_error) = errno;
01031               efree(buf);
01032               RETURN_FALSE;
01033        }
01034 #else
01035        if (NULL == (g = getgrnam(name))) {
01036               POSIX_G(last_error) = errno;
01037               RETURN_FALSE;
01038        }
01039 #endif
01040        array_init(return_value);
01041 
01042        if (!php_posix_group_to_array(g, return_value)) {
01043               zval_dtor(return_value);
01044               php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix group to array");
01045               RETVAL_FALSE;
01046        }
01047 #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
01048        efree(buf);
01049 #endif
01050 }
01051 /* }}} */
01052 
01053 /* {{{ proto array posix_getgrgid(long gid) 
01054    Group database access (POSIX.1, 9.2.1) */
01055 PHP_FUNCTION(posix_getgrgid)
01056 {
01057        long gid;
01058 #if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
01059        int ret;
01060        struct group _g;
01061        struct group *retgrptr = NULL;
01062        long grbuflen;
01063        char *grbuf;
01064 #endif
01065        struct group *g;
01066        
01067        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &gid) == FAILURE) {
01068               RETURN_FALSE;
01069        }
01070 #if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
01071        
01072        grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
01073        if (grbuflen < 1) {
01074               RETURN_FALSE;
01075        }
01076 
01077        grbuf = emalloc(grbuflen);
01078 
01079        ret = getgrgid_r(gid, &_g, grbuf, grbuflen, &retgrptr);
01080        if (ret || retgrptr == NULL) {
01081               POSIX_G(last_error) = ret;
01082               efree(grbuf);
01083               RETURN_FALSE;
01084        }
01085        g = &_g;
01086 #else
01087        if (NULL == (g = getgrgid(gid))) {
01088               POSIX_G(last_error) = errno;
01089               RETURN_FALSE;
01090        }
01091 #endif
01092        array_init(return_value);
01093 
01094        if (!php_posix_group_to_array(g, return_value)) {
01095               zval_dtor(return_value);
01096               php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix group struct to array");
01097               RETVAL_FALSE;
01098        }
01099 #if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
01100        efree(grbuf);
01101 #endif
01102 }
01103 /* }}} */
01104 
01105 int php_posix_passwd_to_array(struct passwd *pw, zval *return_value) /* {{{ */
01106 {
01107        if (NULL == pw)
01108               return 0;
01109        if (NULL == return_value || Z_TYPE_P(return_value) != IS_ARRAY)
01110               return 0;
01111 
01112        add_assoc_string(return_value, "name",      pw->pw_name, 1);
01113        add_assoc_string(return_value, "passwd",    pw->pw_passwd, 1);
01114        add_assoc_long  (return_value, "uid",       pw->pw_uid);
01115        add_assoc_long  (return_value, "gid",            pw->pw_gid);
01116        add_assoc_string(return_value, "gecos",     pw->pw_gecos, 1);
01117        add_assoc_string(return_value, "dir",       pw->pw_dir, 1);
01118        add_assoc_string(return_value, "shell",     pw->pw_shell, 1);
01119        return 1;
01120 }
01121 /* }}} */
01122 
01123 /* {{{ proto array posix_getpwnam(string groupname) 
01124    User database access (POSIX.1, 9.2.2) */
01125 PHP_FUNCTION(posix_getpwnam)
01126 {
01127        struct passwd *pw;
01128        char *name;
01129        int name_len;
01130 #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
01131        struct passwd pwbuf;
01132        long buflen;
01133        char *buf;
01134 #endif
01135 
01136        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
01137               RETURN_FALSE;
01138        }
01139 
01140 #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
01141        buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
01142        if (buflen < 1) {
01143               RETURN_FALSE;
01144        }
01145        buf = emalloc(buflen);
01146        pw = &pwbuf;
01147 
01148        if (getpwnam_r(name, pw, buf, buflen, &pw) || pw == NULL) {
01149               efree(buf);
01150               POSIX_G(last_error) = errno;
01151               RETURN_FALSE;
01152        }
01153 #else
01154        if (NULL == (pw = getpwnam(name))) {
01155               POSIX_G(last_error) = errno;
01156               RETURN_FALSE;
01157        }
01158 #endif 
01159        array_init(return_value);
01160 
01161        if (!php_posix_passwd_to_array(pw, return_value)) {
01162               zval_dtor(return_value);
01163               php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix passwd struct to array");
01164               RETVAL_FALSE;
01165        }
01166 #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
01167        efree(buf);
01168 #endif
01169 }
01170 /* }}} */
01171 
01172 /* {{{ proto array posix_getpwuid(long uid) 
01173    User database access (POSIX.1, 9.2.2) */
01174 PHP_FUNCTION(posix_getpwuid)
01175 {
01176        long uid;
01177 #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
01178        struct passwd _pw;
01179        struct passwd *retpwptr = NULL;
01180        long pwbuflen;
01181        char *pwbuf;
01182        int ret;
01183 #endif
01184        struct passwd *pw;
01185 
01186        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &uid) == FAILURE) {
01187               RETURN_FALSE;
01188        }
01189 #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
01190        pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
01191        if (pwbuflen < 1) {
01192               RETURN_FALSE;
01193        }
01194        pwbuf = emalloc(pwbuflen);
01195 
01196        ret = getpwuid_r(uid, &_pw, pwbuf, pwbuflen, &retpwptr);
01197        if (ret || retpwptr == NULL) {
01198               POSIX_G(last_error) = ret;
01199               efree(pwbuf);
01200               RETURN_FALSE;
01201        }
01202        pw = &_pw;
01203 #else
01204        if (NULL == (pw = getpwuid(uid))) {
01205               POSIX_G(last_error) = errno;
01206               RETURN_FALSE;
01207        }
01208 #endif
01209        array_init(return_value);
01210 
01211        if (!php_posix_passwd_to_array(pw, return_value)) {
01212               zval_dtor(return_value);
01213               php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix passwd struct to array");
01214               RETVAL_FALSE;
01215        }
01216 #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
01217        efree(pwbuf);
01218 #endif
01219 }
01220 /* }}} */
01221 
01222 
01223 #ifdef HAVE_GETRLIMIT
01224 
01225 #define UNLIMITED_STRING "unlimited"
01226 
01227 /* {{{ posix_addlimit
01228  */
01229 static int posix_addlimit(int limit, char *name, zval *return_value TSRMLS_DC) {
01230        int result;
01231        struct rlimit rl;
01232        char hard[80];
01233        char soft[80];
01234 
01235        snprintf(hard, 80, "hard %s", name);
01236        snprintf(soft, 80, "soft %s", name);
01237 
01238        result = getrlimit(limit, &rl);
01239        if (result < 0) {
01240               POSIX_G(last_error) = errno;
01241               return FAILURE;
01242        }
01243 
01244        if (rl.rlim_cur == RLIM_INFINITY) {
01245               add_assoc_stringl(return_value, soft, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1, 1);
01246        } else {
01247               add_assoc_long(return_value, soft, rl.rlim_cur);
01248        }
01249 
01250        if (rl.rlim_max == RLIM_INFINITY) {
01251               add_assoc_stringl(return_value, hard, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1, 1);
01252        } else {
01253               add_assoc_long(return_value, hard, rl.rlim_max);
01254        }
01255 
01256        return SUCCESS;
01257 }
01258 /* }}} */
01259 
01260 /* {{{ limits[]
01261  */
01262 struct limitlist {
01263        int limit;
01264        char *name;
01265 } limits[] = {
01266 #ifdef RLIMIT_CORE
01267        { RLIMIT_CORE,       "core" },
01268 #endif
01269 
01270 #ifdef RLIMIT_DATA
01271        { RLIMIT_DATA,       "data" },
01272 #endif
01273 
01274 #ifdef RLIMIT_STACK
01275        { RLIMIT_STACK,      "stack" },
01276 #endif
01277 
01278 #ifdef RLIMIT_VMEM
01279        { RLIMIT_VMEM, "virtualmem" },
01280 #endif
01281 
01282 #ifdef RLIMIT_AS
01283        { RLIMIT_AS, "totalmem" },
01284 #endif
01285 
01286 #ifdef RLIMIT_RSS
01287        { RLIMIT_RSS, "rss" },
01288 #endif
01289 
01290 #ifdef RLIMIT_NPROC
01291        { RLIMIT_NPROC, "maxproc" },
01292 #endif
01293 
01294 #ifdef RLIMIT_MEMLOCK
01295        { RLIMIT_MEMLOCK, "memlock" },
01296 #endif
01297 
01298 #ifdef RLIMIT_CPU
01299        { RLIMIT_CPU, "cpu" },
01300 #endif
01301 
01302 #ifdef RLIMIT_FSIZE
01303        { RLIMIT_FSIZE, "filesize" },
01304 #endif
01305 
01306 #ifdef RLIMIT_NOFILE
01307        { RLIMIT_NOFILE, "openfiles" },
01308 #endif
01309 
01310 #ifdef RLIMIT_OFILE
01311        { RLIMIT_OFILE, "openfiles" },
01312 #endif
01313 
01314        { 0, NULL }
01315 };
01316 /* }}} */
01317 
01318 
01319 /* {{{ proto array posix_getrlimit(void)
01320    Get system resource consumption limits (This is not a POSIX function, but a BSDism and a SVR4ism. We compile conditionally) */
01321 PHP_FUNCTION(posix_getrlimit)
01322 {
01323        struct limitlist *l = NULL;
01324 
01325        PHP_POSIX_NO_ARGS;
01326 
01327        array_init(return_value);
01328 
01329        for (l=limits; l->name; l++) {
01330               if (posix_addlimit(l->limit, l->name, return_value TSRMLS_CC) == FAILURE) {
01331                      zval_dtor(return_value);
01332                      RETURN_FALSE;
01333               }
01334        }
01335 }
01336 /* }}} */
01337 
01338 #endif /* HAVE_GETRLIMIT */
01339 
01340 /* {{{ proto int posix_get_last_error(void)
01341    Retrieve the error number set by the last posix function which failed. */
01342 PHP_FUNCTION(posix_get_last_error)
01343 {
01344        PHP_POSIX_NO_ARGS;   
01345 
01346        RETURN_LONG(POSIX_G(last_error));
01347 }
01348 /* }}} */
01349 
01350 /* {{{ proto string posix_strerror(int errno)
01351    Retrieve the system error message associated with the given errno. */
01352 PHP_FUNCTION(posix_strerror)
01353 {
01354        long error;
01355 
01356        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &error) == FAILURE) {
01357               RETURN_FALSE;
01358        }
01359 
01360        RETURN_STRING(strerror(error), 1);
01361 }
01362 /* }}} */
01363 
01364 #endif
01365 
01366 #ifdef HAVE_INITGROUPS
01367 /* {{{ proto bool posix_initgroups(string name, int base_group_id)
01368    Calculate the group access list for the user specified in name. */
01369 PHP_FUNCTION(posix_initgroups)
01370 {
01371        long basegid;
01372        char *name;
01373        int name_len;
01374 
01375        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &name, &name_len, &basegid) == FAILURE) {
01376               RETURN_FALSE;
01377        }
01378 
01379        if (name_len == 0) {
01380               RETURN_FALSE;
01381        }
01382 
01383        RETURN_BOOL(!initgroups((const char *)name, basegid));
01384 }
01385 /* }}} */
01386 #endif
01387 
01388 /*
01389  * Local variables:
01390  * tab-width: 4
01391  * c-basic-offset: 4
01392  * End:
01393  * vim600: sw=4 ts=4 fdm=marker
01394  * vim<600: sw=4 ts=4
01395  */