]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/LibC/Uefi/SysCalls.c
StdLib: Add isDirSep character classification macro and function. Implement several...
[mirror_edk2.git] / StdLib / LibC / Uefi / SysCalls.c
index b5079e2c3a0d2e4dcd76314b6d47383bcc077fc6..90d7277f86cdc852af5808336c82e2f738d4454c 100644 (file)
 #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  <MainData.h>\r
-#include  <extern.h>      // Library/include/extern.h: Private to implementation\r
-#include  <sys/EfiSysCall.h>\r
+#include  <extern.h>\r
 \r
 /* EFI versions of BSD system calls used in stdio */\r
 \r
@@ -136,6 +137,13 @@ isatty  (int fd)
   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
@@ -161,6 +169,14 @@ IsDupFd( int fd)
   return Ret;\r
 }\r
 \r
+/** 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
+**/\r
 static int\r
 _closeX  (int fd, int NewState)\r
 {\r
@@ -199,19 +215,18 @@ _closeX  (int fd, int NewState)
   return retval;\r
 }\r
 \r
-/** The close() function shall deallocate the file descriptor indicated by fd.\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 shall be removed (that is, unlocked).\r
+    associated with the file descriptor are removed (that is, unlocked).\r
 \r
-    @return   Upon successful completion, 0 shall be returned; otherwise,\r
-              -1 shall be returned and errno set to indicate the error.\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
-  //Print(L"Closing fd %d\n", fd);\r
   return _closeX(fd, 0);\r
 }\r
 \r
@@ -348,7 +363,7 @@ fcntl     (int fildes, int cmd, ...)
           errno = EINVAL;\r
         }\r
         break;\r
-      //case F_SETFD:\r
+\r
       case F_SETFL:\r
         retval = MyFd->Oflags;        // Get original value\r
         temp = va_arg(p3, int);\r
@@ -356,7 +371,7 @@ fcntl     (int fildes, int cmd, ...)
         temp |= retval & O_SETMASK;\r
         MyFd->Oflags = temp;          // Set new value\r
         break;\r
-      //case F_SETFL:\r
+\r
       case F_SETFD:\r
         retval = MyFd->f_iflags;\r
         break;\r
@@ -365,11 +380,9 @@ fcntl     (int fildes, int cmd, ...)
       //  MyFd->SocProc = va_arg(p3, int);\r
       //  break;\r
       case F_GETFD:\r
-        //retval = MyFd->Oflags;\r
         retval = MyFd->f_iflags;\r
         break;\r
       case F_GETFL:\r
-        //retval = MyFd->f_iflags;\r
         retval = MyFd->Oflags;\r
         break;\r
       //case F_GETOWN:\r
@@ -520,7 +533,7 @@ mkdir (const char *path, __mode_t perms)
   wchar_t            *NewPath;\r
   DeviceNode         *Node;\r
   char               *GenI;\r
-  RETURN_STATUS     Status;\r
+  RETURN_STATUS       Status;\r
   int                 Instance  = 0;\r
   int                 retval = 0;\r
 \r
@@ -860,6 +873,8 @@ rmdir(
     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
@@ -962,8 +977,22 @@ ioctl(
 \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
@@ -1101,18 +1130,21 @@ write  (int fd, const void *buf, size_t nbyte)
 /** 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
-  pathname copied to the array shall contain no components that are\r
-  symbolic links. The size argument is the size in bytes of the character\r
-  array pointed to by the buf argument.\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.\r
-  @retval NULL          Buf was NULL.\r
-  @retval NULL          Size was 0.\r
-  @return buf           The function completed successfully. See errno for info.\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
@@ -1126,14 +1158,13 @@ char
 \r
   Cwd = ShellGetCurrentDir(NULL);\r
   if (Cwd == NULL) {\r
-    errno = EACCES;\r
+    errno = ENOENT;\r
     return NULL;\r
   }\r
   if (size < ((StrLen (Cwd) + 1) * sizeof (CHAR8))) {\r
     errno = ERANGE;\r
     return (NULL);\r
   }\r
-\r
   return (UnicodeStrToAsciiStr(Cwd, buf));\r
 }\r
 \r
@@ -1146,7 +1177,14 @@ char
 \r
   @param[in] path   The new path to set.\r
 \r
-  @todo Add non-shell CWD changing.\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
@@ -1155,6 +1193,8 @@ chdir (const char *path)
   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
@@ -1167,15 +1207,15 @@ chdir (const char *path)
     Status = gEfiShellProtocol->SetCurDir(NULL, UnicodePath);\r
     FreePool(UnicodePath);\r
     if (EFI_ERROR(Status)) {\r
-      errno = EACCES;\r
+        errno = ENOENT;\r
       return -1;\r
     } else {\r
       return 0;\r
     }\r
   }\r
-\r
+  }\r
   /* Add here for non-shell */\r
-  errno = EACCES;\r
+  errno = EPERM;\r
   return -1;\r
 }\r
 \r
@@ -1189,3 +1229,33 @@ pid_t getpgrp(void)
   return ((pid_t)(UINTN)(gImageHandle));\r
 }\r
 \r
+/** Set file access and modification times.\r
+\r
+    @param[in]  path\r
+    @param[in]  times\r
+\r
+    @return\r
+**/\r
+int\r
+utimes(\r
+  const char *path,\r
+  const struct timeval *times\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
+\r