Add Socket Libraries.
Add Posix functions for porting compatibility. Fix compliance issues with ISO/IEC 9899:199409 New Functions: setenv(), fparseln(), GetFileNameFromPath(), rename(), realpath(), setprogname(), getprogname(), strlcat(), strlcpy(), strsep(), setitimer(), getitimer(), timegm(), getopt(), basename(), mkstemp(), ffs(), vsnprintf(), snprintf(), getpass(), usleep(), select(), writev(), strcasecmp(), getcwd(), chdir(), tcgetpgrp(), getpgrp(), gettimeofday(), bcopy(), git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12061 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -63,12 +63,3 @@
|
||||
[LibraryClasses]
|
||||
LibC
|
||||
LibCType
|
||||
|
||||
################################################################
|
||||
#
|
||||
# The Build Options, below, are only used when building the C library.
|
||||
# DO NOT use them when building your application!
|
||||
# Nasty things could happen if you do.
|
||||
#
|
||||
[BuildOptions]
|
||||
GCC:*_*_*_CC_FLAGS = -fno-builtin
|
||||
|
@@ -42,6 +42,8 @@
|
||||
NetBSD: _wcstoul.h,v 1.3 2005/11/29 03:11:59 christos Exp
|
||||
*/
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
|
||||
/*
|
||||
* function template for wcstoul, wcstoull and wcstoumax.
|
||||
*
|
||||
@@ -102,8 +104,8 @@ _FUNCNAME(
|
||||
/*
|
||||
* See strtoul for comments as to the logic used.
|
||||
*/
|
||||
cutoff = __wUINT_MAX / (__wUINT)base;
|
||||
cutlim = (int)(__wUINT_MAX % (__wUINT)base);
|
||||
cutoff = (__wUINT)DivU64x32 ((UINT64) __wUINT_MAX, (UINT32) base);
|
||||
cutlim = (int) ModU64x32 ((UINT64) __wUINT_MAX, (UINT32) base);
|
||||
for (acc = 0, any = 0;; wc = (wint_t) *s++) {
|
||||
i = __wctoint((wchar_t)wc);
|
||||
if (i == -1) {
|
||||
|
@@ -137,7 +137,7 @@ wcrtomb(
|
||||
/* ps appears to be unused */
|
||||
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
return 1; /* Spec. says this should be 1. */
|
||||
|
||||
*s = (char) wchar;
|
||||
return 1;
|
||||
@@ -150,7 +150,12 @@ wctomb(
|
||||
)
|
||||
{
|
||||
|
||||
/* s may be NULL */
|
||||
/*
|
||||
If s is NULL just return if MB Characters have state
|
||||
dependent encodings.
|
||||
*/
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
|
||||
return (int)wcrtomb(s, wchar, NULL);
|
||||
}
|
||||
@@ -176,8 +181,10 @@ mbsrtowcs(
|
||||
if (n != 0) {
|
||||
if (pwcs != NULL) {
|
||||
do {
|
||||
if ((*pwcs++ = (wchar_t) *(*s)++) == 0)
|
||||
if ((*pwcs++ = (wchar_t) *(*s)++) == 0) {
|
||||
*s = NULL;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
} while (--n != 0);
|
||||
} else {
|
||||
@@ -232,8 +239,10 @@ wcsrtombs(
|
||||
|
||||
if (n != 0) {
|
||||
do {
|
||||
if ((*s++ = (char) *(*pwcs)++) == 0)
|
||||
if ((*s++ = (char) *(*pwcs)++) == 0) {
|
||||
*pwcs = NULL;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
} while (--n != 0);
|
||||
}
|
||||
@@ -266,7 +275,13 @@ btowc(int c)
|
||||
int
|
||||
wctob(wint_t c)
|
||||
{
|
||||
if (c == WEOF || c & ~0xFF)
|
||||
/* wctob needs to be consistent with wcrtomb.
|
||||
if wcrtomb says that a character is representable in 1 byte,
|
||||
which this implementation always says, then wctob needs to
|
||||
also represent the character as 1 byte.
|
||||
*/
|
||||
if (c == WEOF) {
|
||||
return EOF;
|
||||
return (int)c;
|
||||
}
|
||||
return (int)(c & 0xFF);
|
||||
}
|
||||
|
@@ -8,13 +8,14 @@
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
the terms and conditions of the BSD License that accompanies this distribution.
|
||||
The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
http://opensource.org/licenses/bsd-license.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
#include <Uefi.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#include <Library/ShellCEntryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
@@ -40,23 +41,30 @@ void __main()
|
||||
;
|
||||
}
|
||||
|
||||
static
|
||||
/** Clean up data as required by the exit() function.
|
||||
|
||||
**/
|
||||
void
|
||||
FinalCleanup( void )
|
||||
exitCleanup(INTN ExitVal)
|
||||
{
|
||||
void (*CleanUp)(void); // Pointer to Cleanup Function
|
||||
int i;
|
||||
|
||||
/* Close any open files */
|
||||
for(i = OPEN_MAX - 1; i >= 0; --i) {
|
||||
(void)close(i); // Close properly handles closing a closed file.
|
||||
if(gMD != NULL) {
|
||||
gMD->ExitValue = (int)ExitVal;
|
||||
CleanUp = gMD->cleanup; // Preserve the pointer to the Cleanup Function
|
||||
|
||||
// Call all registered atexit functions in reverse order
|
||||
i = gMD->num_atexit;
|
||||
if( i > 0) {
|
||||
do {
|
||||
(gMD->atexit_handler[--i])();
|
||||
} while( i > 0);
|
||||
}
|
||||
|
||||
/* Free the global MainData structure */
|
||||
if(gMD != NULL) {
|
||||
if(gMD->NCmdLine != NULL) {
|
||||
FreePool( gMD->NCmdLine );
|
||||
if (CleanUp != NULL) {
|
||||
CleanUp();
|
||||
}
|
||||
FreePool( gMD );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +79,13 @@ ArgvConvert(UINTN Argc, CHAR16 **Argv)
|
||||
char *string;
|
||||
INTN nArgvSize; /* Cumulative size of narrow Argv[i] */
|
||||
|
||||
DEBUG_CODE_BEGIN();
|
||||
Print(L"ArgvConvert called with %d arguments.\n", Argc);
|
||||
for(count = 0; count < ((Argc > 5)? 5: Argc); ++count) {
|
||||
Print(L"Argument[%d] = \"%s\".\n", count, Argv[count]);
|
||||
}
|
||||
DEBUG_CODE_END();
|
||||
|
||||
nArgvSize = Argc;
|
||||
/* Determine space needed for narrow Argv strings. */
|
||||
for(count = 0; count < Argc; ++count) {
|
||||
@@ -98,6 +113,7 @@ ArgvConvert(UINTN Argc, CHAR16 **Argv)
|
||||
nArgv[count] = string;
|
||||
AVsz = wcstombs(string, Argv[count], nArgvSize);
|
||||
string[AVsz] = 0; /* NULL terminate the argument */
|
||||
DEBUG((DEBUG_INFO, "Cvt[%d] %d \"%s\" --> \"%a\"\n", (INT32)count, (INT32)AVsz, Argv[count], nArgv[count]));
|
||||
string += AVsz + 1;
|
||||
nArgvSize -= AVsz + 1;
|
||||
if(nArgvSize < 0) {
|
||||
@@ -119,7 +135,7 @@ ShellAppMain (
|
||||
struct __filedes *mfd;
|
||||
char **nArgv;
|
||||
INTN ExitVal;
|
||||
INTN i;
|
||||
int i;
|
||||
|
||||
ExitVal = (INTN)RETURN_SUCCESS;
|
||||
gMD = AllocateZeroPool(sizeof(struct __MainData));
|
||||
@@ -132,7 +148,6 @@ ShellAppMain (
|
||||
_fltused = 1;
|
||||
errno = 0;
|
||||
EFIerrno = 0;
|
||||
gMD->FinalCleanup = &FinalCleanup;
|
||||
|
||||
#ifdef NT32dvm
|
||||
gMD->ClocksPerSecond = 1; // For NT32 only
|
||||
@@ -166,10 +181,33 @@ ShellAppMain (
|
||||
ExitVal = (INTN)RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
else {
|
||||
ExitVal = (INTN)main( (int)Argc, nArgv);
|
||||
if( setjmp(gMD->MainExit) == 0) {
|
||||
ExitVal = (INTN)main( (int)Argc, gMD->NArgV);
|
||||
exitCleanup(ExitVal);
|
||||
}
|
||||
/* You reach here if:
|
||||
* normal return from main()
|
||||
* call to _Exit(), either directly or through exit().
|
||||
*/
|
||||
ExitVal = (INTN)gMD->ExitValue;
|
||||
}
|
||||
|
||||
if( ExitVal == EXIT_FAILURE) {
|
||||
ExitVal = RETURN_ABORTED;
|
||||
}
|
||||
|
||||
/* Close any open files */
|
||||
for(i = OPEN_MAX - 1; i >= 0; --i) {
|
||||
(void)close(i); // Close properly handles closing a closed file.
|
||||
}
|
||||
|
||||
/* Free the global MainData structure */
|
||||
if(gMD != NULL) {
|
||||
if(gMD->NCmdLine != NULL) {
|
||||
FreePool( gMD->NCmdLine );
|
||||
}
|
||||
FreePool( gMD );
|
||||
}
|
||||
}
|
||||
exit((int)ExitVal);
|
||||
/* Not Reached */
|
||||
return ExitVal;
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
void
|
||||
EFIAPI
|
||||
__assert(const char *func, const char *file, int line, const char *failedexpr)
|
||||
{
|
||||
if (func == NULL)
|
||||
|
@@ -16,7 +16,6 @@ extern int internal_FPU_rmode( void );
|
||||
static INT8 rmode[] = { 1, 3, 2, 0 };
|
||||
|
||||
int
|
||||
EFIAPI
|
||||
__flt_rounds ( void )
|
||||
{
|
||||
return rmode[ internal_FPU_rmode() ];
|
||||
|
@@ -48,12 +48,3 @@
|
||||
LibStdLib
|
||||
LibStdio
|
||||
LibString
|
||||
|
||||
################################################################
|
||||
#
|
||||
# The Build Options, below, are only used when building the Socket library.
|
||||
# DO NOT use them when building your application!
|
||||
# Nasty things could happen if you do.
|
||||
#
|
||||
#[BuildOptions]
|
||||
# MSFT:*_*_IA32_CC_FLAGS = /GL-
|
||||
|
@@ -29,6 +29,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <MainData.h>
|
||||
|
||||
/** Internal worker function used by exit().
|
||||
**/
|
||||
void exitCleanup(INTN ExitVal);
|
||||
|
||||
/* ################# Public Functions ################################### */
|
||||
|
||||
/** The abort function causes abnormal program termination to occur, unless
|
||||
@@ -92,24 +96,7 @@ atexit(void (*handler)(void))
|
||||
void
|
||||
exit(int status)
|
||||
{
|
||||
void (*CleanUp)(void); // Pointer to Cleanup Function
|
||||
int i;
|
||||
|
||||
if(gMD != NULL) {
|
||||
CleanUp = gMD->cleanup; // Preserve the pointer to the Cleanup Function
|
||||
|
||||
// Call all registered atexit functions in reverse order
|
||||
i = gMD->num_atexit;
|
||||
if( i > 0) {
|
||||
do {
|
||||
(gMD->atexit_handler[--i])();
|
||||
} while( i > 0);
|
||||
}
|
||||
|
||||
if (CleanUp != NULL) {
|
||||
CleanUp();
|
||||
}
|
||||
}
|
||||
exitCleanup((INTN) status);
|
||||
_Exit(status);
|
||||
}
|
||||
|
||||
@@ -129,17 +116,12 @@ exit(int status)
|
||||
void
|
||||
_Exit(int status)
|
||||
{
|
||||
RETURN_STATUS ExitVal = (RETURN_STATUS)status;
|
||||
gMD->ExitValue = status; // Save our exit status. Allows a status of 0.
|
||||
longjmp(gMD->MainExit, 0x55); // Get out of here. longjmp can't return 0. Use 0x55 for a non-zero value.
|
||||
|
||||
if( ExitVal == EXIT_FAILURE) {
|
||||
ExitVal = RETURN_ABORTED;
|
||||
}
|
||||
|
||||
if(gMD->FinalCleanup != NULL) {
|
||||
gMD->FinalCleanup(); // gMD does not exist when this returns.
|
||||
}
|
||||
|
||||
gBS->Exit(gImageHandle, ExitVal, 0, NULL); /* abort() */
|
||||
#ifdef __GNUC__
|
||||
__builtin__Exit(status); /* Keep GCC happy - never reached */
|
||||
#endif
|
||||
}
|
||||
|
||||
/** If string is a null pointer, the system function determines whether the
|
||||
|
@@ -8,7 +8,7 @@
|
||||
- atol: strtol(nptr, (char **)NULL, 10)
|
||||
- atoll: strtoll(nptr, (char **)NULL, 10)
|
||||
|
||||
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
the terms and conditions of the BSD License that accompanies this distribution.
|
||||
The full text of the license may be found at
|
||||
@@ -120,7 +120,7 @@ atoll(const char *nptr)
|
||||
static int
|
||||
Digit2Val( int c)
|
||||
{
|
||||
if(__isHexLetter(c)) { /* If c is one of [A-Fa-f]... */
|
||||
if(isalpha(c)) { /* If c is one of [A-Za-z]... */
|
||||
c = toupper(c) - 7; // Adjust so 'A' is ('9' + 1)
|
||||
}
|
||||
return c - '0'; // Value returned is between 0 and 35, inclusive.
|
||||
@@ -183,13 +183,18 @@ Digit2Val( int c)
|
||||
long
|
||||
strtol(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
{
|
||||
const char *pEnd;
|
||||
long Result = 0;
|
||||
long Previous;
|
||||
int temp;
|
||||
BOOLEAN Negative = FALSE;
|
||||
|
||||
pEnd = nptr;
|
||||
|
||||
if((base < 0) || (base == 1) || (base > 36)) {
|
||||
if(endptr != NULL) {
|
||||
*endptr = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// Skip leading spaces.
|
||||
@@ -204,9 +209,29 @@ strtol(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
Negative = TRUE;
|
||||
++nptr;
|
||||
}
|
||||
if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {
|
||||
nptr += 2;
|
||||
|
||||
if(*nptr == '0') { /* Might be Octal or Hex */
|
||||
if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
|
||||
if((base == 0) || (base == 16)) {
|
||||
nptr += 2; /* Skip the "0X" */
|
||||
base = 16; /* In case base was 0 */
|
||||
}
|
||||
}
|
||||
else { /* Looks like Octal */
|
||||
if((base == 0) || (base == 8)) {
|
||||
++nptr; /* Skip the leading "0" */
|
||||
base = 8; /* In case base was 0 */
|
||||
}
|
||||
}
|
||||
}
|
||||
if(base == 0) { /* If still zero then must be decimal */
|
||||
base = 10;
|
||||
}
|
||||
if(*nptr == '0') {
|
||||
for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
|
||||
pEnd = nptr;
|
||||
}
|
||||
|
||||
while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
|
||||
Previous = Result;
|
||||
Result = (Result * base) + (long int)temp;
|
||||
@@ -221,15 +246,15 @@ strtol(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
errno = ERANGE;
|
||||
break;
|
||||
}
|
||||
++nptr;
|
||||
pEnd = ++nptr;
|
||||
}
|
||||
if(Negative) {
|
||||
Result = -Result;
|
||||
}
|
||||
|
||||
// Save pointer to final sequence
|
||||
if( endptr != NULL) {
|
||||
*endptr = (char *)nptr;
|
||||
if(endptr != NULL) {
|
||||
*endptr = (char *)pEnd;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
@@ -247,12 +272,17 @@ strtol(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
unsigned long
|
||||
strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
{
|
||||
const char *pEnd;
|
||||
unsigned long Result = 0;
|
||||
unsigned long Previous;
|
||||
int temp;
|
||||
|
||||
pEnd = nptr;
|
||||
|
||||
if((base < 0) || (base == 1) || (base > 36)) {
|
||||
if(endptr != NULL) {
|
||||
*endptr = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// Skip leading spaces.
|
||||
@@ -262,9 +292,29 @@ strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
if(*nptr == '+') {
|
||||
++nptr;
|
||||
}
|
||||
if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {
|
||||
nptr += 2;
|
||||
|
||||
if(*nptr == '0') { /* Might be Octal or Hex */
|
||||
if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
|
||||
if((base == 0) || (base == 16)) {
|
||||
nptr += 2; /* Skip the "0X" */
|
||||
base = 16; /* In case base was 0 */
|
||||
}
|
||||
}
|
||||
else { /* Looks like Octal */
|
||||
if((base == 0) || (base == 8)) {
|
||||
++nptr; /* Skip the leading "0" */
|
||||
base = 8; /* In case base was 0 */
|
||||
}
|
||||
}
|
||||
}
|
||||
if(base == 0) { /* If still zero then must be decimal */
|
||||
base = 10;
|
||||
}
|
||||
if(*nptr == '0') {
|
||||
for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
|
||||
pEnd = nptr;
|
||||
}
|
||||
|
||||
while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
|
||||
Previous = Result;
|
||||
Result = (Result * base) + (unsigned long)temp;
|
||||
@@ -273,12 +323,12 @@ strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
errno = ERANGE;
|
||||
break;
|
||||
}
|
||||
++nptr;
|
||||
pEnd = ++nptr;
|
||||
}
|
||||
|
||||
// Save pointer to final sequence
|
||||
if( endptr != NULL) {
|
||||
*endptr = (char *)nptr;
|
||||
if(endptr != NULL) {
|
||||
*endptr = (char *)pEnd;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
@@ -297,13 +347,18 @@ strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
long long
|
||||
strtoll(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
{
|
||||
const char *pEnd;
|
||||
long long Result = 0;
|
||||
long long Previous;
|
||||
int temp;
|
||||
BOOLEAN Negative = FALSE;
|
||||
|
||||
pEnd = nptr;
|
||||
|
||||
if((base < 0) || (base == 1) || (base > 36)) {
|
||||
if(endptr != NULL) {
|
||||
*endptr = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// Skip leading spaces.
|
||||
@@ -318,9 +373,29 @@ strtoll(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
Negative = TRUE;
|
||||
++nptr;
|
||||
}
|
||||
if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {
|
||||
nptr += 2;
|
||||
|
||||
if(*nptr == '0') { /* Might be Octal or Hex */
|
||||
if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
|
||||
if((base == 0) || (base == 16)) {
|
||||
nptr += 2; /* Skip the "0X" */
|
||||
base = 16; /* In case base was 0 */
|
||||
}
|
||||
}
|
||||
else { /* Looks like Octal */
|
||||
if((base == 0) || (base == 8)) {
|
||||
++nptr; /* Skip the leading "0" */
|
||||
base = 8; /* In case base was 0 */
|
||||
}
|
||||
}
|
||||
}
|
||||
if(base == 0) { /* If still zero then must be decimal */
|
||||
base = 10;
|
||||
}
|
||||
if(*nptr == '0') {
|
||||
for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
|
||||
pEnd = nptr;
|
||||
}
|
||||
|
||||
while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
|
||||
Previous = Result;
|
||||
Result = (Result * base) + (long long int)temp;
|
||||
@@ -335,15 +410,15 @@ strtoll(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
errno = ERANGE;
|
||||
break;
|
||||
}
|
||||
++nptr;
|
||||
pEnd = ++nptr;
|
||||
}
|
||||
if(Negative) {
|
||||
Result = -Result;
|
||||
}
|
||||
|
||||
// Save pointer to final sequence
|
||||
if( endptr != NULL) {
|
||||
*endptr = (char *)nptr;
|
||||
if(endptr != NULL) {
|
||||
*endptr = (char *)pEnd;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
@@ -361,12 +436,17 @@ strtoll(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
unsigned long long
|
||||
strtoull(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
{
|
||||
const char *pEnd;
|
||||
unsigned long long Result = 0;
|
||||
unsigned long long Previous;
|
||||
int temp;
|
||||
|
||||
pEnd = nptr;
|
||||
|
||||
if((base < 0) || (base == 1) || (base > 36)) {
|
||||
if(endptr != NULL) {
|
||||
*endptr = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// Skip leading spaces.
|
||||
@@ -376,9 +456,29 @@ strtoull(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
if(*nptr == '+') {
|
||||
++nptr;
|
||||
}
|
||||
if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {
|
||||
nptr += 2;
|
||||
|
||||
if(*nptr == '0') { /* Might be Octal or Hex */
|
||||
if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
|
||||
if((base == 0) || (base == 16)) {
|
||||
nptr += 2; /* Skip the "0X" */
|
||||
base = 16; /* In case base was 0 */
|
||||
}
|
||||
}
|
||||
else { /* Looks like Octal */
|
||||
if((base == 0) || (base == 8)) {
|
||||
++nptr; /* Skip the leading "0" */
|
||||
base = 8; /* In case base was 0 */
|
||||
}
|
||||
}
|
||||
}
|
||||
if(base == 0) { /* If still zero then must be decimal */
|
||||
base = 10;
|
||||
}
|
||||
if(*nptr == '0') {
|
||||
for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
|
||||
pEnd = nptr;
|
||||
}
|
||||
|
||||
while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
|
||||
Previous = Result;
|
||||
Result = (Result * base) + (unsigned long long)temp;
|
||||
@@ -387,12 +487,12 @@ strtoull(const char * __restrict nptr, char ** __restrict endptr, int base)
|
||||
errno = ERANGE;
|
||||
break;
|
||||
}
|
||||
++nptr;
|
||||
pEnd = ++nptr;
|
||||
}
|
||||
|
||||
// Save pointer to final sequence
|
||||
if( endptr != NULL) {
|
||||
*endptr = (char *)nptr;
|
||||
if(endptr != NULL) {
|
||||
*endptr = (char *)pEnd;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# Standard C library: StdLib implementations.
|
||||
#
|
||||
# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
@@ -36,6 +36,8 @@
|
||||
strtoumax.c
|
||||
Xabs.c
|
||||
Xdiv.c
|
||||
realpath.c
|
||||
setprogname.c
|
||||
|
||||
[Packages]
|
||||
StdLib/StdLib.dec
|
||||
@@ -53,6 +55,7 @@
|
||||
LibC
|
||||
LibCType
|
||||
LibSignal
|
||||
PathLib
|
||||
|
||||
################################################################
|
||||
#
|
||||
|
57
StdLib/LibC/StdLib/realpath.c
Normal file
57
StdLib/LibC/StdLib/realpath.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/** @file
|
||||
Implement the realpath function.
|
||||
|
||||
Copyright (c) 2011, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <LibConfig.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/PathLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <errno.h>
|
||||
|
||||
/**
|
||||
The realpath() function shall derive, from the pathname pointed to by
|
||||
file_name, an absolute pathname that names the same file, whose resolution
|
||||
does not involve '.', '..', or symbolic links. The generated pathname shall
|
||||
be stored as a null-terminated string, up to a maximum of {PATH_MAX} bytes,
|
||||
in the buffer pointed to by resolved_name.
|
||||
|
||||
If resolved_name is a null pointer, the behavior of realpath() is
|
||||
implementation-defined.
|
||||
|
||||
@param[in] file_name The filename to convert.
|
||||
@param[in,out] resolved_name The resultant name.
|
||||
|
||||
@retval NULL An error occured.
|
||||
@return resolved_name.
|
||||
**/
|
||||
char *
|
||||
realpath(
|
||||
char *file_name,
|
||||
char *resolved_name
|
||||
)
|
||||
{
|
||||
CHAR16 *Temp;
|
||||
if (file_name == NULL || resolved_name == NULL) {
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
Temp = AllocateZeroPool((1+AsciiStrLen(file_name))*sizeof(CHAR16));
|
||||
if (Temp == NULL) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
AsciiStrToUnicodeStr(file_name, Temp);
|
||||
PathCleanUpDirectories(Temp);
|
||||
UnicodeStrToAsciiStr(Temp, resolved_name);
|
||||
return (resolved_name);
|
||||
}
|
64
StdLib/LibC/StdLib/setprogname.c
Normal file
64
StdLib/LibC/StdLib/setprogname.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/** @file setprogname and getprogname
|
||||
|
||||
$NetBSD: setprogname.c,v 1.5 2008/04/28 20:24:12 martin Exp $
|
||||
|
||||
Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Todd Vierling.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <LibConfig.h>
|
||||
|
||||
#ifndef HAVE_SETPROGNAME
|
||||
#include <string.h>
|
||||
|
||||
static const char *__progname = NULL;
|
||||
|
||||
void
|
||||
setprogname(const char *progname)
|
||||
{
|
||||
__progname = strrchr(progname, '/');
|
||||
if (__progname == NULL)
|
||||
__progname = progname;
|
||||
else
|
||||
__progname++;
|
||||
}
|
||||
|
||||
const char *
|
||||
getprogname(void)
|
||||
{
|
||||
return __progname;
|
||||
}
|
||||
|
||||
#endif
|
@@ -48,6 +48,8 @@ __RCSID("$NetBSD: strtoumax.c,v 1.1 2006/04/22 15:33:33 thorpej Exp $");
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(strtoumax, _strtoumax)
|
||||
#endif
|
||||
@@ -98,8 +100,8 @@ strtoumax(const char *nptr, char **endptr, int base)
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
|
||||
cutoff = UINTMAX_MAX / (uintmax_t)base;
|
||||
cutlim = (int)(UINTMAX_MAX % (uintmax_t)base);
|
||||
cutoff = DivU64x32 ((UINT64) UINTMAX_MAX, (UINT32) base);
|
||||
cutlim = (int) ModU64x32 ((UINT64) UINTMAX_MAX, (UINT32) base);
|
||||
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
|
@@ -72,6 +72,7 @@
|
||||
|
||||
snprintf.c
|
||||
vsnprintf.c
|
||||
fparseln.c
|
||||
|
||||
# Wide character functions
|
||||
fgetwc.c #
|
||||
|
@@ -104,7 +104,7 @@ freopen(const char *file, const char *mode, FILE *fp)
|
||||
(void) __sflush(fp);
|
||||
/* if close is NULL, closing is a no-op, hence pointless */
|
||||
isopen = fp->_close != NULL;
|
||||
if ((wantfd = fp->_file) < 0 && isopen) {
|
||||
if (((wantfd = fp->_file) >= 0) && isopen) {
|
||||
(void) (*fp->_close)(fp->_cookie);
|
||||
isopen = 0;
|
||||
}
|
||||
@@ -127,7 +127,7 @@ freopen(const char *file, const char *mode, FILE *fp)
|
||||
* keep fp->_base: it may be the wrong size. This loses the effect
|
||||
* of any setbuffer calls, but stdio has always done this before.
|
||||
*/
|
||||
if (isopen && f != wantfd)
|
||||
if (isopen && (f != wantfd))
|
||||
(void) (*fp->_close)(fp->_cookie);
|
||||
if (fp->_flags & __SMBF)
|
||||
free((char *)fp->_bf._base);
|
||||
|
@@ -238,6 +238,7 @@ fseeko(FILE *fp, off_t offset, int whence)
|
||||
fp->_r = (int)(n - o);
|
||||
if (HASUB(fp))
|
||||
FREEUB(fp);
|
||||
WCIO_FREE(fp); /* Should this really be unconditional??? */
|
||||
fp->_flags &= ~__SEOF;
|
||||
FUNLOCKFILE(fp);
|
||||
return (0);
|
||||
@@ -261,6 +262,7 @@ fseeko(FILE *fp, off_t offset, int whence)
|
||||
fp->_p = fp->_bf._base;
|
||||
if (HASUB(fp))
|
||||
FREEUB(fp);
|
||||
WCIO_FREE(fp); /* Should this really be unconditional??? */
|
||||
fp->_flags &= ~__SEOF;
|
||||
n = (int)(target - curoff);
|
||||
if (n) {
|
||||
@@ -290,9 +292,10 @@ dumb:
|
||||
/* success: clear EOF indicator and discard ungetc() data */
|
||||
if (HASUB(fp))
|
||||
FREEUB(fp);
|
||||
WCIO_FREE(fp); /* Should this really be unconditional??? */
|
||||
fp->_p = fp->_bf._base;
|
||||
fp->_r = 0;
|
||||
/* fp->_w = 0; */ /* unnecessary (I think...) */
|
||||
fp->_w = 0;
|
||||
fp->_flags &= ~__SEOF;
|
||||
FUNLOCKFILE(fp);
|
||||
//Print(L"%a: %d\n", __func__, __LINE__);
|
||||
|
@@ -45,7 +45,7 @@
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#if !HAVE_NBTOOL_CONFIG_H || !HAVE_MKSTEMP || !HAVE_MKDTEMP
|
||||
#if !defined(HAVE_NBTOOL_CONFIG_H) || !defined(HAVE_MKSTEMP) || !defined(HAVE_MKDTEMP)
|
||||
|
||||
#include <sys/EfiCdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
|
@@ -64,11 +64,11 @@ extern int _fwalk(int (*)(FILE *));
|
||||
extern char *_mktemp(char *);
|
||||
extern int __swsetup(FILE *);
|
||||
extern int __sflags(const char *, int *);
|
||||
extern int __svfscanf(FILE * __restrict, const char * __restrict, _BSD_VA_LIST_)
|
||||
extern int __svfscanf(FILE * __restrict, const char * __restrict, va_list)
|
||||
__attribute__((__format__(__scanf__, 2, 0)));
|
||||
extern int __svfscanf_unlocked(FILE * __restrict, const char * __restrict, _BSD_VA_LIST_)
|
||||
extern int __svfscanf_unlocked(FILE * __restrict, const char * __restrict, va_list)
|
||||
__attribute__((__format__(__scanf__, 2, 0)));
|
||||
extern int __vfprintf_unlocked(FILE * __restrict, const char * __restrict, _BSD_VA_LIST_);
|
||||
extern int __vfprintf_unlocked(FILE * __restrict, const char * __restrict, va_list);
|
||||
|
||||
|
||||
extern int __sdidinit;
|
||||
@@ -80,8 +80,8 @@ extern wint_t __fputwc_unlock(wchar_t, FILE *);
|
||||
|
||||
extern char *__fgetstr(FILE * __restrict, size_t * __restrict, int);
|
||||
extern int __slbexpand(FILE *, size_t);
|
||||
extern int __vfwprintf_unlocked(FILE *, const wchar_t *, _BSD_VA_LIST_);
|
||||
extern int __vfwscanf_unlocked(FILE * __restrict, const wchar_t * __restrict, _BSD_VA_LIST_);
|
||||
extern int __vfwprintf_unlocked(FILE *, const wchar_t *, va_list);
|
||||
extern int __vfwscanf_unlocked(FILE * __restrict, const wchar_t * __restrict, va_list);
|
||||
|
||||
/*
|
||||
* Return true iff the given FILE cannot be written now.
|
||||
|
@@ -34,7 +34,7 @@
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#if !HAVE_NBTOOL_CONFIG_H || !HAVE_MKSTEMP
|
||||
#if !defined(HAVE_NBTOOL_CONFIG_H) || !defined(HAVE_MKSTEMP)
|
||||
|
||||
#include <sys/EfiCdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
|
@@ -1,6 +1,13 @@
|
||||
/* $NetBSD: setbuffer.c,v 1.10 2003/08/07 16:43:31 agc Exp $ */
|
||||
/*
|
||||
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials are licensed and made available
|
||||
under the terms and conditions of the BSD License that accompanies this
|
||||
distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@@ -30,16 +37,12 @@
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
NetBSD: setbuffer.c,v 1.10 2003/08/07 16:43:31 agc Exp
|
||||
setbuffer.c 8.1 (Berkeley) 6/4/93
|
||||
*/
|
||||
#include <LibConfig.h>
|
||||
#include <sys/EfiCdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)setbuffer.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: setbuffer.c,v 1.10 2003/08/07 16:43:31 agc Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
@@ -1056,8 +1056,6 @@ reswitch: switch (ch) {
|
||||
xdigs = xdigs_upper;
|
||||
expchar = 'P';
|
||||
}
|
||||
if (prec >= 0)
|
||||
prec++;
|
||||
if (flags & LONGDBL) {
|
||||
fparg.ldbl = GETARG(long double);
|
||||
dtoaresult =
|
||||
@@ -1092,10 +1090,8 @@ reswitch: switch (ch) {
|
||||
case 'e':
|
||||
case 'E':
|
||||
expchar = ch;
|
||||
if (prec < 0) /* account for digit before decpt */
|
||||
prec = DEFPREC + 1;
|
||||
else
|
||||
prec++;
|
||||
if (prec < 0)
|
||||
prec = DEFPREC;
|
||||
goto fp_begin;
|
||||
case 'f':
|
||||
case 'F':
|
||||
@@ -1165,10 +1161,8 @@ fp_common:
|
||||
case 'e':
|
||||
case 'E':
|
||||
expchar = ch;
|
||||
if (prec < 0) /* account for digit before decpt */
|
||||
prec = DEFPREC /* + 1*/ ;
|
||||
else
|
||||
prec++;
|
||||
if (prec < 0)
|
||||
prec = DEFPREC;
|
||||
goto fp_begin;
|
||||
case 'f':
|
||||
case 'F':
|
||||
@@ -1242,16 +1236,21 @@ fp_begin:
|
||||
/*
|
||||
* Make %[gG] smell like %[eE], but
|
||||
* trim trailing zeroes if no # flag.
|
||||
*
|
||||
* Note: The precision field used with [gG] is the number significant
|
||||
* digits to print. When converting to [eE] the digit before the
|
||||
* decimal must not be included in the precision value.
|
||||
*/
|
||||
if (!(flags & ALT))
|
||||
prec = ndig;
|
||||
prec = ndig - 1;
|
||||
}
|
||||
}
|
||||
if (expchar) {
|
||||
dprec = prec; /* In some cases dprec will not be set. Make sure it is set now */
|
||||
expsize = exponent(expstr, expt - 1, expchar);
|
||||
size = expsize + prec;
|
||||
if (prec > 1 || flags & ALT)
|
||||
++size;
|
||||
size = expsize + prec + 1; /* Leading digit + exponent string + precision */
|
||||
if (prec >= 1 || flags & ALT)
|
||||
++size; /* Decimal point is added to character count */
|
||||
} else {
|
||||
/* space for digits before decimal point */
|
||||
if (expt > 0)
|
||||
@@ -1322,7 +1321,7 @@ fp_begin:
|
||||
* defined manner.''
|
||||
* -- ANSI X3J11
|
||||
*/
|
||||
ujval = (uintmax_t)GETARG(void *);
|
||||
ujval = (uintmax_t) (UINTN) GETARG(void *);
|
||||
base = 16;
|
||||
xdigs = xdigs_lower;
|
||||
flags = flags | INTMAXT;
|
||||
@@ -1332,7 +1331,7 @@ fp_begin:
|
||||
flags |= LONGINT;
|
||||
/*FALLTHROUGH*/
|
||||
case 's':
|
||||
if ((flags & LONGINT) != MULTI) {
|
||||
if (((flags & LONGINT) ? 1:0) != MULTI) {
|
||||
if ((result = GETARG(CHAR_T *)) == NULL)
|
||||
result = STRCONST("(null)");
|
||||
} else {
|
||||
@@ -1538,7 +1537,7 @@ number: if ((dprec = prec) >= 0)
|
||||
PRINTANDPAD(result, convbuf + ndig, prec,
|
||||
zeroes);
|
||||
} else { /* %[eE] or sufficiently long %[gG] */
|
||||
if (prec > 1 || flags & ALT) {
|
||||
if (prec >= 1 || flags & ALT) {
|
||||
buf[0] = *result++;
|
||||
buf[1] = *decimal_point;
|
||||
PRINT(buf, 2);
|
||||
@@ -2003,8 +2002,6 @@ cvt(double value, int ndigits, int flags, char *sign, int *decpt, int ch,
|
||||
*decpt = -ndigits + 1;
|
||||
bp += *decpt;
|
||||
}
|
||||
if (value == 0) /* kludge for __dtoa irregularity */
|
||||
rve = bp;
|
||||
while (rve < bp)
|
||||
*rve++ = '0';
|
||||
}
|
||||
|
@@ -198,7 +198,7 @@ literal:
|
||||
goto input_failure;
|
||||
if (wi != c) {
|
||||
ungetwc(wi, fp);
|
||||
goto input_failure;
|
||||
goto match_failure;
|
||||
}
|
||||
nread++;
|
||||
continue;
|
||||
@@ -721,20 +721,19 @@ literal:
|
||||
if ((width = parsefloat(fp, buf, buf + width)) == 0)
|
||||
goto match_failure;
|
||||
if ((flags & SUPPRESS) == 0) {
|
||||
#ifdef notyet
|
||||
#ifdef REAL_LONG_DOUBLE_SUPPORT
|
||||
if (flags & LONGDBL) {
|
||||
long double res = wcstold(buf, &p);
|
||||
*va_arg(ap, long double *) = res;
|
||||
} else
|
||||
#endif
|
||||
if (flags & LONG) {
|
||||
if (flags & (LONG | LONGDBL)) {
|
||||
double res = wcstod(buf, &p);
|
||||
*va_arg(ap, double *) = res;
|
||||
#ifdef notyet
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
float res = wcstof(buf, &p);
|
||||
*va_arg(ap, float *) = res;
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (p - buf != width)
|
||||
|
@@ -50,7 +50,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
vprintf(char const *fmt, _BSD_VA_LIST_ ap)
|
||||
vprintf(char const *fmt, va_list ap)
|
||||
{
|
||||
_DIAGASSERT(fmt != NULL);
|
||||
|
||||
|
@@ -54,7 +54,7 @@ __weak_alias(vsnprintf,_vsnprintf)
|
||||
#endif
|
||||
|
||||
int
|
||||
vsnprintf(char *str, size_t n, const char *fmt, _BSD_VA_LIST_ ap)
|
||||
vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
|
||||
{
|
||||
int ret;
|
||||
FILE f;
|
||||
|
@@ -117,7 +117,7 @@ __weak_alias(vsnprintf_ss,_vsnprintf_ss)
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
int
|
||||
vsnprintf_ss(char *sbuf, size_t slen, const char *fmt0, _BSD_VA_LIST_ ap)
|
||||
vsnprintf_ss(char *sbuf, size_t slen, const char *fmt0, va_list ap)
|
||||
{
|
||||
const char *fmt; /* format string */
|
||||
int ch; /* character from fmt */
|
||||
|
@@ -53,7 +53,7 @@
|
||||
#include "local.h"
|
||||
|
||||
int
|
||||
vsprintf(char *str, const char *fmt, _BSD_VA_LIST_ ap)
|
||||
vsprintf(char *str, const char *fmt, va_list ap)
|
||||
{
|
||||
int ret;
|
||||
FILE f;
|
||||
|
@@ -109,10 +109,15 @@ strcasecmp(const char *s1, const char *s2)
|
||||
{
|
||||
const unsigned char *us1 = (const unsigned char *)s1,
|
||||
*us2 = (const unsigned char *)s2;
|
||||
int Difference;
|
||||
|
||||
while (tolower(*us1) == tolower(*us2++))
|
||||
if (*us1++ == '\0')
|
||||
while ( 0 == ( Difference = tolower(*us1) - tolower(*us2))) {
|
||||
if (*us1 == 0) {
|
||||
return (0);
|
||||
return (tolower(*us1) - tolower(*--us2));
|
||||
}
|
||||
us1 += 1;
|
||||
us2 += 1;
|
||||
}
|
||||
return Difference;
|
||||
}
|
||||
|
||||
|
@@ -33,6 +33,9 @@
|
||||
Searching.c
|
||||
ErrorList.c
|
||||
strncasecmp.c
|
||||
strlcpy.c
|
||||
strlcat.c
|
||||
strsep.c
|
||||
|
||||
[Packages]
|
||||
StdLib/StdLib.dec
|
||||
|
86
StdLib/LibC/String/strlcat.c
Normal file
86
StdLib/LibC/String/strlcat.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/* $NetBSD: strlcat.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */
|
||||
/* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
|
||||
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <LibConfig.h>
|
||||
|
||||
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: strlcat.c,v 1.3 2007/06/04 18:19:27 christos Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#ifdef _LIBC
|
||||
#include "namespace.h"
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
# ifdef __weak_alias
|
||||
__weak_alias(strlcat, _strlcat)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
#include <lib/libkern/libkern.h>
|
||||
#endif /* !_KERNEL && !_STANDALONE */
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
/*
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
* full size of dst, not space left). At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||||
* If retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcat(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
size_t dlen;
|
||||
|
||||
_DIAGASSERT(dst != NULL);
|
||||
_DIAGASSERT(src != NULL);
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return(dlen + strlen(s));
|
||||
while (*s != '\0') {
|
||||
if (n != 1) {
|
||||
*d++ = *s;
|
||||
n--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
return(dlen + (s - src)); /* count does not include NUL */
|
||||
}
|
||||
#endif
|
82
StdLib/LibC/String/strlcpy.c
Normal file
82
StdLib/LibC/String/strlcpy.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/* $NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */
|
||||
/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
|
||||
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <LibConfig.h>
|
||||
|
||||
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#ifdef _LIBC
|
||||
#include "namespace.h"
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
# ifdef __weak_alias
|
||||
__weak_alias(strlcpy, _strlcpy)
|
||||
# endif
|
||||
#endif
|
||||
#else
|
||||
#include <lib/libkern/libkern.h>
|
||||
#endif /* !_KERNEL && !_STANDALONE */
|
||||
|
||||
|
||||
#if !HAVE_STRLCPY
|
||||
/*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz == 0).
|
||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcpy(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
|
||||
_DIAGASSERT(dst != NULL);
|
||||
_DIAGASSERT(src != NULL);
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0 && --n != 0) {
|
||||
do {
|
||||
if ((*d++ = *s++) == 0)
|
||||
break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0) {
|
||||
if (siz != 0)
|
||||
*d = '\0'; /* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
|
||||
return(s - src - 1); /* count does not include NUL */
|
||||
}
|
||||
#endif
|
@@ -40,7 +40,6 @@
|
||||
$NetBSD: strncasecmp.c,v 1.2 2007/06/04 18:19:27 christos Exp $
|
||||
strcasecmp.c 8.1 (Berkeley) 6/4/93
|
||||
**/
|
||||
|
||||
#include <LibConfig.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
|
82
StdLib/LibC/String/strsep.c
Normal file
82
StdLib/LibC/String/strsep.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include <LibConfig.h>
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/*
|
||||
* Get next token from string *stringp, where tokens are possibly-empty
|
||||
* strings separated by characters from delim.
|
||||
*
|
||||
* Writes NULs into the string at *stringp to end tokens.
|
||||
* delim need not remain constant from call to call.
|
||||
* On return, *stringp points past the last NUL written (if there might
|
||||
* be further tokens), or is NULL (if there are definitely no more tokens).
|
||||
*
|
||||
* If *stringp is NULL, strsep returns NULL.
|
||||
*/
|
||||
char *
|
||||
strsep(
|
||||
register char **stringp,
|
||||
register const char *delim
|
||||
)
|
||||
{
|
||||
register char *s;
|
||||
register const char *spanp;
|
||||
register int c, sc;
|
||||
char *tok;
|
||||
|
||||
if ((s = *stringp) == NULL)
|
||||
return (NULL);
|
||||
for (tok = s;;) {
|
||||
c = *s++;
|
||||
spanp = delim;
|
||||
do {
|
||||
if ((sc = *spanp++) == c) {
|
||||
if (c == 0)
|
||||
s = NULL;
|
||||
else
|
||||
s[-1] = 0;
|
||||
*stringp = s;
|
||||
return (tok);
|
||||
}
|
||||
} while (sc != 0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
@@ -82,7 +82,6 @@ static void
|
||||
localsub(const time_t * const timep, const long offset, struct tm * const tmp);
|
||||
|
||||
clock_t
|
||||
EFIAPI
|
||||
__getCPS(void)
|
||||
{
|
||||
return gMD->ClocksPerSecond;
|
||||
@@ -183,7 +182,7 @@ timesub(
|
||||
|
||||
/** The clock function determines the processor time used.
|
||||
|
||||
@return The clock function returns the implementation<EFBFBD>s best
|
||||
@return The clock function returns the implementation's best
|
||||
approximation to the processor time used by the program since the
|
||||
beginning of an implementation-defined era related only to the
|
||||
program invocation. To determine the time in seconds, the value
|
||||
@@ -196,7 +195,6 @@ timesub(
|
||||
CPU TimeStamp Counter ticks since the appliation started.
|
||||
**/
|
||||
clock_t
|
||||
EFIAPI
|
||||
clock(void)
|
||||
{
|
||||
#ifndef NT32dvm
|
||||
@@ -213,7 +211,6 @@ clock(void)
|
||||
/**
|
||||
**/
|
||||
double
|
||||
EFIAPI
|
||||
difftime(time_t time1, time_t time0)
|
||||
{
|
||||
return (double)(time1 - time0);
|
||||
@@ -429,7 +426,7 @@ time2sub(
|
||||
return t;
|
||||
}
|
||||
|
||||
static time_t
|
||||
time_t
|
||||
time2(struct tm * const tmp, void (* const funcp)(const time_t*, long, struct tm*),
|
||||
const long offset, int * const okayp)
|
||||
{
|
||||
@@ -542,7 +539,6 @@ time1(
|
||||
represented, the function returns the value (time_t)(-1).
|
||||
**/
|
||||
time_t
|
||||
EFIAPI
|
||||
mktime(struct tm *timeptr)
|
||||
{
|
||||
/* From NetBSD */
|
||||
@@ -558,14 +554,13 @@ mktime(struct tm *timeptr)
|
||||
/** The time function determines the current calendar time. The encoding of
|
||||
the value is unspecified.
|
||||
|
||||
@return The time function returns the implementation<EFBFBD>s best approximation
|
||||
@return The time function returns the implementation's best approximation
|
||||
to the current calendar time. The value (time_t)(-1) is returned
|
||||
if the calendar time is not available. If timer is not a null
|
||||
pointer, the return value is also assigned to the object it
|
||||
points to.
|
||||
**/
|
||||
time_t
|
||||
EFIAPI
|
||||
time(time_t *timer)
|
||||
{
|
||||
time_t CalTime;
|
||||
@@ -633,7 +628,6 @@ time(time_t *timer)
|
||||
@return The asctime function returns a pointer to the string.
|
||||
**/
|
||||
char *
|
||||
EFIAPI
|
||||
asctime(const struct tm *timeptr)
|
||||
{
|
||||
register const char * wn;
|
||||
@@ -663,7 +657,6 @@ asctime(const struct tm *timeptr)
|
||||
/**
|
||||
**/
|
||||
char *
|
||||
EFIAPI
|
||||
ctime(const time_t *timer)
|
||||
{
|
||||
return asctime(localtime(timer));
|
||||
@@ -672,7 +665,7 @@ ctime(const time_t *timer)
|
||||
/*
|
||||
** gmtsub is to gmtime as localsub is to localtime.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
gmtsub(
|
||||
const time_t * const timep,
|
||||
const long offset,
|
||||
@@ -718,7 +711,6 @@ gmtsub(
|
||||
/**
|
||||
**/
|
||||
struct tm *
|
||||
EFIAPI
|
||||
gmtime(const time_t *timer)
|
||||
{
|
||||
gmtsub(timer, 0L, &gMD->BDTime);
|
||||
@@ -771,7 +763,6 @@ localsub(const time_t * const timep, const long offset, struct tm * const tmp)
|
||||
/**
|
||||
**/
|
||||
struct tm *
|
||||
EFIAPI
|
||||
localtime(const time_t *timer)
|
||||
{
|
||||
tzset();
|
||||
|
@@ -32,6 +32,8 @@
|
||||
strptime.c
|
||||
TimeEfi.c
|
||||
gettimeofday.c
|
||||
timegm.c
|
||||
itimer.c
|
||||
|
||||
[Packages]
|
||||
StdLib/StdLib.dec
|
||||
|
@@ -21,7 +21,6 @@
|
||||
|
||||
/* Convert an EFI_TIME structure into a C Standard tm structure. */
|
||||
void
|
||||
EFIAPI
|
||||
Efi2Tm( EFI_TIME *ET, struct tm *BT)
|
||||
{
|
||||
// Convert EFI time to broken-down time.
|
||||
@@ -39,7 +38,6 @@ Efi2Tm( EFI_TIME *ET, struct tm *BT)
|
||||
|
||||
/* Convert an EFI_TIME structure into a time_t value. */
|
||||
time_t
|
||||
EFIAPI
|
||||
Efi2Time( EFI_TIME *EfiBDtime)
|
||||
{
|
||||
Efi2Tm( EfiBDtime, &gMD->BDTime);
|
||||
|
@@ -110,8 +110,8 @@ struct rule {
|
||||
#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern void EFIAPI gmtload(struct state * const sp);
|
||||
extern void EFIAPI tzset(void);
|
||||
extern void gmtload(struct state * const sp);
|
||||
extern void tzset(void);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _TIMEVAL_H */
|
||||
|
@@ -761,7 +761,6 @@ tzparse(
|
||||
}
|
||||
|
||||
void
|
||||
EFIAPI
|
||||
gmtload(struct state * const sp)
|
||||
{
|
||||
if (tzload(gmt, sp) != 0)
|
||||
@@ -788,7 +787,6 @@ tzsetwall(void)
|
||||
}
|
||||
|
||||
void
|
||||
EFIAPI
|
||||
tzset(void)
|
||||
{
|
||||
register const char * name;
|
||||
|
@@ -44,7 +44,6 @@
|
||||
Heimdal: gettimeofday.c 14773 2005-04-12 11:29:18Z lha $
|
||||
NetBSD: gettimeofday.c,v 1.2 2008/03/22 08:37:21 mlelstv Exp $
|
||||
**/
|
||||
|
||||
#include <LibConfig.h>
|
||||
#include <sys/EfiCdefs.h>
|
||||
#include <sys/time.h>
|
||||
|
277
StdLib/LibC/Time/itimer.c
Normal file
277
StdLib/LibC/Time/itimer.c
Normal file
@@ -0,0 +1,277 @@
|
||||
/** @file
|
||||
setitimer and getitimer functions.
|
||||
|
||||
Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
the terms and conditions of the BSD License that accompanies this distribution.
|
||||
The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
#include <LibConfig.h>
|
||||
#include <sys/EfiSysCall.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <sys/signal.h>
|
||||
#include <signal.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
|
||||
STATIC EFI_EVENT RealTimer = NULL;
|
||||
STATIC EFI_EVENT VirtualTimer = NULL;
|
||||
STATIC EFI_EVENT ProfTimer = NULL;
|
||||
|
||||
STATIC struct itimerval RealTimerInfo = {{0,0},{0,0}};
|
||||
STATIC struct itimerval VirtualTimerInfo = {{0,0},{0,0}};
|
||||
STATIC struct itimerval ProfTimerInfo = {{0,0},{0,0}};
|
||||
|
||||
/**
|
||||
Function to queue the next iteration of the timer.
|
||||
|
||||
This will copy the interval part of the struct into the value and (if
|
||||
non-zero), then queue the next timer event.
|
||||
|
||||
@param[in] TimerInfo The timer info structure.
|
||||
@param[in] Event The EFI timer event.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SetNext (
|
||||
IN struct itimerval *TimerInfo,
|
||||
IN EFI_EVENT Event
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
CopyMem(&(TimerInfo->it_value), &(TimerInfo->it_interval), sizeof(struct timeval));
|
||||
|
||||
//
|
||||
// If now zero then close and be done.
|
||||
//
|
||||
if (TimerInfo->it_value.tv_sec+TimerInfo->it_value.tv_usec == 0) {
|
||||
if (Event != NULL) {
|
||||
gBS->CloseEvent(Event);
|
||||
Event = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Set up for the next loop.
|
||||
//
|
||||
Status = gBS->SetTimer (
|
||||
Event,
|
||||
TimerRelative,
|
||||
TimerInfo->it_value.tv_sec*10000000+TimerInfo->it_value.tv_usec*1000);
|
||||
|
||||
if (EFI_ERROR(Status)) {
|
||||
gBS->CloseEvent(Event);
|
||||
Event = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Notification function for real timer.
|
||||
|
||||
@param[in] Event The event.
|
||||
@param[in] Context Ignored.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
iTimerRealNotifyFunction (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
raise(SIGALRM);
|
||||
SetNext(&RealTimerInfo, RealTimer);
|
||||
}
|
||||
|
||||
/**
|
||||
Notification function for virtual timer.
|
||||
|
||||
@param[in] Event The event.
|
||||
@param[in] Context Ignored.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
iTimerVirtualNotifyFunction (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
raise(SIGVTALRM);
|
||||
SetNext(&VirtualTimerInfo, VirtualTimer);
|
||||
}
|
||||
|
||||
/**
|
||||
Notification function for prof timer.
|
||||
|
||||
@param[in] Event The event.
|
||||
@param[in] Context Ignored.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
iTimerProfNotifyFunction (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
raise(SIGPROF);
|
||||
SetNext(&ProfTimerInfo, ProfTimer);
|
||||
}
|
||||
|
||||
/**
|
||||
The setitimer() function sets the timer specified by which to the value
|
||||
specified in the structure pointed to by value, and if ovalue is not a null
|
||||
pointer, stores the previous value of the timer in the structure pointed to
|
||||
by ovalue.
|
||||
|
||||
A timer value is defined by the itimerval structure. If it_value is non-zero,
|
||||
it indicates the time to the next timer expiration. If it_interval is
|
||||
non-zero, it specifies a value to be used in reloading it_value when the
|
||||
timer expires. Setting it_value to 0 disables a timer, regardless of the
|
||||
value of it_interval. Setting it_interval to 0 disables a timer after its
|
||||
next expiration (assuming it_value is non-zero).
|
||||
|
||||
ITIMER_REAL
|
||||
Decrements in real time. A SIGALRM signal is delivered when this timer
|
||||
expires.
|
||||
|
||||
ITIMER_VIRTUAL
|
||||
Decrements in process virtual time. It runs only when the process is
|
||||
executing. A SIGVTALRM signal is delivered when it expires.
|
||||
|
||||
ITIMER_PROF
|
||||
Decrements both in process virtual time and when the system is running on
|
||||
behalf of the process. It is designed to be used by interpreters in
|
||||
statistically profiling the execution of interpreted programs. Each time
|
||||
the ITIMER_PROF timer expires, the SIGPROF signal is delivered.
|
||||
|
||||
@param[in] which Which timer to set. Possible values are described above.
|
||||
@param[in] value The new value for this timer.
|
||||
@param[out] ovalue The old value for this timer.
|
||||
|
||||
@retval 0 The operation was successful.
|
||||
@retval -1 The operation failed. see errno for more details.
|
||||
**/
|
||||
|
||||
int setitimer(
|
||||
int which,
|
||||
const struct itimerval *value,
|
||||
struct itimerval *ovalue
|
||||
)
|
||||
{
|
||||
EFI_EVENT *EventPointer;
|
||||
EFI_EVENT_NOTIFY NotifyFunction;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (value == NULL) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (which == ITIMER_REAL) {
|
||||
EventPointer = &RealTimer;
|
||||
NotifyFunction = iTimerRealNotifyFunction;
|
||||
if (ovalue != NULL) {
|
||||
CopyMem(ovalue, &RealTimerInfo, sizeof(struct itimerval));
|
||||
}
|
||||
CopyMem(&RealTimerInfo, value, sizeof(struct itimerval));
|
||||
} else if (which == ITIMER_VIRTUAL) {
|
||||
EventPointer = &VirtualTimer;
|
||||
NotifyFunction = iTimerVirtualNotifyFunction;
|
||||
if (ovalue != NULL) {
|
||||
CopyMem(ovalue, &VirtualTimerInfo, sizeof(struct itimerval));
|
||||
}
|
||||
CopyMem(&VirtualTimerInfo, value, sizeof(struct itimerval));
|
||||
} else if (which == ITIMER_PROF) {
|
||||
EventPointer = &ProfTimer;
|
||||
NotifyFunction = iTimerProfNotifyFunction;
|
||||
if (ovalue != NULL) {
|
||||
CopyMem(ovalue, &ProfTimerInfo, sizeof(struct itimerval));
|
||||
}
|
||||
CopyMem(&ProfTimerInfo, value, sizeof(struct itimerval));
|
||||
} else {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (*EventPointer != NULL) {
|
||||
gBS->CloseEvent(*EventPointer);
|
||||
*EventPointer = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// This was a 'please cancel me' request.
|
||||
//
|
||||
if (value->it_value.tv_sec+value->it_value.tv_usec == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_TIMER|EVT_NOTIFY_SIGNAL,
|
||||
EfiGetCurrentTpl(),
|
||||
NotifyFunction,
|
||||
NULL, // no context
|
||||
EventPointer);
|
||||
|
||||
if (EFI_ERROR(Status)) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
Status = gBS->SetTimer (
|
||||
*EventPointer,
|
||||
TimerRelative,
|
||||
value->it_value.tv_sec*10000000+value->it_value.tv_usec*1000);
|
||||
|
||||
if (EFI_ERROR(Status)) {
|
||||
gBS->CloseEvent(*EventPointer);
|
||||
*EventPointer = NULL;
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Function to get the current state of a timer.
|
||||
|
||||
@param[in] which The identifier of the timer to get. See setitimer for
|
||||
details.
|
||||
@param[in] value The pointer to populate. must be pre-allocated to size.
|
||||
|
||||
@return 0 The operation was successful.
|
||||
@return -1 The operation failed.
|
||||
This means that value or which had an invalid value.
|
||||
**/
|
||||
int getitimer(
|
||||
int which,
|
||||
struct itimerval *value
|
||||
)
|
||||
{
|
||||
|
||||
if (value == NULL) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (which == ITIMER_REAL) {
|
||||
CopyMem(value, &RealTimerInfo, sizeof(struct itimerval));
|
||||
} else if (which == ITIMER_VIRTUAL) {
|
||||
CopyMem(value, &VirtualTimerInfo, sizeof(struct itimerval));
|
||||
} else if (which == ITIMER_PROF) {
|
||||
CopyMem(value, &ProfTimerInfo, sizeof(struct itimerval));
|
||||
} else {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@@ -72,9 +72,9 @@
|
||||
|
||||
#define Locale _CurrentTimeLocale
|
||||
|
||||
static char * EFIAPI _add(const char *, char *, const char * const);
|
||||
static char * EFIAPI _conv(const int, const char * const, char * const, const char * const);
|
||||
static char * EFIAPI _fmt(const char *, const struct tm * const, char *, const char * const, int *);
|
||||
static char * _add(const char *, char *, const char * const);
|
||||
static char * _conv(const int, const char * const, char * const, const char * const);
|
||||
static char * _fmt(const char *, const struct tm * const, char *, const char * const, int *);
|
||||
|
||||
#define NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
|
||||
|
||||
@@ -89,7 +89,6 @@ static char * EFIAPI _fmt(const char *, const struct tm * const, char *, const c
|
||||
#define IN_ALL 3
|
||||
|
||||
size_t
|
||||
EFIAPI
|
||||
strftime(
|
||||
char * __restrict s,
|
||||
size_t maxsize,
|
||||
@@ -128,7 +127,6 @@ strftime(
|
||||
}
|
||||
|
||||
static char *
|
||||
EFIAPI
|
||||
_fmt(
|
||||
const char * format,
|
||||
const struct tm * const t,
|
||||
@@ -574,7 +572,6 @@ label:
|
||||
}
|
||||
|
||||
static char *
|
||||
EFIAPI
|
||||
_conv(
|
||||
const int n,
|
||||
const char * const format,
|
||||
@@ -589,7 +586,6 @@ _conv(
|
||||
}
|
||||
|
||||
static char *
|
||||
EFIAPI
|
||||
_add(
|
||||
const char * str,
|
||||
char * pt,
|
||||
|
113
StdLib/LibC/Time/timegm.c
Normal file
113
StdLib/LibC/Time/timegm.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/** @file
|
||||
timegm implementation
|
||||
|
||||
Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
the terms and conditions of the BSD License that accompanies this distribution.
|
||||
The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
* Copyright (c) 1987, 1989 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Arthur David Olson of the National Cancer Institute.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
|
||||
static char *sccsid = "from: @(#)ctime.c 5.26 (Berkeley) 2/23/91";
|
||||
|
||||
|
||||
* This implementation of mktime is lifted straight from the NetBSD (BSD 4.4)
|
||||
* version. I modified it slightly to divorce it from the internals of the
|
||||
* ctime library. Thus this version can't use details of the internal
|
||||
* timezone state file to figure out strange unnormalized struct tm values,
|
||||
* as might result from someone doing date math on the tm struct then passing
|
||||
* it to mktime.
|
||||
*
|
||||
* It just does as well as it can at normalizing the tm input, then does a
|
||||
* binary search of the time space using the system's localtime() function.
|
||||
*
|
||||
* The original binary search was defective in that it didn't consider the
|
||||
* setting of tm_isdst when comparing tm values, causing the search to be
|
||||
* flubbed for times near the dst/standard time changeover. The original
|
||||
* code seems to make up for this by grubbing through the timezone info
|
||||
* whenever the binary search barfed. Since I don't have that luxury in
|
||||
* portable code, I have to take care of tm_isdst in the comparison routine.
|
||||
* This requires knowing how many minutes offset dst is from standard time.
|
||||
*
|
||||
* So, if you live somewhere in the world where dst is not 60 minutes offset,
|
||||
* and your vendor doesn't supply mktime(), you'll have to edit this variable
|
||||
* by hand. Sorry about that.
|
||||
|
||||
$NetBSD: mktime.c,v 1.4 2006/06/11 19:34:10 kardel Exp $
|
||||
**/
|
||||
|
||||
#include <LibConfig.h>
|
||||
#include <time.h>
|
||||
|
||||
/*
|
||||
This funciton is in Time.c, which has a different license than timegm.
|
||||
*/
|
||||
time_t
|
||||
time2(struct tm * const tmp, void (* const funcp)(const time_t*, long, struct tm*),
|
||||
const long offset, int * const okayp);
|
||||
|
||||
/*
|
||||
This funciton is in Time.c, which has a different license than timegm.
|
||||
*/
|
||||
void
|
||||
gmtsub(
|
||||
const time_t * const timep,
|
||||
const long offset,
|
||||
struct tm * const tmp
|
||||
);
|
||||
|
||||
#ifndef WRONG
|
||||
#define WRONG (-1)
|
||||
#endif /* !defined WRONG */
|
||||
|
||||
/*
|
||||
Convert a tm structure to a GMT based time_t.
|
||||
*/
|
||||
time_t timegm( struct tm * tmp )
|
||||
{
|
||||
register time_t t;
|
||||
int okay;
|
||||
|
||||
tmp->tm_isdst = 0;
|
||||
t = time2(tmp, gmtsub, 0, &okay);
|
||||
if (okay || tmp->tm_isdst < 0)
|
||||
return t;
|
||||
|
||||
return WRONG;
|
||||
}
|
@@ -45,6 +45,12 @@ static const int stdioFlags[NUM_SPECIAL] = {
|
||||
static DeviceNode *ConNode[NUM_SPECIAL];
|
||||
static ConInstance *ConInstanceList;
|
||||
|
||||
static wchar_t *ConReadBuf;
|
||||
|
||||
/* Flags settable by Ioctl */
|
||||
static BOOLEAN TtyCooked;
|
||||
static BOOLEAN TtyEcho;
|
||||
|
||||
ssize_t
|
||||
WideTtyCvt( CHAR16 *dest, const char *buf, size_t n)
|
||||
{
|
||||
@@ -127,74 +133,6 @@ da_ConSeek(
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
ssize_t
|
||||
EFIAPI
|
||||
da_ConRead(
|
||||
IN OUT struct __filedes *filp,
|
||||
IN OUT off_t *offset, // Console ignores this
|
||||
IN size_t BufferSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *Proto;
|
||||
ConInstance *Stream;
|
||||
CHAR16 *OutPtr;
|
||||
EFI_INPUT_KEY Key;
|
||||
UINTN NumChar;
|
||||
UINTN Edex;
|
||||
EFI_STATUS Status = RETURN_SUCCESS;
|
||||
UINTN i;
|
||||
|
||||
Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);
|
||||
// Quick check to see if Stream looks reasonable
|
||||
if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
|
||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||
return -1; // Looks like a bad This pointer
|
||||
}
|
||||
if(Stream->InstanceNum != STDIN_FILENO) {
|
||||
// Read only valid for stdin
|
||||
EFIerrno = RETURN_UNSUPPORTED;
|
||||
return -1;
|
||||
}
|
||||
// It looks like things are OK for trying to read
|
||||
// We will accumulate *BufferSize characters or until we encounter
|
||||
// an "activation" character. Currently any control character.
|
||||
Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev;
|
||||
OutPtr = Buffer;
|
||||
NumChar = (BufferSize - 1) / sizeof(CHAR16);
|
||||
i = 0;
|
||||
do {
|
||||
if((Stream->UnGetKey.UnicodeChar == CHAR_NULL) && (Stream->UnGetKey.ScanCode == SCAN_NULL)) {
|
||||
Status = gBS->WaitForEvent( 1, &Proto->WaitForKey, &Edex);
|
||||
if(Status != RETURN_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
Status = Proto->ReadKeyStroke(Proto, &Key);
|
||||
if(Status != RETURN_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Key.ScanCode = Stream->UnGetKey.ScanCode;
|
||||
Key.UnicodeChar = Stream->UnGetKey.UnicodeChar;
|
||||
Stream->UnGetKey.ScanCode = SCAN_NULL;
|
||||
Stream->UnGetKey.UnicodeChar = CHAR_NULL;
|
||||
}
|
||||
if(Key.ScanCode == SCAN_NULL) {
|
||||
*OutPtr++ = Key.UnicodeChar;
|
||||
++i;
|
||||
}
|
||||
if(iswcntrl(Key.UnicodeChar)) { // If a control character, or a scan code
|
||||
break;
|
||||
}
|
||||
} while(i < NumChar);
|
||||
|
||||
*OutPtr = L'\0'; // Terminate the input buffer
|
||||
EFIerrno = Status;
|
||||
return (ssize_t)(i * sizeof(CHAR16)); // Will be 0 if we didn't get a key
|
||||
}
|
||||
|
||||
/* Write a NULL terminated WCS to the EFI console.
|
||||
|
||||
@param[in,out] BufferSize Number of bytes in Buffer. Set to zero if
|
||||
@@ -265,6 +203,109 @@ da_ConWrite(
|
||||
return BufferSize;
|
||||
}
|
||||
|
||||
/** Read characters from the console input device.
|
||||
|
||||
@param[in,out] filp Pointer to file descriptor for this file.
|
||||
@param[in,out] offset Ignored.
|
||||
@param[in] BufferSize Buffer size, in bytes.
|
||||
@param[out] Buffer Buffer in which to place the read characters.
|
||||
|
||||
@return Number of bytes actually placed into Buffer.
|
||||
|
||||
@todo Handle encodings other than ASCII-7 and UEFI.
|
||||
**/
|
||||
static
|
||||
ssize_t
|
||||
EFIAPI
|
||||
da_ConRead(
|
||||
IN OUT struct __filedes *filp,
|
||||
IN OUT off_t *offset, // Console ignores this
|
||||
IN size_t BufferSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *Proto;
|
||||
ConInstance *Stream;
|
||||
wchar_t *OutPtr;
|
||||
EFI_INPUT_KEY Key;
|
||||
UINTN NumChar;
|
||||
UINTN Edex;
|
||||
EFI_STATUS Status = RETURN_SUCCESS;
|
||||
UINTN i;
|
||||
char EchoBuff[MB_CUR_MAX + 1];
|
||||
int NumEcho;
|
||||
|
||||
Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);
|
||||
// Quick check to see if Stream looks reasonable
|
||||
if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
|
||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||
return -1; // Looks like a bad This pointer
|
||||
}
|
||||
if(Stream->InstanceNum != STDIN_FILENO) {
|
||||
// Read only valid for stdin
|
||||
EFIerrno = RETURN_UNSUPPORTED;
|
||||
return -1;
|
||||
}
|
||||
// It looks like things are OK for trying to read
|
||||
// We will accumulate *BufferSize characters or until we encounter
|
||||
// an "activation" character. Currently any control character.
|
||||
Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev;
|
||||
OutPtr = ConReadBuf;
|
||||
NumChar = (BufferSize > MAX_INPUT)? MAX_INPUT : BufferSize;
|
||||
i = 0;
|
||||
do {
|
||||
if((Stream->UnGetKey.UnicodeChar == CHAR_NULL) && (Stream->UnGetKey.ScanCode == SCAN_NULL)) {
|
||||
Status = gBS->WaitForEvent( 1, &Proto->WaitForKey, &Edex);
|
||||
if(Status != RETURN_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
Status = Proto->ReadKeyStroke(Proto, &Key);
|
||||
if(Status != RETURN_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Key.ScanCode = Stream->UnGetKey.ScanCode;
|
||||
Key.UnicodeChar = Stream->UnGetKey.UnicodeChar;
|
||||
Stream->UnGetKey.ScanCode = SCAN_NULL;
|
||||
Stream->UnGetKey.UnicodeChar = CHAR_NULL;
|
||||
}
|
||||
if(Key.ScanCode == SCAN_NULL) {
|
||||
NumEcho = 0;
|
||||
if(TtyCooked && (Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) {
|
||||
*OutPtr++ = CHAR_LINEFEED;
|
||||
NumEcho = wctomb(EchoBuff, CHAR_LINEFEED);
|
||||
}
|
||||
else {
|
||||
*OutPtr++ = Key.UnicodeChar;
|
||||
NumEcho = wctomb(EchoBuff, Key.UnicodeChar);
|
||||
}
|
||||
++i;
|
||||
EchoBuff[NumEcho] = 0; /* Terminate the Echo buffer */
|
||||
if(TtyEcho) {
|
||||
/* Echo the character just input */
|
||||
da_ConWrite(&gMD->fdarray[STDOUT_FILENO], NULL, 2, EchoBuff);
|
||||
}
|
||||
}
|
||||
if(iswcntrl(Key.UnicodeChar)) { // If a control character, or a scan code
|
||||
break;
|
||||
}
|
||||
} while(i < NumChar);
|
||||
|
||||
*OutPtr = L'\0'; // Terminate the input buffer
|
||||
|
||||
/* Convert the input buffer and place in Buffer.
|
||||
If the fully converted input buffer won't fit, write what will and
|
||||
leave the rest in ConReadBuf with ConReadLeft indicating how many
|
||||
unconverted characters remain in ConReadBuf.
|
||||
*/
|
||||
NumEcho = (int)wcstombs(Buffer, ConReadBuf, BufferSize); /* Re-use NumEcho to hold number of bytes in Buffer */
|
||||
/* More work needs to be done before locales other than C can be supported. */
|
||||
|
||||
EFIerrno = Status;
|
||||
return (ssize_t)NumEcho; // Will be 0 if we didn't get a key
|
||||
}
|
||||
|
||||
/** Console-specific helper function for the fstat() function.
|
||||
|
||||
st_size Set to number of characters read for stdin and number written for stdout and stderr.
|
||||
@@ -347,27 +388,28 @@ da_ConIoctl(
|
||||
int
|
||||
EFIAPI
|
||||
da_ConOpen(
|
||||
DeviceNode *DevNode,
|
||||
struct __filedes *filp,
|
||||
void *DevInstance,
|
||||
int DevInstance, // Not used for console devices
|
||||
wchar_t *Path, // Not used for console devices
|
||||
wchar_t *Flags // Not used for console devices
|
||||
wchar_t *MPath // Not used for console devices
|
||||
)
|
||||
{
|
||||
ConInstance *Stream;
|
||||
|
||||
if((filp == NULL) ||
|
||||
(DevInstance == NULL))
|
||||
(DevNode == NULL))
|
||||
{
|
||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||
return -1;
|
||||
}
|
||||
Stream = (ConInstance *)DevInstance;
|
||||
Stream = (ConInstance *)DevNode->InstanceList;
|
||||
// Quick check to see if Stream looks reasonable
|
||||
if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
|
||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||
return -1; // Looks like a bad This pointer
|
||||
}
|
||||
gMD->StdIo[Stream->InstanceNum] = (ConInstance *)DevInstance;
|
||||
gMD->StdIo[Stream->InstanceNum] = Stream;
|
||||
filp->f_iflags |= (S_IFREG | _S_IFCHR | _S_ICONSOLE);
|
||||
filp->f_offset = 0;
|
||||
filp->f_ops = &Stream->Abstraction;
|
||||
@@ -448,7 +490,8 @@ __Cons_construct(
|
||||
int i;
|
||||
|
||||
ConInstanceList = (ConInstance *)AllocateZeroPool(NUM_SPECIAL * sizeof(ConInstance));
|
||||
if(ConInstanceList == NULL) {
|
||||
ConReadBuf = (wchar_t *)AllocateZeroPool((MAX_INPUT + 1) * sizeof(wchar_t));
|
||||
if((ConInstanceList == NULL) || (ConReadBuf == NULL)) {
|
||||
return RETURN_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
@@ -507,6 +550,10 @@ __Cons_construct(
|
||||
}
|
||||
Stream->Parent = ConNode[i];
|
||||
}
|
||||
/* Initialize Ioctl flags until Ioctl is really implemented. */
|
||||
TtyCooked = TRUE;
|
||||
TtyEcho = TRUE;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -527,6 +574,9 @@ __Cons_deconstruct(
|
||||
if(ConInstanceList != NULL) {
|
||||
FreePool(ConInstanceList);
|
||||
}
|
||||
if(ConReadBuf != NULL) {
|
||||
FreePool(ConReadBuf);
|
||||
}
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/syslimits.h>
|
||||
#include <kfile.h>
|
||||
#include <Device/Device.h>
|
||||
#include <MainData.h>
|
||||
@@ -321,7 +322,7 @@ da_ShellIoctl(
|
||||
void *argp ///< May be a pointer or a value
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/** Open an abstract Shell File.
|
||||
@@ -329,10 +330,11 @@ da_ShellIoctl(
|
||||
int
|
||||
EFIAPI
|
||||
da_ShellOpen(
|
||||
DeviceNode *DevNode,
|
||||
struct __filedes *filp,
|
||||
void *DevInstance,
|
||||
int DevInstance, /* Not used by Shell */
|
||||
wchar_t *Path,
|
||||
wchar_t *Flags
|
||||
wchar_t *MPath
|
||||
)
|
||||
{
|
||||
UINT64 OpenMode;
|
||||
@@ -340,8 +342,10 @@ da_ShellOpen(
|
||||
SHELL_FILE_HANDLE FileHandle;
|
||||
GenericInstance *Gip;
|
||||
char *NPath;
|
||||
wchar_t *WPath;
|
||||
RETURN_STATUS Status;
|
||||
int oflags;
|
||||
int retval;
|
||||
|
||||
EFIerrno = RETURN_SUCCESS;
|
||||
|
||||
@@ -356,6 +360,23 @@ da_ShellOpen(
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Re-create the full mapped path for the shell. */
|
||||
if(MPath != NULL) {
|
||||
WPath = AllocateZeroPool(PATH_MAX * sizeof(wchar_t) + 1);
|
||||
if(WPath == NULL) {
|
||||
errno = ENOMEM;
|
||||
EFIerrno = RETURN_OUT_OF_RESOURCES;
|
||||
return -1;
|
||||
}
|
||||
wcsncpy(WPath, MPath, NAME_MAX); /* Get the Map Name */
|
||||
wcsncat(WPath, Path, (PATH_MAX - NAME_MAX)); /* Append the path */
|
||||
}
|
||||
else {
|
||||
WPath = Path;
|
||||
}
|
||||
|
||||
retval = -1; /* Initially assume failure. */
|
||||
|
||||
/* Do we care if the file already exists?
|
||||
If O_TRUNC, then delete the file. It will be created anew subsequently.
|
||||
If O_EXCL, then error if the file exists and O_CREAT is set.
|
||||
@@ -363,23 +384,24 @@ da_ShellOpen(
|
||||
!!!!!!!!! Change this to use ShellSetFileInfo() to actually truncate the file
|
||||
!!!!!!!!! instead of deleting and re-creating it.
|
||||
*/
|
||||
do { /* Do fake exception handling */
|
||||
if((oflags & O_TRUNC) || ((oflags & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT))) {
|
||||
Status = ShellIsFile( Path );
|
||||
Status = ShellIsFile( WPath );
|
||||
if(Status == RETURN_SUCCESS) {
|
||||
// The file exists
|
||||
if(oflags & O_TRUNC) {
|
||||
NPath = AllocateZeroPool(1024);
|
||||
NPath = AllocateZeroPool(PATH_MAX);
|
||||
if(NPath == NULL) {
|
||||
errno = ENOMEM;
|
||||
EFIerrno = RETURN_OUT_OF_RESOURCES;
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
wcstombs(NPath, Path, 1024);
|
||||
wcstombs(NPath, WPath, PATH_MAX);
|
||||
// We do a truncate by deleting the existing file and creating a new one.
|
||||
if(unlink(NPath) != 0) {
|
||||
filp->f_iflags = 0; // Release our reservation on this FD
|
||||
FreePool(NPath);
|
||||
return -1; // errno and EFIerrno are already set.
|
||||
break;
|
||||
}
|
||||
FreePool(NPath);
|
||||
}
|
||||
@@ -387,32 +409,40 @@ da_ShellOpen(
|
||||
errno = EEXIST;
|
||||
EFIerrno = RETURN_ACCESS_DENIED;
|
||||
filp->f_iflags = 0; // Release our reservation on this FD
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call the EFI Shell's Open function
|
||||
Status = ShellOpenFileByName( Path, &FileHandle, OpenMode, Attributes);
|
||||
Status = ShellOpenFileByName( WPath, &FileHandle, OpenMode, Attributes);
|
||||
if(RETURN_ERROR(Status)) {
|
||||
filp->f_iflags = 0; // Release our reservation on this FD
|
||||
// Set errno based upon Status
|
||||
errno = EFI2errno(Status);
|
||||
EFIerrno = Status;
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
retval = 0;
|
||||
// Successfully got a regular File
|
||||
filp->f_iflags |= S_IFREG;
|
||||
|
||||
// Update the info in the fd
|
||||
filp->devdata = (void *)FileHandle;
|
||||
|
||||
Gip = (GenericInstance *)DevInstance;
|
||||
Gip = (GenericInstance *)DevNode->InstanceList;
|
||||
filp->f_offset = 0;
|
||||
filp->f_ops = &Gip->Abstraction;
|
||||
// filp->devdata = FileHandle;
|
||||
// filp->devdata = FileHandle;
|
||||
} while(FALSE);
|
||||
|
||||
return 0;
|
||||
/* If we get this far, WPath is not NULL.
|
||||
If MPath is not NULL, then WPath was allocated so we need to free it.
|
||||
*/
|
||||
if(MPath != NULL) {
|
||||
FreePool(WPath);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#include <sys/poll.h>
|
||||
@@ -468,9 +498,10 @@ da_ShellRename(
|
||||
RETURN_STATUS Status;
|
||||
EFI_FILE_INFO *NewFileInfo;
|
||||
EFI_FILE_INFO *OldFileInfo;
|
||||
char *NewFn;
|
||||
wchar_t *NewFn;
|
||||
int OldFd;
|
||||
SHELL_FILE_HANDLE FileHandle;
|
||||
wchar_t *NormalizedPath;
|
||||
|
||||
// Open old file
|
||||
OldFd = open(from, O_RDWR, 0);
|
||||
@@ -482,22 +513,20 @@ da_ShellRename(
|
||||
OldFileInfo = ShellGetFileInfo( FileHandle);
|
||||
if(OldFileInfo != NULL) {
|
||||
// Copy the Old file info into our new buffer, and free the old.
|
||||
memcpy(OldFileInfo, NewFileInfo, sizeof(EFI_FILE_INFO));
|
||||
memcpy(NewFileInfo, OldFileInfo, sizeof(EFI_FILE_INFO));
|
||||
FreePool(OldFileInfo);
|
||||
// Normalize path and convert to WCS.
|
||||
NormalizedPath = NormalizePath(to);
|
||||
if (NormalizedPath != NULL) {
|
||||
// Strip off all but the file name portion of new
|
||||
NewFn = strrchr(to, '/');
|
||||
if(NewFn == NULL) {
|
||||
NewFn = strrchr(to, '\\');
|
||||
if(NewFn == NULL) {
|
||||
NewFn = (char *)to;
|
||||
}
|
||||
}
|
||||
// Convert new name from MBCS to WCS
|
||||
(void)AsciiStrToUnicodeStr( NewFn, gMD->UString);
|
||||
NewFn = GetFileNameFromPath(NormalizedPath);
|
||||
// Copy the new file name into our new file info buffer
|
||||
wcsncpy(NewFileInfo->FileName, gMD->UString, wcslen(gMD->UString)+1);
|
||||
wcsncpy(NewFileInfo->FileName, NewFn, wcslen(NewFn) + 1);
|
||||
// Update the size of the structure.
|
||||
NewFileInfo->Size = sizeof(EFI_FILE_INFO) + StrSize(NewFn);
|
||||
// Apply the new file name
|
||||
Status = ShellSetFileInfo(FileHandle, NewFileInfo);
|
||||
free(NormalizedPath);
|
||||
free(NewFileInfo);
|
||||
if(Status == EFI_SUCCESS) {
|
||||
// File has been successfully renamed. We are DONE!
|
||||
@@ -507,6 +536,12 @@ da_ShellRename(
|
||||
EFIerrno = Status;
|
||||
}
|
||||
else {
|
||||
free(NewFileInfo);
|
||||
errno = ENOMEM;
|
||||
}
|
||||
}
|
||||
else {
|
||||
free(NewFileInfo);
|
||||
errno = EIO;
|
||||
}
|
||||
}
|
||||
@@ -619,7 +654,7 @@ __ctor_DevShell(
|
||||
Stream->Abstraction.fo_poll = &da_ShellPoll;
|
||||
Stream->Abstraction.fo_flush = &fnullop_flush;
|
||||
Stream->Abstraction.fo_stat = &da_ShellStat;
|
||||
Stream->Abstraction.fo_ioctl = &fbadop_ioctl;
|
||||
Stream->Abstraction.fo_ioctl = &da_ShellIoctl;
|
||||
Stream->Abstraction.fo_delete = &da_ShellDelete;
|
||||
Stream->Abstraction.fo_rmdir = &da_ShellRmdir;
|
||||
Stream->Abstraction.fo_mkdir = &da_ShellMkdir;
|
||||
|
@@ -31,33 +31,33 @@ DeviceNode *daCurrentDevice = NULL; ///< Device currently being accessed
|
||||
fnullop_* Does nothing and returns success.
|
||||
fbadop_* Does nothing and returns EPERM
|
||||
*/
|
||||
int fnullop_fcntl (struct __filedes *filp, UINT32 Cmd, void *p3, void *p4)
|
||||
int EFIAPI fnullop_fcntl (struct __filedes *filp, UINT32 Cmd, void *p3, void *p4)
|
||||
{ return 0; }
|
||||
|
||||
short fnullop_poll (struct __filedes *filp, short Events)
|
||||
short EFIAPI fnullop_poll (struct __filedes *filp, short Events)
|
||||
{
|
||||
return ((POLLIN | POLLRDNORM | POLLOUT) & Events);
|
||||
}
|
||||
|
||||
int fnullop_flush (struct __filedes *filp)
|
||||
int EFIAPI fnullop_flush (struct __filedes *filp)
|
||||
{ return 0; }
|
||||
|
||||
int fbadop_stat (struct __filedes *filp, struct stat *StatBuf, void *Buf)
|
||||
int EFIAPI fbadop_stat (struct __filedes *filp, struct stat *StatBuf, void *Buf)
|
||||
{ return -EPERM; }
|
||||
|
||||
int fbadop_ioctl (struct __filedes *filp, ULONGN Cmd, void *argp)
|
||||
int EFIAPI fbadop_ioctl (struct __filedes *filp, ULONGN Cmd, void *argp)
|
||||
{ return -EPERM; }
|
||||
|
||||
int fbadop_delete (struct __filedes *filp)
|
||||
int EFIAPI fbadop_delete (struct __filedes *filp)
|
||||
{ return -EPERM; }
|
||||
|
||||
int fbadop_mkdir (const char *path, __mode_t perms)
|
||||
int EFIAPI fbadop_mkdir (const char *path, __mode_t perms)
|
||||
{ return -EPERM; }
|
||||
|
||||
int fbadop_rename (const char *from, const char *to)
|
||||
int EFIAPI fbadop_rename (const char *from, const char *to)
|
||||
{ return -EPERM; }
|
||||
|
||||
int fbadop_rmdir (struct __filedes *filp)
|
||||
int EFIAPI fbadop_rmdir (struct __filedes *filp)
|
||||
{ return -EPERM; }
|
||||
|
||||
/** Add a new device to the device list.
|
||||
|
@@ -248,10 +248,16 @@ PathAlias(
|
||||
|
||||
/** Parse a path producing the target device, device instance, and file path.
|
||||
|
||||
It is the caller's responsibility to free() FullPath and MapPath when they
|
||||
are no longer needed.
|
||||
|
||||
@param[in] path
|
||||
@param[out] FullPath
|
||||
@param[out] DevNode
|
||||
@param[out] Which
|
||||
@param[out] MapPath OPTIONAL. If not NULL, it points to the place to save a pointer
|
||||
to the extracted map name. If the path didn't have a map name,
|
||||
then *MapPath is set to NULL.
|
||||
|
||||
@retval RETURN_SUCCESS The path was parsed successfully.
|
||||
@retval RETURN_NOT_FOUND The path does not map to a valid device.
|
||||
@@ -266,7 +272,8 @@ ParsePath(
|
||||
IN const char *path,
|
||||
OUT wchar_t **FullPath,
|
||||
OUT DeviceNode **DevNode,
|
||||
OUT int *Which
|
||||
OUT int *Which,
|
||||
OUT wchar_t **MapPath
|
||||
)
|
||||
{
|
||||
int MapLen;
|
||||
@@ -301,7 +308,7 @@ reclassify:
|
||||
// Get the Map Name, including the trailing ':'. */
|
||||
MPath = calloc(MapLen+2, sizeof(wchar_t));
|
||||
if(MPath != NULL) {
|
||||
wmemcpy(MPath, WPath, MapLen+2);
|
||||
wmemcpy(MPath, WPath, MapLen+1);
|
||||
}
|
||||
else {
|
||||
errno = ENOMEM;
|
||||
@@ -346,6 +353,12 @@ reclassify:
|
||||
if(!RETURN_ERROR(Status)) {
|
||||
*FullPath = WPath;
|
||||
*Which = Instance;
|
||||
if(MapPath != NULL) {
|
||||
*MapPath = MPath;
|
||||
}
|
||||
else if(MPath != NULL) {
|
||||
free(MPath); /* Caller doesn't want it so let MPath go free */
|
||||
}
|
||||
|
||||
/* At this point, WPath is an absolute path,
|
||||
MPath is either NULL or points to the Map Name,
|
||||
@@ -359,6 +372,9 @@ reclassify:
|
||||
if(Node != NULL) {
|
||||
Status = RETURN_SUCCESS;
|
||||
}
|
||||
else {
|
||||
Status = RETURN_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* This is a mapped path. */
|
||||
@@ -375,8 +391,41 @@ reclassify:
|
||||
*DevNode = Node;
|
||||
}
|
||||
}
|
||||
if(MPath != NULL) {
|
||||
free(MPath); // We don't need this any more.
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Parses a normalized wide character path and returns a pointer to the entry
|
||||
following the last \. If a \ is not found in the path the return value will
|
||||
be the same as the input value. All error conditions return NULL.
|
||||
|
||||
The behavior when passing in a path that has not been normalized is undefined.
|
||||
|
||||
@param Path - A pointer to a wide character string containing a path to a
|
||||
directory or a file.
|
||||
|
||||
@return Pointer to the file name or terminal directory. NULL if an error is
|
||||
detected.
|
||||
**/
|
||||
wchar_t *
|
||||
EFIAPI
|
||||
GetFileNameFromPath (
|
||||
const wchar_t *Path
|
||||
)
|
||||
{
|
||||
wchar_t *Tail;
|
||||
|
||||
if (Path == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Tail = wcsrchr(Path, L'\\');
|
||||
if(Tail == NULL) {
|
||||
Tail = (wchar_t *) Path;
|
||||
} else {
|
||||
// Move to the next character after the '\\' to get the file name.
|
||||
Tail++;
|
||||
}
|
||||
|
||||
return Tail;
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = DevConsole
|
||||
FILE_GUID = 42c078ef-14a8-4e30-9329-6f12d796e54a
|
||||
FILE_GUID = f6937495-1f44-4a8a-8a1b-5a669f9396f6
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = DevConsole
|
||||
@@ -49,15 +49,3 @@
|
||||
[Protocols]
|
||||
gEfiSimpleTextInProtocolGuid
|
||||
gEfiSimpleTextOutProtocolGuid
|
||||
|
||||
################################################################
|
||||
#
|
||||
# The Build Options, below, are only used when building the C library.
|
||||
# DO NOT use them when building your application!
|
||||
# Nasty things could happen if you do.
|
||||
#
|
||||
# /Oi is required for Microsoft VC++ to allow "intrinsic" functions to be
|
||||
# defined in this library.
|
||||
#
|
||||
#[BuildOptions]
|
||||
# MSFT:*_*_*_CC_FLAGS = /Oi-
|
||||
|
@@ -19,7 +19,7 @@
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = DevShell
|
||||
FILE_GUID = 42c078ef-14a8-4e30-9329-6f12d796e54a
|
||||
FILE_GUID = 0a1d4fd8-4704-4501-85eb-93399492cbed
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = DevShell
|
||||
@@ -49,15 +49,3 @@
|
||||
LibWchar
|
||||
LibUefi
|
||||
DevUtility
|
||||
|
||||
################################################################
|
||||
#
|
||||
# The Build Options, below, are only used when building the C library.
|
||||
# DO NOT use them when building your application!
|
||||
# Nasty things could happen if you do.
|
||||
#
|
||||
# /Oi is required for Microsoft VC++ to allow "intrinsic" functions to be
|
||||
# defined in this library.
|
||||
#
|
||||
#[BuildOptions]
|
||||
# MSFT:*_*_*_CC_FLAGS = /Oi-
|
||||
|
@@ -15,7 +15,7 @@
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = DevUtility
|
||||
FILE_GUID = 42c078ef-14a8-4e30-9329-6f12d796e54a
|
||||
FILE_GUID = d6a9928c-3397-4dd1-818f-c664ba6dcaaf
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = DevUtility
|
||||
@@ -42,15 +42,3 @@
|
||||
LibC
|
||||
LibWchar
|
||||
LibUefi
|
||||
|
||||
################################################################
|
||||
#
|
||||
# The Build Options, below, are only used when building the C library.
|
||||
# DO NOT use them when building your application!
|
||||
# Nasty things could happen if you do.
|
||||
#
|
||||
# /Oi- is required for Microsoft VC++ to allow "intrinsic" functions to be
|
||||
# defined in this library.
|
||||
#
|
||||
#[BuildOptions]
|
||||
# MSFT:*_*_*_CC_FLAGS = /Oi-
|
||||
|
57
StdLib/LibC/Uefi/GetPass.c
Normal file
57
StdLib/LibC/Uefi/GetPass.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/** @file Implement the getpass function.
|
||||
|
||||
Copyright (c) 2011, Intel Corporation <BR>
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <Library/ShellLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
static CHAR8 *ReturnStringAscii = NULL;
|
||||
|
||||
char *getpass(const char *Prompt)
|
||||
{
|
||||
BOOLEAN Ascii;
|
||||
CHAR16 *ReturnString;
|
||||
|
||||
Ascii = FALSE;
|
||||
|
||||
Print(L"%a", Prompt);
|
||||
|
||||
ReturnString = ShellFileHandleReturnLine (gEfiShellParametersProtocol->StdIn, &Ascii);
|
||||
if (ReturnString == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ReturnStringAscii = AllocateZeroPool((StrLen(ReturnString)+1)*sizeof(CHAR8));
|
||||
if (ReturnStringAscii == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
UnicodeStrToAsciiStr(ReturnString, ReturnStringAscii);
|
||||
|
||||
FreePool(ReturnString);
|
||||
|
||||
return (ReturnStringAscii);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DestructMePlease (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
SHELL_FREE_NON_NULL(ReturnStringAscii);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
79
StdLib/LibC/Uefi/StubFunctions.c
Normal file
79
StdLib/LibC/Uefi/StubFunctions.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/** @file
|
||||
Implement the invalid functions to return failures.
|
||||
|
||||
Copyright (c) 2011, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
#include <sys/EfiCdefs.h>
|
||||
#include <sys/featuretest.h>
|
||||
#include <namespace.h>
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
#include <errno.h>
|
||||
|
||||
struct passwd *
|
||||
getpwuid (uid_t uid)
|
||||
{
|
||||
uid;
|
||||
errno = EPERM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *getlogin (void)
|
||||
{
|
||||
errno = EPERM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
getpwnam (const char *name)
|
||||
{
|
||||
name;
|
||||
errno = EPERM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uid_t getuid (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid_t fork (void)
|
||||
{
|
||||
errno = EPERM;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int chmod (const char *c, mode_t m)
|
||||
{
|
||||
errno = EPERM;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
pid_t wait(int *stat_loc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE *popen (const char *cmd, const char *type)
|
||||
{
|
||||
errno = EPERM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int pclose (FILE *stream)
|
||||
{
|
||||
errno = EPERM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int access (const char *path, int amode)
|
||||
{
|
||||
return 0;
|
||||
}
|
@@ -524,7 +524,7 @@ mkdir (const char *path, __mode_t perms)
|
||||
int Instance = 0;
|
||||
int retval = 0;
|
||||
|
||||
Status = ParsePath(path, &NewPath, &Node, &Instance);
|
||||
Status = ParsePath(path, &NewPath, &Node, &Instance, NULL);
|
||||
if(Status == RETURN_SUCCESS) {
|
||||
GenI = Node->InstanceList;
|
||||
if(GenI == NULL) {
|
||||
@@ -532,7 +532,7 @@ mkdir (const char *path, __mode_t perms)
|
||||
retval = -1;
|
||||
}
|
||||
else {
|
||||
GenI += (Instance * Node->InstanceSize);
|
||||
//GenI += (Instance * Node->InstanceSize);
|
||||
retval = ((GenericInstance *)GenI)->Abstraction.fo_mkdir( path, perms);
|
||||
}
|
||||
free(NewPath);
|
||||
@@ -567,11 +567,15 @@ mkdir (const char *path, __mode_t perms)
|
||||
O_EXCL -- if O_CREAT is also set, open will fail if the file already exists.
|
||||
**/
|
||||
int
|
||||
open (const char *path, int oflags, int mode)
|
||||
open(
|
||||
const char *path,
|
||||
int oflags,
|
||||
int mode
|
||||
)
|
||||
{
|
||||
wchar_t *NewPath;
|
||||
wchar_t *MPath;
|
||||
DeviceNode *Node;
|
||||
char *GenI = NULL;
|
||||
struct __filedes *filp;
|
||||
int Instance = 0;
|
||||
RETURN_STATUS Status;
|
||||
@@ -579,10 +583,10 @@ open (const char *path, int oflags, int mode)
|
||||
int fd = -1;
|
||||
int doresult;
|
||||
|
||||
Status = ParsePath(path, &NewPath, &Node, &Instance);
|
||||
Status = ParsePath(path, &NewPath, &Node, &Instance, &MPath);
|
||||
if(Status == RETURN_SUCCESS) {
|
||||
if((Node != NULL) &&
|
||||
((GenI = Node->InstanceList) == NULL)) {
|
||||
if((Node == NULL) ||
|
||||
(Node->InstanceList == NULL)) {
|
||||
errno = EPERM;
|
||||
}
|
||||
else {
|
||||
@@ -595,15 +599,14 @@ open (const char *path, int oflags, int mode)
|
||||
if( fd < 0 ) {
|
||||
// All available FDs are in use
|
||||
errno = EMFILE;
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
filp = &gMD->fdarray[fd];
|
||||
// Save the flags and mode in the File Descriptor
|
||||
filp->Oflags = oflags;
|
||||
filp->Omode = mode;
|
||||
|
||||
GenI += (Instance * Node->InstanceSize);
|
||||
doresult = Node->OpenFunc(filp, GenI, NewPath, NULL);
|
||||
doresult = Node->OpenFunc(Node, filp, Instance, NewPath, MPath);
|
||||
if(doresult < 0) {
|
||||
filp->f_iflags = 0; // Release this FD
|
||||
fd = -1; // Indicate an error
|
||||
@@ -618,8 +621,14 @@ open (const char *path, int oflags, int mode)
|
||||
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;
|
||||
}
|
||||
@@ -748,6 +757,7 @@ poll (
|
||||
}
|
||||
} while (( 0 == SelectedFDs )
|
||||
&& ( EFI_SUCCESS == Status ));
|
||||
|
||||
//
|
||||
// Stop the timer
|
||||
//
|
||||
@@ -776,7 +786,6 @@ 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
|
||||
argument points to the new pathname of the file.
|
||||
@@ -807,7 +816,6 @@ poll (
|
||||
shall be changed or created.
|
||||
**/
|
||||
int
|
||||
EFIAPI
|
||||
rename(
|
||||
const char *from,
|
||||
const char *to
|
||||
@@ -820,7 +828,7 @@ rename(
|
||||
RETURN_STATUS Status;
|
||||
int retval = -1;
|
||||
|
||||
Status = ParsePath(from, &FromPath, &FromNode, &Instance);
|
||||
Status = ParsePath(from, &FromPath, &FromNode, &Instance, NULL);
|
||||
if(Status == RETURN_SUCCESS) {
|
||||
GenI = FromNode->InstanceList;
|
||||
if(GenI == NULL) {
|
||||
@@ -828,7 +836,7 @@ rename(
|
||||
retval = -1;
|
||||
}
|
||||
else {
|
||||
GenI += (Instance * FromNode->InstanceSize);
|
||||
//GenI += (Instance * FromNode->InstanceSize);
|
||||
retval = ((GenericInstance *)GenI)->Abstraction.fo_rename( from, to);
|
||||
}
|
||||
free(FromPath);
|
||||
@@ -839,7 +847,6 @@ rename(
|
||||
/**
|
||||
**/
|
||||
int
|
||||
EFIAPI
|
||||
rmdir(
|
||||
const char *path
|
||||
)
|
||||
@@ -1006,13 +1013,13 @@ ioctl(
|
||||
from a file associated with a terminal may return one typed line of data.
|
||||
|
||||
If fildes does not refer to a directory, the function reads the requested
|
||||
number of bytes from the file at the file<EFBFBD>s current position and returns
|
||||
number of bytes from the file at the file's current position and returns
|
||||
them in buf. If the read goes beyond the end of the file, the read
|
||||
length is truncated to the end of the file. The file<EFBFBD>s current position is
|
||||
length is truncated to the end of the file. The file's current position is
|
||||
increased by the number of bytes returned.
|
||||
|
||||
If fildes refers to a directory, the function reads the directory entry at
|
||||
the file<EFBFBD>s current position and returns the entry in buf. If buf
|
||||
the file's current position and returns the entry in buf. If buf
|
||||
is not large enough to hold the current directory entry, then
|
||||
errno is set to EBUFSIZE, EFIerrno is set to EFI_BUFFER_TOO_SMALL, and the
|
||||
current file position is not updated. The size of the buffer needed to read
|
||||
@@ -1129,3 +1136,56 @@ char
|
||||
|
||||
return (UnicodeStrToAsciiStr(Cwd, buf));
|
||||
}
|
||||
|
||||
/** Change the current working directory.
|
||||
|
||||
The chdir() function shall cause the directory named by the pathname
|
||||
pointed to by the path argument to become the current working directory;
|
||||
that is, the starting point for path searches for pathnames not beginning
|
||||
with '/'.
|
||||
|
||||
@param[in] path The new path to set.
|
||||
|
||||
@todo Add non-shell CWD changing.
|
||||
**/
|
||||
int
|
||||
chdir (const char *path)
|
||||
{
|
||||
CONST CHAR16 *Cwd;
|
||||
EFI_STATUS Status;
|
||||
CHAR16 *UnicodePath;
|
||||
|
||||
Cwd = ShellGetCurrentDir(NULL);
|
||||
if (Cwd != NULL) {
|
||||
/* We have shell support */
|
||||
UnicodePath = AllocatePool(((AsciiStrLen (path) + 1) * sizeof (CHAR16)));
|
||||
if (UnicodePath == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
AsciiStrToUnicodeStr(path, UnicodePath);
|
||||
Status = gEfiShellProtocol->SetCurDir(NULL, UnicodePath);
|
||||
FreePool(UnicodePath);
|
||||
if (EFI_ERROR(Status)) {
|
||||
errno = EACCES;
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add here for non-shell */
|
||||
errno = EACCES;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pid_t tcgetpgrp (int x)
|
||||
{
|
||||
return ((pid_t)(UINTN)(gImageHandle));
|
||||
}
|
||||
|
||||
pid_t getpgrp(void)
|
||||
{
|
||||
return ((pid_t)(UINTN)(gImageHandle));
|
||||
}
|
||||
|
||||
|
@@ -16,18 +16,24 @@
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = LibUefi
|
||||
FILE_GUID = 39356e02-26bf-4cfb-9564-378ce25e702f
|
||||
FILE_GUID = 1dcff17c-aa53-4b78-b234-864027555035
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = LibUefi
|
||||
LIBRARY_CONSTRUCTOR = DestructMePlease
|
||||
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
select.c
|
||||
SysCalls.c
|
||||
writev.c
|
||||
Xform.c
|
||||
compat.c
|
||||
GetPass.c
|
||||
StubFunctions.c
|
||||
|
||||
[Packages]
|
||||
StdLib/StdLib.dec
|
||||
|
847
StdLib/LibC/Uefi/compat.c
Normal file
847
StdLib/LibC/Uefi/compat.c
Normal file
@@ -0,0 +1,847 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: compat.c,v 1.1.1.1 2008/08/24 05:33:08 gmcgarry Exp $
|
||||
|
||||
* Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Klaus Klein and Jason R. Thorpe.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $NetBSD: compat.c,v 1.1.1.1 2008/08/24 05:33:08 gmcgarry Exp $
|
||||
|
||||
* Copyright (c) 1987, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $NetBSD: compat.c,v 1.1.1.1 2008/08/24 05:33:08 gmcgarry Exp $
|
||||
*/
|
||||
#include <LibConfig.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifndef HAVE_GETOPT
|
||||
char *optarg;
|
||||
int optind = 1;
|
||||
int
|
||||
getopt(int argc, char **argv, char *args)
|
||||
{
|
||||
size_t n;
|
||||
size_t nlen = strlen(args);
|
||||
char cmd;
|
||||
char rv;
|
||||
|
||||
if (argv[optind] && *argv[optind] == '-') {
|
||||
cmd = *(argv[optind] + 1);
|
||||
|
||||
for (n = 0; n < nlen; n++) {
|
||||
if (args[n] == ':')
|
||||
continue;
|
||||
if (args[n] == cmd) {
|
||||
rv = *(argv[optind] + 1);
|
||||
if (args[n+1] == ':') {
|
||||
if (*(argv[optind] + 2) != '\0') {
|
||||
optarg = argv[optind] + 2;
|
||||
optind += 1;
|
||||
} else {
|
||||
optarg = argv[optind + 1];
|
||||
optind += 2;
|
||||
}
|
||||
if (!optarg)
|
||||
optarg="";
|
||||
return rv;
|
||||
} else {
|
||||
optarg = NULL;
|
||||
optind += 1;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define ISPATHSEPARATOR(x) ((x == '/') || (x == '\\'))
|
||||
#else
|
||||
#define ISPATHSEPARATOR(x) (x == '/')
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BASENAME
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 5000
|
||||
#endif
|
||||
|
||||
char *
|
||||
basename(char *path)
|
||||
{
|
||||
static char singledot[] = ".";
|
||||
static char result[PATH_MAX];
|
||||
char *p, *lastp;
|
||||
size_t len;
|
||||
|
||||
/*
|
||||
* If `path' is a null pointer or points to an empty string,
|
||||
* return a pointer to the string ".".
|
||||
*/
|
||||
if ((path == NULL) || (*path == '\0'))
|
||||
return (singledot);
|
||||
|
||||
/* Strip trailing slashes, if any. */
|
||||
lastp = path + strlen(path) - 1;
|
||||
while (lastp != path && ISPATHSEPARATOR(*lastp))
|
||||
lastp--;
|
||||
|
||||
/* Now find the beginning of this (final) component. */
|
||||
p = lastp;
|
||||
while (p != path && !ISPATHSEPARATOR(*(p - 1)))
|
||||
p--;
|
||||
|
||||
/* ...and copy the result into the result buffer. */
|
||||
len = (lastp - p) + 1 /* last char */;
|
||||
if (len > (PATH_MAX - 1))
|
||||
len = PATH_MAX - 1;
|
||||
|
||||
memcpy(result, p, len);
|
||||
result[len] = '\0';
|
||||
|
||||
return (result);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_MKSTEMP) && !defined(WIN32)
|
||||
int
|
||||
mkstemp(char *path)
|
||||
{
|
||||
char *start, *trv;
|
||||
unsigned int pid;
|
||||
|
||||
/* To guarantee multiple calls generate unique names even if
|
||||
the file is not created. 676 different possibilities with 7
|
||||
or more X's, 26 with 6 or less. */
|
||||
static char xtra[2] = "aa";
|
||||
int xcnt = 0;
|
||||
|
||||
pid = getpid();
|
||||
|
||||
/* Move to end of path and count trailing X's. */
|
||||
for (trv = path; *trv; ++trv)
|
||||
if (*trv == 'X')
|
||||
xcnt++;
|
||||
else
|
||||
xcnt = 0;
|
||||
|
||||
/* Use at least one from xtra. Use 2 if more than 6 X's. */
|
||||
if (*(trv - 1) == 'X')
|
||||
*--trv = xtra[0];
|
||||
if (xcnt > 6 && *(trv - 1) == 'X')
|
||||
*--trv = xtra[1];
|
||||
|
||||
/* Set remaining X's to pid digits with 0's to the left. */
|
||||
while (*--trv == 'X') {
|
||||
*trv = (pid % 10) + '0';
|
||||
pid /= 10;
|
||||
}
|
||||
|
||||
/* update xtra for next call. */
|
||||
if (xtra[0] != 'z')
|
||||
xtra[0]++;
|
||||
else {
|
||||
xtra[0] = 'a';
|
||||
if (xtra[1] != 'z')
|
||||
xtra[1]++;
|
||||
else
|
||||
xtra[1] = 'a';
|
||||
}
|
||||
|
||||
return open(path, O_CREAT | O_EXCL | O_RDWR, 0600);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FFS
|
||||
int
|
||||
ffs(int x)
|
||||
{
|
||||
int r = 1;
|
||||
if (!x) return 0;
|
||||
if (!(x & 0xffff)) { x >>= 16; r += 16; }
|
||||
if (!(x & 0xff)) { x >>= 8; r += 8; }
|
||||
if (!(x & 0xf)) { x >>= 4; r += 4; }
|
||||
if (!(x & 3)) { x >>= 2; r += 2; }
|
||||
if (!(x & 1)) { x >>= 1; r += 1; }
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright Patrick Powell 1995
|
||||
* This code is based on code written by Patrick Powell (papowell@astart.com)
|
||||
* It may be used for any purpose as long as this notice remains intact
|
||||
* on all source code distributions
|
||||
*/
|
||||
|
||||
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
|
||||
|
||||
static void
|
||||
dopr(char *buffer, size_t maxlen, const char *format, va_list args);
|
||||
|
||||
static void
|
||||
fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags,
|
||||
int min, int max);
|
||||
|
||||
static void
|
||||
fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base,
|
||||
int min, int max, int flags);
|
||||
|
||||
static void
|
||||
fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue,
|
||||
int min, int max, int flags);
|
||||
|
||||
static void
|
||||
dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
|
||||
|
||||
/*
|
||||
* dopr(): poor man's version of doprintf
|
||||
*/
|
||||
|
||||
/* format read states */
|
||||
#define DP_S_DEFAULT 0
|
||||
#define DP_S_FLAGS 1
|
||||
#define DP_S_MIN 2
|
||||
#define DP_S_DOT 3
|
||||
#define DP_S_MAX 4
|
||||
#define DP_S_MOD 5
|
||||
#define DP_S_CONV 6
|
||||
#define DP_S_DONE 7
|
||||
|
||||
/* format flags - Bits */
|
||||
#define DP_F_MINUS (1 << 0)
|
||||
#define DP_F_PLUS (1 << 1)
|
||||
#define DP_F_SPACE (1 << 2)
|
||||
#define DP_F_NUM (1 << 3)
|
||||
#define DP_F_ZERO (1 << 4)
|
||||
#define DP_F_UP (1 << 5)
|
||||
#define DP_F_UNSIGNED (1 << 6)
|
||||
|
||||
/* Conversion Flags */
|
||||
#define DP_C_SHORT 1
|
||||
#define DP_C_LONG 2
|
||||
#define DP_C_LDOUBLE 3
|
||||
#define DP_C_LONG_LONG 4
|
||||
|
||||
#define char_to_int(p) (p - '0')
|
||||
#define abs_val(p) (p < 0 ? -p : p)
|
||||
|
||||
|
||||
static void
|
||||
dopr(char *buffer, size_t maxlen, const char *format, va_list args)
|
||||
{
|
||||
char *strvalue, ch;
|
||||
long value;
|
||||
long double fvalue;
|
||||
int min = 0, max = -1, state = DP_S_DEFAULT, flags = 0, cflags = 0;
|
||||
size_t currlen = 0;
|
||||
|
||||
ch = *format++;
|
||||
|
||||
while (state != DP_S_DONE) {
|
||||
if ((ch == '\0') || (currlen >= maxlen))
|
||||
state = DP_S_DONE;
|
||||
|
||||
switch(state) {
|
||||
case DP_S_DEFAULT:
|
||||
if (ch == '%')
|
||||
state = DP_S_FLAGS;
|
||||
else
|
||||
dopr_outch(buffer, &currlen, maxlen, ch);
|
||||
ch = *format++;
|
||||
break;
|
||||
case DP_S_FLAGS:
|
||||
switch (ch) {
|
||||
case '-':
|
||||
flags |= DP_F_MINUS;
|
||||
ch = *format++;
|
||||
break;
|
||||
case '+':
|
||||
flags |= DP_F_PLUS;
|
||||
ch = *format++;
|
||||
break;
|
||||
case ' ':
|
||||
flags |= DP_F_SPACE;
|
||||
ch = *format++;
|
||||
break;
|
||||
case '#':
|
||||
flags |= DP_F_NUM;
|
||||
ch = *format++;
|
||||
break;
|
||||
case '0':
|
||||
flags |= DP_F_ZERO;
|
||||
ch = *format++;
|
||||
break;
|
||||
default:
|
||||
state = DP_S_MIN;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DP_S_MIN:
|
||||
if (isdigit((unsigned char)ch)) {
|
||||
min = 10 * min + char_to_int (ch);
|
||||
ch = *format++;
|
||||
} else if (ch == '*') {
|
||||
min = va_arg (args, int);
|
||||
ch = *format++;
|
||||
state = DP_S_DOT;
|
||||
} else
|
||||
state = DP_S_DOT;
|
||||
break;
|
||||
case DP_S_DOT:
|
||||
if (ch == '.') {
|
||||
state = DP_S_MAX;
|
||||
ch = *format++;
|
||||
} else
|
||||
state = DP_S_MOD;
|
||||
break;
|
||||
case DP_S_MAX:
|
||||
if (isdigit((unsigned char)ch)) {
|
||||
if (max < 0)
|
||||
max = 0;
|
||||
max = 10 * max + char_to_int(ch);
|
||||
ch = *format++;
|
||||
} else if (ch == '*') {
|
||||
max = va_arg (args, int);
|
||||
ch = *format++;
|
||||
state = DP_S_MOD;
|
||||
} else
|
||||
state = DP_S_MOD;
|
||||
break;
|
||||
case DP_S_MOD:
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
cflags = DP_C_SHORT;
|
||||
ch = *format++;
|
||||
break;
|
||||
case 'l':
|
||||
cflags = DP_C_LONG;
|
||||
ch = *format++;
|
||||
if (ch == 'l') {
|
||||
cflags = DP_C_LONG_LONG;
|
||||
ch = *format++;
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
cflags = DP_C_LONG_LONG;
|
||||
ch = *format++;
|
||||
break;
|
||||
case 'L':
|
||||
cflags = DP_C_LDOUBLE;
|
||||
ch = *format++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
state = DP_S_CONV;
|
||||
break;
|
||||
case DP_S_CONV:
|
||||
switch (ch) {
|
||||
case 'd':
|
||||
case 'i':
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = va_arg(args, int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg(args, long int);
|
||||
else if (cflags == DP_C_LONG_LONG)
|
||||
value = va_arg (args, long long);
|
||||
else
|
||||
value = va_arg (args, int);
|
||||
fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags);
|
||||
break;
|
||||
case 'o':
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = va_arg(args, unsigned int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg(args, unsigned long int);
|
||||
else if (cflags == DP_C_LONG_LONG)
|
||||
value = va_arg(args, unsigned long long);
|
||||
else
|
||||
value = va_arg(args, unsigned int);
|
||||
fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags);
|
||||
break;
|
||||
case 'u':
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = va_arg(args, unsigned int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg(args, unsigned long int);
|
||||
else if (cflags == DP_C_LONG_LONG)
|
||||
value = va_arg(args, unsigned long long);
|
||||
else
|
||||
value = va_arg(args, unsigned int);
|
||||
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
|
||||
break;
|
||||
case 'X':
|
||||
flags |= DP_F_UP;
|
||||
case 'x':
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = va_arg(args, unsigned int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg(args, unsigned long int);
|
||||
else if (cflags == DP_C_LONG_LONG)
|
||||
value = va_arg(args, unsigned long long);
|
||||
else
|
||||
value = va_arg(args, unsigned int);
|
||||
fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags);
|
||||
break;
|
||||
case 'f':
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg(args, long double);
|
||||
else
|
||||
fvalue = va_arg(args, double);
|
||||
/* um, floating point? */
|
||||
fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags);
|
||||
break;
|
||||
case 'E':
|
||||
flags |= DP_F_UP;
|
||||
case 'e':
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg(args, long double);
|
||||
else
|
||||
fvalue = va_arg(args, double);
|
||||
break;
|
||||
case 'G':
|
||||
flags |= DP_F_UP;
|
||||
case 'g':
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg(args, long double);
|
||||
else
|
||||
fvalue = va_arg(args, double);
|
||||
break;
|
||||
case 'c':
|
||||
dopr_outch(buffer, &currlen, maxlen, va_arg(args, int));
|
||||
break;
|
||||
case 's':
|
||||
strvalue = va_arg(args, char *);
|
||||
if (max < 0)
|
||||
max = maxlen; /* ie, no max */
|
||||
fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max);
|
||||
break;
|
||||
case 'p':
|
||||
strvalue = va_arg(args, void *);
|
||||
fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
|
||||
break;
|
||||
case 'n':
|
||||
if (cflags == DP_C_SHORT) {
|
||||
short int *num;
|
||||
num = va_arg(args, short int *);
|
||||
*num = currlen;
|
||||
} else if (cflags == DP_C_LONG) {
|
||||
long int *num;
|
||||
num = va_arg(args, long int *);
|
||||
*num = currlen;
|
||||
} else if (cflags == DP_C_LONG_LONG) {
|
||||
long long *num;
|
||||
num = va_arg(args, long long *);
|
||||
*num = currlen;
|
||||
} else {
|
||||
int *num;
|
||||
num = va_arg(args, int *);
|
||||
*num = currlen;
|
||||
}
|
||||
break;
|
||||
case '%':
|
||||
dopr_outch(buffer, &currlen, maxlen, ch);
|
||||
break;
|
||||
case 'w': /* not supported yet, treat as next char */
|
||||
ch = *format++;
|
||||
break;
|
||||
default: /* Unknown, skip */
|
||||
break;
|
||||
}
|
||||
ch = *format++;
|
||||
state = DP_S_DEFAULT;
|
||||
flags = cflags = min = 0;
|
||||
max = -1;
|
||||
break;
|
||||
case DP_S_DONE:
|
||||
break;
|
||||
default: /* hmm? */
|
||||
break; /* some picky compilers need this */
|
||||
}
|
||||
}
|
||||
if (currlen < maxlen - 1)
|
||||
buffer[currlen] = '\0';
|
||||
else
|
||||
buffer[maxlen - 1] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
fmtstr(char *buffer, size_t *currlen, size_t maxlen,
|
||||
char *value, int flags, int min, int max)
|
||||
{
|
||||
int cnt = 0, padlen, strln; /* amount to pad */
|
||||
|
||||
if (value == 0)
|
||||
value = "<NULL>";
|
||||
|
||||
for (strln = 0; value[strln]; ++strln); /* strlen */
|
||||
padlen = min - strln;
|
||||
if (padlen < 0)
|
||||
padlen = 0;
|
||||
if (flags & DP_F_MINUS)
|
||||
padlen = -padlen; /* Left Justify */
|
||||
|
||||
while ((padlen > 0) && (cnt < max)) {
|
||||
dopr_outch(buffer, currlen, maxlen, ' ');
|
||||
--padlen;
|
||||
++cnt;
|
||||
}
|
||||
while (*value && (cnt < max)) {
|
||||
dopr_outch(buffer, currlen, maxlen, *value++);
|
||||
++cnt;
|
||||
}
|
||||
while ((padlen < 0) && (cnt < max)) {
|
||||
dopr_outch(buffer, currlen, maxlen, ' ');
|
||||
++padlen;
|
||||
++cnt;
|
||||
}
|
||||
}
|
||||
|
||||
/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
|
||||
|
||||
static void
|
||||
fmtint(char *buffer, size_t *currlen, size_t maxlen,
|
||||
long value, int base, int min, int max, int flags)
|
||||
{
|
||||
unsigned long uvalue;
|
||||
char convert[20];
|
||||
int signvalue = 0, place = 0, caps = 0;
|
||||
int spadlen = 0; /* amount to space pad */
|
||||
int zpadlen = 0; /* amount to zero pad */
|
||||
|
||||
#define PADMAX(x,y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
if (max < 0)
|
||||
max = 0;
|
||||
|
||||
uvalue = value;
|
||||
|
||||
if (!(flags & DP_F_UNSIGNED)) {
|
||||
if (value < 0) {
|
||||
signvalue = '-';
|
||||
uvalue = -value;
|
||||
} else if (flags & DP_F_PLUS) /* Do a sign (+/i) */
|
||||
signvalue = '+';
|
||||
else if (flags & DP_F_SPACE)
|
||||
signvalue = ' ';
|
||||
}
|
||||
|
||||
if (flags & DP_F_UP)
|
||||
caps = 1; /* Should characters be upper case? */
|
||||
do {
|
||||
convert[place++] =
|
||||
(caps ? "0123456789ABCDEF" : "0123456789abcdef")
|
||||
[uvalue % (unsigned)base];
|
||||
uvalue = (uvalue / (unsigned)base );
|
||||
} while (uvalue && (place < 20));
|
||||
if (place == 20)
|
||||
place--;
|
||||
convert[place] = 0;
|
||||
|
||||
zpadlen = max - place;
|
||||
spadlen = min - PADMAX(max, place) - (signvalue ? 1 : 0);
|
||||
if (zpadlen < 0)
|
||||
zpadlen = 0;
|
||||
if (spadlen < 0)
|
||||
spadlen = 0;
|
||||
if (flags & DP_F_ZERO) {
|
||||
zpadlen = PADMAX(zpadlen, spadlen);
|
||||
spadlen = 0;
|
||||
}
|
||||
if (flags & DP_F_MINUS)
|
||||
spadlen = -spadlen; /* Left Justifty */
|
||||
|
||||
/* Spaces */
|
||||
while (spadlen > 0) {
|
||||
dopr_outch(buffer, currlen, maxlen, ' ');
|
||||
--spadlen;
|
||||
}
|
||||
|
||||
/* Sign */
|
||||
if (signvalue)
|
||||
dopr_outch(buffer, currlen, maxlen, signvalue);
|
||||
|
||||
/* Zeros */
|
||||
if (zpadlen > 0) {
|
||||
while (zpadlen > 0) {
|
||||
dopr_outch(buffer, currlen, maxlen, '0');
|
||||
--zpadlen;
|
||||
}
|
||||
}
|
||||
|
||||
/* Digits */
|
||||
while (place > 0)
|
||||
dopr_outch(buffer, currlen, maxlen, convert[--place]);
|
||||
|
||||
/* Left Justified spaces */
|
||||
while (spadlen < 0) {
|
||||
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||
++spadlen;
|
||||
}
|
||||
}
|
||||
|
||||
static long double
|
||||
pow10(int exp)
|
||||
{
|
||||
long double result = 1;
|
||||
|
||||
while (exp) {
|
||||
result *= 10;
|
||||
exp--;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static long
|
||||
round(long double value)
|
||||
{
|
||||
long intpart = value;
|
||||
|
||||
value -= intpart;
|
||||
if (value >= 0.5)
|
||||
intpart++;
|
||||
|
||||
return intpart;
|
||||
}
|
||||
|
||||
static void
|
||||
fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue,
|
||||
int min, int max, int flags)
|
||||
{
|
||||
char iconvert[20], fconvert[20];
|
||||
int signvalue = 0, iplace = 0, fplace = 0;
|
||||
int padlen = 0; /* amount to pad */
|
||||
int zpadlen = 0, caps = 0;
|
||||
long intpart, fracpart;
|
||||
long double ufvalue;
|
||||
|
||||
/*
|
||||
* AIX manpage says the default is 0, but Solaris says the default
|
||||
* is 6, and sprintf on AIX defaults to 6
|
||||
*/
|
||||
if (max < 0)
|
||||
max = 6;
|
||||
|
||||
ufvalue = abs_val(fvalue);
|
||||
|
||||
if (fvalue < 0)
|
||||
signvalue = '-';
|
||||
else if (flags & DP_F_PLUS) /* Do a sign (+/i) */
|
||||
signvalue = '+';
|
||||
else if (flags & DP_F_SPACE)
|
||||
signvalue = ' ';
|
||||
|
||||
intpart = ufvalue;
|
||||
|
||||
/*
|
||||
* Sorry, we only support 9 digits past the decimal because of our
|
||||
* conversion method
|
||||
*/
|
||||
if (max > 9)
|
||||
max = 9;
|
||||
|
||||
/* We "cheat" by converting the fractional part to integer by
|
||||
* multiplying by a factor of 10
|
||||
*/
|
||||
fracpart = round((pow10 (max)) * (ufvalue - intpart));
|
||||
|
||||
if (fracpart >= pow10 (max)) {
|
||||
intpart++;
|
||||
fracpart -= pow10 (max);
|
||||
}
|
||||
|
||||
/* Convert integer part */
|
||||
do {
|
||||
iconvert[iplace++] =
|
||||
(caps ? "0123456789ABCDEF" : "0123456789abcdef")
|
||||
[intpart % 10];
|
||||
intpart = (intpart / 10);
|
||||
} while(intpart && (iplace < 20));
|
||||
if (iplace == 20)
|
||||
iplace--;
|
||||
iconvert[iplace] = 0;
|
||||
|
||||
/* Convert fractional part */
|
||||
do {
|
||||
fconvert[fplace++] =
|
||||
(caps ? "0123456789ABCDEF" : "0123456789abcdef")
|
||||
[fracpart % 10];
|
||||
fracpart = (fracpart / 10);
|
||||
} while(fracpart && (fplace < 20));
|
||||
if (fplace == 20)
|
||||
fplace--;
|
||||
fconvert[fplace] = 0;
|
||||
|
||||
/* -1 for decimal point, another -1 if we are printing a sign */
|
||||
padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
|
||||
zpadlen = max - fplace;
|
||||
if (zpadlen < 0)
|
||||
zpadlen = 0;
|
||||
if (padlen < 0)
|
||||
padlen = 0;
|
||||
if (flags & DP_F_MINUS)
|
||||
padlen = -padlen; /* Left Justifty */
|
||||
|
||||
if ((flags & DP_F_ZERO) && (padlen > 0)) {
|
||||
if (signvalue) {
|
||||
dopr_outch(buffer, currlen, maxlen, signvalue);
|
||||
--padlen;
|
||||
signvalue = 0;
|
||||
}
|
||||
while (padlen > 0) {
|
||||
dopr_outch(buffer, currlen, maxlen, '0');
|
||||
--padlen;
|
||||
}
|
||||
}
|
||||
while (padlen > 0) {
|
||||
dopr_outch(buffer, currlen, maxlen, ' ');
|
||||
--padlen;
|
||||
}
|
||||
if (signvalue)
|
||||
dopr_outch(buffer, currlen, maxlen, signvalue);
|
||||
|
||||
while (iplace > 0)
|
||||
dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]);
|
||||
|
||||
/*
|
||||
* Decimal point. This should probably use locale to find the
|
||||
* correct char to print out.
|
||||
*/
|
||||
dopr_outch(buffer, currlen, maxlen, '.');
|
||||
|
||||
while (fplace > 0)
|
||||
dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]);
|
||||
|
||||
while (zpadlen > 0) {
|
||||
dopr_outch(buffer, currlen, maxlen, '0');
|
||||
--zpadlen;
|
||||
}
|
||||
|
||||
while (padlen < 0) {
|
||||
dopr_outch(buffer, currlen, maxlen, ' ');
|
||||
++padlen;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
|
||||
{
|
||||
if (*currlen < maxlen)
|
||||
buffer[(*currlen)++] = c;
|
||||
}
|
||||
#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
|
||||
|
||||
#ifndef HAVE_VSNPRINTF
|
||||
int
|
||||
vsnprintf(char *str, size_t count, const char *fmt, va_list args)
|
||||
{
|
||||
str[0] = 0;
|
||||
dopr(str, count, fmt, args);
|
||||
|
||||
return(strlen(str));
|
||||
}
|
||||
#endif /* !HAVE_VSNPRINTF */
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
int
|
||||
snprintf(char *str,size_t count,const char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
(void) vsnprintf(str, count, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return(strlen(str));
|
||||
}
|
||||
|
||||
#endif /* !HAVE_SNPRINTF */
|
256
StdLib/LibC/Uefi/select.c
Normal file
256
StdLib/LibC/Uefi/select.c
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* Portions copyright (c) 1999, 2000
|
||||
* Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
*
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley, Intel Corporation, and its contributors.
|
||||
*
|
||||
* 4. Neither the name of University, Intel Corporation, or their respective
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND
|
||||
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS,
|
||||
* INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @(#)sys_generic.c 8.5 (Berkeley) 1/21/94
|
||||
* $Id: select.c,v 1.1.1.1 2003/11/19 01:50:30 kyu3 Exp $
|
||||
*/
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
#include <LibConfig.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <extern.h> /* For ffs() */
|
||||
#ifndef KERNEL
|
||||
#define KERNEL
|
||||
#include <errno.h>
|
||||
#undef KERNEL
|
||||
#else
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef EFI_NT_EMULATOR
|
||||
#define _SELECT_DELAY_ 10000
|
||||
#else
|
||||
#define _SELECT_DELAY_ 1000
|
||||
#endif
|
||||
|
||||
#define MAX_SLEEP_DELAY 0xfffffffe
|
||||
|
||||
//
|
||||
// Name:
|
||||
// usleep
|
||||
//
|
||||
// Description:
|
||||
// Implement usleep(3) function.
|
||||
//
|
||||
// Arguments:
|
||||
// Microseconds to sleep.
|
||||
//
|
||||
// Returns:
|
||||
// 0
|
||||
//
|
||||
int
|
||||
usleep( useconds_t Microseconds )
|
||||
{
|
||||
while ( MAX_SLEEP_DELAY < Microseconds ) {
|
||||
gBS->Stall ( MAX_SLEEP_DELAY );
|
||||
Microseconds -= MAX_SLEEP_DELAY;
|
||||
}
|
||||
gBS->Stall((UINTN)Microseconds );
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
selscan(
|
||||
fd_mask **ibits,
|
||||
fd_mask **obits,
|
||||
int nfd,
|
||||
int *nselected
|
||||
)
|
||||
{
|
||||
int msk;
|
||||
int i;
|
||||
int j;
|
||||
int fd;
|
||||
int n;
|
||||
struct pollfd pfd;
|
||||
int FdCount;
|
||||
fd_mask bits;
|
||||
/* Note: backend also returns POLLHUP/POLLERR if appropriate. */
|
||||
static int16_t flag[3] = { POLLRDNORM, POLLWRNORM, POLLRDBAND };
|
||||
|
||||
for (msk = 0, n = 0; msk < 3; msk++) {
|
||||
if (ibits[msk] == NULL)
|
||||
continue;
|
||||
for (i = 0; i < nfd; i += NFDBITS) {
|
||||
bits = ibits[ msk ][ i / NFDBITS ];
|
||||
while (( 0 != (j = ffs(bits))) && ((fd = i + --j) < nfd)) {
|
||||
bits &= ~(1 << j);
|
||||
|
||||
pfd.fd = fd;
|
||||
pfd.events = flag[msk];
|
||||
pfd.revents = 0;
|
||||
FdCount = poll ( &pfd, 1, 0 );
|
||||
if ( -1 == FdCount ) {
|
||||
return errno;
|
||||
}
|
||||
if ( 0 != FdCount ) {
|
||||
obits[msk][(fd)/NFDBITS] |=
|
||||
(1 << ((fd) % NFDBITS));
|
||||
n++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*nselected = n;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
select(
|
||||
int nd,
|
||||
fd_set *in,
|
||||
fd_set *ou,
|
||||
fd_set *ex,
|
||||
struct timeval *tv
|
||||
)
|
||||
{
|
||||
fd_mask *ibits[3], *obits[3], *selbits, *sbp;
|
||||
int error, forever, nselected;
|
||||
u_int nbufbytes, ncpbytes, nfdbits;
|
||||
int64_t timo;
|
||||
|
||||
if (nd < 0)
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
* Allocate just enough bits for the non-null fd_sets. Use the
|
||||
* preallocated auto buffer if possible.
|
||||
*/
|
||||
nfdbits = roundup(nd, NFDBITS);
|
||||
ncpbytes = nfdbits / NBBY;
|
||||
nbufbytes = 0;
|
||||
if (in != NULL)
|
||||
nbufbytes += 2 * ncpbytes;
|
||||
if (ou != NULL)
|
||||
nbufbytes += 2 * ncpbytes;
|
||||
if (ex != NULL)
|
||||
nbufbytes += 2 * ncpbytes;
|
||||
selbits = malloc(nbufbytes);
|
||||
|
||||
/*
|
||||
* Assign pointers into the bit buffers and fetch the input bits.
|
||||
* Put the output buffers together so that they can be bzeroed
|
||||
* together.
|
||||
*/
|
||||
sbp = selbits;
|
||||
#define getbits(name, x) \
|
||||
do { \
|
||||
if (name == NULL) \
|
||||
ibits[x] = NULL; \
|
||||
else { \
|
||||
ibits[x] = sbp + nbufbytes / 2 / sizeof *sbp; \
|
||||
obits[x] = sbp; \
|
||||
sbp += ncpbytes / sizeof *sbp; \
|
||||
bcopy(name, ibits[x], ncpbytes); \
|
||||
} \
|
||||
} while (0)
|
||||
getbits(in, 0);
|
||||
getbits(ou, 1);
|
||||
getbits(ex, 2);
|
||||
#undef getbits
|
||||
if (nbufbytes != 0)
|
||||
memset(selbits, 0, nbufbytes / 2);
|
||||
|
||||
if (tv) {
|
||||
timo = tv->tv_usec + (tv->tv_sec * 1000000);
|
||||
forever = 0;
|
||||
} else {
|
||||
timo = 0;
|
||||
forever = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Poll for I/O events
|
||||
*/
|
||||
nselected = 0;
|
||||
do {
|
||||
/*
|
||||
* Scan for pending I/O
|
||||
*/
|
||||
error = selscan(ibits, obits, nd, &nselected);
|
||||
if (error || nselected)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Adjust timeout is needed
|
||||
*/
|
||||
if (timo) {
|
||||
/*
|
||||
* Give it a rest
|
||||
*/
|
||||
usleep( _SELECT_DELAY_ );
|
||||
timo -= _SELECT_DELAY_;
|
||||
}
|
||||
|
||||
} while (timo > 0 || forever);
|
||||
|
||||
/* select is not restarted after signals... */
|
||||
if (error == ERESTART)
|
||||
error = EINTR;
|
||||
else if (error == EWOULDBLOCK)
|
||||
error = 0;
|
||||
|
||||
#define putbits(name, x) if (name) bcopy(obits[x], name, ncpbytes)
|
||||
if (error == 0) {
|
||||
putbits(in, 0);
|
||||
putbits(ou, 1);
|
||||
putbits(ex, 2);
|
||||
#undef putbits
|
||||
} else {
|
||||
errno = error;
|
||||
nselected = -1;
|
||||
}
|
||||
|
||||
free( selbits );
|
||||
return ( nselected );
|
||||
}
|
143
StdLib/LibC/Uefi/writev.c
Normal file
143
StdLib/LibC/Uefi/writev.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2000
|
||||
* Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this software must
|
||||
* display the following acknowledgement:
|
||||
*
|
||||
* This product includes software developed by Intel Corporation and its
|
||||
* contributors.
|
||||
*
|
||||
* 4. Neither the name of Intel Corporation or its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*++
|
||||
|
||||
Module Name:
|
||||
|
||||
writev.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Functions implementing the standard "writev" system call interface
|
||||
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
#include <LibConfig.h>
|
||||
|
||||
#ifdef foo
|
||||
#include <efi_interface.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#define KERNEL
|
||||
#include <errno.h>
|
||||
#undef KERNEL
|
||||
#include "./filedesc.h"
|
||||
|
||||
#include <libc_debug.h>
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/uio.h>
|
||||
#include <string.h>
|
||||
#ifndef KERNEL
|
||||
#define KERNEL
|
||||
#include <errno.h>
|
||||
#undef KERNEL
|
||||
#else
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
//
|
||||
// Name:
|
||||
// writev
|
||||
//
|
||||
// Description:
|
||||
// BSD writev interface for libc
|
||||
//
|
||||
// Arguments:
|
||||
// File Descriptor (index into file descriptor table)
|
||||
// iovec pointer
|
||||
// size of iovec array
|
||||
//
|
||||
// Returns:
|
||||
// number of bytes written
|
||||
//
|
||||
|
||||
ssize_t
|
||||
writev(
|
||||
int fd,
|
||||
const struct iovec *iov,
|
||||
int iovcnt
|
||||
)
|
||||
{
|
||||
const struct iovec *pVecTmp;
|
||||
char *pBuf, *pBufTmp;
|
||||
size_t TotalBytes, i, ret;
|
||||
|
||||
//
|
||||
// See how much memory we'll need
|
||||
//
|
||||
|
||||
for (i = 0, TotalBytes = 0, pVecTmp = iov; i < (size_t)iovcnt; i++, pVecTmp++) {
|
||||
TotalBytes += pVecTmp->iov_len;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate a contiguous buffer
|
||||
//
|
||||
|
||||
pBuf = (char*)malloc (TotalBytes);
|
||||
if (pBuf == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Copy vectors to the buffer
|
||||
//
|
||||
|
||||
for (pBufTmp = pBuf; iovcnt; iovcnt--) {
|
||||
bcopy(iov->iov_base, pBuf, iov->iov_len);
|
||||
pBuf += iov->iov_len;
|
||||
iov++;
|
||||
}
|
||||
|
||||
//
|
||||
// Use standard write(2) then free buffer
|
||||
//
|
||||
|
||||
ret = write (fd, pBuf, TotalBytes);
|
||||
free (pBuf);
|
||||
|
||||
return (ret);
|
||||
}
|
Reference in New Issue
Block a user