]>
git.proxmox.com Git - mirror_edk2.git/blob - StdLib/LibC/Uefi/SysCalls.c
a2b627bd121ac9ccfb47d1a996b1eb84814d638f
2 EFI versions of NetBSD system calls.
4 Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Library/UefiLib.h>
16 #include <Library/UefiBootServicesTableLib.h>
17 #include <Library/BaseLib.h>
18 #include <Library/MemoryAllocationLib.h>
19 #include <Library/ShellLib.h>
21 #include <LibConfig.h>
22 #include <sys/EfiCdefs.h>
31 #include <sys/fcntl.h>
33 #include <sys/syslimits.h>
34 #include <sys/filio.h>
35 #include <Efi/SysEfi.h>
38 #include <Device/Device.h>
39 #include <Device/IIO.h>
43 /* EFI versions of BSD system calls used in stdio */
45 /* Validate that fd refers to a valid file descriptor.
46 IsOpen is interpreted as follows:
47 - Positive fd must be OPEN
48 - Zero fd must be CLOSED
49 - Negative fd may be OPEN or CLOSED
51 @retval TRUE fd is VALID
52 @retval FALSE fd is INVALID
55 ValidateFD( int fd
, int IsOpen
)
57 struct __filedes
*filp
;
58 BOOLEAN retval
= FALSE
;
60 if((fd
>= 0) && (fd
< OPEN_MAX
)) {
61 filp
= &gMD
->fdarray
[fd
];
64 retval
= (BOOLEAN
)((filp
->f_iflags
!= 0) && // TRUE if OPEN
65 FILE_IS_USABLE(filp
)); // and Usable (not Larval or Closing)
66 if(IsOpen
== VALID_CLOSED
) {
67 retval
= (BOOLEAN
)!retval
; // We want TRUE if CLOSED
74 /* Find and reserve a free File Descriptor.
76 Returns the first free File Descriptor greater than or equal to the,
77 already validated, fd specified by Minfd.
79 @return Returns -1 if there are no free FDs. Otherwise returns the
83 FindFreeFD( int MinFd
)
85 struct __filedes
*Mfd
;
91 // Get an available fd
92 for(i
=MinFd
; i
< OPEN_MAX
; ++i
) {
93 if(Mfd
[i
].f_iflags
== 0) {
94 Mfd
[i
].f_iflags
= FIF_LARVAL
; // Temporarily mark this fd as reserved
102 /* Mark that an open file is to be deleted when closed. */
104 DeleteOnClose(int fd
)
108 if(ValidateFD( fd
, VALID_OPEN
)) {
109 gMD
->fdarray
[fd
].f_iflags
|= FIF_DELCLOSE
;
118 /** The isatty() function tests whether fd, an open file descriptor,
119 is associated with a terminal device.
121 @param[in] fd File Descriptor for the file to be examined.
123 @retval 1 fd is associated with a terminal.
124 @retval 0 fd is not associated with a terminal. errno is set to
125 EBADF if fd is not a valid open FD.
131 struct __filedes
*Fp
;
133 if(ValidateFD( fd
, VALID_OPEN
)) {
134 Fp
= &gMD
->fdarray
[fd
];
135 retval
= (Fp
->f_iflags
& _S_ITTY
) ? 1 : 0;
143 /** Determine if file descriptor fd is a duplicate of some other fd.
145 @param[in] fd The file descriptor to check.
147 @retval TRUE fd is a duplicate of another fd.
148 @retval FALSE fd is unique.
154 const struct fileops
*FileOps
;
158 if(ValidateFD( fd
, VALID_OPEN
)) {
159 FileOps
= gMD
->fdarray
[fd
].f_ops
;
160 DevData
= gMD
->fdarray
[fd
].devdata
;
161 for(i
=0; i
< OPEN_MAX
; ++i
) {
162 if(i
== fd
) continue;
163 if(ValidateFD( i
, VALID_OPEN
)) { // TRUE if fd is valid and OPEN
164 if((gMD
->fdarray
[i
].f_ops
== FileOps
)
165 &&(gMD
->fdarray
[i
].devdata
== DevData
)) {
175 /** Worker function to Close a file and set its fd to the specified state.
177 @param[in] fd The file descriptor to close.
178 @param[in] NewState State to set the fd to after the file is closed.
180 @retval 0 The operation completed successfully.
181 @retval -1 The operation failed. Further information is in errno.
182 * EBADF fd is not a valid or open file descriptor.
185 _closeX (int fd
, int NewState
)
187 struct __filedes
*Fp
;
190 // Verify my pointers and get my FD.
191 if(ValidateFD( fd
, VALID_OPEN
)) {
192 Fp
= &gMD
->fdarray
[fd
];
193 // Check if there are other users of this FileHandle
194 if(Fp
->RefCount
== 1) { // There should be no other users
196 // Only do the close if no one else is using the FileHandle
197 if(Fp
->f_iflags
& FIF_DELCLOSE
) {
198 /* Handle files marked "Delete on Close". */
199 if(Fp
->f_ops
->fo_delete
!= NULL
) {
200 retval
= Fp
->f_ops
->fo_delete(Fp
);
204 retval
= Fp
->f_ops
->fo_close( Fp
);
207 Fp
->f_iflags
= NewState
; // Close this FD or reserve it
208 Fp
->RefCount
= 0; // No one using this FD
211 --Fp
->RefCount
; /* One less user of this FD */
222 /** The close() function deallocates the file descriptor indicated by fd.
223 To deallocate means to make the file descriptor available for return by
224 subsequent calls to open() or other functions that allocate file
225 descriptors. All outstanding record locks owned by the process on the file
226 associated with the file descriptor are removed (that is, unlocked).
228 @param[in] fd Descriptor for the File to close.
230 @retval 0 Successful completion.
231 @retval -1 An error occurred and errno is set to identify the error.
236 return _closeX(fd
, 0);
239 /** Delete the file specified by path.
241 @param[in] path The MBCS path of the file to delete.
243 @retval -1 Unable to open the file specified by path.
244 @retval -1 If (errno == EPERM), unlink is not permited for this file.
245 @retval -1 Low-level delete filed. Reason is in errno.
246 @retval 0 The file was successfully deleted.
249 unlink (const char *path
)
251 struct __filedes
*Fp
;
255 EFIerrno
= RETURN_SUCCESS
;
257 fd
= open(path
, O_WRONLY
, 0);
259 Fp
= &gMD
->fdarray
[fd
];
261 if(Fp
->f_ops
->fo_delete
!= NULL
) {
262 retval
= Fp
->f_ops
->fo_delete(Fp
);
264 Fp
->f_iflags
= 0; // Close this FD
265 Fp
->RefCount
= 0; // No one using this FD
270 /** The fcntl() function shall perform the operations described below on open
271 files. The fildes argument is a file descriptor.
273 The available values for cmd are defined in <fcntl.h> and are as follows:
274 - F_DUPFD - Return a new file descriptor which shall be the lowest
275 numbered available (that is, not already open) file
276 descriptor greater than or equal to the third argument, arg,
277 taken as an integer of type int. The new file descriptor
278 shall refer to the same open file description as the original
279 file descriptor, and shall share any locks. The FD_CLOEXEC
280 flag associated with the new file descriptor shall be cleared
281 to keep the file open across calls to one of the exec functions.
282 - F_GETFD - Get the file descriptor flags defined in <fcntl.h> that are
283 associated with the file descriptor fildes. File descriptor
284 flags are associated with a single file descriptor and do not
285 affect other file descriptors that refer to the same file.
286 - F_SETFD - Set the file descriptor flags defined in <fcntl.h>, that are
287 associated with fildes, to the third argument, arg, taken
288 as type int. If the FD_CLOEXEC flag in the third argument
289 is 0, the file shall remain open across the exec
290 functions; otherwise, the file shall be closed upon
291 successful execution of one of the exec functions.
292 - F_GETFL - Get the file status flags and file access modes, defined in
293 <fcntl.h>, for the file description associated with fildes.
294 The file access modes can be extracted from the return
295 value using the mask O_ACCMODE, which is defined in
296 <fcntl.h>. File status flags and file access modes are
297 associated with the file description and do not affect
298 other file descriptors that refer to the same file with
299 different open file descriptions.
300 - F_SETFL - Set the file status flags, defined in <fcntl.h>, for the file
301 description associated with fildes from the corresponding
302 bits in the third argument, arg, taken as type int. Bits
303 corresponding to the file access mode and the file creation
304 flags, as defined in <fcntl.h>, that are set in arg shall
305 be ignored. If any bits in arg other than those mentioned
306 here are changed by the application, the result is unspecified.
307 - F_GETOWN - If fildes refers to a socket, get the process or process group
308 ID specified to receive SIGURG signals when out-of-band
309 data is available. Positive values indicate a process ID;
310 negative values, other than -1, indicate a process group
311 ID. If fildes does not refer to a socket, the results are
313 - F_SETOWN - If fildes refers to a socket, set the process or process
314 group ID specified to receive SIGURG signals when
315 out-of-band data is available, using the value of the third
316 argument, arg, taken as type int. Positive values indicate
317 a process ID; negative values, other than -1, indicate a
318 process group ID. If fildes does not refer to a socket, the
319 results are unspecified.
321 The fcntl() function shall fail if:
323 [EBADF] The fildes argument is not a valid open file descriptor.
324 [EINVAL] The cmd argument is invalid, or the cmd argument is F_DUPFD
325 and arg is negative or greater than or equal to {OPEN_MAX}.
326 [EMFILE] The argument cmd is F_DUPFD and {OPEN_MAX} file descriptors
327 are currently open in the calling process, or no file
328 descriptors greater than or equal to arg are available.
329 [EOVERFLOW] One of the values to be returned cannot be represented correctly.
331 @param[in] fildes Descriptor for the file to be controlled.
332 @param[in] cmd Command to be acted upon.
333 @param[in,out] ... Optional additional parameters as required by cmd.
335 @return Upon successful completion, the value returned shall depend on
337 - F_DUPFD - A new file descriptor.
338 - F_GETFD - Value of flags defined in <fcntl.h>. The return value
339 shall not be negative.
340 - F_SETFD - Value other than -1.
341 - F_GETFL - Value of file status flags and access modes. The return
342 value is not negative.
343 - F_SETFL - Value other than -1.
344 - F_GETOWN - Value of the socket owner process or process group;
346 - F_SETOWN - Value other than -1.
347 Otherwise, -1 shall be returned and errno set to indicate the error.
351 fcntl (int fildes
, int cmd
, ...)
354 struct __filedes
*MyFd
;
358 //Print(L"%a( %d, %d, ...)\n", __func__, fildes, cmd);
361 if(ValidateFD( fildes
, VALID_OPEN
)) {
362 MyFd
= &gMD
->fdarray
[fildes
];
366 temp
= va_arg(p3
, int);
367 if(ValidateFD( temp
, VALID_DONT_CARE
)) {
368 temp
= FindFreeFD( temp
);
373 /* temp is now a valid fd reserved for further use
374 so copy fd into temp.
376 (void)memcpy(&gMD
->fdarray
[temp
], MyFd
, sizeof(struct __filedes
));
385 retval
= MyFd
->Oflags
; // Get original value
386 temp
= va_arg(p3
, int);
387 temp
&= O_SETMASK
; // Only certain bits can be set
388 temp
|= retval
& O_SETMASK
;
389 MyFd
->Oflags
= temp
; // Set new value
393 retval
= MyFd
->f_iflags
;
396 // retval = MyFd->SocProc;
397 // MyFd->SocProc = va_arg(p3, int);
400 retval
= MyFd
->f_iflags
;
403 retval
= MyFd
->Oflags
;
406 // retval = MyFd->SocProc;
421 /** The dup() function provides an alternative interface to the
422 service provided by fcntl() using the F_DUPFD command. The call:
424 shall be equivalent to:
425 - fid = fcntl(fildes, F_DUPFD, 0);
427 @param[in] fildes Descriptor for the file to be examined.
429 @return Upon successful completion a non-negative integer, namely the
430 file descriptor, shall be returned; otherwise, -1 shall be
431 returned and errno set to indicate the error.
436 return fcntl(fildes
, F_DUPFD
, 0);
439 /** Make fildes2 refer to a duplicate of fildes.
441 The dup2() function provides an alternative interface to the
442 service provided by fcntl() using the F_DUPFD command. The call:
443 - fid = dup2(fildes, fildes2);
444 shall be equivalent to:
446 - fid = fcntl(fildes, F_DUPFD, fildes2);
447 except for the following:
448 - If fildes2 is less than 0 or greater than or equal to {OPEN_MAX},
449 dup2() shall return -1 with errno set to [EBADF].
450 - If fildes is a valid file descriptor and is equal to fildes2, dup2()
451 shall return fildes2 without closing it.
452 - If fildes is not a valid file descriptor, dup2() shall return -1 and
453 shall not close fildes2.
454 - The value returned shall be equal to the value of fildes2 upon
455 successful completion, or -1 upon failure.
457 @param[in] fildes File Descriptor to be duplicated.
458 @param[in] fildes2 File Descriptor to be made a duplicate of fildes.
460 @return Upon successful completion a non-negative integer, namely
461 fildes2, shall be returned; otherwise, -1 shall be
462 returned and errno set to EBADF indicate the error.
465 dup2 (int fildes
, int fildes2
)
469 if(ValidateFD( fildes
, VALID_OPEN
)) {
471 if( fildes
!= fildes2
) {
472 if(ValidateFD( fildes2
, VALID_DONT_CARE
)) {
473 gMD
->fdarray
[fildes2
].f_iflags
= FIF_LARVAL
; // Mark the file closed, but reserved
474 (void)memcpy(&gMD
->fdarray
[fildes2
], // Duplicate fildes into fildes2
475 &gMD
->fdarray
[fildes
], sizeof(struct __filedes
));
476 gMD
->fdarray
[fildes2
].MyFD
= (UINT16
)fildes2
;
490 /** Reposition a file's read/write offset.
492 The lseek() function repositions the offset of the file descriptor fildes
493 to the argument offset according to the directive how. The argument
494 fildes must be an open file descriptor. lseek() repositions the file
495 pointer fildes as follows:
497 - If how is SEEK_SET, the offset is set to offset bytes.
499 - If how is SEEK_CUR, the offset is set to its current location
502 - If how is SEEK_END, the offset is set to the size of the file
505 The lseek() function allows the file offset to be set beyond the end of
506 the existing end-of-file of the file. If data is later written at this
507 point, subsequent reads of the data in the gap return bytes of zeros
508 (until data is actually written into the gap).
510 Some devices are incapable of seeking. The value of the pointer associ-
511 ated with such a device is undefined.
513 @param[in] fd Descriptor for the File to be affected.
514 @param[in] offset Value to adjust the file position by.
515 @param[in] how How the file position is to be adjusted.
517 @return Upon successful completion, lseek() returns the resulting offset
518 location as measured in bytes from the beginning of the file.
519 Otherwise, a value of -1 is returned and errno is set to
523 lseek (int fd
, __off_t offset
, int how
)
526 // RETURN_STATUS Status = RETURN_SUCCESS;
527 struct __filedes
*filp
;
529 EFIerrno
= RETURN_SUCCESS
; // In case of error without an EFI call
531 if( how
== SEEK_SET
|| how
== SEEK_CUR
|| how
== SEEK_END
) {
532 if(ValidateFD( fd
, VALID_OPEN
)) {
533 filp
= &gMD
->fdarray
[fd
];
534 // Both of our parameters have been verified as valid
535 CurPos
= filp
->f_ops
->fo_lseek( filp
, offset
, how
);
537 filp
->f_offset
= CurPos
;
541 errno
= EBADF
; // Bad File Descriptor
545 errno
= EINVAL
; // Invalid how argument
550 /** The directory path is created with the access permissions specified by
553 The directory is closed after it is created.
555 @param[in] path The path to a directory to create.
556 @param[in] perms Permissions as defined in <sys/stat.h>
558 @retval 0 The directory was created successfully.
559 @retval -1 An error occurred and error codes are stored in errno and EFIerrno.
562 mkdir (const char *path
, __mode_t perms
)
567 RETURN_STATUS Status
;
571 Status
= ParsePath(path
, &NewPath
, &Node
, &Instance
, NULL
);
572 if(Status
== RETURN_SUCCESS
) {
573 GenI
= Node
->InstanceList
;
579 //GenI += (Instance * Node->InstanceSize);
580 retval
= ((GenericInstance
*)GenI
)->Abstraction
.fo_mkdir( path
, perms
);
591 The open() function establishes the connection between a file and a file
592 descriptor. It creates an open file description that refers to a file
593 and a file descriptor that refers to that open file description. The file
594 descriptor is used by other I/O functions to refer to that file.
596 The open() function returns a file descriptor for the named file that is
597 the lowest file descriptor not currently open for that process. The open
598 file description is new, and therefore the file descriptor shall not
599 share it with any other process in the system.
601 The file offset used to mark the current position within the file is set
602 to the beginning of the file.
604 The EFI ShellOpenFileByName() function is used to perform the low-level
605 file open operation. The primary task of open() is to translate from the
606 flags used in the <stdio.h> environment to those used by the EFI function.
608 The file status flags and file access modes of the open file description
609 are set according to the value of oflags.
611 Values for oflags are constructed by a bitwise-inclusive OR of flags from
612 the following list, defined in <fcntl.h>. Applications shall specify
613 exactly one of { O_RDONLY, O_RDWR, O_WRONLY } in the value of oflags.
614 Any combination of { O_NONBLOCK, O_APPEND, O_CREAT, O_TRUNC, O_EXCL } may
615 also be specified in oflags.
617 The only valid flag combinations for ShellOpenFileByName() are:
622 Values for mode specify the access permissions for newly created files.
623 The mode value is saved in the FD to indicate permissions for further operations.
625 O_RDONLY -- flags = EFI_FILE_MODE_READ -- this is always done
626 O_WRONLY -- flags |= EFI_FILE_MODE_WRITE
627 O_RDWR -- flags |= EFI_FILE_MODE_WRITE -- READ is already set
629 O_NONBLOCK -- ignored
630 O_APPEND -- Seek to EOF before every write
631 O_CREAT -- flags |= EFI_FILE_MODE_CREATE
632 O_TRUNC -- delete first then create new
633 O_EXCL -- if O_CREAT is also set, open will fail if the file already exists.
635 @param[in] Path The path argument points to a pathname naming the
637 @param[in] oflags File status flags and file access modes of the
638 open file description.
639 @param[in] mode File access permission bits as defined in
640 <sys/stat.h>. Only used if a file is created
641 as a result of the open.
643 @return Upon successful completion, open() opens the file and returns
644 a non-negative integer representing the lowest numbered
645 unused file descriptor. Otherwise, open returns -1 and sets
646 errno to indicate the error. If a negative value is
647 returned, no files are created or modified.
648 - EMFILE - No file descriptors available -- Max number already open.
649 - EINVAL - Bad value specified for oflags or mode.
650 - ENOMEM - Failure allocating memory for internal buffers.
651 - EEXIST - File exists and open attempted with (O_EXCL | O_CREAT) set.
652 - EIO - UEFI failure. Check value in EFIerrno.
664 struct __filedes
*filp
;
665 struct termios
*Termio
;
667 RETURN_STATUS Status
;
672 Status
= ParsePath(path
, &NewPath
, &Node
, &Instance
, &MPath
);
673 if(Status
== RETURN_SUCCESS
) {
675 (Node
->InstanceList
== NULL
))
680 // Could add a test to see if the file name begins with a period.
681 // If it does, then add the HIDDEN flag to Attributes.
683 // Get an available fd
684 fd
= FindFreeFD( VALID_CLOSED
);
687 // All available FDs are in use
691 filp
= &gMD
->fdarray
[fd
];
692 // Save the flags and mode in the File Descriptor
693 filp
->Oflags
= oflags
;
696 doresult
= Node
->OpenFunc(Node
, filp
, Instance
, NewPath
, MPath
);
698 filp
->f_iflags
= 0; // Release this FD
699 fd
= -1; // Indicate an error
702 // Build our final f_iflags value
703 OpenMode
= ( mode
& S_ACC_READ
) ? S_ACC_READ
: 0;
704 OpenMode
|= ( mode
& S_ACC_WRITE
) ? S_ACC_WRITE
: 0;
706 filp
->f_iflags
|= OpenMode
;
708 if((oflags
& O_TTY_INIT
) && (filp
->f_iflags
& _S_ITTY
) && (filp
->devdata
!= NULL
)) {
709 // Initialize the device's termios flags to a "sane" value
710 Termio
= &((cIIO
*)filp
->devdata
)->Termio
;
711 Termio
->c_iflag
= ICRNL
| IGNSPEC
;
712 Termio
->c_oflag
= OPOST
| ONLCR
| OXTABS
| ONOEOT
| ONOCR
| ONLRET
| OCTRL
;
713 Termio
->c_lflag
= ECHO
| ECHOE
| ECHONL
| ICANON
;
714 Termio
->c_cc
[VERASE
] = 0x08; // ^H Backspace
715 Termio
->c_cc
[VKILL
] = 0x15; // ^U
716 Termio
->c_cc
[VINTR
] = 0x03; // ^C Interrupt character
719 FILE_SET_MATURE(filp
);
725 free(MPath
); // We don't need this any more.
727 // return the fd of our now open file
733 Poll a list of file descriptors.
735 The ::poll routine waits for up to timeout milliseconds for an event
736 to occur on one or more of the file descriptors listed. The event
737 types of interested are specified for each file descriptor in the events
738 field. The actual event detected is returned in the revents field of
740 <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html">POSIX</a>
741 documentation is available online.
743 @param[in] pfd Address of an array of pollfd structures.
745 @param[in] nfds Number of elements in the array of pollfd structures.
747 @param[in] timeout Length of time in milliseconds to wait for the event
749 @return The number of file descriptors with detected events. Zero
750 indicates that the call timed out and -1 indicates an error.
760 struct __filedes
* pDescriptor
;
761 struct pollfd
* pEnd
;
762 struct pollfd
* pPollFD
;
769 // Create the timer for the timeout
772 Status
= EFI_SUCCESS
;
773 if ( INFTIM
!= timeout
) {
774 Status
= gBS
->CreateEvent ( EVT_TIMER
,
779 if ( !EFI_ERROR ( Status
)) {
781 // Start the timeout timer
783 TimerTicks
= timeout
;
784 TimerTicks
*= 1000 * 10;
785 Status
= gBS
->SetTimer ( Timer
,
794 if ( !EFI_ERROR ( Status
)) {
796 // Poll until an event is detected or the timer fires
802 // Poll the list of file descriptors
805 pEnd
= &pPollFD
[ nfds
];
806 while ( pEnd
> pPollFD
) {
808 // Validate the file descriptor
810 if ( !ValidateFD ( pPollFD
->fd
, VALID_OPEN
)) {
816 // Poll the device or file
818 pDescriptor
= &gMD
->fdarray
[ pPollFD
->fd
];
819 pPollFD
->revents
= pDescriptor
->f_ops
->fo_poll ( pDescriptor
,
823 // Determine if this file descriptor detected an event
825 if ( 0 != pPollFD
->revents
) {
827 // Select this descriptor
833 // Set the next file descriptor
841 if ( NULL
!= Timer
) {
842 Status
= gBS
->CheckEvent ( Timer
);
843 if ( EFI_SUCCESS
== Status
) {
849 else if ( EFI_NOT_READY
== Status
) {
850 Status
= EFI_SUCCESS
;
853 } while (( 0 == SelectedFDs
)
854 && ( EFI_SUCCESS
== Status
));
859 if ( NULL
!= Timer
) {
860 gBS
->SetTimer ( Timer
,
873 if ( NULL
!= Timer
) {
874 gBS
->CloseEvent ( Timer
);
878 // Return the number of selected file system descriptors
884 /** The rename() function changes the name of a file.
885 The From argument points to the pathname of the file to be renamed. The To
886 argument points to the new pathname of the file.
888 If the From argument points to the pathname of a file that is not a
889 directory, the To argument shall not point to the pathname of a
890 directory. If the file named by the To argument exists, it shall be
891 removed and From renamed to To. Write access permission is required for
892 both the directory containing old and the directory containing To.
894 If the From argument points to the pathname of a directory, the To
895 argument shall not point to the pathname of a file that is not a
896 directory. If the directory named by the To argument exists, it shall be
897 removed and From renamed to To.
899 The To pathname shall not contain a path prefix that names From. Write
900 access permission is required for the directory containing From and the
901 directory containing To. If the From argument points to the pathname of a
902 directory, write access permission may be required for the directory named
903 by From, and, if it exists, the directory named by To.
905 If the rename() function fails for any reason other than [EIO], any file
906 named by To shall be unaffected.
908 @param[in] From Path to the file to be renamed.
909 @param[in] To The new name of From.
911 @retval 0 Successful completion.
912 @retval -1 An error has occured and errno has been set to further specify the error.
913 Neither the file named by From nor the file named by To are
915 - ENXIO: Path specified is not supported by any loaded driver.
916 - ENOMEM: Insufficient memory to calloc a MapName buffer.
917 - EINVAL: The path parameter is not valid.
926 DeviceNode
*FromNode
;
929 RETURN_STATUS Status
;
932 Status
= ParsePath(From
, &FromPath
, &FromNode
, &Instance
, NULL
);
933 if(Status
== RETURN_SUCCESS
) {
934 GenI
= FromNode
->InstanceList
;
940 //GenI += (Instance * FromNode->InstanceSize);
941 retval
= ((GenericInstance
*)GenI
)->Abstraction
.fo_rename( From
, To
);
948 /** Delete a specified directory.
950 @param[in] path Path to the directory to delete.
952 @retval -1 The directory couldn't be opened (doesn't exist).
953 @retval -1 The directory wasn't empty or an IO error occured.
960 struct __filedes
*filp
;
964 fd
= open(path
, O_RDWR
, 0);
966 filp
= &gMD
->fdarray
[fd
];
968 retval
= filp
->f_ops
->fo_rmdir(filp
);
969 filp
->f_iflags
= 0; // Close this FD
970 filp
->RefCount
= 0; // No one using this FD
975 /** The fstat() function obtains information about an open file associated
976 with the file descriptor fd, and writes it to the area pointed to
979 The statbuf argument is a pointer to a stat structure, as defined
980 in <sys/stat.h>, into which information is placed concerning the file.
982 The structure members st_mode, st_ino, st_dev, st_uid, st_gid, st_atime,
983 st_ctime, and st_mtime shall have meaningful values. The value of the
984 member st_nlink shall be set to the number of links to the file.
986 The fstat() function shall update any time-related fields before writing
987 into the stat structure.
989 The fstat() function is implemented using the ShellGetFileInfo()
992 The stat structure members which don't have direct analogs to EFI file
993 information are filled in as follows:
994 - st_mode Populated with information from fd
995 - st_ino Set to zero. (inode)
996 - st_dev Set to zero.
997 - st_uid Set to zero.
998 - st_gid Set to zero.
999 - st_nlink Set to one.
1001 @param[in] fd File descriptor as returned from open().
1002 @param[out] statbuf Buffer in which the file status is put.
1004 @retval 0 Successful Completion.
1005 @retval -1 An error has occurred and errno has been set to
1009 fstat (int fd
, struct stat
*statbuf
)
1012 struct __filedes
*filp
;
1014 if(ValidateFD( fd
, VALID_OPEN
)) {
1015 filp
= &gMD
->fdarray
[fd
];
1016 retval
= filp
->f_ops
->fo_stat(filp
, statbuf
, NULL
);
1024 /** Obtains information about the file pointed to by path.
1026 Opens the file pointed to by path, calls _EFI_FileInfo with the file's handle,
1027 then closes the file.
1029 @param[in] path Path to the file to obtain information about.
1030 @param[out] statbuf Buffer in which the file status is put.
1032 @retval 0 Successful Completion.
1033 @retval -1 An error has occurred and errno has been set to
1037 stat (const char *path
, struct stat
*statbuf
)
1041 struct __filedes
*filp
;
1043 fd
= open(path
, O_RDONLY
, 0);
1045 filp
= &gMD
->fdarray
[fd
];
1046 retval
= filp
->f_ops
->fo_stat( filp
, statbuf
, NULL
);
1052 /** Same as stat since EFI doesn't have symbolic links.
1054 @param[in] path Path to the file to obtain information about.
1055 @param[out] statbuf Buffer in which the file status is put.
1057 @retval 0 Successful Completion.
1058 @retval -1 An error has occurred and errno has been set to
1062 lstat (const char *path
, struct stat
*statbuf
)
1064 return stat(path
, statbuf
);
1067 /** Control a device.
1069 @param[in] fd Descriptor for the file to be acted upon.
1070 @param[in] request Specifies the operation to perform.
1071 @param[in,out] ... Zero or more parameters as required for request.
1073 @retval >=0 The operation completed successfully.
1074 @retval -1 An error occured. More information is in errno.
1079 unsigned long request
,
1084 struct __filedes
*filp
;
1087 va_start(argp
, request
);
1089 if(ValidateFD( fd
, VALID_OPEN
)) {
1090 filp
= &gMD
->fdarray
[fd
];
1092 if(request
== FIODLEX
) {
1093 /* set Delete-on-Close */
1094 filp
->f_iflags
|= FIF_DELCLOSE
;
1097 else if(request
== FIONDLEX
) {
1098 /* clear Delete-on-Close */
1099 filp
->f_iflags
&= ~FIF_DELCLOSE
;
1103 /* All other requests. */
1104 retval
= filp
->f_ops
->fo_ioctl(filp
, request
, argp
);
1115 /** Read from a file.
1117 The read() function shall attempt to read nbyte bytes from the file
1118 associated with the open file descriptor, fildes, into the buffer pointed
1121 Before any action described below is taken, and if nbyte is zero, the
1122 read() function may detect and return errors as described below. In the
1123 absence of errors, or if error detection is not performed, the read()
1124 function shall return zero and have no other results.
1126 On files that support seeking (for example, a regular file), the read()
1127 shall start at a position in the file given by the file offset associated
1128 with fildes. The file offset shall be incremented by the number of bytes
1131 Files that do not support seeking - for example, terminals - always read
1132 from the current position. The value of a file offset associated with
1133 such a file is undefined.
1135 No data transfer shall occur past the current end-of-file. If the
1136 starting position is at or after the end-of-file, 0 shall be returned.
1138 The read() function reads data previously written to a file. If any
1139 portion of a regular file prior to the end-of-file has not been written,
1140 read() shall return bytes with value 0. For example, lseek() allows the
1141 file offset to be set beyond the end of existing data in the file. If data
1142 is later written at this point, subsequent reads in the gap between the
1143 previous end of data and the newly written data shall return bytes with
1144 value 0 until data is written into the gap.
1146 Upon successful completion, where nbyte is greater than 0, read() shall
1147 mark for update the st_atime field of the file, and shall return the
1148 number of bytes read. This number shall never be greater than nbyte. The
1149 value returned may be less than nbyte if the number of bytes left in the
1150 file is less than nbyte, if the read() request was interrupted by a
1151 signal, or if the file is a pipe or FIFO or special file and has fewer
1152 than nbyte bytes immediately available for reading. For example, a read()
1153 from a file associated with a terminal may return one typed line of data.
1155 If fildes does not refer to a directory, the function reads the requested
1156 number of bytes from the file at the file's current position and returns
1157 them in buf. If the read goes beyond the end of the file, the read
1158 length is truncated to the end of the file. The file's current position is
1159 increased by the number of bytes returned.
1161 If fildes refers to a directory, the function reads the directory entry at
1162 the file's current position and returns the entry in buf. If buf
1163 is not large enough to hold the current directory entry, then
1164 errno is set to EBUFSIZE, EFIerrno is set to EFI_BUFFER_TOO_SMALL, and the
1165 current file position is not updated. The size of the buffer needed to read
1166 the entry will be returned as a negative number. On success, the current
1167 position is updated to the next directory entry. If there are no more
1168 directory entries, the read returns a zero-length buffer.
1169 EFI_FILE_INFO is the structure returned as the directory entry.
1171 @param[in] fildes Descriptor of the file to be read.
1172 @param[out] buf Pointer to location in which to store the read data.
1173 @param[in] nbyte Maximum number of bytes to be read.
1175 @return Upon successful completion, read() returns a non-negative integer
1176 indicating the number of bytes actually read. Otherwise, the
1177 functions return a negative value and sets errno to indicate the
1178 error. If errno is EBUFSIZE, the absolute value of the
1179 return value indicates the size of the buffer needed to read
1180 the directory entry.
1183 read (int fildes
, void *buf
, size_t nbyte
)
1185 struct __filedes
*filp
;
1189 BufSize
= (ssize_t
)nbyte
;
1191 if(ValidateFD( fildes
, VALID_OPEN
)) {
1192 filp
= &gMD
->fdarray
[fildes
];
1194 IIO
= filp
->devdata
;
1195 if(isatty(fildes
) && (IIO
!= NULL
)) {
1196 BufSize
= IIO
->Read(filp
, nbyte
, buf
);
1199 BufSize
= filp
->f_ops
->fo_read(filp
, &filp
->f_offset
, nbyte
, buf
);
1210 /** Write data to a file.
1212 This function writes the specified number of bytes to the file at the current
1213 file position. The current file position is advanced the actual number of bytes
1214 written, which is returned in BufferSize. Partial writes only occur when there
1215 has been a data error during the write attempt (such as "volume space full").
1216 The file is automatically grown to hold the data if required. Direct writes to
1217 opened directories are not supported.
1219 If fildes refers to a terminal device, isatty() returns TRUE, a partial write
1220 will occur if a NULL or EOF character is encountered before n characters have
1221 been written. Characters inserted due to line-end translations will not be
1222 counted. Unconvertable characters are translated into the UEFI character
1223 BLOCKELEMENT_LIGHT_SHADE.
1225 Since the UEFI console device works on wide characters, the buffer is assumed
1226 to contain a single-byte character stream which is then translated to wide
1227 characters using the mbtowc() functions. The resulting wide character stream
1228 is what is actually sent to the UEFI console.
1230 @param[in] fd Descriptor of file to be written to.
1231 @param[in] buf Pointer to data to write to the file.
1232 @param[in] nbyte Number of bytes to be written to the file.
1234 @retval >=0 Number of bytes actually written to the file.
1235 @retval <0 An error occurred. More data is provided by errno.
1238 write (int fd
, const void *buf
, size_t nbyte
)
1240 struct __filedes
*filp
;
1244 BufSize
= (ssize_t
)nbyte
;
1246 if(ValidateFD( fd
, VALID_OPEN
)) {
1247 filp
= &gMD
->fdarray
[fd
];
1248 if ((filp
->Oflags
& O_ACCMODE
) != 0) {
1249 // File is open for writing
1250 IIO
= filp
->devdata
;
1251 if(isatty(fd
) && (IIO
!= NULL
)) {
1252 // Output to an Interactive I/O device
1253 BufSize
= IIO
->Write(filp
, buf
, nbyte
);
1256 // Output to a file, socket, pipe, etc.
1257 BufSize
= filp
->f_ops
->fo_write(filp
, &filp
->f_offset
, nbyte
, buf
);
1261 // File is NOT open for writing
1267 // fd is not for a valid open file
1274 /** Gets the current working directory.
1276 The getcwd() function shall place an absolute pathname of the current
1277 working directory in the array pointed to by buf, and return buf.The
1278 size argument is the size in bytes of the character array pointed to
1279 by the buf argument.
1281 @param[in,out] buf The buffer to fill.
1282 @param[in] size The number of bytes in buffer.
1284 @retval NULL The function failed. The value in errno provides
1285 further information about the cause of the failure.
1286 Values for errno are:
1287 - EINVAL: buf is NULL or size is zero.
1288 - ENOENT: directory does not exist.
1289 - ERANGE: buf size is too small to hold CWD
1291 @retval buf The function completed successfully.
1294 *getcwd (char *buf
, size_t size
)
1298 if (size
== 0 || buf
== NULL
) {
1303 Cwd
= ShellGetCurrentDir(NULL
);
1308 if (size
< ((StrLen (Cwd
) + 1) * sizeof (CHAR8
))) {
1312 return (UnicodeStrToAsciiStr(Cwd
, buf
));
1315 /** Change the current working directory.
1317 The chdir() function shall cause the directory named by the pathname
1318 pointed to by the path argument to become the current working directory;
1319 that is, the starting point for path searches for pathnames not beginning
1322 @param[in] path The new path to set.
1324 @retval 0 Operation completed successfully.
1325 @retval -1 Function failed. The value in errno provides more
1326 information on the cause of failure:
1327 - EPERM: Operation not supported with this Shell version.
1328 - ENOMEM: Unable to allocate memory.
1329 - ENOENT: Target directory does not exist.
1331 @todo Add non-NEW-shell CWD changing.
1334 chdir (const char *path
)
1338 CHAR16
*UnicodePath
;
1340 /* Old Shell does not support Set Current Dir. */
1341 if(gEfiShellProtocol
!= NULL
) {
1342 Cwd
= ShellGetCurrentDir(NULL
);
1344 /* We have shell support */
1345 UnicodePath
= AllocatePool(((AsciiStrLen (path
) + 1) * sizeof (CHAR16
)));
1346 if (UnicodePath
== NULL
) {
1350 AsciiStrToUnicodeStr(path
, UnicodePath
);
1351 Status
= gEfiShellProtocol
->SetCurDir(NULL
, UnicodePath
);
1352 FreePool(UnicodePath
);
1353 if (EFI_ERROR(Status
)) {
1361 /* Add here for non-shell */
1366 /** Get the foreground process group ID associated with a terminal.
1368 Just returns the Image Handle for the requestor since UEFI does not have
1369 a concept of processes or groups.
1371 @param[in] x Ignored.
1373 @return Returns the Image Handle of the application or driver which
1374 called this function.
1376 pid_t
tcgetpgrp (int x
)
1378 return ((pid_t
)(UINTN
)(gImageHandle
));
1381 /** Get the process group ID of the calling process.
1383 Just returns the Image Handle for the requestor since UEFI does not have
1384 a concept of processes or groups.
1386 @return Returns the Image Handle of the application or driver which
1387 called this function.
1391 return ((pid_t
)(UINTN
)(gImageHandle
));
1394 /* Internal worker function for utimes.
1395 This works around an error produced by GCC when the va_* macros
1396 are used within a function with a fixed number of arguments.
1406 struct __filedes
*filp
;
1412 fd
= open(path
, O_RDWR
, 0);
1414 filp
= &gMD
->fdarray
[fd
];
1415 retval
= filp
->f_ops
->fo_ioctl( filp
, FIOSETIME
, ap
);
1422 /** Set file access and modification times.
1424 @param[in] path Path to the file to be modified.
1425 @param[in] times Pointer to an array of two timeval structures
1427 @retval 0 File times successfully set.
1428 @retval -1 An error occured. Error type in errno.
1433 const struct timeval
*times
1436 return va_Utimes(path
, times
);