+++ /dev/null
-/** @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