fileio.c 82 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592
  1. /*++
  2. Copyright (c) 2013 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. fileio.c
  9. Abstract:
  10. This module implements file I/O routines.
  11. Author:
  12. Evan Green 5-Mar-2013
  13. Environment:
  14. User Mode C Library
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include "libcp.h"
  20. #include <alloca.h>
  21. #include <assert.h>
  22. #include <errno.h>
  23. #include <fcntl.h>
  24. #include <paths.h>
  25. #include <poll.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <sys/stat.h>
  30. #include <sys/time.h>
  31. #include <unistd.h>
  32. #include <limits.h>
  33. //
  34. // --------------------------------------------------------------------- Macros
  35. //
  36. #define ASSERT_POLL_FLAGS_EQUIVALENT() \
  37. ASSERT((POLLIN == POLL_EVENT_IN) && \
  38. (POLLRDBAND == POLL_EVENT_IN_HIGH_PRIORITY) && \
  39. (POLLOUT == POLL_EVENT_OUT) && \
  40. (POLLWRBAND == POLL_EVENT_OUT_HIGH_PRIORITY) && \
  41. (POLLERR == POLL_EVENT_ERROR) && \
  42. (POLLHUP == POLL_EVENT_DISCONNECTED) && \
  43. (POLLNVAL == POLL_EVENT_INVALID_HANDLE))
  44. //
  45. // Figure this out on 64 bits, as pollfd needs to have an int for a descriptor,
  46. // but the kernel wants pointer sized descriptors.
  47. //
  48. #define ASSERT_POLL_STRUCTURE_EQUIVALENT() \
  49. ASSERT(sizeof(struct pollfd) == sizeof(POLL_DESCRIPTOR))
  50. //
  51. // ---------------------------------------------------------------- Definitions
  52. //
  53. //
  54. // Define the initial size for the terminal name buffer.
  55. //
  56. #define INITIAL_TERMINAL_NAME_BUFFER_SIZE 64
  57. //
  58. // Define the initial allocation size for the asprintf destination string.
  59. //
  60. #define ASPRINT_INITIAL_BUFFER_SIZE 64
  61. //
  62. // ------------------------------------------------------ Data Type Definitions
  63. //
  64. /*++
  65. Structure Description:
  66. This structure defines the context used during the asprintf/vasprintf
  67. routines.
  68. Members:
  69. Buffer - Stores a pointer to the allocated string buffer.
  70. Size - Stores the number of valid characters currently in the buffer.
  71. Capacity - Stores the maximum number of bytes that can fit in the buffer
  72. before it will need to be reallocated.
  73. --*/
  74. typedef struct _ASPRINT_CONTEXT {
  75. PSTR Buffer;
  76. UINTN Size;
  77. UINTN Capacity;
  78. } ASPRINT_CONTEXT, *PASPRINT_CONTEXT;
  79. //
  80. // ----------------------------------------------- Internal Function Prototypes
  81. //
  82. int
  83. ClpOpen (
  84. int Directory,
  85. const char *Path,
  86. int OpenFlags,
  87. va_list ArgumentList
  88. );
  89. BOOL
  90. ClpAsPrintWriteCharacter (
  91. INT Character,
  92. PPRINT_FORMAT_CONTEXT Context
  93. );
  94. //
  95. // -------------------------------------------------------------------- Globals
  96. //
  97. //
  98. // Store a pointer to the global buffer used by the ttyname function.
  99. //
  100. PSTR ClTerminalNameBuffer;
  101. size_t ClTerminalNameBufferSize;
  102. //
  103. // Store a pointer to the global buffer used by the ctermid function.
  104. //
  105. PSTR ClTerminalIdBuffer;
  106. //
  107. // ------------------------------------------------------------------ Functions
  108. //
  109. LIBC_API
  110. int
  111. open (
  112. const char *Path,
  113. int OpenFlags,
  114. ...
  115. )
  116. /*++
  117. Routine Description:
  118. This routine opens a file and connects it to a file descriptor.
  119. Arguments:
  120. Path - Supplies a pointer to a null terminated string containing the path
  121. of the file to open.
  122. OpenFlags - Supplies a set of flags ORed together. See O_* definitions.
  123. ... - Supplies an optional integer representing the permission mask to set
  124. if the file is to be created by this open call.
  125. Return Value:
  126. Returns a file descriptor on success.
  127. -1 on failure. The errno variable will be set to indicate the error.
  128. --*/
  129. {
  130. va_list ArgumentList;
  131. int Result;
  132. va_start(ArgumentList, OpenFlags);
  133. Result = ClpOpen(AT_FDCWD, Path, OpenFlags, ArgumentList);
  134. va_end(ArgumentList);
  135. return Result;
  136. }
  137. LIBC_API
  138. int
  139. openat (
  140. int Directory,
  141. const char *Path,
  142. int OpenFlags,
  143. ...
  144. )
  145. /*++
  146. Routine Description:
  147. This routine opens a file and connects it to a file descriptor.
  148. Arguments:
  149. Directory - Supplies an optional file descriptor. If the given path
  150. is a relative path, the directory referenced by this descriptor will
  151. be used as a starting point for path resolution. Supply AT_FDCWD to
  152. use the working directory for relative paths.
  153. Path - Supplies a pointer to a null terminated string containing the path
  154. of the file to open.
  155. OpenFlags - Supplies a set of flags ORed together. See O_* definitions.
  156. ... - Supplies an optional integer representing the permission mask to set
  157. if the file is to be created by this open call.
  158. Return Value:
  159. Returns a file descriptor on success.
  160. -1 on failure. The errno variable will be set to indicate the error.
  161. --*/
  162. {
  163. va_list ArgumentList;
  164. int Result;
  165. va_start(ArgumentList, OpenFlags);
  166. Result = ClpOpen(Directory, Path, OpenFlags, ArgumentList);
  167. va_end(ArgumentList);
  168. return Result;
  169. }
  170. LIBC_API
  171. int
  172. fcntl (
  173. int FileDescriptor,
  174. int Command,
  175. ...
  176. )
  177. /*++
  178. Routine Description:
  179. This routine performs a file control operation on an open file handle.
  180. Arguments:
  181. FileDescriptor - Supplies the file descriptor to operate on.
  182. Command - Supplies the file control command. See F_* definitions.
  183. ... - Supplies any additional command-specific arguments.
  184. Return Value:
  185. Returns some value other than -1 to indicate success. For some commands
  186. (like F_DUPFD) this is a file descriptor. For others (like F_GETFD and
  187. F_GETFL) this is a bitfield of status flags.
  188. -1 on error, and errno will be set to indicate the error.
  189. --*/
  190. {
  191. va_list ArgumentList;
  192. off_t CurrentOffset;
  193. int DescriptorMinimum;
  194. FILE_CONTROL_COMMAND FileControlCommand;
  195. struct flock *FileLock;
  196. ULONG Flags;
  197. off_t Length;
  198. FILE_CONTROL_PARAMETERS_UNION Parameters;
  199. int ReturnValue;
  200. int SetFlags;
  201. struct stat Stat;
  202. KSTATUS Status;
  203. ReturnValue = -1;
  204. FileControlCommand = FileControlCommandInvalid;
  205. FileLock = NULL;
  206. va_start(ArgumentList, Command);
  207. switch (Command) {
  208. case F_DUPFD:
  209. FileControlCommand = FileControlCommandDuplicate;
  210. DescriptorMinimum = va_arg(ArgumentList, int);
  211. if (DescriptorMinimum < 0) {
  212. Status = STATUS_INVALID_PARAMETER;
  213. goto fcntlEnd;
  214. }
  215. Parameters.DuplicateDescriptor = (HANDLE)(UINTN)DescriptorMinimum;
  216. break;
  217. case F_GETFD:
  218. FileControlCommand = FileControlCommandGetFlags;
  219. Parameters.Flags = 0;
  220. break;
  221. case F_SETFD:
  222. FileControlCommand = FileControlCommandSetFlags;
  223. Parameters.Flags = 0;
  224. SetFlags = va_arg(ArgumentList, int);
  225. if ((SetFlags & FD_CLOEXEC) != 0) {
  226. Parameters.Flags |= FILE_DESCRIPTOR_CLOSE_ON_EXECUTE;
  227. }
  228. break;
  229. case F_GETFL:
  230. FileControlCommand = FileControlCommandGetStatusAndAccess;
  231. Parameters.Flags = 0;
  232. break;
  233. case F_SETFL:
  234. FileControlCommand = FileControlCommandSetStatus;
  235. Parameters.Flags = 0;
  236. //
  237. // Only a few flags are honored by the kernel. Changing access mode
  238. // for instance is not possible.
  239. //
  240. SetFlags = va_arg(ArgumentList, int);
  241. if ((SetFlags & O_APPEND) != 0) {
  242. Parameters.Flags |= SYS_OPEN_FLAG_APPEND;
  243. }
  244. if ((SetFlags & O_NONBLOCK) != 0) {
  245. Parameters.Flags |= SYS_OPEN_FLAG_NON_BLOCKING;
  246. }
  247. if ((SetFlags & O_NOATIME) != 0) {
  248. Parameters.Flags |= SYS_OPEN_FLAG_NO_ACCESS_TIME;
  249. }
  250. if ((SetFlags & O_ASYNC) != 0) {
  251. Parameters.Flags |= SYS_OPEN_FLAG_ASYNCHRONOUS;
  252. }
  253. break;
  254. case F_GETOWN:
  255. FileControlCommand = FileControlCommandGetSignalOwner;
  256. Parameters.Owner = 0;
  257. break;
  258. case F_SETOWN:
  259. FileControlCommand = FileControlCommandSetSignalOwner;
  260. Parameters.Owner = va_arg(ArgumentList, pid_t);
  261. break;
  262. case F_GETLK:
  263. case F_SETLK:
  264. case F_SETLKW:
  265. if (Command == F_GETLK) {
  266. FileControlCommand = FileControlCommandGetLock;
  267. } else if (Command == F_SETLK) {
  268. FileControlCommand = FileControlCommandSetLock;
  269. } else {
  270. assert(Command == F_SETLKW);
  271. FileControlCommand = FileControlCommandBlockingSetLock;
  272. }
  273. //
  274. // Convert the flock structure to a file lock. Start with the type.
  275. //
  276. FileLock = va_arg(ArgumentList, struct flock *);
  277. switch (FileLock->l_type) {
  278. case F_RDLCK:
  279. Parameters.FileLock.Type = FileLockRead;
  280. break;
  281. case F_WRLCK:
  282. Parameters.FileLock.Type = FileLockReadWrite;
  283. break;
  284. case F_UNLCK:
  285. Parameters.FileLock.Type = FileLockUnlock;
  286. break;
  287. default:
  288. Status = STATUS_INVALID_PARAMETER;
  289. goto fcntlEnd;
  290. }
  291. //
  292. // Make the offset relative to the beginning of the file.
  293. //
  294. Parameters.FileLock.Offset = FileLock->l_start;
  295. switch (FileLock->l_whence) {
  296. case SEEK_SET:
  297. break;
  298. case SEEK_CUR:
  299. CurrentOffset = lseek(FileDescriptor, 0, SEEK_CUR);
  300. if (CurrentOffset == -1) {
  301. Status = STATUS_INVALID_PARAMETER;
  302. goto fcntlEnd;
  303. }
  304. Parameters.FileLock.Offset += CurrentOffset;
  305. break;
  306. case SEEK_END:
  307. if (fstat(FileDescriptor, &Stat) != 0) {
  308. Status = STATUS_INVALID_PARAMETER;
  309. goto fcntlEnd;
  310. }
  311. Parameters.FileLock.Offset += Stat.st_size;
  312. break;
  313. }
  314. //
  315. // Get the length sorted out, which may be negative.
  316. //
  317. Length = FileLock->l_len;
  318. if (Length < 0) {
  319. if (Parameters.FileLock.Offset < (ULONGLONG)Length) {
  320. Length = Parameters.FileLock.Offset;
  321. }
  322. Parameters.FileLock.Offset -= Length;
  323. Length = -Length;
  324. }
  325. Parameters.FileLock.Size = Length;
  326. Parameters.FileLock.ProcessId = 0;
  327. break;
  328. case F_CLOSEM:
  329. FileControlCommand = FileControlCommandCloseFrom;
  330. break;
  331. default:
  332. Status = STATUS_INVALID_PARAMETER;
  333. goto fcntlEnd;
  334. }
  335. Status = OsFileControl((HANDLE)(UINTN)FileDescriptor,
  336. FileControlCommand,
  337. &Parameters);
  338. if (!KSUCCESS(Status)) {
  339. //
  340. // The kernel returns access denied if the open handle permissions
  341. // aren't correct, which this routine converts to invalid handle.
  342. // The kernel also returns resource in use, which this routine
  343. // converts to try again.
  344. //
  345. if ((Command == F_GETLK) || (Command == F_SETLK) ||
  346. (Command == F_SETLKW)) {
  347. if (Status == STATUS_ACCESS_DENIED) {
  348. Status = STATUS_INVALID_HANDLE;
  349. } else if (Status == STATUS_RESOURCE_IN_USE) {
  350. Status = STATUS_TRY_AGAIN;
  351. }
  352. }
  353. goto fcntlEnd;
  354. }
  355. switch (Command) {
  356. case F_DUPFD:
  357. ReturnValue = (int)(UINTN)(Parameters.DuplicateDescriptor);
  358. break;
  359. case F_GETFD:
  360. ReturnValue = 0;
  361. if ((Parameters.Flags & FILE_DESCRIPTOR_CLOSE_ON_EXECUTE) != 0) {
  362. ReturnValue |= FD_CLOEXEC;
  363. }
  364. break;
  365. case F_SETFD:
  366. case F_SETFL:
  367. case F_CLOSEM:
  368. ReturnValue = 0;
  369. break;
  370. case F_GETFL:
  371. ReturnValue = 0;
  372. Flags = Parameters.Flags;
  373. if ((Flags & SYS_OPEN_FLAG_READ) != 0) {
  374. ReturnValue |= O_RDONLY;
  375. }
  376. if ((Flags & SYS_OPEN_FLAG_WRITE) != 0) {
  377. ReturnValue |= O_WRONLY;
  378. }
  379. if ((Flags & SYS_OPEN_FLAG_EXECUTE) != 0) {
  380. ReturnValue |= O_EXEC;
  381. }
  382. if ((Flags & SYS_OPEN_FLAG_TRUNCATE) != 0) {
  383. ReturnValue |= O_TRUNC;
  384. }
  385. if ((Flags & SYS_OPEN_FLAG_APPEND) != 0) {
  386. ReturnValue |= O_APPEND;
  387. }
  388. if ((Flags & SYS_OPEN_FLAG_NON_BLOCKING) != 0) {
  389. ReturnValue |= O_NONBLOCK;
  390. }
  391. if ((Flags & SYS_OPEN_FLAG_CREATE) != 0) {
  392. ReturnValue |= O_CREAT;
  393. }
  394. if ((Flags & SYS_OPEN_FLAG_FAIL_IF_EXISTS) != 0) {
  395. ReturnValue |= O_EXCL;
  396. }
  397. if ((Flags & SYS_OPEN_FLAG_DIRECTORY) != 0) {
  398. ReturnValue |= O_DIRECTORY;
  399. }
  400. if ((Flags & SYS_OPEN_FLAG_NO_SYMBOLIC_LINK) != 0) {
  401. ReturnValue |= O_NOFOLLOW;
  402. }
  403. if ((Flags & SYS_OPEN_FLAG_SYNCHRONIZED) != 0) {
  404. ReturnValue |= O_SYNC;
  405. }
  406. if ((Flags & SYS_OPEN_FLAG_NO_CONTROLLING_TERMINAL) != 0) {
  407. ReturnValue |= O_NOCTTY;
  408. }
  409. if ((Flags & SYS_OPEN_FLAG_NO_ACCESS_TIME) != 0) {
  410. ReturnValue |= O_NOATIME;
  411. }
  412. if ((Flags & SYS_OPEN_FLAG_ASYNCHRONOUS) != 0) {
  413. ReturnValue |= O_ASYNC;
  414. }
  415. break;
  416. case F_GETLK:
  417. case F_SETLK:
  418. case F_SETLKW:
  419. //
  420. // Convert back to an flock structure.
  421. //
  422. switch (Parameters.FileLock.Type) {
  423. case FileLockRead:
  424. FileLock->l_type = F_RDLCK;
  425. break;
  426. case FileLockReadWrite:
  427. FileLock->l_type = F_WRLCK;
  428. break;
  429. //
  430. // If unlocked, don't convert any other parameters. F_GETLK is
  431. // supposed to return EINVAL if no valid locking information was
  432. // returned.
  433. //
  434. case FileLockUnlock:
  435. FileLock->l_type = F_UNLCK;
  436. if (Command == F_GETLK) {
  437. Status = STATUS_INVALID_PARAMETER;
  438. }
  439. ReturnValue = 0;
  440. goto fcntlEnd;
  441. default:
  442. assert(FALSE);
  443. Status = STATUS_INVALID_PARAMETER;
  444. goto fcntlEnd;
  445. }
  446. FileLock->l_start = Parameters.FileLock.Offset;
  447. FileLock->l_len = Parameters.FileLock.Size;
  448. FileLock->l_pid = Parameters.FileLock.ProcessId;
  449. FileLock->l_whence = SEEK_SET;
  450. ReturnValue = 0;
  451. break;
  452. case F_GETOWN:
  453. ReturnValue = Parameters.Owner;
  454. break;
  455. case F_SETOWN:
  456. ReturnValue = 0;
  457. break;
  458. default:
  459. assert(FALSE);
  460. goto fcntlEnd;
  461. }
  462. fcntlEnd:
  463. va_end(ArgumentList);
  464. if (!KSUCCESS(Status)) {
  465. ReturnValue = -1;
  466. errno = ClConvertKstatusToErrorNumber(Status);
  467. }
  468. return ReturnValue;
  469. }
  470. LIBC_API
  471. int
  472. close (
  473. int FileDescriptor
  474. )
  475. /*++
  476. Routine Description:
  477. This routine closes a file descriptor.
  478. Arguments:
  479. FileDescriptor - Supplies the file descriptor to close.
  480. Return Value:
  481. 0 on success.
  482. -1 if the file could not be closed properly. The state of the file
  483. descriptor is undefined, but in many cases is still open. The errno
  484. variable will be set to contain more detailed information.
  485. --*/
  486. {
  487. KSTATUS Status;
  488. Status = OsClose((HANDLE)(UINTN)FileDescriptor);
  489. if (!KSUCCESS(Status)) {
  490. errno = ClConvertKstatusToErrorNumber(Status);
  491. return -1;
  492. }
  493. return 0;
  494. }
  495. LIBC_API
  496. int
  497. closefrom (
  498. int FileDescriptor
  499. )
  500. /*++
  501. Routine Description:
  502. This routine closes all file descriptors with a value greater than or
  503. equal to the given file descriptor.
  504. Arguments:
  505. FileDescriptor - Supplies the minimum file descriptor number.
  506. Return Value:
  507. 0 on success.
  508. -1 if a file descriptor could not be closed properly. The state of the file
  509. descriptor is undefined, but in many cases is still open. The errno
  510. variable will be set to contain more detailed information.
  511. --*/
  512. {
  513. return fcntl(FileDescriptor, F_CLOSEM);
  514. }
  515. LIBC_API
  516. ssize_t
  517. read (
  518. int FileDescriptor,
  519. void *Buffer,
  520. size_t ByteCount
  521. )
  522. /*++
  523. Routine Description:
  524. This routine attempts to read the specifed number of bytes from the given
  525. open file descriptor.
  526. Arguments:
  527. FileDescriptor - Supplies the file descriptor returned by the open function.
  528. Buffer - Supplies a pointer to the buffer where the read bytes will be
  529. returned.
  530. ByteCount - Supplies the number of bytes to read.
  531. Return Value:
  532. Returns the number of bytes successfully read from the file.
  533. -1 on failure, and errno will contain more information.
  534. --*/
  535. {
  536. UINTN BytesCompleted;
  537. KSTATUS Status;
  538. //
  539. // Truncate the byte count, so that it does not exceed the maximum number
  540. // of bytes that can be returned.
  541. //
  542. if (ByteCount > (size_t)SSIZE_MAX) {
  543. ByteCount = (size_t)SSIZE_MAX;
  544. }
  545. //
  546. // Ask the OS to actually do the I/O.
  547. //
  548. Status = OsPerformIo((HANDLE)(UINTN)FileDescriptor,
  549. IO_OFFSET_NONE,
  550. ByteCount,
  551. 0,
  552. SYS_WAIT_TIME_INDEFINITE,
  553. (PVOID)Buffer,
  554. &BytesCompleted);
  555. if (Status == STATUS_TIMEOUT) {
  556. errno = EAGAIN;
  557. return -1;
  558. } else if ((!KSUCCESS(Status)) && (Status != STATUS_END_OF_FILE)) {
  559. errno = ClConvertKstatusToErrorNumber(Status);
  560. if (BytesCompleted == 0) {
  561. BytesCompleted = -1;
  562. }
  563. }
  564. return (ssize_t)BytesCompleted;
  565. }
  566. LIBC_API
  567. ssize_t
  568. pread (
  569. int FileDescriptor,
  570. void *Buffer,
  571. size_t ByteCount,
  572. off_t Offset
  573. )
  574. /*++
  575. Routine Description:
  576. This routine attempts to read the specifed number of bytes from the given
  577. open file descriptor at a given offset. It does not change the current
  578. file pointer.
  579. Arguments:
  580. FileDescriptor - Supplies the file descriptor returned by the open function.
  581. Buffer - Supplies a pointer to the buffer where the read bytes will be
  582. returned.
  583. ByteCount - Supplies the number of bytes to read.
  584. Offset - Supplies the offset from the start of the file to read from.
  585. Return Value:
  586. Returns the number of bytes successfully read from the file.
  587. -1 on failure, and errno will contain more information.
  588. --*/
  589. {
  590. UINTN BytesCompleted;
  591. KSTATUS Status;
  592. //
  593. // Truncate the byte count, so that it does not exceed the maximum number
  594. // of bytes that can be returned.
  595. //
  596. if (ByteCount > (size_t)SSIZE_MAX) {
  597. ByteCount = (size_t)SSIZE_MAX;
  598. }
  599. //
  600. // Ask the OS to actually do the I/O.
  601. //
  602. Status = OsPerformIo((HANDLE)(UINTN)FileDescriptor,
  603. Offset,
  604. ByteCount,
  605. 0,
  606. SYS_WAIT_TIME_INDEFINITE,
  607. (PVOID)Buffer,
  608. &BytesCompleted);
  609. if (Status == STATUS_TIMEOUT) {
  610. errno = EAGAIN;
  611. return -1;
  612. } else if ((!KSUCCESS(Status)) && (Status != STATUS_END_OF_FILE)) {
  613. errno = ClConvertKstatusToErrorNumber(Status);
  614. if (BytesCompleted == 0) {
  615. BytesCompleted = -1;
  616. }
  617. }
  618. return (ssize_t)BytesCompleted;
  619. }
  620. LIBC_API
  621. int
  622. rename (
  623. const char *SourcePath,
  624. const char *DestinationPath
  625. )
  626. /*++
  627. Routine Description:
  628. This routine attempts to rename the object at the given path. This routine
  629. operates on symbolic links themselves, not the destinations of symbolic
  630. links. If the source and destination paths are equal, this routine will do
  631. nothing and return successfully. If the source path is not a directory, the
  632. destination path must not be a directory. If the destination file exists,
  633. it will be deleted. The caller must have write access in both the old and
  634. new directories. If the source path is a directory, the destination path
  635. must not exist or be an empty directory. The destination path must not have
  636. a path prefix of the source (ie it's illegal to move /my/path into
  637. /my/path/stuff).
  638. Arguments:
  639. SourcePath - Supplies a pointer to a null terminated string containing the
  640. name of the file or directory to rename.
  641. DestinationPath - Supplies a pointer to a null terminated string
  642. containing the path to rename the file or directory to. This path
  643. cannot span file systems.
  644. Return Value:
  645. 0 on success.
  646. -1 on failure, and the errno variable will be set to contain more
  647. information.
  648. --*/
  649. {
  650. return renameat(AT_FDCWD, SourcePath, AT_FDCWD, DestinationPath);
  651. }
  652. LIBC_API
  653. int
  654. renameat (
  655. int SourceDirectory,
  656. const char *SourcePath,
  657. int DestinationDirectory,
  658. const char *DestinationPath
  659. )
  660. /*++
  661. Routine Description:
  662. This routine operates the same as the rename function, except it allows
  663. relative source and/or destination paths to begin from a directory
  664. specified by the given file descriptors.
  665. Arguments:
  666. SourceDirectory - Supplies a file descriptor to the directory to start
  667. source path searches from. If the source path is absolute, this value
  668. is ignored. If this is AT_FDCWD, then source path searches will
  669. start from the current working directory.
  670. SourcePath - Supplies a pointer to a null terminated string containing the
  671. name of the file or directory to rename.
  672. DestinationPath - Supplies a pointer to a null terminated string
  673. containing the path to rename the file or directory to. This path
  674. cannot span file systems.
  675. DestinationDirectory - Supplies an optional file descriptor to the
  676. directory to start destination path searches from. If the destination
  677. path is absolute, this value is ignored. If this is AT_FDCWD, then
  678. destination path searches will start from the current working directory.
  679. Return Value:
  680. 0 on success.
  681. -1 on failure, and the errno variable will be set to contain more
  682. information.
  683. --*/
  684. {
  685. KSTATUS Status;
  686. if ((SourcePath == NULL) || (DestinationPath == NULL)) {
  687. errno = EINVAL;
  688. return -1;
  689. }
  690. Status = OsRename((HANDLE)(UINTN)SourceDirectory,
  691. (PSTR)SourcePath,
  692. strlen(SourcePath) + 1,
  693. (HANDLE)(UINTN)DestinationDirectory,
  694. (PSTR)DestinationPath,
  695. strlen(DestinationPath) + 1);
  696. if (!KSUCCESS(Status)) {
  697. errno = ClConvertKstatusToErrorNumber(Status);
  698. return -1;
  699. }
  700. return 0;
  701. }
  702. LIBC_API
  703. ssize_t
  704. write (
  705. int FileDescriptor,
  706. const void *Buffer,
  707. size_t ByteCount
  708. )
  709. /*++
  710. Routine Description:
  711. This routine attempts to write the specifed number of bytes to the given
  712. open file descriptor.
  713. Arguments:
  714. FileDescriptor - Supplies the file descriptor returned by the open function.
  715. Buffer - Supplies a pointer to the buffer containing the bytes to be
  716. written.
  717. ByteCount - Supplies the number of bytes to write.
  718. Return Value:
  719. Returns the number of bytes successfully written to the file.
  720. -1 on failure, and errno will contain more information.
  721. --*/
  722. {
  723. UINTN BytesCompleted;
  724. KSTATUS Status;
  725. //
  726. // Truncate the byte count, so that it does not exceed the maximum number
  727. // of bytes that can be returned.
  728. //
  729. if (ByteCount > (size_t)SSIZE_MAX) {
  730. ByteCount = (size_t)SSIZE_MAX;
  731. }
  732. //
  733. // Ask the OS to actually do the I/O.
  734. //
  735. Status = OsPerformIo((HANDLE)(UINTN)FileDescriptor,
  736. IO_OFFSET_NONE,
  737. ByteCount,
  738. SYS_IO_FLAG_WRITE,
  739. SYS_WAIT_TIME_INDEFINITE,
  740. (PVOID)Buffer,
  741. &BytesCompleted);
  742. if (Status == STATUS_TIMEOUT) {
  743. errno = EAGAIN;
  744. return -1;
  745. } else if (!KSUCCESS(Status)) {
  746. errno = ClConvertKstatusToErrorNumber(Status);
  747. BytesCompleted = -1;
  748. }
  749. return (ssize_t)BytesCompleted;
  750. }
  751. LIBC_API
  752. ssize_t
  753. pwrite (
  754. int FileDescriptor,
  755. const void *Buffer,
  756. size_t ByteCount,
  757. off_t Offset
  758. )
  759. /*++
  760. Routine Description:
  761. This routine attempts to write the specifed number of bytes to the given
  762. open file descriptor at a given offset. It does not update the current
  763. file position.
  764. Arguments:
  765. FileDescriptor - Supplies the file descriptor returned by the open function.
  766. Buffer - Supplies a pointer to the buffer containing the bytes to be
  767. written.
  768. ByteCount - Supplies the number of bytes to write.
  769. Offset - Supplies the offset from the start of the file to write to.
  770. Return Value:
  771. Returns the number of bytes successfully written to the file.
  772. -1 on failure, and errno will contain more information.
  773. --*/
  774. {
  775. UINTN BytesCompleted;
  776. KSTATUS Status;
  777. //
  778. // Truncate the byte count, so that it does not exceed the maximum number
  779. // of bytes that can be returned.
  780. //
  781. if (ByteCount > (size_t)SSIZE_MAX) {
  782. ByteCount = (size_t)SSIZE_MAX;
  783. }
  784. //
  785. // Ask the OS to actually do the I/O.
  786. //
  787. Status = OsPerformIo((HANDLE)(UINTN)FileDescriptor,
  788. Offset,
  789. ByteCount,
  790. SYS_IO_FLAG_WRITE,
  791. SYS_WAIT_TIME_INDEFINITE,
  792. (PVOID)Buffer,
  793. &BytesCompleted);
  794. if (Status == STATUS_TIMEOUT) {
  795. errno = EAGAIN;
  796. return -1;
  797. } else if (!KSUCCESS(Status)) {
  798. errno = ClConvertKstatusToErrorNumber(Status);
  799. BytesCompleted = -1;
  800. }
  801. return (ssize_t)BytesCompleted;
  802. }
  803. LIBC_API
  804. int
  805. fsync (
  806. int FileDescriptor
  807. )
  808. /*++
  809. Routine Description:
  810. This routine flushes all the data associated with the open file descriptor
  811. to its corresponding backing device. It does not return until the data has
  812. been flushed.
  813. Arguments:
  814. FileDescriptor - Supplies the file descriptor returned by the open function.
  815. Return Value:
  816. 0 on success.
  817. -1 on failure, and the errno variable will be set to contain more
  818. information.
  819. --*/
  820. {
  821. KSTATUS Status;
  822. Status = OsFlush((HANDLE)(UINTN)FileDescriptor, 0);
  823. if (!KSUCCESS(Status)) {
  824. errno = ClConvertKstatusToErrorNumber(Status);
  825. return -1;
  826. }
  827. return 0;
  828. }
  829. LIBC_API
  830. int
  831. fdatasync (
  832. int FileDescriptor
  833. )
  834. /*++
  835. Routine Description:
  836. This routine flushes all the data associated with the open file descriptor
  837. to its corresponding backing device. It does not return until the data has
  838. been flushed. It is similar to fsync but does not flush modified metadata
  839. if that metadata is unimportant to retrieving the file later. For example,
  840. last access and modified times wouldn't require a metadata flush, but file
  841. size change would.
  842. Arguments:
  843. FileDescriptor - Supplies the file descriptor returned by the open function.
  844. Return Value:
  845. 0 on success.
  846. -1 on failure, and the errno variable will be set to contain more
  847. information.
  848. --*/
  849. {
  850. //
  851. // For now, there is no actual distinction between this function and fsync.
  852. //
  853. return fsync(FileDescriptor);
  854. }
  855. LIBC_API
  856. void
  857. sync (
  858. void
  859. )
  860. /*++
  861. Routine Description:
  862. This routine schedules a flush for all file system related data that is in
  863. memory. Upon return, it is not guaranteed that the writing of the data is
  864. complete.
  865. Arguments:
  866. None.
  867. Return Value:
  868. None.
  869. --*/
  870. {
  871. OsFlush(INVALID_HANDLE, SYS_FLUSH_FLAG_ALL);
  872. return;
  873. }
  874. LIBC_API
  875. off_t
  876. lseek (
  877. int FileDescriptor,
  878. off_t Offset,
  879. int Whence
  880. )
  881. /*++
  882. Routine Description:
  883. This routine sets the file offset for the open file descriptor.
  884. Arguments:
  885. FileDescriptor - Supplies the file descriptor returned by the open function.
  886. Offset - Supplies the offset from the reference location given in the
  887. Whence argument.
  888. Whence - Supplies the reference location to base the offset off of. Valid
  889. value are:
  890. SEEK_SET - The offset will be added to the the beginning of the file.
  891. SEEK_CUR - The offset will be added to the current file position.
  892. SEEK_END - The offset will be added to the end of the file.
  893. Return Value:
  894. Returns the resulting file offset after the operation.
  895. -1 on failure, and errno will contain more information. The file offset
  896. will remain unchanged.
  897. --*/
  898. {
  899. IO_OFFSET NewOffset;
  900. SEEK_COMMAND SeekCommand;
  901. KSTATUS Status;
  902. switch (Whence) {
  903. case SEEK_SET:
  904. SeekCommand = SeekCommandFromBeginning;
  905. break;
  906. case SEEK_CUR:
  907. SeekCommand = SeekCommandFromCurrentOffset;
  908. break;
  909. case SEEK_END:
  910. SeekCommand = SeekCommandFromEnd;
  911. break;
  912. default:
  913. Status = STATUS_INVALID_PARAMETER;
  914. goto lseekEnd;
  915. }
  916. Status = OsSeek((HANDLE)(UINTN)FileDescriptor,
  917. SeekCommand,
  918. Offset,
  919. &NewOffset);
  920. if (!KSUCCESS(Status)) {
  921. goto lseekEnd;
  922. }
  923. lseekEnd:
  924. if (!KSUCCESS(Status)) {
  925. if (Status == STATUS_NOT_SUPPORTED) {
  926. errno = ESPIPE;
  927. } else {
  928. errno = ClConvertKstatusToErrorNumber(Status);
  929. }
  930. return (off_t)-1;
  931. }
  932. return (off_t)NewOffset;
  933. }
  934. LIBC_API
  935. int
  936. ftruncate (
  937. int FileDescriptor,
  938. off_t NewSize
  939. )
  940. /*++
  941. Routine Description:
  942. This routine sets the file size of the given file descriptor. If the new
  943. size is smaller than the original size, then the remaining data will be
  944. discarded. If the new size is larger than the original size, then the
  945. extra space will be filled with zeroes.
  946. Arguments:
  947. FileDescriptor - Supplies the file descriptor whose size should be
  948. modified.
  949. NewSize - Supplies the new size of the file descriptor in bytes.
  950. Return Value:
  951. 0 on success.
  952. -1 on failure. The errno variable will be set to indicate the error.
  953. --*/
  954. {
  955. FILE_CONTROL_PARAMETERS_UNION Parameters;
  956. FILE_PROPERTIES Properties;
  957. KSTATUS Status;
  958. Properties.Size = NewSize;
  959. Parameters.SetFileInformation.FieldsToSet = FILE_PROPERTY_FIELD_FILE_SIZE;
  960. Parameters.SetFileInformation.FileProperties = &Properties;
  961. Status = OsFileControl((HANDLE)(UINTN)FileDescriptor,
  962. FileControlCommandSetFileInformation,
  963. &Parameters);
  964. if (!KSUCCESS(Status)) {
  965. errno = ClConvertKstatusToErrorNumber(Status);
  966. return -1;
  967. }
  968. return 0;
  969. }
  970. LIBC_API
  971. int
  972. truncate (
  973. const char *Path,
  974. off_t NewSize
  975. )
  976. /*++
  977. Routine Description:
  978. This routine sets the file size of the given file path. If the new size is
  979. smaller than the original size, then the remaining data will be discarded.
  980. If the new size is larger than the original size, then the extra space will
  981. be filled with zeroes.
  982. Arguments:
  983. Path - Supplies a pointer to a null terminated string containing the path
  984. of the file whose size should be changed.
  985. NewSize - Supplies the new size of the file descriptor in bytes.
  986. Return Value:
  987. 0 on success.
  988. -1 on failure. The errno variable will be set to indicate the error.
  989. --*/
  990. {
  991. FILE_PROPERTIES Properties;
  992. SET_FILE_INFORMATION Request;
  993. KSTATUS Status;
  994. Properties.Size = NewSize;
  995. Request.FieldsToSet = FILE_PROPERTY_FIELD_FILE_SIZE;
  996. Request.FileProperties = &Properties;
  997. Status = OsSetFileInformation(INVALID_HANDLE,
  998. (PSTR)Path,
  999. strlen(Path) + 1,
  1000. TRUE,
  1001. &Request);
  1002. if (!KSUCCESS(Status)) {
  1003. errno = ClConvertKstatusToErrorNumber(Status);
  1004. return -1;
  1005. }
  1006. return 0;
  1007. }
  1008. LIBC_API
  1009. int
  1010. pipe (
  1011. int FileDescriptors[2]
  1012. )
  1013. /*++
  1014. Routine Description:
  1015. This routine creates an anonymous pipe.
  1016. Arguments:
  1017. FileDescriptors - Supplies a pointer where handles will be returned
  1018. representing the read and write ends of the pipe.
  1019. Return Value:
  1020. 0 on success.
  1021. -1 on failure. The errno variable will be set to indicate the error.
  1022. --*/
  1023. {
  1024. return pipe2(FileDescriptors, 0);
  1025. }
  1026. LIBC_API
  1027. int
  1028. pipe2 (
  1029. int FileDescriptors[2],
  1030. int Flags
  1031. )
  1032. /*++
  1033. Routine Description:
  1034. This routine creates an anonymous pipe.
  1035. Arguments:
  1036. FileDescriptors - Supplies a pointer where handles will be returned
  1037. representing the read and write ends of the pipe.
  1038. Flags - Supplies a bitfield of open flags governing the behavior of the new
  1039. descriptors. Only O_NONBLOCK and O_CLOEXEC are honored.
  1040. Return Value:
  1041. 0 on success.
  1042. -1 on failure. The errno variable will be set to indicate the error.
  1043. --*/
  1044. {
  1045. ULONG OpenFlags;
  1046. ULONG Permissions;
  1047. HANDLE ReadHandle;
  1048. KSTATUS Status;
  1049. HANDLE WriteHandle;
  1050. Permissions = FILE_PERMISSION_USER_READ | FILE_PERMISSION_USER_WRITE;
  1051. OpenFlags = 0;
  1052. if ((Flags & O_CLOEXEC) != 0) {
  1053. OpenFlags |= SYS_OPEN_FLAG_CLOSE_ON_EXECUTE;
  1054. }
  1055. if ((Flags & O_NONBLOCK) != 0) {
  1056. OpenFlags |= SYS_OPEN_FLAG_NON_BLOCKING;
  1057. }
  1058. Status = OsCreatePipe(INVALID_HANDLE,
  1059. NULL,
  1060. 0,
  1061. OpenFlags,
  1062. Permissions,
  1063. &ReadHandle,
  1064. &WriteHandle);
  1065. if (!KSUCCESS(Status)) {
  1066. errno = ClConvertKstatusToErrorNumber(Status);
  1067. return -1;
  1068. }
  1069. FileDescriptors[0] = (int)(UINTN)ReadHandle;
  1070. FileDescriptors[1] = (int)(UINTN)WriteHandle;
  1071. return 0;
  1072. }
  1073. LIBC_API
  1074. int
  1075. symlink (
  1076. const char *LinkTarget,
  1077. const char *LinkName
  1078. )
  1079. /*++
  1080. Routine Description:
  1081. This routine creates a symbolic link with the given name pointed at the
  1082. supplied target path.
  1083. Arguments:
  1084. LinkTarget - Supplies the location that the link points to.
  1085. LinkName - Supplies the path where the link should be created.
  1086. Return Value:
  1087. 0 on success.
  1088. -1 on failure, and errno will be set to contain more information.
  1089. --*/
  1090. {
  1091. return symlinkat(LinkTarget, AT_FDCWD, LinkName);
  1092. }
  1093. LIBC_API
  1094. int
  1095. symlinkat (
  1096. const char *LinkTarget,
  1097. int Directory,
  1098. const char *LinkName
  1099. )
  1100. /*++
  1101. Routine Description:
  1102. This routine creates a symbolic link with the given name pointed at the
  1103. supplied target path.
  1104. Arguments:
  1105. LinkTarget - Supplies the location that the link points to.
  1106. Directory - Supplies an optional file descriptor. If the given path to the
  1107. link name is a relative path, the directory referenced by this
  1108. descriptor will be used as a starting point for path resolution. Supply
  1109. AT_FDCWD to use the working directory for relative paths.
  1110. LinkName - Supplies the path where the link should be created.
  1111. Return Value:
  1112. 0 on success.
  1113. -1 on failure, and errno will be set to contain more information.
  1114. --*/
  1115. {
  1116. KSTATUS Status;
  1117. Status = OsCreateSymbolicLink((HANDLE)(UINTN)Directory,
  1118. (PSTR)LinkName,
  1119. strlen(LinkName) + 1,
  1120. (PSTR)LinkTarget,
  1121. strlen(LinkTarget));
  1122. if (!KSUCCESS(Status)) {
  1123. errno = ClConvertKstatusToErrorNumber(Status);
  1124. return -1;
  1125. }
  1126. return 0;
  1127. }
  1128. LIBC_API
  1129. ssize_t
  1130. readlink (
  1131. const char *Path,
  1132. char *LinkDestinationBuffer,
  1133. size_t LinkDestinationBufferSize
  1134. )
  1135. /*++
  1136. Routine Description:
  1137. This routine reads the destination path of a symbolic link.
  1138. Arguments:
  1139. Path - Supplies a pointer to the symbolic link path.
  1140. LinkDestinationBuffer - Supplies a pointer to a buffer where the
  1141. destination of the link will be returned. A null terminator is not
  1142. written.
  1143. LinkDestinationBufferSize - Supplies the size of the link destination
  1144. buffer in bytes.
  1145. Return Value:
  1146. Returns the number of bytes placed into the buffer on success.
  1147. -1 on failure. The errno variable will be set to indicate the error, and
  1148. the buffer will remain unchanged.
  1149. --*/
  1150. {
  1151. ssize_t Result;
  1152. Result = readlinkat(AT_FDCWD,
  1153. Path,
  1154. LinkDestinationBuffer,
  1155. LinkDestinationBufferSize);
  1156. return Result;
  1157. }
  1158. LIBC_API
  1159. ssize_t
  1160. readlinkat (
  1161. int Directory,
  1162. const char *Path,
  1163. char *LinkDestinationBuffer,
  1164. size_t LinkDestinationBufferSize
  1165. )
  1166. /*++
  1167. Routine Description:
  1168. This routine reads the destination path of a symbolic link.
  1169. Arguments:
  1170. Directory - Supplies an optional file descriptor. If the given path
  1171. is a relative path, the directory referenced by this descriptor will
  1172. be used as a starting point for path resolution. Supply AT_FDCWD to
  1173. use the working directory for relative paths.
  1174. Path - Supplies a pointer to the symbolic link path.
  1175. LinkDestinationBuffer - Supplies a pointer to a buffer where the
  1176. destination of the link will be returned. A null terminator is not
  1177. written.
  1178. LinkDestinationBufferSize - Supplies the size of the link destination
  1179. buffer in bytes.
  1180. Return Value:
  1181. Returns the number of bytes placed into the buffer on success.
  1182. -1 on failure. The errno variable will be set to indicate the error, and
  1183. the buffer will remain unchanged.
  1184. --*/
  1185. {
  1186. ULONG LinkDestinationSize;
  1187. KSTATUS Status;
  1188. Status = OsReadSymbolicLink((HANDLE)(UINTN)Directory,
  1189. (PSTR)Path,
  1190. strlen(Path) + 1,
  1191. LinkDestinationBuffer,
  1192. LinkDestinationBufferSize,
  1193. &LinkDestinationSize);
  1194. if (!KSUCCESS(Status)) {
  1195. if (Status == STATUS_BUFFER_TOO_SMALL) {
  1196. errno = ERANGE;
  1197. } else {
  1198. errno = ClConvertKstatusToErrorNumber(Status);
  1199. }
  1200. return -1;
  1201. }
  1202. return LinkDestinationSize;
  1203. }
  1204. LIBC_API
  1205. int
  1206. link (
  1207. const char *ExistingFile,
  1208. const char *LinkPath
  1209. )
  1210. /*++
  1211. Routine Description:
  1212. This routine creates a hard link to the given file.
  1213. Arguments:
  1214. ExistingFile - Supplies a pointer to a null-terminated string containing
  1215. the path to the file that already exists.
  1216. LinkPath - Supplies a pointer to a null-terminated string containing the
  1217. path of the new link to create.
  1218. Return Value:
  1219. 0 on success.
  1220. -1 on failure. The errno variable will be set to indicate the error.
  1221. --*/
  1222. {
  1223. return linkat(AT_FDCWD, ExistingFile, AT_FDCWD, LinkPath, 0);
  1224. }
  1225. LIBC_API
  1226. int
  1227. linkat (
  1228. int ExistingFileDirectory,
  1229. const char *ExistingFile,
  1230. int LinkPathDirectory,
  1231. const char *LinkPath,
  1232. int Flags
  1233. )
  1234. /*++
  1235. Routine Description:
  1236. This routine creates a hard link to the given file.
  1237. Arguments:
  1238. ExistingFileDirectory - Supplies an optional file descriptor. If the given
  1239. existing file path is a relative path, the directory referenced by this
  1240. descriptor will be used as a starting point for path resolution. Supply
  1241. AT_FDCWD to use the working directory for relative paths.
  1242. ExistingFile - Supplies a pointer to a null-terminated string containing
  1243. the path to the file that already exists.
  1244. LinkPathDirectory - Supplies an optional file descriptor. If the given new
  1245. link is a relative path, the directory referenced by this descriptor
  1246. will be used as a starting point for path resolution. Supply AT_FDCWD
  1247. to use the working directory for relative paths.
  1248. LinkPath - Supplies a pointer to a null-terminated string containing the
  1249. path of the new link to create.
  1250. Flags - Supplies AT_SYMLINK_FOLLOW if the routine should link to the
  1251. destination of the symbolic link if the existing file path is a
  1252. symbolic link. Supply 0 to create a link to the symbolic link itself.
  1253. Return Value:
  1254. 0 on success.
  1255. -1 on failure. The errno variable will be set to indicate the error.
  1256. --*/
  1257. {
  1258. BOOL FollowLinks;
  1259. KSTATUS Status;
  1260. FollowLinks = FALSE;
  1261. if ((Flags & AT_SYMLINK_FOLLOW) != 0) {
  1262. FollowLinks = TRUE;
  1263. }
  1264. Status = OsCreateHardLink((HANDLE)(UINTN)ExistingFileDirectory,
  1265. (PSTR)ExistingFile,
  1266. strlen(ExistingFile) + 1,
  1267. (HANDLE)(UINTN)LinkPathDirectory,
  1268. (PSTR)LinkPath,
  1269. strlen(LinkPath) + 1,
  1270. FollowLinks);
  1271. if (!KSUCCESS(Status)) {
  1272. errno = ClConvertKstatusToErrorNumber(Status);
  1273. return -1;
  1274. }
  1275. return 0;
  1276. }
  1277. LIBC_API
  1278. int
  1279. remove (
  1280. const char *Path
  1281. )
  1282. /*++
  1283. Routine Description:
  1284. This routine attempts to delete the object at the given path. If the
  1285. object pointed to by the given path is a directory, the behavior of remove
  1286. is identical to rmdir. Otherwise, the behavior of remove is identical to
  1287. unlink.
  1288. Arguments:
  1289. Path - Supplies a pointer to a null terminated string containing the path
  1290. of the entry to remove.
  1291. Return Value:
  1292. 0 on success.
  1293. -1 on failure, and errno will be set to provide more details. In failure
  1294. cases, the directory will not be removed.
  1295. --*/
  1296. {
  1297. int Result;
  1298. struct stat Stat;
  1299. Result = lstat(Path, &Stat);
  1300. if (Result < 0) {
  1301. return Result;
  1302. }
  1303. if (S_ISDIR(Stat.st_mode)) {
  1304. return rmdir(Path);
  1305. }
  1306. return unlink(Path);
  1307. }
  1308. LIBC_API
  1309. int
  1310. unlink (
  1311. const char *Path
  1312. )
  1313. /*++
  1314. Routine Description:
  1315. This routine attempts to delete the object at the given path. If the path
  1316. points to a directory, the directory must be empty. If the path points to
  1317. a file, the hard link count on the file is decremented. If the hard link
  1318. count reaches zero and no processes have the file open, the contents of the
  1319. file are destroyed. If processes have open handles to the file, the
  1320. destruction of the file contents are deferred until the last handle to the
  1321. old file is closed. If the path points to a symbolic link, the link itself
  1322. is removed and not the destination. The removal of the entry from the
  1323. directory is immediate.
  1324. Arguments:
  1325. Path - Supplies a pointer to a null terminated string containing the path
  1326. of the entry to remove.
  1327. Return Value:
  1328. 0 on success.
  1329. -1 on failure, and errno will be set to provide more details. In failure
  1330. cases, the directory will not be removed.
  1331. --*/
  1332. {
  1333. return unlinkat(AT_FDCWD, Path, 0);
  1334. }
  1335. LIBC_API
  1336. int
  1337. unlinkat (
  1338. int Directory,
  1339. const char *Path,
  1340. int Flags
  1341. )
  1342. /*++
  1343. Routine Description:
  1344. This routine attempts to delete the object at the given path. If the path
  1345. points to a directory, the directory must be empty. If the path points to
  1346. a file, the hard link count on the file is decremented. If the hard link
  1347. count reaches zero and no processes have the file open, the contents of the
  1348. file are destroyed. If processes have open handles to the file, the
  1349. destruction of the file contents are deferred until the last handle to the
  1350. old file is closed. If the path points to a symbolic link, the link itself
  1351. is removed and not the destination. The removal of the entry from the
  1352. directory is immediate.
  1353. Arguments:
  1354. Directory - Supplies an optional file descriptor. If the given path
  1355. is a relative path, the directory referenced by this descriptor will
  1356. be used as a starting point for path resolution. Supply AT_FDCWD to
  1357. use the working directory for relative paths.
  1358. Path - Supplies a pointer to a null terminated string containing the path
  1359. of the entry to remove.
  1360. Flags - Supplies a bitfield of flags. Supply AT_REMOVEDIR to attempt to
  1361. remove a directory (and only a directory). Supply zero to attempt to
  1362. remove a non-directory.
  1363. Return Value:
  1364. 0 on success.
  1365. -1 on failure, and errno will be set to provide more details. In failure
  1366. cases, the directory will not be removed.
  1367. --*/
  1368. {
  1369. ULONG OsFlags;
  1370. KSTATUS Status;
  1371. OsFlags = 0;
  1372. if ((Flags & AT_REMOVEDIR) != 0) {
  1373. OsFlags |= SYS_DELETE_FLAG_DIRECTORY;
  1374. }
  1375. if (Path == NULL) {
  1376. errno = EFAULT;
  1377. return -1;
  1378. }
  1379. Status = OsDelete((HANDLE)(UINTN)Directory,
  1380. (PSTR)Path,
  1381. strlen(Path) + 1,
  1382. OsFlags);
  1383. if (!KSUCCESS(Status)) {
  1384. errno = ClConvertKstatusToErrorNumber(Status);
  1385. return -1;
  1386. }
  1387. return 0;
  1388. }
  1389. LIBC_API
  1390. int
  1391. dup (
  1392. int FileDescriptor
  1393. )
  1394. /*++
  1395. Routine Description:
  1396. This routine duplicates the given file descriptor.
  1397. Arguments:
  1398. FileDescriptor - Supplies the file descriptor to duplicate.
  1399. Return Value:
  1400. Returns the new file descriptor which represents a copy of the original
  1401. file descriptor.
  1402. -1 on failure, and errno will be set to contain more information.
  1403. --*/
  1404. {
  1405. HANDLE NewHandle;
  1406. KSTATUS Status;
  1407. NewHandle = INVALID_HANDLE;
  1408. Status = OsDuplicateHandle((HANDLE)(UINTN)FileDescriptor, &NewHandle, 0);
  1409. if (!KSUCCESS(Status)) {
  1410. errno = ClConvertKstatusToErrorNumber(Status);
  1411. return -1;
  1412. }
  1413. return (int)(UINTN)NewHandle;
  1414. }
  1415. LIBC_API
  1416. int
  1417. dup2 (
  1418. int FileDescriptor,
  1419. int CopyDescriptor
  1420. )
  1421. /*++
  1422. Routine Description:
  1423. This routine duplicates the given file descriptor to the destination
  1424. descriptor, closing the original destination descriptor file along the way.
  1425. Arguments:
  1426. FileDescriptor - Supplies the file descriptor to duplicate.
  1427. CopyDescriptor - Supplies the descriptor number of returned copy.
  1428. Return Value:
  1429. Returns the new file descriptor which represents a copy of the original,
  1430. which is also equal to the input copy descriptor parameter.
  1431. -1 on failure, and errno will be set to contain more information.
  1432. --*/
  1433. {
  1434. HANDLE NewHandle;
  1435. KSTATUS Status;
  1436. NewHandle = (HANDLE)(UINTN)CopyDescriptor;
  1437. if (CopyDescriptor < 0) {
  1438. errno = EBADF;
  1439. return -1;
  1440. }
  1441. Status = OsDuplicateHandle((HANDLE)(UINTN)FileDescriptor, &NewHandle, 0);
  1442. if (!KSUCCESS(Status)) {
  1443. errno = ClConvertKstatusToErrorNumber(Status);
  1444. return -1;
  1445. }
  1446. assert(NewHandle == (HANDLE)(UINTN)CopyDescriptor);
  1447. return (int)(UINTN)NewHandle;
  1448. }
  1449. LIBC_API
  1450. int
  1451. dup3 (
  1452. int FileDescriptor,
  1453. int CopyDescriptor,
  1454. int Flags
  1455. )
  1456. /*++
  1457. Routine Description:
  1458. This routine duplicates the given file descriptor to the destination
  1459. descriptor, closing the original destination descriptor file along the way.
  1460. Arguments:
  1461. FileDescriptor - Supplies the file descriptor to duplicate.
  1462. CopyDescriptor - Supplies the descriptor number of returned copy. If this
  1463. is equal to the original file descriptor, then the call fails with
  1464. EINVAL.
  1465. Flags - Supplies O_* open flags governing the new descriptor. Only
  1466. O_CLOEXEC is permitted.
  1467. Return Value:
  1468. Returns the new file descriptor which represents a copy of the original,
  1469. which is also equal to the input copy descriptor parameter.
  1470. -1 on failure, and errno will be set to contain more information.
  1471. --*/
  1472. {
  1473. HANDLE NewHandle;
  1474. ULONG OpenFlags;
  1475. KSTATUS Status;
  1476. if (FileDescriptor == CopyDescriptor) {
  1477. errno = EINVAL;
  1478. return -1;
  1479. }
  1480. NewHandle = (HANDLE)(UINTN)CopyDescriptor;
  1481. OpenFlags = 0;
  1482. if ((Flags & O_CLOEXEC) != 0) {
  1483. OpenFlags |= SYS_OPEN_FLAG_CLOSE_ON_EXECUTE;
  1484. }
  1485. Status = OsDuplicateHandle((HANDLE)(UINTN)FileDescriptor,
  1486. &NewHandle,
  1487. OpenFlags);
  1488. if (!KSUCCESS(Status)) {
  1489. errno = ClConvertKstatusToErrorNumber(Status);
  1490. return -1;
  1491. }
  1492. assert(NewHandle == (HANDLE)(UINTN)CopyDescriptor);
  1493. return (int)(UINTN)NewHandle;
  1494. }
  1495. LIBC_API
  1496. int
  1497. lockf (
  1498. int FileDescriptor,
  1499. int Function,
  1500. off_t Size
  1501. )
  1502. /*++
  1503. Routine Description:
  1504. This routine locks or unlocks sections of a file with advisory-mode locks.
  1505. All locks for a process are removed when the process terminates. Record
  1506. locking is supported at least for regular files, and may be supported for
  1507. other file types.
  1508. Arguments:
  1509. FileDescriptor - Supplies the file descriptor to query. To establish a
  1510. lock, the given file descriptor must be opened with O_WRONLY or O_RDWR.
  1511. Function - Supplies the action to be taken. Valid values are:
  1512. F_ULOCK - Unlocks a locked section.
  1513. F_LOCK - Locks a section for exclusive use (blocking if already locked).
  1514. F_TLOCK - Test and lock for exclusive use, not blocking.
  1515. F_TEST - Test for a section of locks by other processes.
  1516. Size - Supplies the number of contiguous bytes to be locked or unlocked.
  1517. The section to be locked or unlocked starts at the current offset in
  1518. the file and extends forward for a positve size or backwards for a
  1519. negative size (the preceding bytes up to but not including the current
  1520. offset). If size is 0, the section from the current offset through the
  1521. largest possible offset shall be locked. Locks may exist past the
  1522. current end of file.
  1523. Return Value:
  1524. 0 on success.
  1525. -1 on error, and errno will be set to contain more information. The errno
  1526. variable may be set to the following values:
  1527. EACCES or EAGAIN if the function argument is F_TLOCK or F_TEST and the
  1528. section is already locked by another process.
  1529. EDEADLK if the function argument is F_LOCK and a deadlock is detected.
  1530. EINVAL if the function is valid or the size plus the current offset is less
  1531. than zero.
  1532. EOVERFLOW if the range cannot properly be represented in an off_t.
  1533. --*/
  1534. {
  1535. int ControlOperation;
  1536. struct flock Parameters;
  1537. Parameters.l_start = 0;
  1538. Parameters.l_len = Size;
  1539. Parameters.l_pid = 0;
  1540. Parameters.l_type = F_WRLCK;
  1541. Parameters.l_whence = SEEK_CUR;
  1542. if (Function == F_ULOCK) {
  1543. ControlOperation = F_SETLK;
  1544. Parameters.l_type = F_UNLCK;
  1545. } else if (Function == F_LOCK) {
  1546. ControlOperation = F_SETLKW;
  1547. } else if (Function == F_TLOCK) {
  1548. ControlOperation = F_SETLK;
  1549. } else if (Function == F_TEST) {
  1550. ControlOperation = F_GETLK;
  1551. } else {
  1552. errno = EINVAL;
  1553. return -1;
  1554. }
  1555. return fcntl(FileDescriptor, ControlOperation, &Parameters);
  1556. }
  1557. LIBC_API
  1558. int
  1559. dprintf (
  1560. int FileDescriptor,
  1561. const char *Format,
  1562. ...
  1563. )
  1564. /*++
  1565. Routine Description:
  1566. This routine prints a formatted string to the given file descriptor.
  1567. Arguments:
  1568. FileDescriptor - Supplies the file descriptor to print to.
  1569. Format - Supplies the printf format string.
  1570. ... - Supplies a variable number of arguments, as required by the printf
  1571. format string argument.
  1572. Return Value:
  1573. Returns the number of bytes successfully converted, not including the null
  1574. terminator.
  1575. Returns a negative number if an error was encountered.
  1576. --*/
  1577. {
  1578. va_list Arguments;
  1579. int Result;
  1580. va_start(Arguments, Format);
  1581. Result = vdprintf(FileDescriptor, Format, Arguments);
  1582. va_end(Arguments);
  1583. return Result;
  1584. }
  1585. LIBC_API
  1586. int
  1587. vdprintf (
  1588. int FileDescriptor,
  1589. const char *Format,
  1590. va_list Arguments
  1591. )
  1592. /*++
  1593. Routine Description:
  1594. This routine prints a formatted string to the given file descriptor.
  1595. Arguments:
  1596. FileDescriptor - Supplies the file descriptor to print to.
  1597. Format - Supplies the printf format string.
  1598. Arguments - Supplies the argument list to the format string. The va_end
  1599. macro is not invoked on this list.
  1600. Return Value:
  1601. Returns the number of bytes successfully converted. A null terminator is
  1602. not written.
  1603. Returns a negative number if an error was encountered.
  1604. --*/
  1605. {
  1606. int Result;
  1607. PSTR String;
  1608. size_t TotalWritten;
  1609. ssize_t Written;
  1610. String = NULL;
  1611. Result = vasprintf(&String, Format, Arguments);
  1612. if (Result <= 0) {
  1613. return Result;
  1614. }
  1615. TotalWritten = 0;
  1616. while (TotalWritten < Result) {
  1617. do {
  1618. Written = write(FileDescriptor,
  1619. String + TotalWritten,
  1620. Result - TotalWritten);
  1621. } while ((Written < 0) && (errno == EINTR));
  1622. if (Written <= 0) {
  1623. Result = Written;
  1624. break;
  1625. }
  1626. TotalWritten += Written;
  1627. }
  1628. free(String);
  1629. return Result;
  1630. }
  1631. LIBC_API
  1632. int
  1633. sprintf (
  1634. char *OutputString,
  1635. const char *Format,
  1636. ...
  1637. )
  1638. /*++
  1639. Routine Description:
  1640. This routine prints a formatted string to the given buffer. This routine
  1641. should be avoided if possible as it can be the cause of buffer overflow
  1642. issues. Use snprintf instead, a function that explicitly bounds the output
  1643. buffer.
  1644. Arguments:
  1645. OutputString - Supplies the buffer where the formatted string will be
  1646. returned. It is the caller's responsibility to ensure this buffer is
  1647. large enough to hold the formatted string.
  1648. Format - Supplies the printf format string.
  1649. ... - Supplies a variable number of arguments, as required by the printf
  1650. format string argument.
  1651. Return Value:
  1652. Returns the number of bytes successfully converted, not including the null
  1653. terminator.
  1654. Returns a negative number if an error was encountered.
  1655. --*/
  1656. {
  1657. va_list Arguments;
  1658. int Result;
  1659. va_start(Arguments, Format);
  1660. Result = vsprintf(OutputString, Format, Arguments);
  1661. va_end(Arguments);
  1662. return Result;
  1663. }
  1664. LIBC_API
  1665. int
  1666. snprintf (
  1667. char *OutputString,
  1668. size_t OutputStringSize,
  1669. const char *Format,
  1670. ...
  1671. )
  1672. /*++
  1673. Routine Description:
  1674. This routine prints a formatted string to the given bounded buffer.
  1675. Arguments:
  1676. OutputString - Supplies the buffer where the formatted string will be
  1677. returned.
  1678. OutputStringSize - Supplies the number of bytes in the output buffer.
  1679. Format - Supplies the printf format string.
  1680. ... - Supplies a variable number of arguments, as required by the printf
  1681. format string argument.
  1682. Return Value:
  1683. Returns the number of bytes that would have been converted had
  1684. OutputStringSize been large enough, not including the null terminator.
  1685. Returns a negative number if an error was encountered.
  1686. --*/
  1687. {
  1688. va_list Arguments;
  1689. int Result;
  1690. va_start(Arguments, Format);
  1691. Result = vsnprintf(OutputString, OutputStringSize, Format, Arguments);
  1692. va_end(Arguments);
  1693. return Result;
  1694. }
  1695. LIBC_API
  1696. int
  1697. vsnprintf (
  1698. char *OutputString,
  1699. size_t OutputStringSize,
  1700. const char *Format,
  1701. va_list Arguments
  1702. )
  1703. /*++
  1704. Routine Description:
  1705. This routine implements the core string print format function.
  1706. Arguments:
  1707. OutputString - Supplies a pointer to the buffer where the resulting string
  1708. will be written.
  1709. OutputStringSize - Supplies the size of the output string buffer, in bytes.
  1710. If the format is too long for the output buffer, the resulting string
  1711. will be truncated and the last byte will always be a null terminator.
  1712. Format - Supplies the printf format string.
  1713. Arguments - Supplies the argument list to the format string. The va_end
  1714. macro is not invoked on this list.
  1715. Return Value:
  1716. Returns the number of bytes that would have been converted had
  1717. OutputStringSize been large enough, not including the null terminator.
  1718. Returns a negative number if an error was encountered.
  1719. --*/
  1720. {
  1721. ULONG Result;
  1722. Result = RtlFormatString(OutputString,
  1723. OutputStringSize,
  1724. CharacterEncodingDefault,
  1725. (PSTR)Format,
  1726. Arguments);
  1727. return Result - 1;
  1728. }
  1729. LIBC_API
  1730. int
  1731. vsprintf (
  1732. char *OutputString,
  1733. const char *Format,
  1734. va_list Arguments
  1735. )
  1736. /*++
  1737. Routine Description:
  1738. This routine implements the core string print format function.
  1739. Arguments:
  1740. OutputString - Supplies a pointer to the buffer where the resulting string
  1741. will be written.
  1742. Format - Supplies the printf format string.
  1743. Arguments - Supplies the argument list to the format string. The va_end
  1744. macro is not invoked on this list.
  1745. Return Value:
  1746. Returns the number of bytes successfully converted, not including the null
  1747. terminator.
  1748. Returns a negative number if an error was encountered.
  1749. --*/
  1750. {
  1751. return vsnprintf(OutputString, MAX_LONG, Format, Arguments);
  1752. }
  1753. LIBC_API
  1754. int
  1755. asprintf (
  1756. char **OutputString,
  1757. const char *Format,
  1758. ...
  1759. )
  1760. /*++
  1761. Routine Description:
  1762. This routine prints a formatting string to a string similar to vsnprintf,
  1763. except the destination string is allocated by this function using malloc.
  1764. Arguments:
  1765. OutputString - Supplies a pointer where a pointer to a newly allocated
  1766. buffer containing the formatted string result (including the null
  1767. terminator) will be returned. The caller is reponsible for freeing this
  1768. string.
  1769. Format - Supplies the printf format string.
  1770. ... - Supplies the argument list to the format string.
  1771. Return Value:
  1772. Returns the number of bytes successfully converted, not including the null
  1773. terminator.
  1774. Returns a negative number if an error was encountered.
  1775. --*/
  1776. {
  1777. va_list Arguments;
  1778. int Status;
  1779. va_start(Arguments, Format);
  1780. Status = vasprintf(OutputString, Format, Arguments);
  1781. va_end(Arguments);
  1782. return Status;
  1783. }
  1784. LIBC_API
  1785. int
  1786. vasprintf (
  1787. char **OutputString,
  1788. const char *Format,
  1789. va_list Arguments
  1790. )
  1791. /*++
  1792. Routine Description:
  1793. This routine prints a formatting string to a string similar to vsnprintf,
  1794. except the destination string is allocated by this function using malloc.
  1795. Arguments:
  1796. OutputString - Supplies a pointer where a pointer to a newly allocated
  1797. buffer containing the formatted string result (including the null
  1798. terminator) will be returned. The caller is reponsible for freeing this
  1799. string.
  1800. Format - Supplies the printf format string.
  1801. Arguments - Supplies the argument list to the format string. The va_end
  1802. macro is not invoked on this list.
  1803. Return Value:
  1804. Returns the number of bytes successfully converted, not including the null
  1805. terminator.
  1806. Returns a negative number if an error was encountered.
  1807. --*/
  1808. {
  1809. ASPRINT_CONTEXT AsContext;
  1810. PRINT_FORMAT_CONTEXT PrintContext;
  1811. *OutputString = NULL;
  1812. memset(&PrintContext, 0, sizeof(PRINT_FORMAT_CONTEXT));
  1813. PrintContext.Context = &AsContext;
  1814. PrintContext.WriteCharacter = ClpAsPrintWriteCharacter;
  1815. RtlInitializeMultibyteState(&(PrintContext.State),
  1816. CharacterEncodingDefault);
  1817. AsContext.Buffer = malloc(ASPRINT_INITIAL_BUFFER_SIZE);
  1818. if (AsContext.Buffer == NULL) {
  1819. return -1;
  1820. }
  1821. AsContext.Size = 0;
  1822. AsContext.Capacity = ASPRINT_INITIAL_BUFFER_SIZE;
  1823. RtlFormat(&PrintContext, (PSTR)Format, Arguments);
  1824. if (AsContext.Buffer == NULL) {
  1825. return -1;
  1826. }
  1827. ASSERT(AsContext.Size < AsContext.Capacity);
  1828. AsContext.Buffer[AsContext.Size] = '\0';
  1829. *OutputString = AsContext.Buffer;
  1830. return PrintContext.CharactersWritten;
  1831. }
  1832. LIBC_API
  1833. int
  1834. poll (
  1835. struct pollfd PollDescriptors[],
  1836. nfds_t DescriptorCount,
  1837. int Timeout
  1838. )
  1839. /*++
  1840. Routine Description:
  1841. This routine blocks waiting for specified activity on a range of file
  1842. descriptors.
  1843. Arguments:
  1844. PollDescriptors - Supplies an array of poll descriptor structures,
  1845. indicating which descriptors should be waited on and which events
  1846. should qualify in each descriptor.
  1847. DescriptorCount - Supplies the number of descriptors in the array.
  1848. Timeout - Supplies the amount of time in milliseconds to block before
  1849. giving up and returning anyway. Supply 0 to not block at all, and
  1850. supply -1 to wait for an indefinite amount of time. The timeout will be
  1851. at least as long as supplied, but may also be rounded up.
  1852. Return Value:
  1853. Returns a positive number to indicate success and the number of file
  1854. descriptors that had events occur.
  1855. Returns 0 to indicate a timeout.
  1856. Returns -1 to indicate an error, and errno will be set to contain more
  1857. information.
  1858. --*/
  1859. {
  1860. struct timespec *TimeoutPointer;
  1861. struct timespec Timespec;
  1862. if (Timeout >= 0) {
  1863. Timespec.tv_sec = Timeout / MILLISECONDS_PER_SECOND;
  1864. Timespec.tv_nsec = (Timeout % MILLISECONDS_PER_SECOND) *
  1865. NANOSECONDS_PER_MILLISECOND;
  1866. TimeoutPointer = &Timespec;
  1867. } else {
  1868. TimeoutPointer = NULL;
  1869. }
  1870. return ppoll(PollDescriptors, DescriptorCount, TimeoutPointer, NULL);
  1871. }
  1872. LIBC_API
  1873. int
  1874. ppoll (
  1875. struct pollfd PollDescriptors[],
  1876. nfds_t DescriptorCount,
  1877. const struct timespec *Timeout,
  1878. const sigset_t *SignalMask
  1879. )
  1880. /*++
  1881. Routine Description:
  1882. This routine blocks waiting for specified activity on a range of file
  1883. descriptors.
  1884. Arguments:
  1885. PollDescriptors - Supplies an array of poll descriptor structures,
  1886. indicating which descriptors should be waited on and which events
  1887. should qualify in each descriptor.
  1888. DescriptorCount - Supplies the number of descriptors in the array.
  1889. Timeout - Supplies the amount of time to block before giving up and
  1890. returning anyway. Supply 0 to not block at all, and supply -1 to wait
  1891. for an indefinite amount of time. The timeout will be at least as long
  1892. as supplied, but may also be rounded up.
  1893. SignalMask - Supplies an optional pointer to a signal mask to set
  1894. atomically for the duration of the wait.
  1895. Return Value:
  1896. Returns a positive number to indicate success and the number of file
  1897. descriptors that had events occur.
  1898. Returns 0 to indicate a timeout.
  1899. Returns -1 to indicate an error, and errno will be set to contain more
  1900. information.
  1901. --*/
  1902. {
  1903. ULONG DescriptorsSelected;
  1904. INT Result;
  1905. KSTATUS Status;
  1906. ULONG TimeoutMilliseconds;
  1907. if (DescriptorCount > sysconf(_SC_OPEN_MAX)) {
  1908. errno = EINVAL;
  1909. return -1;
  1910. }
  1911. ASSERT_POLL_FLAGS_EQUIVALENT();
  1912. ASSERT_POLL_STRUCTURE_EQUIVALENT();
  1913. Result = ClpConvertSpecificTimeoutToSystemTimeout(Timeout,
  1914. &TimeoutMilliseconds);
  1915. if (Result != 0) {
  1916. errno = Result;
  1917. return -1;
  1918. }
  1919. //
  1920. // Perform the actual poll call, and return if failure is received.
  1921. //
  1922. Status = OsPoll((PSIGNAL_SET)SignalMask,
  1923. (PPOLL_DESCRIPTOR)PollDescriptors,
  1924. DescriptorCount,
  1925. TimeoutMilliseconds,
  1926. &DescriptorsSelected);
  1927. if (!KSUCCESS(Status)) {
  1928. goto pollEnd;
  1929. }
  1930. pollEnd:
  1931. if ((!KSUCCESS(Status)) && (Status != STATUS_TIMEOUT)) {
  1932. errno = ClConvertKstatusToErrorNumber(Status);
  1933. return -1;
  1934. }
  1935. return (int)DescriptorsSelected;
  1936. }
  1937. LIBC_API
  1938. int
  1939. select (
  1940. int DescriptorCount,
  1941. fd_set *ReadDescriptors,
  1942. fd_set *WriteDescriptors,
  1943. fd_set *ErrorDescriptors,
  1944. struct timeval *Timeout
  1945. )
  1946. /*++
  1947. Routine Description:
  1948. This routine indicates which of the specified file descriptors are ready
  1949. for reading, writing, and have error conditions.
  1950. Arguments:
  1951. DescriptorCount - Supplies the range of file descriptors to be tested.
  1952. This routine tests file descriptors in the range of 0 to the descriptor
  1953. count - 1.
  1954. ReadDescriptors - Supplies an optional pointer to a set of descriptors that
  1955. on input supplies the set of descriptors to be checked for reading. On
  1956. output, contains the set of descriptors that are ready to be read.
  1957. WriteDescriptors - Supplies an optional pointer to a set of descriptors that
  1958. on input supplies the set of descriptors to be checked for writing. On
  1959. output, contains the set of descriptors that are ready to be written to.
  1960. ErrorDescriptors - Supplies an optional pointer to a set of descriptors that
  1961. on input supplies the set of descriptors to be checked for errors. On
  1962. output, contains the set of descriptors that have errors.
  1963. Timeout - Supplies an optional to a structure that defines how long to wait
  1964. for one or more of the descriptors to become ready. If all members of
  1965. this structure are 0, the function will not block. If this argument is
  1966. not supplied, the function will block indefinitely until one of the
  1967. events is ready. If all three descriptor structure pointers is null,
  1968. this routine will block for the specified amount of time and then
  1969. return.
  1970. Return Value:
  1971. On success, returns the total number of bits set in the resulting bitmaps.
  1972. 0 if the timeout expired.
  1973. -1 on error, and errno will be set to contain more information.
  1974. --*/
  1975. {
  1976. int Result;
  1977. struct timespec *TimeoutPointer;
  1978. struct timespec Timespec;
  1979. if (Timeout != NULL) {
  1980. Timespec.tv_sec = Timeout->tv_sec;
  1981. Timespec.tv_nsec = Timeout->tv_usec * NANOSECONDS_PER_MICROSECOND;
  1982. TimeoutPointer = &Timespec;
  1983. } else {
  1984. TimeoutPointer = NULL;
  1985. }
  1986. Result = pselect(DescriptorCount,
  1987. ReadDescriptors,
  1988. WriteDescriptors,
  1989. ErrorDescriptors,
  1990. TimeoutPointer,
  1991. NULL);
  1992. return Result;
  1993. }
  1994. LIBC_API
  1995. int
  1996. pselect (
  1997. int DescriptorCount,
  1998. fd_set *ReadDescriptors,
  1999. fd_set *WriteDescriptors,
  2000. fd_set *ErrorDescriptors,
  2001. const struct timespec *Timeout,
  2002. const sigset_t *SignalMask
  2003. )
  2004. /*++
  2005. Routine Description:
  2006. This routine indicates which of the specified file descriptors are ready
  2007. for reading, writing, and have error conditions.
  2008. Arguments:
  2009. DescriptorCount - Supplies the range of file descriptors to be tested.
  2010. This routine tests file descriptors in the range of 0 to the descriptor
  2011. count - 1.
  2012. ReadDescriptors - Supplies an optional pointer to a set of descriptors that
  2013. on input supplies the set of descriptors to be checked for reading. On
  2014. output, contains the set of descriptors that are ready to be read.
  2015. WriteDescriptors - Supplies an optional pointer to a set of descriptors that
  2016. on input supplies the set of descriptors to be checked for writing. On
  2017. output, contains the set of descriptors that are ready to be written to.
  2018. ErrorDescriptors - Supplies an optional pointer to a set of descriptors that
  2019. on input supplies the set of descriptors to be checked for errors. On
  2020. output, contains the set of descriptors that have errors.
  2021. Timeout - Supplies an optional to a structure that defines how long to wait
  2022. for one or more of the descriptors to become ready. If all members of
  2023. this structure are 0, the function will not block. If this argument is
  2024. not supplied, the function will block indefinitely until one of the
  2025. events is ready. If all three descriptor structure pointers is null,
  2026. this routine will block for the specified amount of time and then
  2027. return.
  2028. SignalMask - Supplies an optional pointer to the signal mask to set for
  2029. the duration of the wait.
  2030. Return Value:
  2031. On success, returns the total number of bits set in the resulting bitmaps.
  2032. 0 if the timeout expired.
  2033. -1 on error, and errno will be set to contain more information.
  2034. --*/
  2035. {
  2036. ULONG ArrayIndex;
  2037. INT BitCount;
  2038. PPOLL_DESCRIPTOR Descriptor;
  2039. ULONG DescriptorIndex;
  2040. PPOLL_DESCRIPTOR Descriptors;
  2041. ULONG DescriptorsSelected;
  2042. ULONG Events;
  2043. ULONG PollIndex;
  2044. INT Result;
  2045. KSTATUS Status;
  2046. ULONG TimeoutInMilliseconds;
  2047. if (DescriptorCount < 0) {
  2048. errno = EINVAL;
  2049. return -1;
  2050. }
  2051. Result = ClpConvertSpecificTimeoutToSystemTimeout(Timeout,
  2052. &TimeoutInMilliseconds);
  2053. if (Result != 0) {
  2054. errno = Result;
  2055. return -1;
  2056. }
  2057. Descriptors = NULL;
  2058. DescriptorsSelected = 0;
  2059. if (DescriptorCount > FD_SETSIZE) {
  2060. DescriptorCount = FD_SETSIZE;
  2061. }
  2062. Descriptors = alloca(sizeof(POLL_DESCRIPTOR) * DescriptorCount);
  2063. if (Descriptors == NULL) {
  2064. errno = ENOMEM;
  2065. return -1;
  2066. }
  2067. //
  2068. // Fill out the new poll descriptors.
  2069. //
  2070. ArrayIndex = 0;
  2071. for (DescriptorIndex = 0;
  2072. DescriptorIndex < DescriptorCount;
  2073. DescriptorIndex += 1) {
  2074. Events = 0;
  2075. if ((ReadDescriptors != NULL) &&
  2076. (FD_ISSET(DescriptorIndex, ReadDescriptors) != FALSE)) {
  2077. Events |= POLL_EVENT_IN;
  2078. }
  2079. if ((WriteDescriptors != NULL) &&
  2080. (FD_ISSET(DescriptorIndex, WriteDescriptors) != FALSE)) {
  2081. Events |= POLL_EVENT_OUT;
  2082. }
  2083. if ((ErrorDescriptors != NULL) &&
  2084. (FD_ISSET(DescriptorIndex, ErrorDescriptors) != FALSE)) {
  2085. Events |= POLL_EVENT_ERROR;
  2086. }
  2087. if (Events == 0) {
  2088. continue;
  2089. }
  2090. Descriptor = &(Descriptors[ArrayIndex]);
  2091. ArrayIndex += 1;
  2092. Descriptor->Handle = (HANDLE)(UINTN)DescriptorIndex;
  2093. Descriptor->Events = Events;
  2094. Descriptor->ReturnedEvents = 0;
  2095. }
  2096. //
  2097. // Peform the poll.
  2098. //
  2099. Status = OsPoll((PSIGNAL_SET)SignalMask,
  2100. Descriptors,
  2101. ArrayIndex,
  2102. TimeoutInMilliseconds,
  2103. &DescriptorsSelected);
  2104. if ((!KSUCCESS(Status)) && (Status != STATUS_TIMEOUT)) {
  2105. goto pselectEnd;
  2106. }
  2107. //
  2108. // Check for invalid handles, since POSIX says on failure the bitmasks
  2109. // should not be modified.
  2110. //
  2111. for (PollIndex = 0; PollIndex < ArrayIndex; PollIndex += 1) {
  2112. if ((Descriptors[PollIndex].ReturnedEvents &
  2113. POLL_EVENT_INVALID_HANDLE) != 0) {
  2114. Status = STATUS_INVALID_HANDLE;
  2115. goto pselectEnd;
  2116. }
  2117. }
  2118. //
  2119. // Go back and mark all the descriptors in the set that had events. Loop
  2120. // over the poll events this time to skip the empty regions of the bitmasks.
  2121. //
  2122. BitCount = 0;
  2123. Descriptor = &(Descriptors[0]);
  2124. for (PollIndex = 0; PollIndex < ArrayIndex; PollIndex += 1) {
  2125. Events = Descriptor->ReturnedEvents;
  2126. DescriptorIndex = (UINTN)(Descriptor->Handle);
  2127. ASSERT(DescriptorIndex < DescriptorCount);
  2128. //
  2129. // If the caller didn't want error events but one fired, set the in and
  2130. // out events to force them to take action.
  2131. //
  2132. if (((Events & POLL_ERROR_EVENTS) != 0) && (ErrorDescriptors == NULL)) {
  2133. Events |= POLL_EVENT_IN | POLL_EVENT_OUT;
  2134. }
  2135. if ((ReadDescriptors != NULL) &&
  2136. (FD_ISSET(DescriptorIndex, ReadDescriptors) != FALSE)) {
  2137. if ((Events & POLL_EVENT_IN) == 0) {
  2138. FD_CLR(DescriptorIndex, ReadDescriptors);
  2139. } else {
  2140. BitCount += 1;
  2141. }
  2142. }
  2143. if ((WriteDescriptors != NULL) &&
  2144. (FD_ISSET(DescriptorIndex, WriteDescriptors) != FALSE)) {
  2145. if ((Events & POLL_EVENT_OUT) == 0) {
  2146. FD_CLR(DescriptorIndex, WriteDescriptors);
  2147. } else {
  2148. BitCount += 1;
  2149. }
  2150. }
  2151. //
  2152. // Errors work a little differently, if it's supplied then the bits get
  2153. // set whether they were asked for or not.
  2154. //
  2155. if (ErrorDescriptors != NULL) {
  2156. if ((Events & POLL_NONMASKABLE_EVENTS) != 0) {
  2157. FD_SET(DescriptorIndex, ErrorDescriptors);
  2158. BitCount += 1;
  2159. } else {
  2160. FD_CLR(DescriptorIndex, ErrorDescriptors);
  2161. }
  2162. }
  2163. Descriptor += 1;
  2164. }
  2165. pselectEnd:
  2166. if (!KSUCCESS(Status)) {
  2167. if (Status != STATUS_TIMEOUT) {
  2168. errno = ClConvertKstatusToErrorNumber(Status);
  2169. return -1;
  2170. }
  2171. }
  2172. return BitCount;
  2173. }
  2174. LIBC_API
  2175. char *
  2176. ttyname (
  2177. int FileDescriptor
  2178. )
  2179. /*++
  2180. Routine Description:
  2181. This routine returns the null-terminated pathname of the terminal
  2182. associated with the given file descriptor. This function is neither
  2183. reentrant nor thread safe.
  2184. Arguments:
  2185. FileDescriptor - Supplies the file descriptor to query.
  2186. Return Value:
  2187. Returns a pointer to the supplied buffer on success. This buffer may be
  2188. overwritten by subsequent calls to this routine.
  2189. NULL on failure and errno will be set to contain more information. Common
  2190. error values are:
  2191. EBADF if the file descriptor is not valid.
  2192. ENOTTY if the file descriptor is not a terminal.
  2193. ENOMEM if not enough memory was available.
  2194. --*/
  2195. {
  2196. char *NewBuffer;
  2197. size_t NewBufferSize;
  2198. int OldError;
  2199. char *Result;
  2200. if (ClTerminalNameBufferSize == 0) {
  2201. ClTerminalNameBuffer = malloc(INITIAL_TERMINAL_NAME_BUFFER_SIZE);
  2202. if (ClTerminalNameBuffer == NULL) {
  2203. errno = ENOMEM;
  2204. return NULL;
  2205. }
  2206. ClTerminalNameBufferSize = INITIAL_TERMINAL_NAME_BUFFER_SIZE;
  2207. }
  2208. OldError = errno;
  2209. while (TRUE) {
  2210. Result = ttyname_r(FileDescriptor,
  2211. ClTerminalNameBuffer,
  2212. ClTerminalNameBufferSize);
  2213. if ((Result != NULL) || (errno != ERANGE)) {
  2214. break;
  2215. }
  2216. errno = OldError;
  2217. NewBufferSize = ClTerminalNameBufferSize * 2;
  2218. NewBuffer = realloc(ClTerminalNameBuffer, NewBufferSize);
  2219. if (NewBuffer == NULL) {
  2220. errno = ENOMEM;
  2221. return NULL;
  2222. }
  2223. ClTerminalNameBuffer = NewBuffer;
  2224. ClTerminalNameBufferSize = NewBufferSize;
  2225. }
  2226. return Result;
  2227. }
  2228. LIBC_API
  2229. char *
  2230. ttyname_r (
  2231. int FileDescriptor,
  2232. char *Name,
  2233. size_t NameSize
  2234. )
  2235. /*++
  2236. Routine Description:
  2237. This routine returns the null-terminated pathname of the terminal
  2238. associated with the given file descriptor.
  2239. Arguments:
  2240. FileDescriptor - Supplies the file descriptor to query.
  2241. Name - Supplies a pointer to the buffer where the name will be returned
  2242. on success.
  2243. NameSize - Supplies the size of the name buffer in bytes.
  2244. Return Value:
  2245. Returns a pointer to the supplied buffer on success.
  2246. NULL on failure and errno will be set to contain more information. Common
  2247. error values are:
  2248. EBADF if the file descriptor is not valid.
  2249. ENOTTY if the file descriptor is not a terminal.
  2250. ERANGE if the supplied buffer was not large enough.
  2251. --*/
  2252. {
  2253. UINTN Size;
  2254. KSTATUS Status;
  2255. if (isatty(FileDescriptor) == 0) {
  2256. errno = ENOTTY;
  2257. return NULL;
  2258. }
  2259. Size = NameSize;
  2260. Status = OsGetFilePath((HANDLE)(UINTN)FileDescriptor, Name, &Size);
  2261. if (!KSUCCESS(Status)) {
  2262. errno = ClConvertKstatusToErrorNumber(Status);
  2263. return NULL;
  2264. }
  2265. return Name;
  2266. }
  2267. LIBC_API
  2268. char *
  2269. ctermid (
  2270. char *Buffer
  2271. )
  2272. /*++
  2273. Routine Description:
  2274. This routine returns the null-terminated path of the controlling terminal
  2275. for the current process. Access to the terminal path returned by this
  2276. function is not guaranteed.
  2277. Arguments:
  2278. Buffer - Supplies an optional pointer to a buffer of at least length
  2279. L_ctermid where the path to the terminal will be returned. If this is
  2280. NULL, static storage will be used and returned, in which case the
  2281. caller should not modify or free the buffer.
  2282. Return Value:
  2283. Returns a pointer to the string containing the path of the controlling
  2284. terminal on success.
  2285. NULL on failure.
  2286. --*/
  2287. {
  2288. if (ClTerminalIdBuffer == NULL) {
  2289. ClTerminalIdBuffer = malloc(L_ctermid);
  2290. if (ClTerminalIdBuffer == NULL) {
  2291. errno = ENOMEM;
  2292. return NULL;
  2293. }
  2294. }
  2295. return ctermid_r(ClTerminalIdBuffer);
  2296. }
  2297. LIBC_API
  2298. char *
  2299. ctermid_r (
  2300. char *Buffer
  2301. )
  2302. /*++
  2303. Routine Description:
  2304. This routine returns the null-terminated path of the controlling terminal
  2305. for the current process.
  2306. Arguments:
  2307. Buffer - Supplies a pointer to a buffer of at least length L_ctermid where
  2308. the path to the terminal will be returned.
  2309. Return Value:
  2310. Returns a pointer to the supplied buffer on success.
  2311. NULL on failure.
  2312. --*/
  2313. {
  2314. if (Buffer == NULL) {
  2315. return NULL;
  2316. }
  2317. snprintf(Buffer, L_ctermid, _PATH_TTY);
  2318. return Buffer;
  2319. }
  2320. LIBC_API
  2321. int
  2322. ioctl (
  2323. int FileDescriptor,
  2324. int Request,
  2325. ...
  2326. )
  2327. /*++
  2328. Routine Description:
  2329. This routine sends an I/O control request to the given file descriptor.
  2330. Arguments:
  2331. FileDescriptor - Supplies the file descriptor to send the control request
  2332. to.
  2333. Request - Supplies the numeric request to send. This is device-specific.
  2334. ... - Supplies a variable number of arguments for historical reasons, but
  2335. this routine expects there to be exactly one more argument, a pointer
  2336. to memory. The size of this memory is request-specific, but can be no
  2337. larger than 4096 bytes. The native version of this routine can specify
  2338. larger values.
  2339. Return Value:
  2340. 0 on success.
  2341. -1 on failure, and errno will be set to contain more information.
  2342. --*/
  2343. {
  2344. void *Argument;
  2345. va_list ArgumentList;
  2346. KSTATUS Status;
  2347. va_start(ArgumentList, Request);
  2348. Argument = va_arg(ArgumentList, void *);
  2349. va_end(ArgumentList);
  2350. Status = OsUserControl((HANDLE)(UINTN)FileDescriptor,
  2351. Request,
  2352. Argument,
  2353. 4096);
  2354. if (!KSUCCESS(Status)) {
  2355. errno = ClConvertKstatusToErrorNumber(Status);
  2356. return -1;
  2357. }
  2358. return 0;
  2359. }
  2360. //
  2361. // --------------------------------------------------------- Internal Functions
  2362. //
  2363. int
  2364. ClpOpen (
  2365. int Directory,
  2366. const char *Path,
  2367. int OpenFlags,
  2368. va_list ArgumentList
  2369. )
  2370. /*++
  2371. Routine Description:
  2372. This routine opens a file and connects it to a file descriptor.
  2373. Arguments:
  2374. Directory - Supplies an optional file descriptor. If the given path
  2375. is a relative path, the directory referenced by this descriptor will
  2376. be used as a starting point for path resolution. Supply AT_FDCWD to
  2377. use the working directory for relative paths. This is normally the
  2378. expected behavior.
  2379. Path - Supplies a pointer to a null terminated string containing the path
  2380. of the file to open.
  2381. OpenFlags - Supplies a set of flags ORed together. See O_* definitions.
  2382. ArgumentList - Supplies the variadic arguments to the open call.
  2383. Return Value:
  2384. Returns a file descriptor on success.
  2385. -1 on failure. The errno variable will be set to indicate the error.
  2386. --*/
  2387. {
  2388. mode_t CreateMode;
  2389. FILE_PERMISSIONS CreatePermissions;
  2390. HANDLE FileHandle;
  2391. ULONG OsOpenFlags;
  2392. ULONG PathLength;
  2393. KSTATUS Status;
  2394. if (Path == NULL) {
  2395. errno = EINVAL;
  2396. return -1;
  2397. }
  2398. PathLength = RtlStringLength((PSTR)Path) + 1;
  2399. OsOpenFlags = 0;
  2400. CreatePermissions = 0;
  2401. //
  2402. // This assert stands for not just the openat call, but for all the *at
  2403. // calls out there that rely on this assumption.
  2404. //
  2405. assert(INVALID_HANDLE == (HANDLE)AT_FDCWD);
  2406. //
  2407. // Set the access mask.
  2408. //
  2409. switch (OpenFlags & O_ACCMODE) {
  2410. case O_RDONLY:
  2411. OsOpenFlags |= SYS_OPEN_FLAG_READ;
  2412. break;
  2413. case O_WRONLY:
  2414. OsOpenFlags |= SYS_OPEN_FLAG_WRITE;
  2415. break;
  2416. case O_RDWR:
  2417. OsOpenFlags |= SYS_OPEN_FLAG_READ | SYS_OPEN_FLAG_WRITE;
  2418. break;
  2419. default:
  2420. break;
  2421. }
  2422. assert(O_EXEC == O_SEARCH);
  2423. if ((OpenFlags & O_EXEC) != 0) {
  2424. OsOpenFlags |= SYS_OPEN_FLAG_EXECUTE;
  2425. }
  2426. if ((OpenFlags & O_TRUNC) != 0) {
  2427. OsOpenFlags |= SYS_OPEN_FLAG_TRUNCATE;
  2428. }
  2429. if ((OpenFlags & O_APPEND) != 0) {
  2430. OsOpenFlags |= SYS_OPEN_FLAG_APPEND;
  2431. }
  2432. if ((OpenFlags & O_NONBLOCK) != 0) {
  2433. OsOpenFlags |= SYS_OPEN_FLAG_NON_BLOCKING;
  2434. }
  2435. if ((OpenFlags & O_DIRECTORY) != 0) {
  2436. OsOpenFlags |= SYS_OPEN_FLAG_DIRECTORY;
  2437. }
  2438. if ((OpenFlags & O_NOFOLLOW) != 0) {
  2439. OsOpenFlags |= SYS_OPEN_FLAG_NO_SYMBOLIC_LINK;
  2440. }
  2441. if ((OpenFlags & O_NOATIME) != 0) {
  2442. OsOpenFlags |= SYS_OPEN_FLAG_NO_ACCESS_TIME;
  2443. }
  2444. assert((O_SYNC == O_DSYNC) && (O_SYNC == O_RSYNC));
  2445. if ((OpenFlags & O_SYNC) != 0) {
  2446. OsOpenFlags |= SYS_OPEN_FLAG_SYNCHRONIZED;
  2447. }
  2448. if ((OpenFlags & O_NOCTTY) != 0) {
  2449. OsOpenFlags |= SYS_OPEN_FLAG_NO_CONTROLLING_TERMINAL;
  2450. }
  2451. if ((OpenFlags & O_CLOEXEC) != 0) {
  2452. OsOpenFlags |= SYS_OPEN_FLAG_CLOSE_ON_EXECUTE;
  2453. }
  2454. //
  2455. // O_PATH is equivalent to opening with no access.
  2456. //
  2457. if ((OpenFlags & O_PATH) != 0) {
  2458. OsOpenFlags &= ~(SYS_OPEN_FLAG_READ | SYS_OPEN_FLAG_WRITE |
  2459. SYS_OPEN_FLAG_EXECUTE);
  2460. }
  2461. if ((OpenFlags & O_ASYNC) != 0) {
  2462. OsOpenFlags |= SYS_OPEN_FLAG_ASYNCHRONOUS;
  2463. }
  2464. //
  2465. // Set other flags.
  2466. //
  2467. if ((OpenFlags & O_CREAT) != 0) {
  2468. OsOpenFlags |= SYS_OPEN_FLAG_CREATE;
  2469. if ((OpenFlags & O_EXCL) != 0) {
  2470. OsOpenFlags |= SYS_OPEN_FLAG_FAIL_IF_EXISTS;
  2471. }
  2472. CreateMode = va_arg(ArgumentList, mode_t);
  2473. ASSERT_FILE_PERMISSIONS_EQUIVALENT();
  2474. CreatePermissions = CreateMode;
  2475. }
  2476. Status = OsOpen((HANDLE)(UINTN)Directory,
  2477. (PSTR)Path,
  2478. PathLength,
  2479. OsOpenFlags,
  2480. CreatePermissions,
  2481. &FileHandle);
  2482. if (!KSUCCESS(Status)) {
  2483. errno = ClConvertKstatusToErrorNumber(Status);
  2484. return -1;
  2485. }
  2486. return (int)(UINTN)FileHandle;
  2487. }
  2488. BOOL
  2489. ClpAsPrintWriteCharacter (
  2490. INT Character,
  2491. PPRINT_FORMAT_CONTEXT Context
  2492. )
  2493. /*++
  2494. Routine Description:
  2495. This routine writes a character to the output during a printf-style
  2496. formatting operation.
  2497. Arguments:
  2498. Character - Supplies the character to be written.
  2499. Context - Supplies a pointer to the printf-context.
  2500. Return Value:
  2501. TRUE on success.
  2502. FALSE on failure.
  2503. --*/
  2504. {
  2505. PASPRINT_CONTEXT AsContext;
  2506. PSTR NewBuffer;
  2507. UINTN NewCapacity;
  2508. AsContext = Context->Context;
  2509. //
  2510. // Reallocate the buffer if needed.
  2511. //
  2512. if (AsContext->Size + 1 >= AsContext->Capacity) {
  2513. NewCapacity = AsContext->Capacity * 2;
  2514. NewBuffer = NULL;
  2515. if (NewCapacity > AsContext->Capacity) {
  2516. NewBuffer = realloc(AsContext->Buffer, NewCapacity);
  2517. }
  2518. if (NewBuffer == NULL) {
  2519. free(AsContext->Buffer);
  2520. AsContext->Buffer = NULL;
  2521. return FALSE;
  2522. }
  2523. AsContext->Buffer = NewBuffer;
  2524. AsContext->Capacity = NewCapacity;
  2525. }
  2526. AsContext->Buffer[AsContext->Size] = Character;
  2527. AsContext->Size += 1;
  2528. return TRUE;
  2529. }