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

1.1     ! misho       1: /*
        !             2:    +----------------------------------------------------------------------+
        !             3:    | PHP Version 5                                                        |
        !             4:    +----------------------------------------------------------------------+
        !             5:    | Copyright (c) 1997-2012 The PHP Group                                |
        !             6:    +----------------------------------------------------------------------+
        !             7:    | This source file is subject to version 3.01 of the PHP license,      |
        !             8:    | that is bundled with this package in the file LICENSE, and is        |
        !             9:    | available through the world-wide-web at the following url:           |
        !            10:    | http://www.php.net/license/3_01.txt                                  |
        !            11:    | If you did not receive a copy of the PHP license and are unable to   |
        !            12:    | obtain it through the world-wide-web, please send a note to          |
        !            13:    | license@php.net so we can mail you a copy immediately.               |
        !            14:    +----------------------------------------------------------------------+
        !            15:    | Author: Kristian Koehntopp <kris@koehntopp.de>                       |
        !            16:    +----------------------------------------------------------------------+
        !            17:  */
        !            18: 
        !            19: /* $Id: posix.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            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();
        !           313:        php_info_print_table_row(2, "Revision", "$Revision: 321634 $");
        !           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:        
        !           841:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &path, &path_len, &mode) == FAILURE) {
        !           842:                RETURN_FALSE;
        !           843:        }
        !           844: 
        !           845:        if (strlen(path) != path_len) {
        !           846:                RETURN_FALSE;
        !           847:        }
        !           848: 
        !           849:        if (php_check_open_basedir_ex(path, 0 TSRMLS_CC) ||
        !           850:                        (PG(safe_mode) && (!php_checkuid(path, NULL, CHECKUID_ALLOW_ONLY_DIR)))) {
        !           851:                RETURN_FALSE;
        !           852:        }
        !           853: 
        !           854:        result = mkfifo(path, mode);
        !           855:        if (result < 0) {
        !           856:                POSIX_G(last_error) = errno;
        !           857:                RETURN_FALSE;
        !           858:        }
        !           859: 
        !           860:        RETURN_TRUE;
        !           861: }
        !           862: #endif
        !           863: /* }}} */
        !           864: 
        !           865: /* {{{ proto bool posix_mknod(string pathname, int mode [, int major [, int minor]])
        !           866:    Make a special or ordinary file (POSIX.1) */
        !           867: #ifdef HAVE_MKNOD
        !           868: PHP_FUNCTION(posix_mknod)
        !           869: {
        !           870:        char *path;
        !           871:        int path_len;
        !           872:        long mode;
        !           873:        long major = 0, minor = 0;
        !           874:        int result;
        !           875:        dev_t php_dev;
        !           876: 
        !           877:        php_dev = 0;
        !           878: 
        !           879:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|ll", &path, &path_len,
        !           880:                        &mode, &major, &minor) == FAILURE) {
        !           881:                RETURN_FALSE;
        !           882:        }
        !           883: 
        !           884:        if (strlen(path) != path_len) {
        !           885:                RETURN_FALSE;
        !           886:        }
        !           887: 
        !           888:        if (php_check_open_basedir_ex(path, 0 TSRMLS_CC) ||
        !           889:                        (PG(safe_mode) && (!php_checkuid(path, NULL, CHECKUID_ALLOW_ONLY_DIR)))) {
        !           890:                RETURN_FALSE;
        !           891:        }
        !           892: 
        !           893:        if ((mode & S_IFCHR) || (mode & S_IFBLK)) {
        !           894:                if (ZEND_NUM_ARGS() == 2) {
        !           895:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "For S_IFCHR and S_IFBLK you need to pass a major device kernel identifier");
        !           896:                        RETURN_FALSE;
        !           897:                }
        !           898:                if (major == 0) {
        !           899:                        php_error_docref(NULL TSRMLS_CC, E_WARNING,
        !           900:                                "Expects argument 3 to be non-zero for POSIX_S_IFCHR and POSIX_S_IFBLK");
        !           901:                        RETURN_FALSE;
        !           902:                } else {
        !           903: #if defined(HAVE_MAKEDEV) || defined(makedev)
        !           904:                        php_dev = makedev(major, minor);
        !           905: #else
        !           906:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create a block or character device, creating a normal file instead");
        !           907: #endif
        !           908:                }
        !           909:        }
        !           910: 
        !           911:        result = mknod(path, mode, php_dev);
        !           912:        if (result < 0) {
        !           913:                POSIX_G(last_error) = errno;
        !           914:                RETURN_FALSE;
        !           915:        }
        !           916: 
        !           917:        RETURN_TRUE;
        !           918: }
        !           919: #endif
        !           920: /* }}} */
        !           921: 
        !           922: /* Takes a pointer to posix group and a pointer to an already initialized ZVAL
        !           923:  * array container and fills the array with the posix group member data. */
        !           924: int php_posix_group_to_array(struct group *g, zval *array_group) /* {{{ */
        !           925: {
        !           926:        zval *array_members;
        !           927:        int count;
        !           928: 
        !           929:        if (NULL == g)
        !           930:                return 0;
        !           931: 
        !           932:        if (array_group == NULL || Z_TYPE_P(array_group) != IS_ARRAY)
        !           933:                return 0;
        !           934: 
        !           935:        MAKE_STD_ZVAL(array_members);
        !           936:        array_init(array_members);
        !           937:        
        !           938:        add_assoc_string(array_group, "name", g->gr_name, 1);
        !           939:        add_assoc_string(array_group, "passwd", g->gr_passwd, 1);
        !           940:        for (count=0; g->gr_mem[count] != NULL; count++) {
        !           941:                add_next_index_string(array_members, g->gr_mem[count], 1);
        !           942:        }
        !           943:        zend_hash_update(Z_ARRVAL_P(array_group), "members", sizeof("members"), (void*)&array_members, sizeof(zval*), NULL);
        !           944:        add_assoc_long(array_group, "gid", g->gr_gid);
        !           945:        return 1;
        !           946: }
        !           947: /* }}} */
        !           948: 
        !           949: /*
        !           950:        POSIX.1, 5.5.1 unlink()
        !           951:        POSIX.1, 5.5.2 rmdir()
        !           952:        POSIX.1, 5.5.3 rename()
        !           953:        POSIX.1, 5.6.x stat(), chmod(), utime() already supported by PHP.
        !           954: */
        !           955: 
        !           956: /* {{{ proto bool posix_access(string file [, int mode])
        !           957:    Determine accessibility of a file (POSIX.1 5.6.3) */
        !           958: PHP_FUNCTION(posix_access)
        !           959: {
        !           960:        long mode = 0;
        !           961:        int filename_len, ret;
        !           962:        char *filename, *path;
        !           963: 
        !           964:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &filename, &filename_len, &mode) == FAILURE) {
        !           965:                RETURN_FALSE;
        !           966:        }
        !           967: 
        !           968:        if (strlen(filename) != filename_len) {
        !           969:                RETURN_FALSE;
        !           970:        }
        !           971: 
        !           972:        path = expand_filepath(filename, NULL TSRMLS_CC);
        !           973:        if (!path) {
        !           974:                POSIX_G(last_error) = EIO;
        !           975:                RETURN_FALSE;
        !           976:        }
        !           977: 
        !           978:        if (php_check_open_basedir_ex(path, 0 TSRMLS_CC) ||
        !           979:                        (PG(safe_mode) && (!php_checkuid_ex(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR, CHECKUID_NO_ERRORS)))) {
        !           980:                efree(path);
        !           981:                POSIX_G(last_error) = EPERM;
        !           982:                RETURN_FALSE;
        !           983:        }
        !           984: 
        !           985:        ret = access(path, mode);
        !           986:        efree(path);
        !           987: 
        !           988:        if (ret) {
        !           989:                POSIX_G(last_error) = errno;
        !           990:                RETURN_FALSE;
        !           991:        }
        !           992: 
        !           993:        RETURN_TRUE;
        !           994: }
        !           995: /* }}} */
        !           996: 
        !           997: /*
        !           998:        POSIX.1, 6.x most I/O functions already supported by PHP.
        !           999:        POSIX.1, 7.x tty functions, TODO
        !          1000:        POSIX.1, 8.x interactions with other C language functions
        !          1001:        POSIX.1, 9.x system database access
        !          1002: */
        !          1003: 
        !          1004: /* {{{ proto array posix_getgrnam(string groupname)
        !          1005:    Group database access (POSIX.1, 9.2.1) */
        !          1006: PHP_FUNCTION(posix_getgrnam)
        !          1007: {
        !          1008:        char *name;
        !          1009:        struct group *g;
        !          1010:        int name_len;
        !          1011: #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
        !          1012:        struct group gbuf;
        !          1013:        long buflen;
        !          1014:        char *buf;
        !          1015: #endif
        !          1016:        
        !          1017:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
        !          1018:                RETURN_FALSE;
        !          1019:        }
        !          1020: 
        !          1021: #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
        !          1022:        buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
        !          1023:        if (buflen < 1) {
        !          1024:                RETURN_FALSE;
        !          1025:        }
        !          1026:        buf = emalloc(buflen);
        !          1027:        g = &gbuf;
        !          1028: 
        !          1029:        if (getgrnam_r(name, g, buf, buflen, &g) || g == NULL) {
        !          1030:                POSIX_G(last_error) = errno;
        !          1031:                efree(buf);
        !          1032:                RETURN_FALSE;
        !          1033:        }
        !          1034: #else
        !          1035:        if (NULL == (g = getgrnam(name))) {
        !          1036:                POSIX_G(last_error) = errno;
        !          1037:                RETURN_FALSE;
        !          1038:        }
        !          1039: #endif
        !          1040:        array_init(return_value);
        !          1041: 
        !          1042:        if (!php_posix_group_to_array(g, return_value)) {
        !          1043:                zval_dtor(return_value);
        !          1044:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix group to array");
        !          1045:                RETVAL_FALSE;
        !          1046:        }
        !          1047: #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
        !          1048:        efree(buf);
        !          1049: #endif
        !          1050: }
        !          1051: /* }}} */
        !          1052: 
        !          1053: /* {{{ proto array posix_getgrgid(long gid) 
        !          1054:    Group database access (POSIX.1, 9.2.1) */
        !          1055: PHP_FUNCTION(posix_getgrgid)
        !          1056: {
        !          1057:        long gid;
        !          1058: #if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
        !          1059:        int ret;
        !          1060:        struct group _g;
        !          1061:        struct group *retgrptr = NULL;
        !          1062:        long grbuflen;
        !          1063:        char *grbuf;
        !          1064: #endif
        !          1065:        struct group *g;
        !          1066:        
        !          1067:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &gid) == FAILURE) {
        !          1068:                RETURN_FALSE;
        !          1069:        }
        !          1070: #if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
        !          1071:        
        !          1072:        grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
        !          1073:        if (grbuflen < 1) {
        !          1074:                RETURN_FALSE;
        !          1075:        }
        !          1076: 
        !          1077:        grbuf = emalloc(grbuflen);
        !          1078: 
        !          1079:        ret = getgrgid_r(gid, &_g, grbuf, grbuflen, &retgrptr);
        !          1080:        if (ret || retgrptr == NULL) {
        !          1081:                POSIX_G(last_error) = ret;
        !          1082:                efree(grbuf);
        !          1083:                RETURN_FALSE;
        !          1084:        }
        !          1085:        g = &_g;
        !          1086: #else
        !          1087:        if (NULL == (g = getgrgid(gid))) {
        !          1088:                POSIX_G(last_error) = errno;
        !          1089:                RETURN_FALSE;
        !          1090:        }
        !          1091: #endif
        !          1092:        array_init(return_value);
        !          1093: 
        !          1094:        if (!php_posix_group_to_array(g, return_value)) {
        !          1095:                zval_dtor(return_value);
        !          1096:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix group struct to array");
        !          1097:                RETVAL_FALSE;
        !          1098:        }
        !          1099: #if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
        !          1100:        efree(grbuf);
        !          1101: #endif
        !          1102: }
        !          1103: /* }}} */
        !          1104: 
        !          1105: int php_posix_passwd_to_array(struct passwd *pw, zval *return_value) /* {{{ */
        !          1106: {
        !          1107:        if (NULL == pw)
        !          1108:                return 0;
        !          1109:        if (NULL == return_value || Z_TYPE_P(return_value) != IS_ARRAY)
        !          1110:                return 0;
        !          1111: 
        !          1112:        add_assoc_string(return_value, "name",      pw->pw_name, 1);
        !          1113:        add_assoc_string(return_value, "passwd",    pw->pw_passwd, 1);
        !          1114:        add_assoc_long  (return_value, "uid",       pw->pw_uid);
        !          1115:        add_assoc_long  (return_value, "gid",           pw->pw_gid);
        !          1116:        add_assoc_string(return_value, "gecos",     pw->pw_gecos, 1);
        !          1117:        add_assoc_string(return_value, "dir",       pw->pw_dir, 1);
        !          1118:        add_assoc_string(return_value, "shell",     pw->pw_shell, 1);
        !          1119:        return 1;
        !          1120: }
        !          1121: /* }}} */
        !          1122: 
        !          1123: /* {{{ proto array posix_getpwnam(string groupname) 
        !          1124:    User database access (POSIX.1, 9.2.2) */
        !          1125: PHP_FUNCTION(posix_getpwnam)
        !          1126: {
        !          1127:        struct passwd *pw;
        !          1128:        char *name;
        !          1129:        int name_len;
        !          1130: #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
        !          1131:        struct passwd pwbuf;
        !          1132:        long buflen;
        !          1133:        char *buf;
        !          1134: #endif
        !          1135: 
        !          1136:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
        !          1137:                RETURN_FALSE;
        !          1138:        }
        !          1139: 
        !          1140: #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
        !          1141:        buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
        !          1142:        if (buflen < 1) {
        !          1143:                RETURN_FALSE;
        !          1144:        }
        !          1145:        buf = emalloc(buflen);
        !          1146:        pw = &pwbuf;
        !          1147: 
        !          1148:        if (getpwnam_r(name, pw, buf, buflen, &pw) || pw == NULL) {
        !          1149:                efree(buf);
        !          1150:                POSIX_G(last_error) = errno;
        !          1151:                RETURN_FALSE;
        !          1152:        }
        !          1153: #else
        !          1154:        if (NULL == (pw = getpwnam(name))) {
        !          1155:                POSIX_G(last_error) = errno;
        !          1156:                RETURN_FALSE;
        !          1157:        }
        !          1158: #endif 
        !          1159:        array_init(return_value);
        !          1160: 
        !          1161:        if (!php_posix_passwd_to_array(pw, return_value)) {
        !          1162:                zval_dtor(return_value);
        !          1163:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix passwd struct to array");
        !          1164:                RETVAL_FALSE;
        !          1165:        }
        !          1166: #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
        !          1167:        efree(buf);
        !          1168: #endif
        !          1169: }
        !          1170: /* }}} */
        !          1171: 
        !          1172: /* {{{ proto array posix_getpwuid(long uid) 
        !          1173:    User database access (POSIX.1, 9.2.2) */
        !          1174: PHP_FUNCTION(posix_getpwuid)
        !          1175: {
        !          1176:        long uid;
        !          1177: #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
        !          1178:        struct passwd _pw;
        !          1179:        struct passwd *retpwptr = NULL;
        !          1180:        long pwbuflen;
        !          1181:        char *pwbuf;
        !          1182:        int ret;
        !          1183: #endif
        !          1184:        struct passwd *pw;
        !          1185: 
        !          1186:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &uid) == FAILURE) {
        !          1187:                RETURN_FALSE;
        !          1188:        }
        !          1189: #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
        !          1190:        pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
        !          1191:        if (pwbuflen < 1) {
        !          1192:                RETURN_FALSE;
        !          1193:        }
        !          1194:        pwbuf = emalloc(pwbuflen);
        !          1195: 
        !          1196:        ret = getpwuid_r(uid, &_pw, pwbuf, pwbuflen, &retpwptr);
        !          1197:        if (ret || retpwptr == NULL) {
        !          1198:                POSIX_G(last_error) = ret;
        !          1199:                efree(pwbuf);
        !          1200:                RETURN_FALSE;
        !          1201:        }
        !          1202:        pw = &_pw;
        !          1203: #else
        !          1204:        if (NULL == (pw = getpwuid(uid))) {
        !          1205:                POSIX_G(last_error) = errno;
        !          1206:                RETURN_FALSE;
        !          1207:        }
        !          1208: #endif
        !          1209:        array_init(return_value);
        !          1210: 
        !          1211:        if (!php_posix_passwd_to_array(pw, return_value)) {
        !          1212:                zval_dtor(return_value);
        !          1213:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix passwd struct to array");
        !          1214:                RETVAL_FALSE;
        !          1215:        }
        !          1216: #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
        !          1217:        efree(pwbuf);
        !          1218: #endif
        !          1219: }
        !          1220: /* }}} */
        !          1221: 
        !          1222: 
        !          1223: #ifdef HAVE_GETRLIMIT
        !          1224: 
        !          1225: #define UNLIMITED_STRING "unlimited"
        !          1226: 
        !          1227: /* {{{ posix_addlimit
        !          1228:  */
        !          1229: static int posix_addlimit(int limit, char *name, zval *return_value TSRMLS_DC) {
        !          1230:        int result;
        !          1231:        struct rlimit rl;
        !          1232:        char hard[80];
        !          1233:        char soft[80];
        !          1234: 
        !          1235:        snprintf(hard, 80, "hard %s", name);
        !          1236:        snprintf(soft, 80, "soft %s", name);
        !          1237: 
        !          1238:        result = getrlimit(limit, &rl);
        !          1239:        if (result < 0) {
        !          1240:                POSIX_G(last_error) = errno;
        !          1241:                return FAILURE;
        !          1242:        }
        !          1243: 
        !          1244:        if (rl.rlim_cur == RLIM_INFINITY) {
        !          1245:                add_assoc_stringl(return_value, soft, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1, 1);
        !          1246:        } else {
        !          1247:                add_assoc_long(return_value, soft, rl.rlim_cur);
        !          1248:        }
        !          1249: 
        !          1250:        if (rl.rlim_max == RLIM_INFINITY) {
        !          1251:                add_assoc_stringl(return_value, hard, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1, 1);
        !          1252:        } else {
        !          1253:                add_assoc_long(return_value, hard, rl.rlim_max);
        !          1254:        }
        !          1255: 
        !          1256:        return SUCCESS;
        !          1257: }
        !          1258: /* }}} */
        !          1259: 
        !          1260: /* {{{ limits[]
        !          1261:  */
        !          1262: struct limitlist {
        !          1263:        int limit;
        !          1264:        char *name;
        !          1265: } limits[] = {
        !          1266: #ifdef RLIMIT_CORE
        !          1267:        { RLIMIT_CORE,  "core" },
        !          1268: #endif
        !          1269: 
        !          1270: #ifdef RLIMIT_DATA
        !          1271:        { RLIMIT_DATA,  "data" },
        !          1272: #endif
        !          1273: 
        !          1274: #ifdef RLIMIT_STACK
        !          1275:        { RLIMIT_STACK, "stack" },
        !          1276: #endif
        !          1277: 
        !          1278: #ifdef RLIMIT_VMEM
        !          1279:        { RLIMIT_VMEM, "virtualmem" },
        !          1280: #endif
        !          1281: 
        !          1282: #ifdef RLIMIT_AS
        !          1283:        { RLIMIT_AS, "totalmem" },
        !          1284: #endif
        !          1285: 
        !          1286: #ifdef RLIMIT_RSS
        !          1287:        { RLIMIT_RSS, "rss" },
        !          1288: #endif
        !          1289: 
        !          1290: #ifdef RLIMIT_NPROC
        !          1291:        { RLIMIT_NPROC, "maxproc" },
        !          1292: #endif
        !          1293: 
        !          1294: #ifdef RLIMIT_MEMLOCK
        !          1295:        { RLIMIT_MEMLOCK, "memlock" },
        !          1296: #endif
        !          1297: 
        !          1298: #ifdef RLIMIT_CPU
        !          1299:        { RLIMIT_CPU,   "cpu" },
        !          1300: #endif
        !          1301: 
        !          1302: #ifdef RLIMIT_FSIZE
        !          1303:        { RLIMIT_FSIZE, "filesize" },
        !          1304: #endif
        !          1305: 
        !          1306: #ifdef RLIMIT_NOFILE
        !          1307:        { RLIMIT_NOFILE, "openfiles" },
        !          1308: #endif
        !          1309: 
        !          1310: #ifdef RLIMIT_OFILE
        !          1311:        { RLIMIT_OFILE, "openfiles" },
        !          1312: #endif
        !          1313: 
        !          1314:        { 0, NULL }
        !          1315: };
        !          1316: /* }}} */
        !          1317: 
        !          1318: 
        !          1319: /* {{{ proto array posix_getrlimit(void)
        !          1320:    Get system resource consumption limits (This is not a POSIX function, but a BSDism and a SVR4ism. We compile conditionally) */
        !          1321: PHP_FUNCTION(posix_getrlimit)
        !          1322: {
        !          1323:        struct limitlist *l = NULL;
        !          1324: 
        !          1325:        PHP_POSIX_NO_ARGS;
        !          1326: 
        !          1327:        array_init(return_value);
        !          1328: 
        !          1329:        for (l=limits; l->name; l++) {
        !          1330:                if (posix_addlimit(l->limit, l->name, return_value TSRMLS_CC) == FAILURE) {
        !          1331:                        zval_dtor(return_value);
        !          1332:                        RETURN_FALSE;
        !          1333:                }
        !          1334:        }
        !          1335: }
        !          1336: /* }}} */
        !          1337: 
        !          1338: #endif /* HAVE_GETRLIMIT */
        !          1339: 
        !          1340: /* {{{ proto int posix_get_last_error(void)
        !          1341:    Retrieve the error number set by the last posix function which failed. */
        !          1342: PHP_FUNCTION(posix_get_last_error)
        !          1343: {
        !          1344:        PHP_POSIX_NO_ARGS;      
        !          1345: 
        !          1346:        RETURN_LONG(POSIX_G(last_error));
        !          1347: }
        !          1348: /* }}} */
        !          1349: 
        !          1350: /* {{{ proto string posix_strerror(int errno)
        !          1351:    Retrieve the system error message associated with the given errno. */
        !          1352: PHP_FUNCTION(posix_strerror)
        !          1353: {
        !          1354:        long error;
        !          1355: 
        !          1356:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &error) == FAILURE) {
        !          1357:                RETURN_FALSE;
        !          1358:        }
        !          1359: 
        !          1360:        RETURN_STRING(strerror(error), 1);
        !          1361: }
        !          1362: /* }}} */
        !          1363: 
        !          1364: #endif
        !          1365: 
        !          1366: #ifdef HAVE_INITGROUPS
        !          1367: /* {{{ proto bool posix_initgroups(string name, int base_group_id)
        !          1368:    Calculate the group access list for the user specified in name. */
        !          1369: PHP_FUNCTION(posix_initgroups)
        !          1370: {
        !          1371:        long basegid;
        !          1372:        char *name;
        !          1373:        int name_len;
        !          1374: 
        !          1375:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &name, &name_len, &basegid) == FAILURE) {
        !          1376:                RETURN_FALSE;
        !          1377:        }
        !          1378: 
        !          1379:        if (name_len == 0) {
        !          1380:                RETURN_FALSE;
        !          1381:        }
        !          1382: 
        !          1383:        RETURN_BOOL(!initgroups((const char *)name, basegid));
        !          1384: }
        !          1385: /* }}} */
        !          1386: #endif
        !          1387: 
        !          1388: /*
        !          1389:  * Local variables:
        !          1390:  * tab-width: 4
        !          1391:  * c-basic-offset: 4
        !          1392:  * End:
        !          1393:  * vim600: sw=4 ts=4 fdm=marker
        !          1394:  * vim<600: sw=4 ts=4
        !          1395:  */

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