StdLib: Add terminal type line editing (Interactive IO) for console devices.
Adds a subset of the terminal I/O capabilities described in the Single Unix Specification, V4. Supports: Erase previous character. Default is Backspace or ^H Erase line. Default is ^U TAB characters are supported and, by default, are rendered as 8 spaces. They will still be read as a single TAB character. Both Canonical and Non-Canonical modes are supported. If a terminal device is opened with O_TTY_INIT in the mode, the device will be initialized to "sane" values for interactive use. It will be in Canonical mode, Enter will be translated to NewLine and on output, a NewLine is translated to CRLF. Echoing will be on, control characters are output as ^X, and TABs are expanded. See the new <sys/termios.h> file for more information. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: daryl.mcdaniel@intel.com Reviewed-by: erik.c.bjorge@intel.com Reviewed-by: leroy.p.leahy@intel.com Reviewed-by: lee.g.rosenbaum@intel.com Reviewed-by: jaben.carsey@intel.com git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13989 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
#include <unistd.h>
|
||||
#include <kfile.h>
|
||||
#include <Device/Device.h>
|
||||
#include <Device/IIO.h>
|
||||
#include <MainData.h>
|
||||
#include <extern.h>
|
||||
|
||||
@@ -114,12 +115,14 @@ DeleteOnClose(int fd)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/** The isatty() function tests whether fildes, an open file descriptor,
|
||||
/** The isatty() function tests whether fd, an open file descriptor,
|
||||
is associated with a terminal device.
|
||||
|
||||
@retval 1 fildes is associated with a terminal.
|
||||
@retval 0 fildes is not associated with a terminal. errno is set to
|
||||
EBADF if fildes is not a valid open FD.
|
||||
@param[in] fd File Descriptor for the file to be examined.
|
||||
|
||||
@retval 1 fd is associated with a terminal.
|
||||
@retval 0 fd is not associated with a terminal. errno is set to
|
||||
EBADF if fd is not a valid open FD.
|
||||
**/
|
||||
int
|
||||
isatty (int fd)
|
||||
@@ -129,7 +132,7 @@ isatty (int fd)
|
||||
|
||||
if(ValidateFD( fd, VALID_OPEN)) {
|
||||
Fp = &gMD->fdarray[fd];
|
||||
retval = Fp->f_iflags & _S_ITTY;
|
||||
retval = (Fp->f_iflags & _S_ITTY) ? 1 : 0;
|
||||
}
|
||||
else {
|
||||
errno = EBADF;
|
||||
@@ -169,13 +172,14 @@ IsDupFd( int fd)
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/** Close a file and set its fd to the specified state.
|
||||
/** Worker function to Close a file and set its fd to the specified state.
|
||||
|
||||
@param[in] fd The file descriptor to close.
|
||||
@param[in] NewState State to set the fd to after the file is closed.
|
||||
|
||||
@retval 0 The operation completed successfully.
|
||||
@retval -1 The operation failed. Further information is in errno.
|
||||
* EBADF fd is not a valid or open file descriptor.
|
||||
**/
|
||||
static int
|
||||
_closeX (int fd, int NewState)
|
||||
@@ -221,6 +225,8 @@ _closeX (int fd, int NewState)
|
||||
descriptors. All outstanding record locks owned by the process on the file
|
||||
associated with the file descriptor are removed (that is, unlocked).
|
||||
|
||||
@param[in] fd Descriptor for the File to close.
|
||||
|
||||
@retval 0 Successful completion.
|
||||
@retval -1 An error occurred and errno is set to identify the error.
|
||||
**/
|
||||
@@ -230,7 +236,14 @@ close (int fd)
|
||||
return _closeX(fd, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
/** Delete the file specified by path.
|
||||
|
||||
@param[in] path The MBCS path of the file to delete.
|
||||
|
||||
@retval -1 Unable to open the file specified by path.
|
||||
@retval -1 If (errno == EPERM), unlink is not permited for this file.
|
||||
@retval -1 Low-level delete filed. Reason is in errno.
|
||||
@retval 0 The file was successfully deleted.
|
||||
**/
|
||||
int
|
||||
unlink (const char *path)
|
||||
@@ -315,6 +328,10 @@ unlink (const char *path)
|
||||
descriptors greater than or equal to arg are available.
|
||||
[EOVERFLOW] One of the values to be returned cannot be represented correctly.
|
||||
|
||||
@param[in] fildes Descriptor for the file to be controlled.
|
||||
@param[in] cmd Command to be acted upon.
|
||||
@param[in,out] ... Optional additional parameters as required by cmd.
|
||||
|
||||
@return Upon successful completion, the value returned shall depend on
|
||||
cmd as follows:
|
||||
- F_DUPFD - A new file descriptor.
|
||||
@@ -407,6 +424,8 @@ fcntl (int fildes, int cmd, ...)
|
||||
shall be equivalent to:
|
||||
- fid = fcntl(fildes, F_DUPFD, 0);
|
||||
|
||||
@param[in] fildes Descriptor for the file to be examined.
|
||||
|
||||
@return Upon successful completion a non-negative integer, namely the
|
||||
file descriptor, shall be returned; otherwise, -1 shall be
|
||||
returned and errno set to indicate the error.
|
||||
@@ -417,7 +436,9 @@ dup (int fildes)
|
||||
return fcntl(fildes, F_DUPFD, 0);
|
||||
}
|
||||
|
||||
/** The dup2() function provides an alternative interface to the
|
||||
/** Make fildes2 refer to a duplicate of fildes.
|
||||
|
||||
The dup2() function provides an alternative interface to the
|
||||
service provided by fcntl() using the F_DUPFD command. The call:
|
||||
- fid = dup2(fildes, fildes2);
|
||||
shall be equivalent to:
|
||||
@@ -433,6 +454,9 @@ dup (int fildes)
|
||||
- The value returned shall be equal to the value of fildes2 upon
|
||||
successful completion, or -1 upon failure.
|
||||
|
||||
@param[in] fildes File Descriptor to be duplicated.
|
||||
@param[in] fildes2 File Descriptor to be made a duplicate of fildes.
|
||||
|
||||
@return Upon successful completion a non-negative integer, namely
|
||||
fildes2, shall be returned; otherwise, -1 shall be
|
||||
returned and errno set to EBADF indicate the error.
|
||||
@@ -470,13 +494,13 @@ dup2 (int fildes, int fildes2)
|
||||
fildes must be an open file descriptor. lseek() repositions the file
|
||||
pointer fildes as follows:
|
||||
|
||||
If how is SEEK_SET, the offset is set to offset bytes.
|
||||
- If how is SEEK_SET, the offset is set to offset bytes.
|
||||
|
||||
If how is SEEK_CUR, the offset is set to its current location
|
||||
plus offset bytes.
|
||||
- If how is SEEK_CUR, the offset is set to its current location
|
||||
plus offset bytes.
|
||||
|
||||
If how is SEEK_END, the offset is set to the size of the file
|
||||
plus offset bytes.
|
||||
- If how is SEEK_END, the offset is set to the size of the file
|
||||
plus offset bytes.
|
||||
|
||||
The lseek() function allows the file offset to be set beyond the end of
|
||||
the existing end-of-file of the file. If data is later written at this
|
||||
@@ -486,6 +510,10 @@ dup2 (int fildes, int fildes2)
|
||||
Some devices are incapable of seeking. The value of the pointer associ-
|
||||
ated with such a device is undefined.
|
||||
|
||||
@param[in] fd Descriptor for the File to be affected.
|
||||
@param[in] offset Value to adjust the file position by.
|
||||
@param[in] how How the file position is to be adjusted.
|
||||
|
||||
@return Upon successful completion, lseek() returns the resulting offset
|
||||
location as measured in bytes from the beginning of the file.
|
||||
Otherwise, a value of -1 is returned and errno is set to
|
||||
@@ -524,6 +552,9 @@ lseek (int fd, __off_t offset, int how)
|
||||
|
||||
The directory is closed after it is created.
|
||||
|
||||
@param[in] path The path to a directory to create.
|
||||
@param[in] perms Permissions as defined in <sys/stat.h>
|
||||
|
||||
@retval 0 The directory was created successfully.
|
||||
@retval -1 An error occurred and error codes are stored in errno and EFIerrno.
|
||||
**/
|
||||
@@ -606,19 +637,19 @@ mkdir (const char *path, __mode_t perms)
|
||||
@param[in] oflags File status flags and file access modes of the
|
||||
open file description.
|
||||
@param[in] mode File access permission bits as defined in
|
||||
<sys/stat.h>.
|
||||
<sys/stat.h>. Only used if a file is created
|
||||
as a result of the open.
|
||||
|
||||
@return Upon successful completion, open() opens the file and returns
|
||||
a non-negative integer representing the lowest numbered
|
||||
unused file descriptor. Otherwise, open returns -1 and sets
|
||||
errno to indicate the error. If a negative value is
|
||||
returned, no files are created or modified.
|
||||
|
||||
@retval EMFILE No file descriptors available -- Max number already open.
|
||||
@retval EINVAL Bad value specified for oflags or mode.
|
||||
@retval ENOMEM Failure allocating memory for internal buffers.
|
||||
@retval EEXIST File exists and open attempted with (O_EXCL | O_CREAT) set.
|
||||
@retval EIO UEFI failure. Check value in EFIerrno.
|
||||
- EMFILE - No file descriptors available -- Max number already open.
|
||||
- EINVAL - Bad value specified for oflags or mode.
|
||||
- ENOMEM - Failure allocating memory for internal buffers.
|
||||
- EEXIST - File exists and open attempted with (O_EXCL | O_CREAT) set.
|
||||
- EIO - UEFI failure. Check value in EFIerrno.
|
||||
**/
|
||||
int
|
||||
open(
|
||||
@@ -631,18 +662,20 @@ open(
|
||||
wchar_t *MPath;
|
||||
DeviceNode *Node;
|
||||
struct __filedes *filp;
|
||||
struct termios *Termio;
|
||||
int Instance = 0;
|
||||
RETURN_STATUS Status;
|
||||
UINT64 OpenMode;
|
||||
UINT32 OpenMode;
|
||||
int fd = -1;
|
||||
int doresult;
|
||||
|
||||
Status = ParsePath(path, &NewPath, &Node, &Instance, &MPath);
|
||||
if(Status == RETURN_SUCCESS) {
|
||||
if((Node == NULL) ||
|
||||
(Node->InstanceList == NULL)) {
|
||||
(Node->InstanceList == NULL))
|
||||
{
|
||||
errno = EPERM;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Could add a test to see if the file name begins with a period.
|
||||
// If it does, then add the HIDDEN flag to Attributes.
|
||||
@@ -666,23 +699,31 @@ open(
|
||||
fd = -1; // Indicate an error
|
||||
}
|
||||
else {
|
||||
// Re-use OpenMode in order to build our final f_iflags value
|
||||
// Build our final f_iflags value
|
||||
OpenMode = ( mode & S_ACC_READ ) ? S_ACC_READ : 0;
|
||||
OpenMode |= ( mode & S_ACC_WRITE ) ? S_ACC_WRITE : 0;
|
||||
|
||||
filp->f_iflags |= (UINT32)OpenMode;
|
||||
filp->f_iflags |= OpenMode;
|
||||
|
||||
if((oflags & O_TTY_INIT) && (filp->f_iflags & _S_ITTY) && (filp->devdata != NULL)) {
|
||||
// Initialize the device's termios flags to a "sane" value
|
||||
Termio = &((cIIO *)filp->devdata)->Termio;
|
||||
Termio->c_iflag = ICRNL;
|
||||
Termio->c_oflag = OPOST | ONLCR | OXTABS | ONOEOT | ONOCR | ONLRET | OCTRL;
|
||||
Termio->c_lflag = ECHO | ECHOE | ECHONL | ICANON;
|
||||
Termio->c_cc[VERASE] = 0x08; // ^H Backspace
|
||||
Termio->c_cc[VKILL] = 0x15; // ^U
|
||||
Termio->c_cc[VINTR] = 0x03; // ^C Interrupt character
|
||||
}
|
||||
++filp->RefCount;
|
||||
FILE_SET_MATURE(filp);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(NewPath != NULL) {
|
||||
free(NewPath);
|
||||
}
|
||||
}
|
||||
if(MPath != NULL) {
|
||||
free(MPath); // We don't need this any more.
|
||||
}
|
||||
|
||||
// return the fd of our now open file
|
||||
return fd;
|
||||
}
|
||||
@@ -699,11 +740,11 @@ open(
|
||||
<a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html">POSIX</a>
|
||||
documentation is available online.
|
||||
|
||||
@param [in] pfd Address of an array of pollfd structures.
|
||||
@param[in] pfd Address of an array of pollfd structures.
|
||||
|
||||
@param [in] nfds Number of elements in the array of pollfd structures.
|
||||
@param[in] nfds Number of elements in the array of pollfd structures.
|
||||
|
||||
@param [in] timeout Length of time in milliseconds to wait for the event
|
||||
@param[in] timeout Length of time in milliseconds to wait for the event
|
||||
|
||||
@return The number of file descriptors with detected events. Zero
|
||||
indicates that the call timed out and -1 indicates an error.
|
||||
@@ -841,38 +882,44 @@ poll (
|
||||
|
||||
|
||||
/** The rename() function changes the name of a file.
|
||||
The old argument points to the pathname of the file to be renamed. The new
|
||||
The From argument points to the pathname of the file to be renamed. The To
|
||||
argument points to the new pathname of the file.
|
||||
|
||||
If the old argument points to the pathname of a file that is not a
|
||||
directory, the new argument shall not point to the pathname of a
|
||||
directory. If the file named by the new argument exists, it shall be
|
||||
removed and old renamed to new. Write access permission is required for
|
||||
both the directory containing old and the directory containing new.
|
||||
If the From argument points to the pathname of a file that is not a
|
||||
directory, the To argument shall not point to the pathname of a
|
||||
directory. If the file named by the To argument exists, it shall be
|
||||
removed and From renamed to To. Write access permission is required for
|
||||
both the directory containing old and the directory containing To.
|
||||
|
||||
If the old argument points to the pathname of a directory, the new
|
||||
If the From argument points to the pathname of a directory, the To
|
||||
argument shall not point to the pathname of a file that is not a
|
||||
directory. If the directory named by the new argument exists, it shall be
|
||||
removed and old renamed to new.
|
||||
directory. If the directory named by the To argument exists, it shall be
|
||||
removed and From renamed to To.
|
||||
|
||||
The new pathname shall not contain a path prefix that names old. Write
|
||||
access permission is required for the directory containing old and the
|
||||
directory containing new. If the old argument points to the pathname of a
|
||||
The To pathname shall not contain a path prefix that names From. Write
|
||||
access permission is required for the directory containing From and the
|
||||
directory containing To. If the From argument points to the pathname of a
|
||||
directory, write access permission may be required for the directory named
|
||||
by old, and, if it exists, the directory named by new.
|
||||
by From, and, if it exists, the directory named by To.
|
||||
|
||||
If the rename() function fails for any reason other than [EIO], any file
|
||||
named by new shall be unaffected.
|
||||
named by To shall be unaffected.
|
||||
|
||||
@return Upon successful completion, rename() shall return 0; otherwise,
|
||||
-1 shall be returned, errno shall be set to indicate the error,
|
||||
and neither the file named by old nor the file named by new
|
||||
shall be changed or created.
|
||||
@param[in] From Path to the file to be renamed.
|
||||
@param[in] To The new name of From.
|
||||
|
||||
@retval 0 Successful completion.
|
||||
@retval -1 An error has occured and errno has been set to further specify the error.
|
||||
Neither the file named by From nor the file named by To are
|
||||
changed or created.
|
||||
- ENXIO: Path specified is not supported by any loaded driver.
|
||||
- ENOMEM: Insufficient memory to calloc a MapName buffer.
|
||||
- EINVAL: The path parameter is not valid.
|
||||
**/
|
||||
int
|
||||
rename(
|
||||
const char *from,
|
||||
const char *to
|
||||
const char *From,
|
||||
const char *To
|
||||
)
|
||||
{
|
||||
wchar_t *FromPath;
|
||||
@@ -882,7 +929,7 @@ rename(
|
||||
RETURN_STATUS Status;
|
||||
int retval = -1;
|
||||
|
||||
Status = ParsePath(from, &FromPath, &FromNode, &Instance, NULL);
|
||||
Status = ParsePath(From, &FromPath, &FromNode, &Instance, NULL);
|
||||
if(Status == RETURN_SUCCESS) {
|
||||
GenI = FromNode->InstanceList;
|
||||
if(GenI == NULL) {
|
||||
@@ -891,14 +938,19 @@ rename(
|
||||
}
|
||||
else {
|
||||
//GenI += (Instance * FromNode->InstanceSize);
|
||||
retval = ((GenericInstance *)GenI)->Abstraction.fo_rename( from, to);
|
||||
retval = ((GenericInstance *)GenI)->Abstraction.fo_rename( From, To);
|
||||
}
|
||||
free(FromPath);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
/** Delete a specified directory.
|
||||
|
||||
@param[in] path Path to the directory to delete.
|
||||
|
||||
@retval -1 The directory couldn't be opened (doesn't exist).
|
||||
@retval -1 The directory wasn't empty or an IO error occured.
|
||||
**/
|
||||
int
|
||||
rmdir(
|
||||
@@ -921,10 +973,10 @@ rmdir(
|
||||
}
|
||||
|
||||
/** The fstat() function obtains information about an open file associated
|
||||
with the file descriptor fildes, and shall write it to the area pointed to
|
||||
by buf.
|
||||
with the file descriptor fd, and writes it to the area pointed to
|
||||
by statbuf.
|
||||
|
||||
The buf argument is a pointer to a stat structure, as defined
|
||||
The statbuf argument is a pointer to a stat structure, as defined
|
||||
in <sys/stat.h>, into which information is placed concerning the file.
|
||||
|
||||
The structure members st_mode, st_ino, st_dev, st_uid, st_gid, st_atime,
|
||||
@@ -939,7 +991,7 @@ rmdir(
|
||||
|
||||
The stat structure members which don't have direct analogs to EFI file
|
||||
information are filled in as follows:
|
||||
- st_mode Populated with information from fildes
|
||||
- st_mode Populated with information from fd
|
||||
- st_ino Set to zero. (inode)
|
||||
- st_dev Set to zero.
|
||||
- st_uid Set to zero.
|
||||
@@ -974,6 +1026,9 @@ fstat (int fd, struct stat *statbuf)
|
||||
Opens the file pointed to by path, calls _EFI_FileInfo with the file's handle,
|
||||
then closes the file.
|
||||
|
||||
@param[in] path Path to the file to obtain information about.
|
||||
@param[out] statbuf Buffer in which the file status is put.
|
||||
|
||||
@retval 0 Successful Completion.
|
||||
@retval -1 An error has occurred and errno has been set to
|
||||
identify the error.
|
||||
@@ -994,7 +1049,15 @@ stat (const char *path, struct stat *statbuf)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/** Same as stat since EFI doesn't have symbolic links. **/
|
||||
/** Same as stat since EFI doesn't have symbolic links.
|
||||
|
||||
@param[in] path Path to the file to obtain information about.
|
||||
@param[out] statbuf Buffer in which the file status is put.
|
||||
|
||||
@retval 0 Successful Completion.
|
||||
@retval -1 An error has occurred and errno has been set to
|
||||
identify the error.
|
||||
**/
|
||||
int
|
||||
lstat (const char *path, struct stat *statbuf)
|
||||
{
|
||||
@@ -1002,6 +1065,13 @@ lstat (const char *path, struct stat *statbuf)
|
||||
}
|
||||
|
||||
/** Control a device.
|
||||
|
||||
@param[in] fd Descriptor for the file to be acted upon.
|
||||
@param[in] request Specifies the operation to perform.
|
||||
@param[in,out] ... Zero or more parameters as required for request.
|
||||
|
||||
@retval >=0 The operation completed successfully.
|
||||
@retval -1 An error occured. More information is in errno.
|
||||
**/
|
||||
int
|
||||
ioctl(
|
||||
@@ -1098,6 +1168,10 @@ ioctl(
|
||||
directory entries, the read returns a zero-length buffer.
|
||||
EFI_FILE_INFO is the structure returned as the directory entry.
|
||||
|
||||
@param[in] fildes Descriptor of the file to be read.
|
||||
@param[out] buf Pointer to location in which to store the read data.
|
||||
@param[in] nbyte Maximum number of bytes to be read.
|
||||
|
||||
@return Upon successful completion, read() returns a non-negative integer
|
||||
indicating the number of bytes actually read. Otherwise, the
|
||||
functions return a negative value and sets errno to indicate the
|
||||
@@ -1109,62 +1183,91 @@ ssize_t
|
||||
read (int fildes, void *buf, size_t nbyte)
|
||||
{
|
||||
struct __filedes *filp;
|
||||
cIIO *IIO;
|
||||
ssize_t BufSize;
|
||||
|
||||
BufSize = (ssize_t)nbyte;
|
||||
if(ValidateFD( fildes, VALID_OPEN)) {
|
||||
filp = &gMD->fdarray[fildes];
|
||||
if(BufSize > 0) {
|
||||
if(ValidateFD( fildes, VALID_OPEN)) {
|
||||
filp = &gMD->fdarray[fildes];
|
||||
|
||||
BufSize = filp->f_ops->fo_read(filp, &filp->f_offset, nbyte, buf);
|
||||
}
|
||||
else {
|
||||
errno = EBADF;
|
||||
BufSize = -EBADF;
|
||||
IIO = filp->devdata;
|
||||
if(isatty(fildes) && (IIO != NULL)) {
|
||||
BufSize = IIO->Read(filp, nbyte, buf);
|
||||
}
|
||||
else {
|
||||
BufSize = filp->f_ops->fo_read(filp, &filp->f_offset, nbyte, buf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
errno = EBADF;
|
||||
BufSize = -1;
|
||||
}
|
||||
}
|
||||
return BufSize;
|
||||
}
|
||||
|
||||
/** Write data to a file.
|
||||
|
||||
This function writes the specified number of bytes to the file at the current
|
||||
file position. The current file position is advanced the actual number of bytes
|
||||
written, which is returned in BufferSize. Partial writes only occur when there
|
||||
has been a data error during the write attempt (such as "volume space full").
|
||||
The file is automatically grown to hold the data if required. Direct writes to
|
||||
opened directories are not supported.
|
||||
This function writes the specified number of bytes to the file at the current
|
||||
file position. The current file position is advanced the actual number of bytes
|
||||
written, which is returned in BufferSize. Partial writes only occur when there
|
||||
has been a data error during the write attempt (such as "volume space full").
|
||||
The file is automatically grown to hold the data if required. Direct writes to
|
||||
opened directories are not supported.
|
||||
|
||||
If fildes refers to a terminal device, isatty() returns TRUE, a partial write
|
||||
will occur if a NULL or EOF character is encountered before n characters have
|
||||
been written. Characters inserted due to line-end translations will not be
|
||||
counted. Unconvertable characters are translated into the UEFI character
|
||||
BLOCKELEMENT_LIGHT_SHADE.
|
||||
If fildes refers to a terminal device, isatty() returns TRUE, a partial write
|
||||
will occur if a NULL or EOF character is encountered before n characters have
|
||||
been written. Characters inserted due to line-end translations will not be
|
||||
counted. Unconvertable characters are translated into the UEFI character
|
||||
BLOCKELEMENT_LIGHT_SHADE.
|
||||
|
||||
Since the UEFI console device works on wide characters, the buffer is assumed
|
||||
to contain a single-byte character stream which is then translated to wide
|
||||
characters using the btowc() functions. The resulting wide character stream
|
||||
is what is actually sent to the UEFI console.
|
||||
Since the UEFI console device works on wide characters, the buffer is assumed
|
||||
to contain a single-byte character stream which is then translated to wide
|
||||
characters using the mbtowc() functions. The resulting wide character stream
|
||||
is what is actually sent to the UEFI console.
|
||||
|
||||
QUESTION: Should writes to stdout or stderr always succeed?
|
||||
@param[in] fd Descriptor of file to be written to.
|
||||
@param[in] buf Pointer to data to write to the file.
|
||||
@param[in] nbyte Number of bytes to be written to the file.
|
||||
|
||||
@retval >=0 Number of bytes actually written to the file.
|
||||
@retval <0 An error occurred. More data is provided by errno.
|
||||
**/
|
||||
ssize_t
|
||||
write (int fd, const void *buf, size_t nbyte)
|
||||
{
|
||||
struct __filedes *filp;
|
||||
cIIO *IIO;
|
||||
ssize_t BufSize;
|
||||
// EFI_FILE_HANDLE FileHandle;
|
||||
// RETURN_STATUS Status = RETURN_SUCCESS;
|
||||
|
||||
BufSize = (ssize_t)nbyte;
|
||||
|
||||
if(ValidateFD( fd, VALID_OPEN)) {
|
||||
filp = &gMD->fdarray[fd];
|
||||
|
||||
BufSize = filp->f_ops->fo_write(filp, &filp->f_offset, nbyte, buf);
|
||||
if ((filp->Oflags & O_ACCMODE) != 0) {
|
||||
// File is open for writing
|
||||
IIO = filp->devdata;
|
||||
if(isatty(fd) && (IIO != NULL)) {
|
||||
// Output to an Interactive I/O device
|
||||
BufSize = IIO->Write(filp, buf, nbyte);
|
||||
}
|
||||
else {
|
||||
// Output to a file, socket, pipe, etc.
|
||||
BufSize = filp->f_ops->fo_write(filp, &filp->f_offset, nbyte, buf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// File is NOT open for writing
|
||||
errno = EINVAL;
|
||||
BufSize = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// fd is not for a valid open file
|
||||
errno = EBADF;
|
||||
BufSize = -EBADF;
|
||||
}
|
||||
BufSize = -1;
|
||||
}
|
||||
return BufSize;
|
||||
}
|
||||
|
||||
@@ -1260,11 +1363,29 @@ chdir (const char *path)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Get the foreground process group ID associated with a terminal.
|
||||
|
||||
Just returns the Image Handle for the requestor since UEFI does not have
|
||||
a concept of processes or groups.
|
||||
|
||||
@param[in] x Ignored.
|
||||
|
||||
@return Returns the Image Handle of the application or driver which
|
||||
called this function.
|
||||
**/
|
||||
pid_t tcgetpgrp (int x)
|
||||
{
|
||||
return ((pid_t)(UINTN)(gImageHandle));
|
||||
}
|
||||
|
||||
/** Get the process group ID of the calling process.
|
||||
|
||||
Just returns the Image Handle for the requestor since UEFI does not have
|
||||
a concept of processes or groups.
|
||||
|
||||
@return Returns the Image Handle of the application or driver which
|
||||
called this function.
|
||||
**/
|
||||
pid_t getpgrp(void)
|
||||
{
|
||||
return ((pid_t)(UINTN)(gImageHandle));
|
||||
@@ -1300,10 +1421,11 @@ va_Utimes(
|
||||
|
||||
/** Set file access and modification times.
|
||||
|
||||
@param[in] path
|
||||
@param[in] times
|
||||
@param[in] path Path to the file to be modified.
|
||||
@param[in] times Pointer to an array of two timeval structures
|
||||
|
||||
@return
|
||||
@retval 0 File times successfully set.
|
||||
@retval -1 An error occured. Error type in errno.
|
||||
**/
|
||||
int
|
||||
utimes(
|
||||
@@ -1313,4 +1435,3 @@ utimes(
|
||||
{
|
||||
return va_Utimes(path, times);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user