#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
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
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
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
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
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
// 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
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
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
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
/** 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
\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
\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
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
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
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