Annotation of embedaddon/php/ext/posix/posix.c, revision 1.1.1.3

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>