posix.c 34 KB

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