]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/LibC/Uefi/SysCalls.c
edk2: Remove AppPkg, StdLib, StdLibPrivateInternalFiles
[mirror_edk2.git] / StdLib / LibC / Uefi / SysCalls.c
diff --git a/StdLib/LibC/Uefi/SysCalls.c b/StdLib/LibC/Uefi/SysCalls.c
deleted file mode 100644 (file)
index faa73ed..0000000
+++ /dev/null
@@ -1,1448 +0,0 @@
-/** @file\r
-  EFI versions of NetBSD system calls.\r
-\r
-  Copyright (c) 2016, Daryl McDaniel. All rights reserved.<BR>\r
-  Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials are licensed and made available under\r
-  the terms and conditions of the BSD License that accompanies this distribution.\r
-  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-#include  <Uefi.h>\r
-#include  <Library/UefiLib.h>\r
-#include  <Library/UefiBootServicesTableLib.h>\r
-#include  <Library/BaseLib.h>\r
-#include  <Library/MemoryAllocationLib.h>\r
-#include  <Library/ShellLib.h>\r
-\r
-#include  <LibConfig.h>\r
-#include  <sys/EfiCdefs.h>\r
-\r
-#include  <sys/ansi.h>\r
-#include  <errno.h>\r
-#include  <stdarg.h>\r
-#include  <stdlib.h>\r
-#include  <string.h>\r
-#include  <wchar.h>\r
-#include  <sys/poll.h>\r
-#include  <sys/fcntl.h>\r
-#include  <sys/stat.h>\r
-#include  <sys/syslimits.h>\r
-#include  <sys/filio.h>\r
-#include  <Efi/SysEfi.h>\r
-#include  <unistd.h>\r
-#include  <kfile.h>\r
-#include  <Device/Device.h>\r
-#include  <Device/IIO.h>\r
-#include  <MainData.h>\r
-#include  <extern.h>\r
-\r
-/* EFI versions of BSD system calls used in stdio */\r
-\r
-/*  Validate that fd refers to a valid file descriptor.\r
-    IsOpen is interpreted as follows:\r
-      - Positive  fd must be OPEN\r
-      - Zero      fd must be CLOSED\r
-      - Negative  fd may be OPEN or CLOSED\r
-\r
-    @retval TRUE  fd is VALID\r
-    @retval FALSE fd is INVALID\r
-*/\r
-BOOLEAN\r
-ValidateFD( int fd, int IsOpen)\r
-{\r
-  struct __filedes    *filp;\r
-  BOOLEAN   retval = FALSE;\r
-\r
-  if((fd >= 0) && (fd < OPEN_MAX)) {\r
-    filp = &gMD->fdarray[fd];\r
-    retval = TRUE;\r
-    if(IsOpen >= 0) {\r
-      retval = (BOOLEAN)((filp->f_iflags != 0)  &&    // TRUE if OPEN\r
-                         FILE_IS_USABLE(filp));         // and Usable (not Larval or Closing)\r
-      if(IsOpen == VALID_CLOSED) {\r
-        retval = (BOOLEAN)!retval;                      // We want TRUE if CLOSED\r
-      }\r
-    }\r
-  }\r
-  return retval;\r
-}\r
-\r
-/* Find and reserve a free File Descriptor.\r
-\r
-  Returns the first free File Descriptor greater than or equal to the,\r
-  already validated, fd specified by Minfd.\r
-\r
-  @return   Returns -1 if there are no free FDs.  Otherwise returns the\r
-            found fd.\r
-*/\r
-int\r
-FindFreeFD( int MinFd )\r
-{\r
-  struct __filedes    *Mfd;\r
-  int i;\r
-  int fd = -1;\r
-\r
-  Mfd = gMD->fdarray;\r
-\r
-  // Get an available fd\r
-  for(i=MinFd; i < OPEN_MAX; ++i) {\r
-    if(Mfd[i].f_iflags == 0) {\r
-      Mfd[i].f_iflags = FIF_LARVAL; // Temporarily mark this fd as reserved\r
-      fd = i;\r
-      break;\r
-    }\r
-  }\r
-  return fd;\r
-}\r
-\r
-/* Mark that an open file is to be deleted when closed. */\r
-int\r
-DeleteOnClose(int fd)\r
-{\r
-  int   retval = 0;\r
-\r
-  if(ValidateFD( fd, VALID_OPEN)) {\r
-    gMD->fdarray[fd].f_iflags |= FIF_DELCLOSE;\r
-  }\r
-  else {\r
-    errno = EBADF;\r
-    retval = -1;\r
-  }\r
-  return retval;\r
-}\r
-\r
-/** The isatty() function tests whether fd, an open file descriptor,\r
-    is associated with a terminal device.\r
-\r
-    @param[in]  fd  File Descriptor for the file to be examined.\r
-\r
-    @retval   1   fd is associated with a terminal.\r
-    @retval   0   fd is not associated with a terminal.  errno is set to\r
-                  EBADF if fd is not a valid open FD.\r
-**/\r
-int\r
-isatty  (int fd)\r
-{\r
-  int   retval = 0;\r
-  struct __filedes *Fp;\r
-\r
-  if(ValidateFD( fd, VALID_OPEN)) {\r
-    Fp = &gMD->fdarray[fd];\r
-    retval =  (Fp->f_iflags & _S_ITTY) ? 1 : 0;\r
-  }\r
-  else {\r
-    errno = EBADF;\r
-  }\r
-  return retval;\r
-}\r
-\r
-/** Determine if file descriptor fd is a duplicate of some other fd.\r
-\r
-    @param[in]    fd    The file descriptor to check.\r
-\r
-    @retval   TRUE    fd is a duplicate of another fd.\r
-    @retval   FALSE   fd is unique.\r
-**/\r
-static BOOLEAN\r
-IsDupFd( int fd)\r
-{\r
-  void * DevData;\r
-  const struct fileops   *FileOps;\r
-  int                   i;\r
-  BOOLEAN               Ret = FALSE;\r
-\r
-  if(ValidateFD( fd, VALID_OPEN )) {\r
-    FileOps = gMD->fdarray[fd].f_ops;\r
-    DevData = gMD->fdarray[fd].devdata;\r
-    for(i=0; i < OPEN_MAX; ++i) {\r
-      if(i == fd)   continue;\r
-      if(ValidateFD( i, VALID_OPEN )) {   // TRUE if fd is valid and OPEN\r
-        if((gMD->fdarray[i].f_ops == FileOps)\r
-          &&(gMD->fdarray[i].devdata == DevData )) {\r
-          Ret = TRUE;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-  }\r
-  return Ret;\r
-}\r
-\r
-/** Worker function to Close a file and set its fd to the specified state.\r
-\r
-    @param[in]    fd          The file descriptor to close.\r
-    @param[in]    NewState    State to set the fd to after the file is closed.\r
-\r
-    @retval    0    The operation completed successfully.\r
-    @retval   -1    The operation failed.  Further information is in errno.\r
-                      * EBADF   fd is not a valid or open file descriptor.\r
-**/\r
-static int\r
-_closeX  (int fd, int NewState)\r
-{\r
-  struct __filedes     *Fp;\r
-  int                   retval = 0;\r
-\r
-  // Verify my pointers and get my FD.\r
-  if(ValidateFD( fd, VALID_OPEN )) {\r
-    Fp = &gMD->fdarray[fd];\r
-    // Check if there are other users of this FileHandle\r
-    if(Fp->RefCount == 1) { // There should be no other users\r
-      if(! IsDupFd(fd)) {\r
-        // Only do the close if no one else is using the FileHandle\r
-        if(Fp->f_iflags & FIF_DELCLOSE) {\r
-          /* Handle files marked "Delete on Close". */\r
-          if(Fp->f_ops->fo_delete != NULL) {\r
-            retval = Fp->f_ops->fo_delete(Fp);\r
-          }\r
-        }\r
-        else {\r
-          retval = Fp->f_ops->fo_close( Fp);\r
-        }\r
-      }\r
-      Fp->f_iflags = NewState;    // Close this FD or reserve it\r
-      Fp->RefCount = 0;           // No one using this FD\r
-    }\r
-    else {\r
-      --Fp->RefCount;   /* One less user of this FD */\r
-    }\r
-  }\r
-  else {\r
-    // Bad FD\r
-    retval = -1;\r
-    errno = EBADF;\r
-  }\r
-  return retval;\r
-}\r
-\r
-/** The close() function deallocates the file descriptor indicated by fd.\r
-    To deallocate means to make the file descriptor available for return by\r
-    subsequent calls to open() or other functions that allocate file\r
-    descriptors. All outstanding record locks owned by the process on the file\r
-    associated with the file descriptor are removed (that is, unlocked).\r
-\r
-    @param[in]    fd          Descriptor for the File to close.\r
-\r
-    @retval   0     Successful completion.\r
-    @retval   -1    An error occurred and errno is set to identify the error.\r
-**/\r
-int\r
-close  (int fd)\r
-{\r
-  return _closeX(fd, 0);\r
-}\r
-\r
-/** Delete the file specified by path.\r
-\r
-    @param[in]    path  The MBCS path of the file to delete.\r
-\r
-    @retval   -1  Unable to open the file specified by path.\r
-    @retval   -1  If (errno == EPERM), unlink is not permited for this file.\r
-    @retval   -1  Low-level delete filed.  Reason is in errno.\r
-    @retval   0   The file was successfully deleted.\r
-**/\r
-int\r
-unlink (const char *path)\r
-{\r
-  struct __filedes     *Fp;\r
-  int                   fd;\r
-  int                   retval = -1;\r
-\r
-  EFIerrno = RETURN_SUCCESS;\r
-\r
-  fd = open(path, O_WRONLY, 0);\r
-  if(fd >= 0) {\r
-    Fp = &gMD->fdarray[fd];\r
-\r
-    if(Fp->f_ops->fo_delete != NULL) {\r
-      retval = Fp->f_ops->fo_delete(Fp);\r
-  }\r
-    Fp->f_iflags = 0;    // Close this FD\r
-    Fp->RefCount = 0;    // No one using this FD\r
-  }\r
-  return retval;\r
-}\r
-\r
-/** The fcntl() function shall perform the operations described below on open\r
-    files. The fildes argument is a file descriptor.\r
-\r
-    The available values for cmd are defined in <fcntl.h> and are as follows:\r
-      - F_DUPFD - Return a new file descriptor which shall be the lowest\r
-                  numbered available (that is, not already open) file\r
-                  descriptor greater than or equal to the third argument, arg,\r
-                  taken as an integer of type int. The new file descriptor\r
-                  shall refer to the same open file description as the original\r
-                  file descriptor, and shall share any locks. The FD_CLOEXEC\r
-                  flag associated with the new file descriptor shall be cleared\r
-                  to keep the file open across calls to one of the exec functions.\r
-      - F_GETFD - Get the file descriptor flags defined in <fcntl.h> that are\r
-                  associated with the file descriptor fildes. File descriptor\r
-                  flags are associated with a single file descriptor and do not\r
-                  affect other file descriptors that refer to the same file.\r
-      - F_SETFD - Set the file descriptor flags defined in <fcntl.h>, that are\r
-                  associated with fildes, to the third argument, arg, taken\r
-                  as type int. If the FD_CLOEXEC flag in the third argument\r
-                  is 0, the file shall remain open across the exec\r
-                  functions; otherwise, the file shall be closed upon\r
-                  successful execution of one of the exec functions.\r
-      - F_GETFL - Get the file status flags and file access modes, defined in\r
-                  <fcntl.h>, for the file description associated with fildes.\r
-                  The file access modes can be extracted from the return\r
-                  value using the mask O_ACCMODE, which is defined in\r
-                  <fcntl.h>. File status flags and file access modes are\r
-                  associated with the file description and do not affect\r
-                  other file descriptors that refer to the same file with\r
-                  different open file descriptions.\r
-      - F_SETFL - Set the file status flags, defined in <fcntl.h>, for the file\r
-                  description associated with fildes from the corresponding\r
-                  bits in the third argument, arg, taken as type int. Bits\r
-                  corresponding to the file access mode and the file creation\r
-                  flags, as defined in <fcntl.h>, that are set in arg shall\r
-                  be ignored. If any bits in arg other than those mentioned\r
-                  here are changed by the application, the result is unspecified.\r
-      - F_GETOWN -  If fildes refers to a socket, get the process or process group\r
-                  ID specified to receive SIGURG signals when out-of-band\r
-                  data is available. Positive values indicate a process ID;\r
-                  negative values, other than -1, indicate a process group\r
-                  ID. If fildes does not refer to a socket, the results are\r
-                  unspecified.\r
-      - F_SETOWN -  If fildes refers to a socket, set the process or process\r
-                  group ID specified to receive SIGURG signals when\r
-                  out-of-band data is available, using the value of the third\r
-                  argument, arg, taken as type int. Positive values indicate\r
-                  a process ID; negative values, other than -1, indicate a\r
-                  process group ID. If fildes does not refer to a socket, the\r
-                  results are unspecified.\r
-\r
-    The fcntl() function shall fail if:\r
-\r
-    [EBADF]       The fildes argument is not a valid open file descriptor.\r
-    [EINVAL]      The cmd argument is invalid, or the cmd argument is F_DUPFD\r
-                  and arg is negative or greater than or equal to {OPEN_MAX}.\r
-    [EMFILE]      The argument cmd is F_DUPFD and {OPEN_MAX} file descriptors\r
-                  are currently open in the calling process, or no file\r
-                  descriptors greater than or equal to arg are available.\r
-    [EOVERFLOW]   One of the values to be returned cannot be represented correctly.\r
-\r
-    @param[in]      fildes    Descriptor for the file to be controlled.\r
-    @param[in]      cmd       Command to be acted upon.\r
-    @param[in,out]  ...       Optional additional parameters as required by cmd.\r
-\r
-    @return   Upon successful completion, the value returned shall depend on\r
-              cmd as follows:\r
-                - F_DUPFD - A new file descriptor.\r
-                - F_GETFD - Value of flags defined in <fcntl.h>. The return value\r
-                            shall not be negative.\r
-                - F_SETFD - Value other than -1.\r
-                - F_GETFL - Value of file status flags and access modes. The return\r
-                            value is not negative.\r
-                - F_SETFL - Value other than -1.\r
-                - F_GETOWN  - Value of the socket owner process or process group;\r
-                            this will not be -1.\r
-                - F_SETOWN - Value other than -1.\r
-              Otherwise, -1 shall be returned and errno set to indicate the error.\r
-\r
-**/\r
-int\r
-fcntl     (int fildes, int cmd, ...)\r
-{\r
-  va_list             p3;\r
-  struct __filedes   *MyFd;\r
-  int                 retval = -1;\r
-  int                 temp;\r
-\r
-//Print(L"%a( %d, %d, ...)\n", __func__, fildes, cmd);\r
-  va_start(p3, cmd);\r
-\r
-  if(ValidateFD( fildes, VALID_OPEN )) {\r
-    MyFd = &gMD->fdarray[fildes];\r
-\r
-    switch(cmd) {\r
-      case F_DUPFD:\r
-        temp = va_arg(p3, int);\r
-        if(ValidateFD( temp, VALID_DONT_CARE )) {\r
-          temp = FindFreeFD( temp );\r
-          if(temp < 0) {\r
-            errno = EMFILE;\r
-            break;\r
-          }\r
-          /* temp is now a valid fd reserved for further use\r
-             so copy fd into temp.\r
-          */\r
-          (void)memcpy(&gMD->fdarray[temp], MyFd, sizeof(struct __filedes));\r
-          retval = temp;\r
-        }\r
-        else {\r
-          errno = EINVAL;\r
-        }\r
-        break;\r
-\r
-      case F_SETFL:\r
-        retval = MyFd->Oflags;        // Get original value\r
-        temp = va_arg(p3, int);\r
-        temp &= O_SETMASK;            // Only certain bits can be set\r
-        temp |= retval & O_SETMASK;\r
-        MyFd->Oflags = temp;          // Set new value\r
-        break;\r
-\r
-      case F_SETFD:\r
-        retval = MyFd->f_iflags;\r
-        break;\r
-      //case F_SETOWN:\r
-      //  retval = MyFd->SocProc;\r
-      //  MyFd->SocProc = va_arg(p3, int);\r
-      //  break;\r
-      case F_GETFD:\r
-        retval = MyFd->f_iflags;\r
-        break;\r
-      case F_GETFL:\r
-        retval = MyFd->Oflags;\r
-        break;\r
-      //case F_GETOWN:\r
-      //  retval = MyFd->SocProc;\r
-      //  break;\r
-      default:\r
-        errno  = EINVAL;\r
-        break;\r
-    }\r
-  }\r
-  else {\r
-    // Bad FD\r
-    errno = EBADF;\r
-  }\r
-  va_end(p3);\r
-  return retval;;\r
-}\r
-\r
-/** The dup() function provides an alternative interface to the\r
-    service provided by fcntl() using the F_DUPFD command. The call:\r
-      - fid = dup(fildes);\r
-    shall be equivalent to:\r
-      - fid = fcntl(fildes, F_DUPFD, 0);\r
-\r
-    @param[in]    fildes    Descriptor for the file to be examined.\r
-\r
-    @return   Upon successful completion a non-negative integer, namely the\r
-              file descriptor, shall be returned; otherwise, -1 shall be\r
-              returned and errno set to indicate the error.\r
-**/\r
-int\r
-dup   (int fildes)\r
-{\r
-  return fcntl(fildes, F_DUPFD, 0);\r
-}\r
-\r
-/** Make fildes2 refer to a duplicate of fildes.\r
-\r
-    The dup2() function provides an alternative interface to the\r
-    service provided by fcntl() using the F_DUPFD command. The call:\r
-      - fid = dup2(fildes, fildes2);\r
-    shall be equivalent to:\r
-      - close(fildes2);\r
-      - fid = fcntl(fildes, F_DUPFD, fildes2);\r
-    except for the following:\r
-      - If fildes2 is less than 0 or greater than or equal to {OPEN_MAX},\r
-        dup2() shall return -1 with errno set to [EBADF].\r
-      - If fildes is a valid file descriptor and is equal to fildes2, dup2()\r
-        shall return fildes2 without closing it.\r
-      - If fildes is not a valid file descriptor, dup2() shall return -1 and\r
-        shall not close fildes2.\r
-      - The value returned shall be equal to the value of fildes2 upon\r
-        successful completion, or -1 upon failure.\r
-\r
-    @param[in]  fildes    File Descriptor to be duplicated.\r
-    @param[in]  fildes2   File Descriptor to be made a duplicate of fildes.\r
-\r
-    @return   Upon successful completion a non-negative integer, namely\r
-              fildes2, shall be returned; otherwise, -1 shall be\r
-              returned and errno set to EBADF indicate the error.\r
-**/\r
-int\r
-dup2    (int fildes, int fildes2)\r
-{\r
-  int retval = -1;\r
-\r
-  if(ValidateFD( fildes, VALID_OPEN)) {\r
-    retval = fildes2;\r
-    if( fildes != fildes2) {\r
-      if(ValidateFD( fildes2, VALID_DONT_CARE)) {\r
-        gMD->fdarray[fildes2].f_iflags = FIF_LARVAL;  // Mark the file closed, but reserved\r
-        (void)memcpy(&gMD->fdarray[fildes2],      // Duplicate fildes into fildes2\r
-                     &gMD->fdarray[fildes], sizeof(struct __filedes));\r
-        gMD->fdarray[fildes2].MyFD = (UINT16)fildes2;\r
-      }\r
-      else {\r
-        errno = EBADF;\r
-        retval = -1;\r
-      }\r
-    }\r
-  }\r
-  else {\r
-    errno = EBADF;\r
-  }\r
-  return retval;\r
-}\r
-\r
-/** Reposition a file's read/write offset.\r
-\r
-    The lseek() function repositions the offset of the file descriptor fildes\r
-    to the argument offset according to the directive how.  The argument\r
-    fildes must be an open file descriptor.  lseek() repositions the file\r
-    pointer fildes as follows:\r
-\r
-      - If how is SEEK_SET, the offset is set to offset bytes.\r
-\r
-      - If how is SEEK_CUR, the offset is set to its current location\r
-        plus offset bytes.\r
-\r
-      - If how is SEEK_END, the offset is set to the size of the file\r
-        plus offset bytes.\r
-\r
-    The lseek() function allows the file offset to be set beyond the end of\r
-    the existing end-of-file of the file.  If data is later written at this\r
-    point, subsequent reads of the data in the gap return bytes of zeros\r
-    (until data is actually written into the gap).\r
-\r
-    Some devices are incapable of seeking.  The value of the pointer associ-\r
-    ated with such a device is undefined.\r
-\r
-    @param[in]  fd        Descriptor for the File to be affected.\r
-    @param[in]  offset    Value to adjust the file position by.\r
-    @param[in]  how       How the file position is to be adjusted.\r
-\r
-    @return   Upon successful completion, lseek() returns the resulting offset\r
-              location as measured in bytes from the beginning of the file.\r
-              Otherwise, a value of -1 is returned and errno is set to\r
-              indicate the error.\r
-**/\r
-__off_t\r
-lseek (int fd, __off_t offset, int how)\r
-{\r
-  __off_t             CurPos = -1;\r
-//  RETURN_STATUS       Status = RETURN_SUCCESS;\r
-  struct __filedes   *filp;\r
-\r
-  EFIerrno = RETURN_SUCCESS;    // In case of error without an EFI call\r
-\r
-  if( how == SEEK_SET || how == SEEK_CUR  || how == SEEK_END) {\r
-    if(ValidateFD( fd, VALID_OPEN)) {\r
-      filp = &gMD->fdarray[fd];\r
-      // Both of our parameters have been verified as valid\r
-      CurPos = filp->f_ops->fo_lseek( filp, offset, how);\r
-      if(CurPos >= 0) {\r
-        filp->f_offset = CurPos;\r
-      }\r
-    }\r
-    else {\r
-      errno = EBADF;  // Bad File Descriptor\r
-    }\r
-  }\r
-  else {\r
-    errno = EINVAL;   // Invalid how argument\r
-  }\r
-  return CurPos;\r
-}\r
-\r
-/** The directory path is created with the access permissions specified by\r
-    perms.\r
-\r
-    The directory is closed after it is created.\r
-\r
-    @param[in]  path    The path to a directory to create.\r
-    @param[in]  perms   Permissions as defined in <sys/stat.h>\r
-\r
-    @retval   0   The directory was created successfully.\r
-    @retval  -1   An error occurred and error codes are stored in errno and EFIerrno.\r
-**/\r
-int\r
-mkdir (const char *path, __mode_t perms)\r
-{\r
-  wchar_t            *NewPath;\r
-  DeviceNode         *Node;\r
-  char               *GenI;\r
-  RETURN_STATUS       Status;\r
-  int                 Instance  = 0;\r
-  int                 retval = 0;\r
-\r
-  Status = ParsePath(path, &NewPath, &Node, &Instance, NULL);\r
-  if(Status == RETURN_SUCCESS) {\r
-    GenI = Node->InstanceList;\r
-    if(GenI == NULL) {\r
-      errno   = EPERM;\r
-      retval  = -1;\r
-      }\r
-    else {\r
-      //GenI += (Instance * Node->InstanceSize);\r
-      retval = ((GenericInstance *)GenI)->Abstraction.fo_mkdir( path, perms);\r
-      }\r
-    free(NewPath);\r
-    }\r
-  else {\r
-    retval = -1;\r
-  }\r
-  return retval;\r
-}\r
-\r
-/** Open a file.\r
-    The open() function establishes the connection between a file and a file\r
-    descriptor.  It creates an open file description that refers to a file\r
-    and a file descriptor that refers to that open file description. The file\r
-    descriptor is used by other I/O functions to refer to that file.\r
-\r
-    The open() function returns a file descriptor for the named file that is\r
-    the lowest file descriptor not currently open for that process. The open\r
-    file description is new, and therefore the file descriptor shall not\r
-    share it with any other process in the system.\r
-\r
-    The file offset used to mark the current position within the file is set\r
-    to the beginning of the file.\r
-\r
-    The EFI ShellOpenFileByName() function is used to perform the low-level\r
-    file open operation.  The primary task of open() is to translate from the\r
-    flags used in the <stdio.h> environment to those used by the EFI function.\r
-\r
-    The file status flags and file access modes of the open file description\r
-    are set according to the value of oflags.\r
-\r
-    Values for oflags are constructed by a bitwise-inclusive OR of flags from\r
-    the following list, defined in <fcntl.h>. Applications shall specify\r
-    exactly one of { O_RDONLY, O_RDWR, O_WRONLY } in the value of oflags.\r
-    Any combination of { O_NONBLOCK, O_APPEND, O_CREAT, O_TRUNC, O_EXCL } may\r
-    also be specified in oflags.\r
-\r
-    The only valid flag combinations for ShellOpenFileByName() are:\r
-      - Read\r
-      - Read/Write\r
-      - Create/Read/Write\r
-\r
-    Values for mode specify the access permissions for newly created files.\r
-    The mode value is saved in the FD to indicate permissions for further operations.\r
-\r
-    O_RDONLY      -- flags = EFI_FILE_MODE_READ -- this is always done\r
-    O_WRONLY      -- flags |= EFI_FILE_MODE_WRITE\r
-    O_RDWR        -- flags |= EFI_FILE_MODE_WRITE -- READ is already set\r
-\r
-    O_NONBLOCK    -- ignored\r
-    O_APPEND      -- Seek to EOF before every write\r
-    O_CREAT       -- flags |= EFI_FILE_MODE_CREATE\r
-    O_TRUNC       -- delete first then create new\r
-    O_EXCL        -- if O_CREAT is also set, open will fail if the file already exists.\r
-\r
-    @param[in]    Path      The path argument points to a pathname naming the\r
-                            object to be opened.\r
-    @param[in]    oflags    File status flags and file access modes of the\r
-                            open file description.\r
-    @param[in]    mode      File access permission bits as defined in\r
-                            <sys/stat.h>.  Only used if a file is created\r
-                            as a result of the open.\r
-\r
-    @return     Upon successful completion, open() opens the file and returns\r
-                a non-negative integer representing the lowest numbered\r
-                unused file descriptor. Otherwise, open returns -1 and sets\r
-                errno to indicate the error. If a negative value is\r
-                returned, no files are created or modified.\r
-                  - EMFILE - No file descriptors available -- Max number already open.\r
-                  - EINVAL - Bad value specified for oflags or mode.\r
-                  - ENOMEM - Failure allocating memory for internal buffers.\r
-                  - EEXIST - File exists and open attempted with (O_EXCL | O_CREAT) set.\r
-                  - EIO - UEFI failure.  Check value in EFIerrno.\r
-**/\r
-int\r
-open(\r
-  const char *path,\r
-  int oflags,\r
-  int mode\r
-  )\r
-{\r
-  wchar_t              *NewPath;\r
-  wchar_t              *MPath;\r
-  DeviceNode           *Node;\r
-  struct __filedes     *filp;\r
-  struct termios       *Termio;\r
-  int                   Instance  = 0;\r
-  RETURN_STATUS         Status;\r
-  UINT32                OpenMode;\r
-  int                   fd = -1;\r
-  int                   doresult;\r
-\r
-  Status = ParsePath(path, &NewPath, &Node, &Instance, &MPath);\r
-  if(Status == RETURN_SUCCESS) {\r
-    if ((Node == NULL)               ||\r
-        (Node->InstanceList == NULL))\r
-    {\r
-      errno   = EPERM;\r
-    }\r
-    else {\r
-      // Could add a test to see if the file name begins with a period.\r
-      // If it does, then add the HIDDEN flag to Attributes.\r
-\r
-      // Get an available fd\r
-      fd = FindFreeFD( VALID_CLOSED );\r
-\r
-      if( fd < 0 ) {\r
-        // All available FDs are in use\r
-        errno = EMFILE;\r
-      }\r
-      else {\r
-        filp = &gMD->fdarray[fd];\r
-        // Save the flags and mode in the File Descriptor\r
-        filp->Oflags = oflags;\r
-        filp->Omode = mode;\r
-\r
-        doresult = Node->OpenFunc(Node, filp, Instance, NewPath, MPath);\r
-        if(doresult < 0) {\r
-          filp->f_iflags = 0;   // Release this FD\r
-          fd = -1;              // Indicate an error\r
-        }\r
-        else {\r
-          // Build our final f_iflags value\r
-          OpenMode  = ( mode & S_ACC_READ )  ? S_ACC_READ : 0;\r
-          OpenMode |= ( mode & S_ACC_WRITE ) ? S_ACC_WRITE : 0;\r
-\r
-          filp->f_iflags |= OpenMode;\r
-\r
-          if((oflags & O_TTY_INIT) && (filp->f_iflags & _S_ITTY) && (filp->devdata != NULL)) {\r
-            // Initialize the device's termios flags to a "sane" value\r
-            Termio = &((cIIO *)filp->devdata)->Termio;\r
-            Termio->c_iflag = ICRNL | IGNSPEC;\r
-            Termio->c_oflag = OPOST | ONLCR | OXTABS | ONOEOT | ONOCR | ONLRET | OCTRL;\r
-            Termio->c_lflag = ECHO | ECHOE | ECHONL | ICANON;\r
-            Termio->c_cc[VERASE]  = 0x08;   // ^H Backspace\r
-            Termio->c_cc[VKILL]   = 0x15;   // ^U\r
-            Termio->c_cc[VINTR]   = 0x03;   // ^C Interrupt character\r
-          }\r
-          ++filp->RefCount;\r
-          FILE_SET_MATURE(filp);\r
-        }\r
-      }\r
-    }\r
-    free(NewPath);\r
-  }\r
-  free(MPath);    // We don't need this any more.\r
-\r
-  // return the fd of our now open file\r
-  return fd;\r
-}\r
-\r
-\r
-/**\r
-  Poll a list of file descriptors.\r
-\r
-  The ::poll routine waits for up to timeout milliseconds for an event\r
-  to occur on one or more of the file descriptors listed.  The event\r
-  types of interested are specified for each file descriptor in the events\r
-  field.  The actual event detected is returned in the revents field of\r
-  the array.  The\r
-  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html">POSIX</a>\r
-  documentation is available online.\r
-\r
-  @param[in]  pfd       Address of an array of pollfd structures.\r
-\r
-  @param[in]  nfds      Number of elements in the array of pollfd structures.\r
-\r
-  @param[in]  timeout   Length of time in milliseconds to wait for the event\r
-\r
-  @return     The number of file descriptors with detected events.  Zero\r
-              indicates that the call timed out and -1 indicates an error.\r
-\r
- **/\r
-int\r
-poll (\r
-  struct pollfd * pfd,\r
-  nfds_t nfds,\r
-  int timeout\r
-  )\r
-{\r
-  struct __filedes * pDescriptor;\r
-  struct pollfd * pEnd;\r
-  struct pollfd * pPollFD;\r
-  int SelectedFDs;\r
-  EFI_STATUS Status;\r
-  EFI_EVENT Timer;\r
-  UINT64 TimerTicks;\r
-\r
-  //\r
-  //  Create the timer for the timeout\r
-  //\r
-  Timer = NULL;\r
-  Status = EFI_SUCCESS;\r
-  if ( INFTIM != timeout ) {\r
-    Status = gBS->CreateEvent ( EVT_TIMER,\r
-                                TPL_NOTIFY,\r
-                                NULL,\r
-                                NULL,\r
-                                &Timer );\r
-    if ( !EFI_ERROR ( Status )) {\r
-      //\r
-      //  Start the timeout timer\r
-      //\r
-      TimerTicks = timeout;\r
-      TimerTicks *= 1000 * 10;\r
-      Status = gBS->SetTimer ( Timer,\r
-                               TimerRelative,\r
-                               TimerTicks );\r
-    }\r
-    else {\r
-      SelectedFDs = -1;\r
-      errno = ENOMEM;\r
-    }\r
-  }\r
-  if ( !EFI_ERROR ( Status )) {\r
-    //\r
-    //  Poll until an event is detected or the timer fires\r
-    //\r
-    SelectedFDs = 0;\r
-    errno = 0;\r
-    do {\r
-      //\r
-      //  Poll the list of file descriptors\r
-      //\r
-      pPollFD = pfd;\r
-      pEnd = &pPollFD [ nfds ];\r
-      while ( pEnd > pPollFD ) {\r
-        //\r
-        //  Validate the file descriptor\r
-        //\r
-        if ( !ValidateFD ( pPollFD->fd, VALID_OPEN )) {\r
-          errno = EINVAL;\r
-          return -1;\r
-        }\r
-\r
-        //\r
-        //  Poll the device or file\r
-        //\r
-        pDescriptor = &gMD->fdarray [ pPollFD->fd ];\r
-        pPollFD->revents = pDescriptor->f_ops->fo_poll ( pDescriptor,\r
-                                                         pPollFD->events );\r
-\r
-        //\r
-        //  Determine if this file descriptor detected an event\r
-        //\r
-        if ( 0 != pPollFD->revents ) {\r
-          //\r
-          //  Select this descriptor\r
-          //\r
-          SelectedFDs += 1;\r
-        }\r
-\r
-        //\r
-        //  Set the next file descriptor\r
-        //\r
-        pPollFD += 1;\r
-      }\r
-\r
-      //\r
-      //  Check for timeout\r
-      //\r
-      if ( NULL != Timer ) {\r
-        Status = gBS->CheckEvent ( Timer );\r
-        if ( EFI_SUCCESS == Status ) {\r
-          //\r
-          //  Timeout\r
-          //\r
-          break;\r
-        }\r
-        else if ( EFI_NOT_READY == Status ) {\r
-          Status = EFI_SUCCESS;\r
-    }\r
-    }\r
-    } while (( 0 == SelectedFDs )\r
-        && ( EFI_SUCCESS == Status ));\r
-\r
-    //\r
-    //  Stop the timer\r
-    //\r
-    if ( NULL != Timer ) {\r
-      gBS->SetTimer ( Timer,\r
-                      TimerCancel,\r
-                      0 );\r
-  }\r
-  }\r
-  else {\r
-    SelectedFDs = -1;\r
-    errno = EAGAIN;\r
-  }\r
-\r
-  //\r
-  //  Release the timer\r
-  //\r
-  if ( NULL != Timer ) {\r
-    gBS->CloseEvent ( Timer );\r
-  }\r
-\r
-  //\r
-  //  Return the number of selected file system descriptors\r
-  //\r
-  return SelectedFDs;\r
-}\r
-\r
-\r
-/** The rename() function changes the name of a file.\r
-    The From argument points to the pathname of the file to be renamed. The To\r
-    argument points to the new pathname of the file.\r
-\r
-    If the From argument points to the pathname of a file that is not a\r
-    directory, the To argument shall not point to the pathname of a\r
-    directory. If the file named by the To argument exists, it shall be\r
-    removed and From renamed to To. Write access permission is required for\r
-    both the directory containing old and the directory containing To.\r
-\r
-    If the From argument points to the pathname of a directory, the To\r
-    argument shall not point to the pathname of a file that is not a\r
-    directory. If the directory named by the To argument exists, it shall be\r
-    removed and From renamed to To.\r
-\r
-    The To pathname shall not contain a path prefix that names From. Write\r
-    access permission is required for the directory containing From and the\r
-    directory containing To. If the From argument points to the pathname of a\r
-    directory, write access permission may be required for the directory named\r
-    by From, and, if it exists, the directory named by To.\r
-\r
-    If the rename() function fails for any reason other than [EIO], any file\r
-    named by To shall be unaffected.\r
-\r
-    @param[in]  From    Path to the file to be renamed.\r
-    @param[in]  To      The new name of From.\r
-\r
-    @retval   0     Successful completion.\r
-    @retval   -1    An error has occured and errno has been set to further specify the error.\r
-                    Neither the file named by From nor the file named by To are\r
-                    changed or created.\r
-                      - ENXIO: Path specified is not supported by any loaded driver.\r
-                      - ENOMEM: Insufficient memory to calloc a MapName buffer.\r
-                      - EINVAL: The path parameter is not valid.\r
-**/\r
-int\r
-rename(\r
-  const char *From,\r
-  const char *To\r
-  )\r
-{\r
-  wchar_t            *FromPath;\r
-  DeviceNode         *FromNode;\r
-  char               *GenI;\r
-  int                 Instance    = 0;\r
-  RETURN_STATUS       Status;\r
-  int                 retval      = -1;\r
-\r
-  Status = ParsePath(From, &FromPath, &FromNode, &Instance, NULL);\r
-  if(Status == RETURN_SUCCESS) {\r
-    GenI = FromNode->InstanceList;\r
-    if(GenI == NULL) {\r
-      errno   = EPERM;\r
-      retval  = -1;\r
-      }\r
-      else {\r
-      //GenI += (Instance * FromNode->InstanceSize);\r
-      retval = ((GenericInstance *)GenI)->Abstraction.fo_rename( From, To);\r
-              }\r
-    free(FromPath);\r
-            }\r
-  return retval;\r
-}\r
-\r
-/** Delete a specified directory.\r
-\r
-    @param[in]  path    Path to the directory to delete.\r
-\r
-    @retval   -1    The directory couldn't be opened (doesn't exist).\r
-    @retval   -1    The directory wasn't empty or an IO error occured.\r
-**/\r
-int\r
-rmdir(\r
-  const char *path\r
-  )\r
-{\r
-  struct __filedes   *filp;\r
-  int                 fd;\r
-  int                 retval = -1;\r
-\r
-  fd = open(path, O_RDWR, 0);\r
-  if(fd >= 0) {\r
-    filp = &gMD->fdarray[fd];\r
-\r
-    retval = filp->f_ops->fo_rmdir(filp);\r
-    filp->f_iflags = 0;           // Close this FD\r
-    filp->RefCount = 0;           // No one using this FD\r
-  }\r
-  return retval;\r
-}\r
-\r
-/** The fstat() function obtains information about an open file associated\r
-    with the file descriptor fd, and writes it to the area pointed to\r
-    by statbuf.\r
-\r
-    The statbuf argument is a pointer to a stat structure, as defined\r
-    in <sys/stat.h>, into which information is placed concerning the file.\r
-\r
-    The structure members st_mode, st_ino, st_dev, st_uid, st_gid, st_atime,\r
-    st_ctime, and st_mtime shall have meaningful values. The value of the\r
-    member st_nlink shall be set to the number of links to the file.\r
-\r
-    The fstat() function shall update any time-related fields before writing\r
-    into the stat structure.\r
-\r
-    The fstat() function is implemented using the ShellGetFileInfo()\r
-    function.\r
-\r
-    The stat structure members which don't have direct analogs to EFI file\r
-    information are filled in as follows:\r
-      - st_mode     Populated with information from fd\r
-      - st_ino      Set to zero.  (inode)\r
-      - st_dev      Set to zero.\r
-      - st_uid      Set to zero.\r
-      - st_gid      Set to zero.\r
-      - st_nlink    Set to one.\r
-\r
-    @param[in]    fd        File descriptor as returned from open().\r
-    @param[out]   statbuf   Buffer in which the file status is put.\r
-\r
-    @retval    0  Successful Completion.\r
-    @retval   -1  An error has occurred and errno has been set to\r
-                  identify the error.\r
-**/\r
-int\r
-fstat (int fd, struct stat *statbuf)\r
-{\r
-  int                 retval = -1;\r
-  struct __filedes   *filp;\r
-\r
-  if(ValidateFD( fd, VALID_OPEN)) {\r
-    filp = &gMD->fdarray[fd];\r
-    retval = filp->f_ops->fo_stat(filp, statbuf, NULL);\r
-      }\r
-      else {\r
-    errno   =  EBADF;\r
-      }\r
-  return retval;\r
-}\r
-\r
-/** Obtains information about the file pointed to by path.\r
-\r
-    Opens the file pointed to by path, calls _EFI_FileInfo with the file's handle,\r
-    then closes the file.\r
-\r
-    @param[in]    path      Path to the file to obtain information about.\r
-    @param[out]   statbuf   Buffer in which the file status is put.\r
-\r
-    @retval    0  Successful Completion.\r
-    @retval   -1  An error has occurred and errno has been set to\r
-                  identify the error.\r
-**/\r
-int\r
-stat   (const char *path, struct stat *statbuf)\r
-{\r
-  int                 fd;\r
-  int                 retval  = -1;\r
-  struct __filedes   *filp;\r
-\r
-  fd = open(path, O_RDONLY, 0);\r
-  if(fd >= 0) {\r
-    filp = &gMD->fdarray[fd];\r
-    retval = filp->f_ops->fo_stat( filp, statbuf, NULL);\r
-    close(fd);\r
-  }\r
-  return retval;\r
-}\r
-\r
-/**  Same as stat since EFI doesn't have symbolic links.\r
-\r
-    @param[in]    path      Path to the file to obtain information about.\r
-    @param[out]   statbuf   Buffer in which the file status is put.\r
-\r
-    @retval    0  Successful Completion.\r
-    @retval   -1  An error has occurred and errno has been set to\r
-                  identify the error.\r
-**/\r
-int\r
-lstat (const char *path, struct stat *statbuf)\r
-{\r
-  return stat(path, statbuf);\r
-}\r
-\r
-/** Control a device.\r
-\r
-    @param[in]        fd        Descriptor for the file to be acted upon.\r
-    @param[in]        request   Specifies the operation to perform.\r
-    @param[in,out]    ...       Zero or more parameters as required for request.\r
-\r
-    @retval   >=0   The operation completed successfully.\r
-    @retval   -1    An error occured.  More information is in errno.\r
-**/\r
-int\r
-ioctl(\r
-  int             fd,\r
-  unsigned long   request,\r
-  ...\r
-  )\r
-{\r
-  int                 retval = -1;\r
-  struct __filedes   *filp;\r
-  va_list             argp;\r
-\r
-  va_start(argp, request);\r
-\r
-  if(ValidateFD( fd, VALID_OPEN)) {\r
-    filp = &gMD->fdarray[fd];\r
-\r
-    if(request == FIODLEX) {\r
-      /* set Delete-on-Close */\r
-      filp->f_iflags |= FIF_DELCLOSE;\r
-      retval = 0;\r
-    }\r
-    else if(request == FIONDLEX) {\r
-      /* clear Delete-on-Close */\r
-      filp->f_iflags &= ~FIF_DELCLOSE;\r
-      retval = 0;\r
-    }\r
-    else {\r
-      /* All other requests. */\r
-      retval = filp->f_ops->fo_ioctl(filp, request, argp);\r
-    }\r
-  }\r
-  else {\r
-    errno   =  EBADF;\r
-  }\r
-  va_end(argp);\r
-\r
-  return retval;\r
-}\r
-\r
-/** Read from a file.\r
-\r
-    The read() function shall attempt to read nbyte bytes from the file\r
-    associated with the open file descriptor, fildes, into the buffer pointed\r
-    to by buf.\r
-\r
-    Before any action described below is taken, and if nbyte is zero, the\r
-    read() function may detect and return errors as described below. In the\r
-    absence of errors, or if error detection is not performed, the read()\r
-    function shall return zero and have no other results.\r
-\r
-    On files that support seeking (for example, a regular file), the read()\r
-    shall start at a position in the file given by the file offset associated\r
-    with fildes. The file offset shall be incremented by the number of bytes\r
-    actually read.\r
-\r
-    Files that do not support seeking - for example, terminals - always read\r
-    from the current position. The value of a file offset associated with\r
-    such a file is undefined.\r
-\r
-    No data transfer shall occur past the current end-of-file. If the\r
-    starting position is at or after the end-of-file, 0 shall be returned.\r
-\r
-    The read() function reads data previously written to a file. If any\r
-    portion of a regular file prior to the end-of-file has not been written,\r
-    read() shall return bytes with value 0. For example, lseek() allows the\r
-    file offset to be set beyond the end of existing data in the file. If data\r
-    is later written at this point, subsequent reads in the gap between the\r
-    previous end of data and the newly written data shall return bytes with\r
-    value 0 until data is written into the gap.\r
-\r
-    Upon successful completion, where nbyte is greater than 0, read() shall\r
-    mark for update the st_atime field of the file, and shall return the\r
-    number of bytes read. This number shall never be greater than nbyte. The\r
-    value returned may be less than nbyte if the number of bytes left in the\r
-    file is less than nbyte, if the read() request was interrupted by a\r
-    signal, or if the file is a pipe or FIFO or special file and has fewer\r
-    than nbyte bytes immediately available for reading. For example, a read()\r
-    from a file associated with a terminal may return one typed line of data.\r
-\r
-    If fildes does not refer to a directory, the function reads the requested\r
-    number of bytes from the file at the file's current position and returns\r
-    them in buf. If the read goes beyond the end of the file, the read\r
-    length is truncated to the end of the file. The file's current position is\r
-    increased by the number of bytes returned.\r
-\r
-    If fildes refers to a directory, the function reads the directory entry at\r
-    the file's current position and returns the entry in buf. If buf\r
-    is not large enough to hold the current directory entry, then\r
-    errno is set to EBUFSIZE, EFIerrno is set to EFI_BUFFER_TOO_SMALL, and the\r
-    current file position is not updated. The size of the buffer needed to read\r
-    the entry will be returned as a negative number. On success, the current\r
-    position is updated to the next directory entry. If there are no more\r
-    directory entries, the read returns a zero-length buffer.\r
-    EFI_FILE_INFO is the structure returned as the directory entry.\r
-\r
-    @param[in]    fildes  Descriptor of the file to be read.\r
-    @param[out]   buf     Pointer to location in which to store the read data.\r
-    @param[in]    nbyte   Maximum number of bytes to be read.\r
-\r
-    @return   Upon successful completion, read() returns a non-negative integer\r
-              indicating the number of bytes actually read. Otherwise, the\r
-              functions return a negative value and sets errno to indicate the\r
-              error.  If errno is EBUFSIZE, the absolute value of the\r
-              return value indicates the size of the buffer needed to read\r
-              the directory entry.\r
-**/\r
-ssize_t\r
-read   (int fildes, void *buf, size_t nbyte)\r
-{\r
-  struct __filedes *filp;\r
-  cIIO             *IIO;\r
-  ssize_t           BufSize;\r
-\r
-  BufSize = (ssize_t)nbyte;\r
-  if(BufSize > 0) {\r
-    if(ValidateFD( fildes, VALID_OPEN)) {\r
-      filp = &gMD->fdarray[fildes];\r
-\r
-      IIO = filp->devdata;\r
-      if(isatty(fildes) && (IIO != NULL)) {\r
-        BufSize = IIO->Read(filp, nbyte, buf);\r
-      }\r
-      else {\r
-        BufSize = filp->f_ops->fo_read(filp, &filp->f_offset, nbyte, buf);\r
-      }\r
-    }\r
-    else {\r
-      errno = EBADF;\r
-      BufSize = -1;\r
-    }\r
-  }\r
-  return BufSize;\r
-}\r
-\r
-/** Write data to a file.\r
-\r
-    This function writes the specified number of bytes to the file at the current\r
-    file position. The current file position is advanced the actual number of bytes\r
-    written. Partial writes only occur when there has been a data error during\r
-    the write attempt (such as "volume space full").  The file is automatically\r
-    grown to hold the data if required.\r
-\r
-    Direct writes to opened directories are not supported.\r
-\r
-    If fildes refers to a terminal device, isatty() returns TRUE, a partial write\r
-    will occur if a NULL or EOF character is encountered before n characters have\r
-    been written.  Characters inserted due to line-end translations or TAB\r
-    expansion will not be counted.  Unconvertable characters are translated into\r
-    the UEFI character BLOCKELEMENT_LIGHT_SHADE.\r
-\r
-    Since the UEFI console device works on wide characters, the buffer is assumed\r
-    to contain a byte-oriented multi-byte character stream which is then\r
-    translated to wide characters using the mbtowc() functions.  The resulting\r
-    wide character stream is what is actually sent to the UEFI console.\r
-\r
-    Although both text and binary wide-oriented streams are conceptually\r
-    sequences of wide characters, the external file associated with a\r
-    wide-oriented stream is a sequence of multibyte characters,\r
-    generalized as follows:\r
-      - Multibyte encodings within files may contain embedded null bytes\r
-        (unlike multibyte encodings valid for use internal to the program).\r
-      - A file need not begin nor end in the initial shift state.\r
-\r
-    @param[in]  fd      Descriptor of file to be written to.\r
-    @param[in]  buf     Pointer to data to write to the file.\r
-    @param[in]  nbyte   Number of bytes to be written to the file.\r
-\r
-    @retval   >=0   Number of bytes actually written to the file.\r
-    @retval   <0    An error occurred.  More data is provided by errno.\r
-**/\r
-ssize_t\r
-write  (int fd, const void *buf, size_t nbyte)\r
-{\r
-  struct __filedes *filp;\r
-  cIIO             *IIO;\r
-  ssize_t           BufSize;\r
-\r
-  BufSize = (ssize_t)nbyte;\r
-\r
-  if(ValidateFD( fd, VALID_OPEN)) {\r
-    filp = &gMD->fdarray[fd];\r
-    if ((filp->Oflags & O_ACCMODE) != 0) {\r
-      // File is open for writing\r
-      IIO = filp->devdata;\r
-      if(isatty(fd) && (IIO != NULL)) {\r
-        // Output to an Interactive I/O device\r
-        // (Terminal device or the slave side of a pseudo-tty)\r
-        BufSize = IIO->Write(filp, buf, nbyte);\r
-      }\r
-      else {\r
-        // Output to a regular file, socket, pipe, etc.\r
-        BufSize = filp->f_ops->fo_write(filp, &filp->f_offset, nbyte, buf);\r
-      }\r
-    }\r
-    else {\r
-      // File is NOT open for writing\r
-      errno = EINVAL;\r
-      BufSize = -1;\r
-    }\r
-  }\r
-  else {\r
-    // fd is not for a valid open file\r
-    errno = EBADF;\r
-    BufSize = -1;\r
-  }\r
-  return BufSize;\r
-}\r
-\r
-/** Gets the current working directory.\r
-\r
-  The getcwd() function shall place an absolute pathname of the current\r
-  working directory in the array pointed to by buf, and return buf.The\r
-  size argument is the size in bytes of the character array pointed to\r
-  by the buf argument.\r
-\r
-  @param[in,out] buf    The buffer to fill.\r
-  @param[in]     size   The number of bytes in buffer.\r
-\r
-  @retval NULL          The function failed.  The value in errno provides\r
-                        further information about the cause of the failure.\r
-                        Values for errno are:\r
-                          - EINVAL: buf is NULL or size is zero.\r
-                          - ENOENT: directory does not exist.\r
-                          - ERANGE: buf size is too small to hold CWD\r
-\r
-  @retval buf           The function completed successfully.\r
-**/\r
-char\r
-*getcwd (char *buf, size_t size)\r
-{\r
-  CONST CHAR16 *Cwd;\r
-\r
-  if (size == 0 || buf == NULL) {\r
-    errno = EINVAL;\r
-    return NULL;\r
-    }\r
-\r
-  Cwd = ShellGetCurrentDir(NULL);\r
-  if (Cwd == NULL) {\r
-    errno = ENOENT;\r
-    return NULL;\r
-  }\r
-  if (size < ((StrLen (Cwd) + 1) * sizeof (CHAR8))) {\r
-    errno = ERANGE;\r
-    return (NULL);\r
-  }\r
-  return (UnicodeStrToAsciiStr(Cwd, buf));\r
-}\r
-\r
-/** Change the current working directory.\r
-\r
-  The chdir() function shall cause the directory named by the pathname\r
-  pointed to by the path argument to become the current working directory;\r
-  that is, the starting point for path searches for pathnames not beginning\r
-  with '/'.\r
-\r
-  @param[in] path   The new path to set.\r
-\r
-  @retval   0   Operation completed successfully.\r
-  @retval  -1   Function failed.  The value in errno provides more\r
-                information on the cause of failure:\r
-                  - EPERM: Operation not supported with this Shell version.\r
-                  - ENOMEM: Unable to allocate memory.\r
-                  - ENOENT: Target directory does not exist.\r
-\r
-  @todo Add non-NEW-shell CWD changing.\r
-**/\r
-int\r
-chdir (const char *path)\r
-{\r
-  CONST CHAR16 *Cwd;\r
-  EFI_STATUS   Status;\r
-  CHAR16       *UnicodePath;\r
-\r
-  /* Old Shell does not support Set Current Dir. */\r
-  if(gEfiShellProtocol != NULL) {\r
-    Cwd = ShellGetCurrentDir(NULL);\r
-    if (Cwd != NULL) {\r
-      /* We have shell support */\r
-      UnicodePath = AllocatePool(((AsciiStrLen (path) + 1) * sizeof (CHAR16)));\r
-      if (UnicodePath == NULL) {\r
-        errno = ENOMEM;\r
-        return -1;\r
-      }\r
-      AsciiStrToUnicodeStr(path, UnicodePath);\r
-      Status = gEfiShellProtocol->SetCurDir(NULL, UnicodePath);\r
-      FreePool(UnicodePath);\r
-      if (EFI_ERROR(Status)) {\r
-        errno = ENOENT;\r
-        return -1;\r
-      } else {\r
-        return 0;\r
-      }\r
-    }\r
-  }\r
-  /* Add here for non-shell */\r
-  errno = EPERM;\r
-  return -1;\r
-}\r
-\r
-/** Get the foreground process group ID associated with a terminal.\r
-\r
-    Just returns the Image Handle for the requestor since UEFI does not have\r
-    a concept of processes or groups.\r
-\r
-    @param[in]    x   Ignored.\r
-\r
-    @return   Returns the Image Handle of the application or driver which\r
-              called this function.\r
-**/\r
-pid_t tcgetpgrp (int x)\r
-{\r
-  return ((pid_t)(UINTN)(gImageHandle));\r
-}\r
-\r
-/** Get the process group ID of the calling process.\r
-\r
-    Just returns the Image Handle for the requestor since UEFI does not have\r
-    a concept of processes or groups.\r
-\r
-    @return   Returns the Image Handle of the application or driver which\r
-              called this function.\r
-**/\r
-pid_t getpgrp(void)\r
-{\r
-  return ((pid_t)(UINTN)(gImageHandle));\r
-}\r
-\r
-/* Internal worker function for utimes.\r
-    This works around an error produced by GCC when the va_* macros\r
-    are used within a function with a fixed number of arguments.\r
-*/\r
-static\r
-int\r
-EFIAPI\r
-va_Utimes(\r
-  const char   *path,\r
-  ...\r
-  )\r
-{\r
-  struct __filedes   *filp;\r
-  va_list             ap;\r
-  int                 fd;\r
-  int                 retval  = -1;\r
-\r
-  va_start(ap, path);\r
-  fd = open(path, O_RDWR, 0);\r
-  if(fd >= 0) {\r
-    filp = &gMD->fdarray[fd];\r
-    retval = filp->f_ops->fo_ioctl( filp, FIOSETIME, ap);\r
-    close(fd);\r
-  }\r
-  va_end(ap);\r
-  return retval;\r
-}\r
-\r
-/** Set file access and modification times.\r
-\r
-    @param[in]  path    Path to the file to be modified.\r
-    @param[in]  times   Pointer to an array of two timeval structures\r
-\r
-    @retval   0     File times successfully set.\r
-    @retval   -1    An error occured.  Error type in errno.\r
-**/\r
-int\r
-utimes(\r
-  const char *path,\r
-  const struct timeval *times\r
-  )\r
-{\r
-  return va_Utimes(path, times);\r
-}\r