From: darylm503 Date: Tue, 28 Jun 2011 02:34:10 +0000 (+0000) Subject: Add device abstraction code for the UEFI Console and UEFI Shell-based file systems. X-Git-Tag: edk2-stable201903~14604 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=53e1e5c647b73e45569ed6e8b8a0a5b276aa685e Add device abstraction code for the UEFI Console and UEFI Shell-based file systems. Make argv use narrow characters instead of wide characters. Add setenv functionality. Add poll() system call. Change signal names into macros – required for standards compliance. The enums were renamed and moved to sys/signal.h and the new macros reference the enums. Added SIGBREAK, which is required for Python. Modify stdio functions to fail cleanly when called with a NULL File Pointer argument. Added that just includes . By adding this wrapper, we improve compatibility with *nix files which assume exists. Add Added macros for bcopy(), bcmp() and strsep(). Modify the clock() function so that it does not hang when running under an emulation environment such as NT32. Move TM structure specific macros from the private tzfile.h into Add strncasecmp function. Add strptime function. Add gettimeofday function. Add getcwd function. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11908 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/StdLib/Include/netdb.h b/StdLib/Include/netdb.h new file mode 100644 index 0000000000..e645f77bd3 --- /dev/null +++ b/StdLib/Include/netdb.h @@ -0,0 +1,362 @@ +/* $NetBSD: netdb.h,v 1.55.2.1 2007/05/17 21:25:10 jdc Exp $ */ + +/* + * Copyright (c) 1980, 1983, 1988, 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. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * 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, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION 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. + * - + * Portions Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * 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 WIDE Project and + * its contributors. + * 4. Neither the name of the project 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 PROJECT 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 PROJECT 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. + * - + * --Copyright-- + */ + +/* + * @(#)netdb.h 8.1 (Berkeley) 6/2/93 + * Id: netdb.h,v 1.15.18.6 2006/10/02 01:23:09 marka Exp + */ + +#ifndef _NETDB_H_ +#define _NETDB_H_ + +#include +#include +#include +#include +#include +#include +/* + * Data types + */ +#ifndef socklen_t +typedef __socklen_t socklen_t; +#define socklen_t __socklen_t +#endif + +#ifdef _EFI_SIZE_T_ + typedef _EFI_SIZE_T_ size_t; + #undef _EFI_SIZE_T_ + #undef _BSD_SIZE_T_ +#endif + +////#if defined(_NETBSD_SOURCE) +////#ifndef _PATH_HEQUIV +////#define _PATH_HEQUIV "/etc/hosts.equiv" +////#endif +#ifndef _PATH_HOSTS +#define _PATH_HOSTS "/etc/hosts" +#endif +#ifndef _PATH_NETWORKS +#define _PATH_NETWORKS "/etc/networks" +#endif +#ifndef _PATH_PROTOCOLS +#define _PATH_PROTOCOLS "/etc/protocols" +#endif +#ifndef _PATH_SERVICES +#define _PATH_SERVICES "/etc/services" +#endif +////#ifndef _PATH_SERVICES_DB +////#define _PATH_SERVICES_DB "/var/db/services.db" +////#endif +////#endif + +__BEGIN_DECLS +extern int h_errno; +__END_DECLS + +/*% + * Structures returned by network data base library. All addresses are + * supplied in host order, and returned in network order (suitable for + * use in system calls). + */ +struct hostent { + char *h_name; /*%< official name of host */ + char **h_aliases; /*%< alias list */ + int h_addrtype; /*%< host address type */ + int h_length; /*%< length of address */ + char **h_addr_list; /*%< list of addresses from name server */ +#define h_addr h_addr_list[0] /*%< address, for backward compatiblity */ +}; + +/*% + * Assumption here is that a network number + * fits in an unsigned long -- probably a poor one. + */ +struct netent { + char *n_name; /*%< official name of net */ + char **n_aliases; /*%< alias list */ + int n_addrtype; /*%< net address type */ +#if (defined(__sparc__) && defined(_LP64)) || \ + (defined(__sh__) && defined(_LP64) && (_BYTE_ORDER == _BIG_ENDIAN)) + int __n_pad0; /* ABI compatibility */ +#endif + uint32_t n_net; /*%< network # */ +#if defined(__alpha__) || (defined(__i386__) && defined(_LP64)) || \ + (defined(__sh__) && defined(_LP64) && (_BYTE_ORDER == _LITTLE_ENDIAN)) + int __n_pad0; /* ABI compatibility */ +#endif +}; + +struct servent { + char *s_name; /*%< official service name */ + char **s_aliases; /*%< alias list */ + int s_port; /*%< port # */ + char *s_proto; /*%< protocol to use */ +}; + +struct protoent { + char *p_name; /*%< official protocol name */ + char **p_aliases; /*%< alias list */ + int p_proto; /*%< protocol # */ +}; + +/* + * Note: ai_addrlen used to be a size_t, per RFC 2553. + * In XNS5.2, and subsequently in POSIX-2001 and + * draft-ietf-ipngwg-rfc2553bis-02.txt it was changed to a socklen_t. + * To accommodate for this while preserving binary compatibility with the + * old interface, we prepend or append 32 bits of padding, depending on + * the (LP64) architecture's endianness. + * + * This should be deleted the next time the libc major number is + * incremented. + */ +#if (_POSIX_C_SOURCE - 0) >= 200112L || (_XOPEN_SOURCE - 0) >= 520 || \ + defined(_NETBSD_SOURCE) +struct addrinfo { + int ai_flags; /*%< AI_PASSIVE, AI_CANONNAME */ + int ai_family; /*%< PF_xxx */ + int ai_socktype; /*%< SOCK_xxx */ + int ai_protocol; /*%< 0 or IPPROTO_xxx for IPv4 and IPv6 */ +#if defined(__sparc__) && defined(_LP64) + int __ai_pad0; /* ABI compatibility */ +#endif + socklen_t ai_addrlen; /*%< length of ai_addr */ +#if defined(__alpha__) || (defined(__i386__) && defined(_LP64)) + int __ai_pad0; /* ABI compatibility */ +#endif + char *ai_canonname; /*%< canonical name for hostname */ + struct sockaddr *ai_addr; /*%< binary address */ + struct addrinfo *ai_next; /*%< next structure in linked list */ +}; +#endif + +/*% + * Error return codes from gethostbyname() and gethostbyaddr() + * (left in extern int h_errno). + */ + +#if defined(_NETBSD_SOURCE) +#define NETDB_INTERNAL -1 /*%< see errno */ +#define NETDB_SUCCESS 0 /*%< no problem */ +#endif +////#define NO_ADDRESS NO_DATA /* no address, look for MX record */ +#define HOST_NOT_FOUND 1 /*%< Authoritative Answer Host not found */ +#define TRY_AGAIN 2 /*%< Non-Authoritive Host not found, or SERVERFAIL */ +#define NO_RECOVERY 3 /*%< Non recoverable errors, FORMERR, REFUSED, NOTIMP */ +////#define NO_DATA 4 /*%< Valid name, no data record of requested type */ +////#if defined(_NETBSD_SOURCE) +////#define NO_ADDRESS NO_DATA /*%< no address, look for MX record */ +////#endif + +/* + * Error return codes from getaddrinfo() + */ +#if 0 // Not supported by UEFI +#if (_POSIX_C_SOURCE - 0) >= 200112L || (_XOPEN_SOURCE - 0) >= 520 || \ + defined(_NETBSD_SOURCE) +#define EAI_ADDRFAMILY 1 /*%< address family for hostname not supported */ +#define EAI_AGAIN 2 /*%< temporary failure in name resolution */ +#define EAI_BADFLAGS 3 /*%< invalid value for ai_flags */ +#define EAI_FAIL 4 /*%< non-recoverable failure in name resolution */ +#define EAI_FAMILY 5 /*%< ai_family not supported */ +#define EAI_MEMORY 6 /*%< memory allocation failure */ +#define EAI_NODATA 7 /*%< no address associated with hostname */ +#define EAI_NONAME 8 /*%< hostname nor servname provided, or not known */ +#define EAI_SERVICE 9 /*%< servname not supported for ai_socktype */ +#define EAI_SOCKTYPE 10 /*%< ai_socktype not supported */ +#define EAI_SYSTEM 11 /*%< system error returned in errno */ +#define EAI_BADHINTS 12 /* invalid value for hints */ +#define EAI_PROTOCOL 13 /* resolved protocol is unknown */ +#define EAI_OVERFLOW 14 /* argument buffer overflow */ +#define EAI_MAX 15 +#endif /* _POSIX_C_SOURCE >= 200112 || _XOPEN_SOURCE >= 520 || _NETBSD_SOURCE */ +#endif // 0 Not supported by UEFI + +/*% + * Flag values for getaddrinfo() + */ +#if 0 // Not supported by UEFI +#if (_POSIX_C_SOURCE - 0) >= 200112L || (_XOPEN_SOURCE - 0) >= 520 || \ + defined(_NETBSD_SOURCE) +#define AI_PASSIVE 0x00000001 /* get address to use bind() */ +#endif +#endif // 0 Not supported by UEFI + +#define AI_CANONNAME 0x00000002 /* fill ai_canonname */ + +#if 0 // Not supported by UEFI +#if (_POSIX_C_SOURCE - 0) >= 200112L || (_XOPEN_SOURCE - 0) >= 520 || \ + defined(_NETBSD_SOURCE) +#define AI_NUMERICHOST 0x00000004 /* prevent host name resolution */ +#define AI_NUMERICSERV 0x00000008 /* prevent service name resolution */ +/* valid flags for addrinfo (not a standard def, apps should not use it) */ +#define AI_MASK \ + (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV) +#endif +#endif // 0 Not supported by UEFI + +/*% + * Constants for getnameinfo() + */ +////#if defined(_NETBSD_SOURCE) +#define NI_MAXHOST 1025 +#define NI_MAXSERV 32 +////#endif + +/*% + * Flag values for getnameinfo() + */ +////#define NI_NOFQDN 0x00000001 +#define NI_NUMERICHOST 0x00000002 +////#define NI_NAMEREQD 0x00000004 +#define NI_NUMERICSERV 0x00000008 +////#define NI_DGRAM 0x00000010 +////#define NI_NUMERICSCOPE 0x00000040 + +#if 0 // Not supported by UEFI +#if (_POSIX_C_SOURCE - 0) >= 200112L || (_XOPEN_SOURCE - 0) >= 520 || \ + defined(_NETBSD_SOURCE) +/*% + * Scope delimit character + */ +#if defined(_NETBSD_SOURCE) +#define SCOPE_DELIMITER '%' +#endif +#endif /* (_POSIX_C_SOURCE - 0) >= 200112L || ... */ +#endif // 0 Not supported by UEFI + +__BEGIN_DECLS +void endhostent(void); +void endnetent(void); +void endprotoent(void); +void endservent(void); +#if 0 // Not supported by UEFI +#if (_XOPEN_SOURCE - 0) >= 520 && (_XOPEN_SOURCE - 0) < 600 || \ + defined(_NETBSD_SOURCE) +#if 0 /* we do not ship this */ +void freehostent(struct hostent *); +#endif +#endif +#endif // 0 Not supported by UEFI +struct hostent *gethostbyaddr(const char *, socklen_t, int); +struct hostent *gethostbyname(const char *); +#if defined(_NETBSD_SOURCE) +struct hostent *gethostbyname2(const char *, int); +#endif +struct hostent *gethostent(void); +struct netent *getnetbyaddr(uint32_t, int); +struct netent *getnetbyname(const char *); +struct netent *getnetent(void); +struct protoent *getprotobyname(const char *); +struct protoent *getprotobynumber(int); +struct protoent *getprotoent(void); +struct servent *getservbyname(const char *, const char *); +struct servent *getservbyport(int, const char *); +struct servent *getservent(void); +////#if defined(_NETBSD_SOURCE) +////void herror(const char *); +////const char *hstrerror(int); +////#endif +void sethostent(int); +////#if defined(_NETBSD_SOURCE) +/* void sethostfile(const char *); */ +////#endif +void setnetent(int); +void setprotoent(int); +#if (_POSIX_C_SOURCE - 0) >= 200112L || (_XOPEN_SOURCE - 0) >= 520 || \ + defined(_NETBSD_SOURCE) +void setservent(int); +int getaddrinfo(const char * __restrict, const char * __restrict, + const struct addrinfo * __restrict, + struct addrinfo ** __restrict); +int getnameinfo(const struct sockaddr * __restrict, socklen_t, + char * __restrict, socklen_t, + char * __restrict, socklen_t, int); +void freeaddrinfo(struct addrinfo *); +const char *gai_strerror(int); +#endif +void setservent(int); + +__END_DECLS + +#endif /* !_NETDB_H_ */ diff --git a/StdLib/Include/netinet6/in6.h b/StdLib/Include/netinet6/in6.h index 7e81bb7084..f9a645aef1 100644 --- a/StdLib/Include/netinet6/in6.h +++ b/StdLib/Include/netinet6/in6.h @@ -736,9 +736,10 @@ extern u_char ip6_protox[]; #include -#ifdef _BSD_SIZE_T_ -typedef _BSD_SIZE_T_ size_t; +#ifdef _EFI_SIZE_T_ +typedef _EFI_SIZE_T_ size_t; #define _SIZE_T +#undef _EFI_SIZE_T_ #undef _BSD_SIZE_T_ #endif diff --git a/StdLib/Include/paths.h b/StdLib/Include/paths.h index 44c1dd1ece..389272f0d9 100644 --- a/StdLib/Include/paths.h +++ b/StdLib/Include/paths.h @@ -58,12 +58,9 @@ //#define _PATH_AUDIOCTL0 "/dev/audioctl0" //#define _PATH_BPF "/dev/bpf" //#define _PATH_CLOCKCTL "/dev/clockctl" -#define _PATH_CONSOLE "console:" -#define _PATH_CONSTTY "constty:" //#define _PATH_CSMAPPER "/usr/share/i18n/csmapper" //#define _PATH_DEFTAPE "/dev/nrst0" //#define _PATH_DEVDB "/var/run/dev.db" -#define _PATH_DEVNULL "null:" //#define _PATH_DRUM "/dev/drum" //#define _PATH_ESDB "/usr/share/i18n/esdb" //#define _PATH_FTPUSERS "/etc/ftpusers" @@ -72,7 +69,6 @@ //#define _PATH_KMEM "/dev/kmem" //#define _PATH_KSYMS "/dev/ksyms" //#define _PATH_KVMDB "/var/db/kvm.db" -#define _PATH_LOCALE "/Efi/Locale" //#define _PATH_MAILDIR "/var/mail" //#define _PATH_MAN "/usr/share/man" //#define _PATH_MEM "/dev/mem" @@ -86,33 +82,51 @@ //#define _PATH_SOUND "/dev/sound" //#define _PATH_SOUND0 "/dev/sound0" //#define _PATH_SYSMON "/dev/sysmon" -#define _PATH_TTY "tty:" //#define _PATH_UNIX "/netbsd" //#define _PATH_URANDOM "/dev/urandom" //#define _PATH_VI "/usr/bin/vi" + +// DOS style device paths +#define _PATH_TTYDEV "tty:" +#define _PATH_NULLDEV "null:" +#define _PATH_CONSOLE "console:" +#define _PATH_CONSTTY "constty:" #define _PATH_STDIN "stdin:" #define _PATH_STDOUT "stdout:" #define _PATH_STDERR "stderr:" +#define _PATH_SOCKET "socket:" + +// *nix style device paths +#define _PATH_DEVTTY "/dev/tty" +#define _PATH_DEVNULL "/dev/null" +#define _PATH_DEVCONSOLE "/dev/console" +#define _PATH_DEVCONSTTY "/dev/constty" +#define _PATH_DEVSTDIN "/dev/stdin" +#define _PATH_DEVSTDOUT "/dev/stdout" +#define _PATH_DEVSTDERR "/dev/stderr" +#define _PATH_DEVSOCKET "/dev/socket" + +// Special files and locations +#define _PATH_HOSTS "/Efi/etc/hosts" +#define _PATH_SERVICES "/Efi/etc/services" +#define _PATH_HOSTNAME "/Efi/etc/hostname" +#define _PATH_LOCALE "/Efi/etc/Locale" +#define _PATH_FSTAB "/Efi/etc/fstab" /* * Provide trailing slash, since mostly used for building pathnames. * see the __CONCAT() macro from for cpp examples. */ -//#define _PATH_DEV "/dev/" +#define _PATH_DEV "/dev/" +#define _PATH_TMP "/Efi/Temp/" //#define _PATH_DEV_PTS "/dev/pts/" //#define _PATH_EMUL_AOUT "/emul/aout/" -#define _PATH_TMP "/Efi/Temp/" //#define _PATH_VARDB "/var/db/" //#define _PATH_VARRUN "/var/run/" //#define _PATH_VARTMP "/var/tmp/" -//#ifdef RESCUEDIR //#define _PATH_BSHELL RESCUEDIR "/sh" //#define _PATH_CSHELL RESCUEDIR "/csh" -//#else -//#define _PATH_BSHELL "/bin/sh" -//#define _PATH_CSHELL "/bin/csh" -//#endif #endif /* !_PATHS_H_ */ diff --git a/StdLib/Include/signal.h b/StdLib/Include/signal.h index 52873c764d..a84369f310 100644 --- a/StdLib/Include/signal.h +++ b/StdLib/Include/signal.h @@ -50,13 +50,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. corresponding to the specified condition. Many existing programs expect these to be macros. **/ -#define SIGINT 1 ///< receipt of an interactive attention signal -#define SIGILL 2 ///< detection of an invalid function image, such as an invalid instruction -#define SIGABRT 3 ///< abnormal termination, such as is initiated by the abort function -#define SIGFPE 4 ///< an erroneous arithmetic operation, such as zero divide or an operation resulting in overflow -#define SIGSEGV 5 ///< an invalid access to storage -#define SIGTERM 6 ///< a termination request sent to the program -#define SIG_LAST 7 ///< One more than the largest signal number +#define SIGINT __SigInt ///< receipt of an interactive attention signal +#define SIGILL __SigIll ///< detection of an invalid function image, such as an invalid instruction +#define SIGABRT __SigAbrt ///< abnormal termination, such as is initiated by the abort function +#define SIGFPE __SigFpe ///< an erroneous arithmetic operation, such as zero divide or an operation resulting in overflow +#define SIGSEGV __SigSegv ///< an invalid access to storage +#define SIGTERM __SigTerm ///< a termination request sent to the program +#define SIGBREAK __SigBreak ///< added for Python +#define SIG_LAST __Sig_Last ///< One more than the largest signal number __BEGIN_DECLS diff --git a/StdLib/Include/stdio.h b/StdLib/Include/stdio.h index d6eadf513c..7a60a290ac 100644 --- a/StdLib/Include/stdio.h +++ b/StdLib/Include/stdio.h @@ -44,6 +44,7 @@ #ifdef _EFI_SIZE_T_ typedef _EFI_SIZE_T_ size_t; #undef _EFI_SIZE_T_ + #undef _BSD_SIZE_T_ #endif /* diff --git a/StdLib/Include/stdlib.h b/StdLib/Include/stdlib.h index 2b19fd224b..2cfc9fe1ff 100644 --- a/StdLib/Include/stdlib.h +++ b/StdLib/Include/stdlib.h @@ -2,7 +2,7 @@ The header declares five types and several functions of general utility, and defines several macros. - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 that accompanies this distribution. The full text of the license may be found at @@ -133,10 +133,14 @@ void exit(int status) __noreturn; buffered data are not flushed, open streams are not closed, and temporary files are not removed by abort. + While this function does not return, it can NOT be marked as "__noreturn" + without causing a warning to be emitted because the compilers can not + determine that the function truly does not return. + The status returned to the host environment is determined in the same way as for the exit function. **/ -void _Exit(int status) __noreturn; +void _Exit(int status); /** The getenv function searches an environment list, provided by the host environment, for a string that matches the string pointed to by name. The @@ -151,6 +155,24 @@ void _Exit(int status) __noreturn; **/ char *getenv(const char *name); +/** + Add or update a variable in the environment list + + @param name Address of a zero terminated name string + @param value Address of a zero terminated value string + @param rewrite TRUE allows overwriting existing values + + @retval Returns 0 upon success + @retval Returns -1 upon failure, sets errno with more information + +**/ +int +setenv ( + register const char * name, + register const char * value, + int rewrite + ); + /** If string is a null pointer, the system function determines whether the host environment has a command processor. If string is not a null pointer, the system function passes the string pointed to by string to that command @@ -499,37 +521,125 @@ void qsort( void *base, size_t nmemb, size_t size, /* ################ Multibyte/wide character conversion functions ####### */ -/** +/** Determine the number of bytes comprising a multibyte character. - @return + If s is not a null pointer, the mblen function determines the number of bytes + contained in the multibyte character pointed to by s. Except that the + conversion state of the mbtowc function is not affected, it is equivalent to + mbtowc((wchar_t *)0, s, n); + + The implementation shall behave as if no library function calls the mblen + function. + + @return If s is a null pointer, the mblen function returns a nonzero or + zero value, if multibyte character encodings, respectively, do + or do not have state-dependent encodings. If s is not a null + pointer, the mblen function either returns 0 (if s points to the + null character), or returns the number of bytes that are contained + in the multibyte character (if the next n or fewer bytes form a + valid multibyte character), or returns -1 (if they do not form a + valid multibyte character). **/ int mblen(const char *, size_t); -/** +/** Convert a multibyte character into a wide character. - @return + If s is not a null pointer, the mbtowc function inspects at most n bytes + beginning with the byte pointed to by s to determine the number of bytes + needed to complete the next multibyte character (including any shift + sequences). If the function determines that the next multibyte character + is complete and valid, it determines the value of the corresponding wide + character and then, if pwc is not a null pointer, stores that value in + the object pointed to by pwc. If the corresponding wide character is the + null wide character, the function is left in the initial conversion state. + + The implementation shall behave as if no library function calls the + mbtowc function. + + @return If s is a null pointer, the mbtowc function returns a nonzero or + zero value, if multibyte character encodings, respectively, do + or do not have state-dependent encodings. If s is not a null + pointer, the mbtowc function either returns 0 (if s points to + the null character), or returns the number of bytes that are + contained in the converted multibyte character (if the next n or + fewer bytes form a valid multibyte character), or returns -1 + (if they do not form a valid multibyte character). + + In no case will the value returned be greater than n or the value + of the MB_CUR_MAX macro. **/ int mbtowc(wchar_t * __restrict, const char * __restrict, size_t); /** +The wctomb function determines the number of bytes needed to represent the multibyte +character corresponding to the wide character given by wc (including any shift +sequences), and stores the multibyte character representation in the array whose first +element is pointed to by s (if s is not a null pointer). At most MB_CUR_MAX characters +are stored. If wc is a null wide character, a null byte is stored, preceded by any shift +sequence needed to restore the initial shift state, and the function is left in the initial +conversion state. + +The implementation shall behave as if no library function calls the wctomb function. @return +If s is a null pointer, the wctomb function returns a nonzero or zero value, if multibyte +character encodings, respectively, do or do not have state-dependent encodings. If s is +not a null pointer, the wctomb function returns -1 if the value of wc does not correspond +to a valid multibyte character, or returns the number of bytes that are contained in the +multibyte character corresponding to the value of wc. + +In no case will the value returned be greater than the value of the MB_CUR_MAX macro. + **/ int wctomb(char *, wchar_t); /* ################ Multibyte/wide string conversion functions ########## */ -/** +/** Convert a multibyte character string into a wide-character string. + + The mbstowcs function converts a sequence of multibyte characters that + begins in the initial shift state from the array pointed to by src into + a sequence of corresponding wide characters and stores not more than limit + wide characters into the array pointed to by dest. No multibyte + characters that follow a null character (which is converted into a null + wide character) will be examined or converted. Each multibyte character + is converted as if by a call to the mbtowc function, except that the + conversion state of the mbtowc function is not affected. + + No more than limit elements will be modified in the array pointed to by dest. + If copying takes place between objects that overlap, + the behavior is undefined. + + @return If an invalid multibyte character is encountered, the mbstowcs + function returns (size_t)(-1). Otherwise, the mbstowcs function + returns the number of array elements modified, not including a + terminating null wide character, if any. - @return **/ -size_t mbstowcs(wchar_t * __restrict , const char * __restrict, size_t); +size_t mbstowcs(wchar_t * __restrict dest, const char * __restrict src, size_t limit); -/** +/** Convert a wide-character string into a multibyte character string. - @return + The wcstombs function converts a sequence of wide characters from the + array pointed to by src into a sequence of corresponding multibyte + characters that begins in the initial shift state, and stores these + multibyte characters into the array pointed to by dest, stopping if a + multibyte character would exceed the limit of limit total bytes or if a + null character is stored. Each wide character is converted as if by + a call to the wctomb function, except that the conversion state of + the wctomb function is not affected. + + No more than limit bytes will be modified in the array pointed to by dest. + If copying takes place between objects that overlap, + the behavior is undefined. + + @return If a wide character is encountered that does not correspond to a + valid multibyte character, the wcstombs function returns + (size_t)(-1). Otherwise, the wcstombs function returns the number + of bytes modified, not including a terminating null character, + if any. **/ -size_t wcstombs(char * __restrict, const wchar_t * __restrict, size_t); +size_t wcstombs(char * __restrict dest, const wchar_t * __restrict src, size_t limit); __END_DECLS diff --git a/StdLib/Include/string.h b/StdLib/Include/string.h index 920d6c8dd6..992ca0ba18 100644 --- a/StdLib/Include/string.h +++ b/StdLib/Include/string.h @@ -15,7 +15,7 @@ interpreted as if it had the type unsigned char (and therefore every possible object representation is valid and has a different value). -Copyright (c) 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2010 - 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 that accompanies this distribution. The full text of the license may be found at @@ -323,6 +323,16 @@ char *strdup (const char *); int strerror_r(int, char *, size_t); int strcasecmp(const char *s1, const char *s2); void *memccpy (void *, const void *, int, size_t); +int strncasecmp(const char *s1, const char *s2, size_t n); + +// bcopy is same as memcpy but it is a void function, being used in socket lib +#define bcopy(a,b,c) ( memcpy((void *)a, (void *)b, (size_t)c)) + +// bcmp is same as memcmp, returns 0 for successful compare, non-zero otherwise +#define bcmp(a,b,c) ( memcmp((void *)a, (void *)b, (size_t)c)) + +//strsep is the same as strtok, the only difference is for strsep the 1st parameter is a char** +#define strsep(a,b) (strtok(*a,b)) __END_DECLS diff --git a/StdLib/Include/sys/EfiSysCall.h b/StdLib/Include/sys/EfiSysCall.h index 14ecb49890..7b299108e6 100644 --- a/StdLib/Include/sys/EfiSysCall.h +++ b/StdLib/Include/sys/EfiSysCall.h @@ -3,7 +3,7 @@ Concept derived from NetBSD's unistd.h file. - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 that accompanies this distribution. The full text of the license may be found at @@ -19,7 +19,7 @@ #include #include -struct stat; // Structure declared in +struct stat; /* Structure declared in */ #define STDIN_FILENO 0 /* standard input file descriptor */ #define STDOUT_FILENO 1 /* standard output file descriptor */ @@ -31,53 +31,90 @@ struct stat; // Structure declared in #define W_OK 0x02 /* test for write permission */ #define R_OK 0x04 /* test for read permission */ -/* whence values for lseek(2) */ -#define SEEK_SET 0 /* set file offset to offset */ -#define SEEK_CUR 1 /* set file offset to current plus offset */ -#define SEEK_END 2 /* set file offset to EOF plus offset */ +/* whence values for lseek(2) + Always ensure that these are consistent with and ! +*/ +#ifndef SEEK_SET + #define SEEK_SET 0 /* set file offset to offset */ +#endif +#ifndef SEEK_CUR + #define SEEK_CUR 1 /* set file offset to current plus offset */ +#endif +#ifndef SEEK_END + #define SEEK_END 2 /* set file offset to EOF plus offset */ +#endif + +// Parameters for the ValidateFD function. +#define VALID_OPEN 1 +#define VALID_CLOSED 0 +#define VALID_DONT_CARE -1 __BEGIN_DECLS /* EFI versions of BSD system calls used in stdio */ -extern int close (int fd); -extern ssize_t read (int fd, void *buf, size_t n); -extern ssize_t write (int fd, const void *buf, size_t n); -extern int unlink (const char *name); -extern int dup2 (int, int); -extern int rmdir (const char *); -extern int isatty (int); +int close (int fd); +ssize_t read (int fd, void *buf, size_t n); +ssize_t write (int fd, const void *buf, size_t n); +int unlink (const char *name); +int dup2 (int, int); +int rmdir (const char *); +int isatty (int); /* These system calls are also declared in sys/fcntl.h */ #ifndef __FCNTL_SYSCALLS_DECLARED #define __FCNTL_SYSCALLS_DECLARED - extern int open (const char *name, int oflags, int mode); - extern int creat (const char *, mode_t); - extern int fcntl (int, int, ...); + int open (const char *name, int oflags, int mode); + int creat (const char *, mode_t); + int fcntl (int, int, ...); #endif // __FCNTL_SYSCALLS_DECLARED /* These system calls are also declared in stat.h */ #ifndef __STAT_SYSCALLS_DECLARED #define __STAT_SYSCALLS_DECLARED - extern int mkdir (const char *, mode_t); - extern int fstat (int, struct stat *); - extern int lstat (const char *, struct stat *); - extern int stat (const char *, void *); -// extern int chmod (const char *, mode_t); + int mkdir (const char *, mode_t); + int fstat (int, struct stat *); + int lstat (const char *, struct stat *); + int stat (const char *, void *); +// int chmod (const char *, mode_t); #endif // __STAT_SYSCALLS_DECLARED // These are also declared in sys/types.h #ifndef __OFF_T_SYSCALLS_DECLARED #define __OFF_T_SYSCALLS_DECLARED - extern off_t lseek (int, off_t, int); - extern int truncate (const char *, off_t); - extern int ftruncate (int, off_t); // IEEE Std 1003.1b-93 + off_t lseek (int, off_t, int); + int truncate (const char *, off_t); + int ftruncate (int, off_t); // IEEE Std 1003.1b-93 #endif /* __OFF_T_SYSCALLS_DECLARED */ +/* EFI-specific Functions. */ +int DeleteOnClose(int fd); /* Mark an open file to be deleted when closed. */ + +/* Find and reserve a free File Descriptor. + + Returns the first free File Descriptor greater than or equal to the, + already validated, fd specified by Minfd. + + @return Returns -1 if there are no free FDs. Otherwise returns the + found fd. +*/ +int FindFreeFD (int MinFd); + +/* Validate that fd refers to a valid file descriptor. + IsOpen is interpreted as follows: + - Positive fd must be OPEN + - Zero fd must be CLOSED + - Negative fd may be OPEN or CLOSED + + @retval TRUE fd is VALID + @retval FALSE fd is INVALID +*/ +BOOLEAN ValidateFD (int fd, int IsOpen); + /* These system calls don't YET have EFI implementations. */ -extern int access (const char *path, int amode); -extern int chdir (const char *); -extern char *getcwd (char *, size_t); -extern int reboot (int, char *); +int access (const char *path, int amode); +int chdir (const char *); +char *getcwd (char *, size_t); +int reboot (int, char *); __END_DECLS diff --git a/StdLib/Include/sys/ansi.h b/StdLib/Include/sys/ansi.h index a52a9994c9..4fb12987a5 100644 --- a/StdLib/Include/sys/ansi.h +++ b/StdLib/Include/sys/ansi.h @@ -55,7 +55,7 @@ typedef __uint32_t __mode_t; /* file permissions */ typedef __int64_t __off_t; /* file offset */ typedef __int32_t __pid_t; /* process id */ typedef __uint8_t __sa_family_t; /* socket address family */ -typedef UINTN __socklen_t; /* socket-related datum length */ +typedef UINT32 __socklen_t; /* socket-related datum length */ typedef __uint32_t __uid_t; /* user id */ typedef __uint64_t __fsblkcnt_t; /* fs block count (statvfs) */ typedef __uint64_t __fsfilcnt_t; /* fs file count */ diff --git a/StdLib/Include/sys/cdefs.h b/StdLib/Include/sys/cdefs.h new file mode 100644 index 0000000000..c6e3d7b120 --- /dev/null +++ b/StdLib/Include/sys/cdefs.h @@ -0,0 +1,15 @@ +/** @file + Wrapper to allow existing references to , + in code being ported, to work. + + 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 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. +**/ + +#include diff --git a/StdLib/Include/sys/cdefs_aout.h b/StdLib/Include/sys/cdefs_aout.h index ce4ca06193..c7920a02b1 100644 --- a/StdLib/Include/sys/cdefs_aout.h +++ b/StdLib/Include/sys/cdefs_aout.h @@ -88,7 +88,8 @@ #undef __KERNEL_RCSID -#define __RCSID(_s) __IDSTRING(rcsid,_s) +//#define __RCSID(_s) __IDSTRING(rcsid,_s) +#define __RCSID(_s) #define __SCCSID(_s) #define __SCCSID2(_s) #if 0 /* XXX userland __COPYRIGHTs have \ns in them */ diff --git a/StdLib/Include/sys/dirent.h b/StdLib/Include/sys/dirent.h index 1d5f91185f..373664d091 100644 --- a/StdLib/Include/sys/dirent.h +++ b/StdLib/Include/sys/dirent.h @@ -4,7 +4,7 @@ The information is based upon the EFI_FILE_INFO structure in MdePkg/Include/Guid/FileInfo.h. - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 @@ -49,6 +49,7 @@ #include #include +#include #define MAXNAMLEN 511 @@ -66,10 +67,10 @@ struct dirent { UINT64 PhysicalSize; // The amount of physical space the file consumes // on the file system volume. UINT64 Attribute; // The time the file was created. - timespec CreateTime; // The time when the file was last accessed. - timespec LastAccessTime; // The time when the file’s contents were last modified. - timespec ModificationTime; // The attribute bits for the file. See below. - CHAR16 FileName[]; // The Null-terminated name of the file. + struct timespec CreateTime; // The time when the file was last accessed. + struct timespec LastAccessTime; // The time when the file’s contents were last modified. + struct timespec ModificationTime; // The attribute bits for the file. See below. + CHAR16 FileName[1]; // The Null-terminated name of the file. }; /* diff --git a/StdLib/Include/sys/fcntl.h b/StdLib/Include/sys/fcntl.h index cd720c03d9..8b691b19f8 100644 --- a/StdLib/Include/sys/fcntl.h +++ b/StdLib/Include/sys/fcntl.h @@ -57,8 +57,7 @@ /* * File status flags: these are used by open(2), fcntl(2). * They are also used (indirectly) in the kernel file structure f_flags, - * which is a superset of the open/fcntl flags. Open flags and f_flags - * are inter-convertible using OFLAGS(fflags) and FFLAGS(oflags). + * which is a superset of the open/fcntl flags. * Open/fcntl flags begin with O_; kernel-internal flags begin with F. */ /* open-only flags */ @@ -70,10 +69,6 @@ /* * Kernel encoding of open mode; separate read and write bits that are * independently testable: 1 greater than the above. - * - * XXX - * FREAD and FWRITE are excluded from the #ifdef _KERNEL so that TIOCFLUSH, - * which was documented to use FREAD/FWRITE, continues to work. */ #define FREAD 0x00000001 #define FWRITE 0x00000002 diff --git a/StdLib/Include/sys/ioctl.h b/StdLib/Include/sys/ioctl.h new file mode 100644 index 0000000000..2378fd2c84 --- /dev/null +++ b/StdLib/Include/sys/ioctl.h @@ -0,0 +1,101 @@ +/** @file + Device Control, ioctl, definitions and declarations. + + 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 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) 1982, 1986, 1990, 1993, 1994 + * 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. + * + * 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: ioctl.h,v 1.34 2005/12/11 12:25:20 christos Exp + ioctl.h 8.6 (Berkeley) 3/28/94 +**/ +#ifndef _SYS_IOCTL_H_ +#define _SYS_IOCTL_H_ + + +//#include + +/* + * Pun for SunOS prior to 3.2. SunOS 3.2 and later support TIOCGWINSZ + * and TIOCSWINSZ (yes, even 3.2-3.5, the fact that it wasn't documented + * nonwithstanding). + */ +struct ttysize { + unsigned short ts_lines; + unsigned short ts_cols; + unsigned short ts_xxx; + unsigned short ts_yyy; +}; +//#define TIOCGSIZE TIOCGWINSZ +//#define TIOCSSIZE TIOCSWINSZ + +//#include + +//#include +//#include +//#include + +/* + * Passthrough ioctl commands. These are passed through to devices + * as they are, it is expected that the device (an LKM, for example), + * will know how to deal with them. One for each emulation, so that + * no namespace clashes will occur between them, for devices that + * may be dealing with specific ioctls for multiple emulations. + */ + +struct ioctl_pt { + unsigned long com; + void *data; +}; + +#define PTIOCNETBSD _IOW('Z', 0, struct ioctl_pt) +#define PTIOCSUNOS _IOW('Z', 1, struct ioctl_pt) +#define PTIOCSVR4 _IOW('Z', 2, struct ioctl_pt) +#define PTIOCLINUX _IOW('Z', 3, struct ioctl_pt) +#define PTIOCFREEBSD _IOW('Z', 4, struct ioctl_pt) +#define PTIOCOSF1 _IOW('Z', 5, struct ioctl_pt) +#define PTIOCULTRIX _IOW('Z', 6, struct ioctl_pt) +#define PTIOCWIN32 _IOW('Z', 7, struct ioctl_pt) + +#include + +__BEGIN_DECLS +int ioctl(int, unsigned long, ...); +__END_DECLS +#endif /* !_SYS_IOCTL_H_ */ diff --git a/StdLib/Include/sys/poll.h b/StdLib/Include/sys/poll.h new file mode 100644 index 0000000000..ead648d490 --- /dev/null +++ b/StdLib/Include/sys/poll.h @@ -0,0 +1,91 @@ +/** @file + Definitions in support of the poll() function. + + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum. + * + * 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. + + 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 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. + + NetBSD: poll.h,v 1.11 2005/12/11 12:25:20 christos Exp +**/ +#ifndef _SYS_POLL_H_ +#define _SYS_POLL_H_ + +#include +#include + +typedef unsigned int nfds_t; + +struct pollfd { + int fd; /* file descriptor */ + short events; /* events to look for */ + short revents; /* events returned */ +}; + +/* + * Testable events (may be specified in events field). + */ +#define POLLIN 0x0001 +#define POLLPRI 0x0002 +#define POLLOUT 0x0004 +#define POLLRDNORM 0x0040 +#define POLLWRNORM POLLOUT +#define POLLRDBAND 0x0080 +#define POLLWRBAND 0x0100 + +/* + * Non-testable events (ignored in events field, valid in return only). + */ +#define POLLERR 0x0008 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 // Invalid parameter in POLL call +#define POLL_RETONLY (POLLERR | POLLHUP | POLLNVAL) + +/* + * Infinite timeout value. + */ +#define INFTIM -1 + +__BEGIN_DECLS +int poll(struct pollfd *, nfds_t, int); +__END_DECLS + +#endif /* !_SYS_POLL_H_ */ diff --git a/StdLib/Include/sys/signal.h b/StdLib/Include/sys/signal.h index 8cc32f08c9..e945a62bfe 100644 --- a/StdLib/Include/sys/signal.h +++ b/StdLib/Include/sys/signal.h @@ -14,6 +14,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include +enum { + __SigInt = 1, + __SigIll, + __SigAbrt, + __SigFpe, + __SigSegv, + __SigTerm, + __SigBreak, + __Sig_Last +}; + /** The type of a signal handler function. **/ typedef void __sighandler_t(int); diff --git a/StdLib/Include/sys/socket.h b/StdLib/Include/sys/socket.h index 8cc297d58b..11434ed641 100644 --- a/StdLib/Include/sys/socket.h +++ b/StdLib/Include/sys/socket.h @@ -86,8 +86,9 @@ typedef __socklen_t socklen_t; #include -#ifdef _BSD_SIZE_T_ -typedef _BSD_SIZE_T_ size_t; +#ifdef _EFI_SIZE_T_ +typedef _EFI_SIZE_T_ size_t; +#undef _EFI_SIZE_T_ #undef _BSD_SIZE_T_ #endif diff --git a/StdLib/Include/sys/stat.h b/StdLib/Include/sys/stat.h index adc61ecf80..47e993b8be 100644 --- a/StdLib/Include/sys/stat.h +++ b/StdLib/Include/sys/stat.h @@ -1,6 +1,6 @@ /** @file - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 that accompanies this distribution. The full text of the license may be found at @@ -54,6 +54,7 @@ struct stat { off_t st_size; /* file size, in bytes */ off_t st_physsize; /* physical space the file consumes */ + off_t st_curpos; /* current position within the file, or XY coord. for Console */ dtime_t st_birthtime; /* time of creation */ dtime_t st_atime; /* time of last access */ dtime_t st_mtime; /* time of last data modification */ @@ -113,7 +114,8 @@ struct stat { Traditionally, the remainder of the flags are specified in Octal but they are expressed in Hex here for modern clarity. */ -#define _S_IFMT 0x0001F000 /* type-of-file mask */ +#define _S_IFMT 0x000FF000 /* type-of-file mask */ +#define _S_IFIFO 0x00001000 /* named pipe (fifo) */ #define _S_IFCHR 0x00002000 /* character special */ #define _S_IFDIR 0x00004000 /* directory */ #define _S_IFBLK 0x00006000 /* block special */ @@ -121,9 +123,10 @@ struct stat { #define _S_IFSOCK 0x0000C000 /* socket */ #define _S_ITTY 0x00010000 /* File connects to a TTY device */ #define _S_IWTTY 0x00020000 /* TTY receives Wide characters */ +#define _S_ICONSOLE 0x00030000 /* UEFI Console Device */ /* UEFI specific (FAT file system) File attributes. - Specifiec in Hexadecimal instead of Octal. + Specified in Hexadecimal instead of Octal. These bits correspond to the xx portion of _S_IFMT */ #define S_IREADONLY 0x00100000 // Read Only File @@ -133,9 +136,10 @@ struct stat { #define S_IARCHIVE 0x02000000 // Archive Bit #define S_IROFS 0x08000000 /* Read Only File System */ +#define S_EFIONLY 0xF0000000 /* Flags only used by the EFI system calls. */ + #define S_EFISHIFT 20 // LS bit of the UEFI attributes -//#define _S_IFIFO 0010000 /* named pipe (fifo) */ //#define _S_IFLNK 0120000 /* symbolic link */ //#define _S_IFWHT 0160000 /* whiteout */ //#define _S_ARCH1 0200000 /* Archive state 1, ls -l shows 'a' */ @@ -146,12 +150,12 @@ struct stat { #define S_IFMT _S_IFMT #define S_IFBLK _S_IFBLK #define S_IFREG _S_IFREG -//#define S_IFIFO _S_IFIFO -//#define S_IFCHR _S_IFCHR -//#define S_IFDIR _S_IFDIR +#define S_IFIFO _S_IFIFO +#define S_IFCHR _S_IFCHR +#define S_IFDIR _S_IFDIR //#define S_IFLNK _S_IFLNK //#define S_ISVTX _S_ISVTX -//#define S_IFSOCK _S_IFSOCK +#define S_IFSOCK _S_IFSOCK //#define S_IFWHT _S_IFWHT //#define S_ARCH1 _S_ARCH1 @@ -163,7 +167,7 @@ struct stat { #define S_ISBLK(m) ((m & _S_IFMT) == _S_IFBLK) /* block special */ #define S_ISSOCK(m) ((m & _S_IFMT) == _S_IFSOCK) /* socket */ -//#define S_ISFIFO(m) ((m & _S_IFMT) == _S_IFIFO) /* fifo */ +#define S_ISFIFO(m) ((m & _S_IFMT) == _S_IFIFO) /* fifo */ //#define S_ISLNK(m) ((m & _S_IFMT) == _S_IFLNK) /* symbolic link */ //#define S_ISWHT(m) ((m & _S_IFMT) == _S_IFWHT) /* whiteout */ diff --git a/StdLib/Include/sys/syslimits.h b/StdLib/Include/sys/syslimits.h index a26104c7f6..80b18c3917 100644 --- a/StdLib/Include/sys/syslimits.h +++ b/StdLib/Include/sys/syslimits.h @@ -37,6 +37,8 @@ #include #define ARG_MAX (2 * 1024) /* max bytes for an exec function */ +#define ARGC_MAX (ARG_MAX / 2) /* Maximum value for argc */ + #ifndef CHILD_MAX #define CHILD_MAX 128 /* max simultaneous processes */ #endif diff --git a/StdLib/Include/sys/time.h b/StdLib/Include/sys/time.h index 1dd10b598f..4b17317200 100644 --- a/StdLib/Include/sys/time.h +++ b/StdLib/Include/sys/time.h @@ -1,11 +1,11 @@ /** @file System-specific declarations and macros related to time. - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -180,4 +180,7 @@ void Efi2Tm( EFI_TIME *EfiBDtime, struct tm *NewTime); __END_DECLS +/* BSD compatibility functions */ +int gettimeofday (struct timeval *tp, void *ignore); + #endif /* !_SYS_TIME_H_ */ diff --git a/StdLib/Include/sys/types.h b/StdLib/Include/sys/types.h index 9e95fd3ea3..68e3ba3ddd 100644 --- a/StdLib/Include/sys/types.h +++ b/StdLib/Include/sys/types.h @@ -243,8 +243,8 @@ typedef int64_t dtime_t; /* on-disk time_t */ #undef _EFI_CLOCK_T #endif -#if defined(_BSD_SIZE_T_) && defined(_EFI_SIZE_T_) - typedef _BSD_SIZE_T_ size_t; +#ifdef _EFI_SIZE_T_ + typedef _EFI_SIZE_T_ size_t; #define _SIZE_T #undef _BSD_SIZE_T_ #undef _EFI_SIZE_T_ diff --git a/StdLib/Include/sys/uio.h b/StdLib/Include/sys/uio.h index 8c3ee8fbf9..e6d667ba30 100644 --- a/StdLib/Include/sys/uio.h +++ b/StdLib/Include/sys/uio.h @@ -43,8 +43,9 @@ #include #include -#ifdef _BSD_SIZE_T_ -typedef _BSD_SIZE_T_ size_t; +#ifdef _EFI_SIZE_T_ +typedef _EFI_SIZE_T_ size_t; +#undef _EFI_SIZE_T_ #undef _BSD_SIZE_T_ #endif diff --git a/StdLib/Include/sys/unistd.h b/StdLib/Include/sys/unistd.h new file mode 100644 index 0000000000..0e7158c7c8 --- /dev/null +++ b/StdLib/Include/sys/unistd.h @@ -0,0 +1,192 @@ +/* $NetBSD: unistd.h,v 1.35 2006/08/14 18:17:48 rpaulo Exp $ */ + +/* + * Copyright (c) 1989, 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. + * + * @(#)unistd.h 8.2 (Berkeley) 1/7/94 + */ + +#ifndef _SYS_UNISTD_H_ +#define _SYS_UNISTD_H_ + +#include + +/* compile-time symbolic constants */ +#define _POSIX_JOB_CONTROL /* implementation supports job control */ + +/* + * According to POSIX 1003.1: + * "The saved set-user-ID capability allows a program to regain the + * effective user ID established at the last exec call." + * However, the setuid/setgid function as specified by POSIX 1003.1 does + * not allow changing the effective ID from the super-user without also + * changed the saved ID, so it is impossible to get super-user privileges + * back later. Instead we provide this feature independent of the current + * effective ID through the seteuid/setegid function. In addition, we do + * not use the saved ID as specified by POSIX 1003.1 in setuid/setgid, + * because this would make it impossible for a set-user-ID executable + * owned by a user other than the super-user to permanently revoke its + * extra privileges. + */ +#ifdef _NOT_AVAILABLE +#define _POSIX_SAVED_IDS /* saved set-user-ID and set-group-ID */ +#endif + +#define _POSIX_VERSION 199009L +#define _POSIX2_VERSION 199212L + +/* execution-time symbolic constants */ + /* chown requires appropriate privileges */ +#define _POSIX_CHOWN_RESTRICTED 1 + /* clock selection */ +#define _POSIX_CLOCK_SELECTION -1 + /* too-long path components generate errors */ +#define _POSIX_NO_TRUNC 1 + /* may disable terminal special characters */ +#define _POSIX_VDISABLE ((unsigned char)'\377') + /* file synchronization is available */ +#define _POSIX_FSYNC 1 + /* synchronized I/O is available */ +#define _POSIX_SYNCHRONIZED_IO 1 + /* memory mapped files */ +#define _POSIX_MAPPED_FILES 1 + /* memory locking of whole address space */ +#define _POSIX_MEMLOCK 1 + /* memory locking address ranges */ +#define _POSIX_MEMLOCK_RANGE 1 + /* memory access protections */ +#define _POSIX_MEMORY_PROTECTION 1 + /* monotonic clock */ +#define _POSIX_MONOTONIC_CLOCK 200112L + /* threads */ +#define _POSIX_THREADS 200112L + /* semaphores */ +#define _POSIX_SEMAPHORES 0 + /* barriers */ +#define _POSIX_BARRIERS 200112L + /* timers */ +#define _POSIX_TIMERS 200112L + /* spin locks */ +#define _POSIX_SPIN_LOCKS 200112L + /* read/write locks */ +#define _POSIX_READER_WRITER_LOCKS 200112L + /* XPG4.2 shared memory */ +#define _XOPEN_SHM 0 + +#if defined(_NETBSD_SOURCE) +/* whence values for lseek(2); renamed by POSIX 1003.1 */ +#define L_SET SEEK_SET +#define L_INCR SEEK_CUR +#define L_XTND SEEK_END + +/* + * fsync_range values. + * + * Note the following flag values were chosen to not overlap + * values for SEEK_XXX flags. While not currently implemented, + * it is possible to extend this call to respect SEEK_CUR and + * SEEK_END offset addressing modes. + */ +#define FDATASYNC 0x0010 /* sync data and minimal metadata */ +#define FFILESYNC 0x0020 /* sync data and metadata */ +#define FDISKSYNC 0x0040 /* flush disk caches after sync */ +#endif + +/* configurable pathname variables; use as argument to pathconf(3) */ +#define _PC_LINK_MAX 1 +#define _PC_MAX_CANON 2 +#define _PC_MAX_INPUT 3 +#define _PC_NAME_MAX 4 +#define _PC_PATH_MAX 5 +#define _PC_PIPE_BUF 6 +#define _PC_CHOWN_RESTRICTED 7 +#define _PC_NO_TRUNC 8 +#define _PC_VDISABLE 9 +#define _PC_SYNC_IO 10 +#define _PC_FILESIZEBITS 11 + +/* configurable system variables; use as argument to sysconf(3) */ +/* + * XXX The value of _SC_CLK_TCK is embedded in . + * XXX The value of _SC_PAGESIZE is embedded in . + */ +#define _SC_ARG_MAX 1 +#define _SC_CHILD_MAX 2 +#define _O_SC_CLK_TCK 3 /* Old version, always 100 */ +#define _SC_NGROUPS_MAX 4 +#define _SC_OPEN_MAX 5 +#define _SC_JOB_CONTROL 6 +#define _SC_SAVED_IDS 7 +#define _SC_VERSION 8 +#define _SC_BC_BASE_MAX 9 +#define _SC_BC_DIM_MAX 10 +#define _SC_BC_SCALE_MAX 11 +#define _SC_BC_STRING_MAX 12 +#define _SC_COLL_WEIGHTS_MAX 13 +#define _SC_EXPR_NEST_MAX 14 +#define _SC_LINE_MAX 15 +#define _SC_RE_DUP_MAX 16 +#define _SC_2_VERSION 17 +#define _SC_2_C_BIND 18 +#define _SC_2_C_DEV 19 +#define _SC_2_CHAR_TERM 20 +#define _SC_2_FORT_DEV 21 +#define _SC_2_FORT_RUN 22 +#define _SC_2_LOCALEDEF 23 +#define _SC_2_SW_DEV 24 +#define _SC_2_UPE 25 +#define _SC_STREAM_MAX 26 +#define _SC_TZNAME_MAX 27 +#define _SC_PAGESIZE 28 +#define _SC_PAGE_SIZE _SC_PAGESIZE /* 1170 compatibility */ +#define _SC_FSYNC 29 +#define _SC_XOPEN_SHM 30 +#define _SC_SYNCHRONIZED_IO 31 +#define _SC_IOV_MAX 32 +#define _SC_MAPPED_FILES 33 +#define _SC_MEMLOCK 34 +#define _SC_MEMLOCK_RANGE 35 +#define _SC_MEMORY_PROTECTION 36 +#define _SC_LOGIN_NAME_MAX 37 +#define _SC_MONOTONIC_CLOCK 38 +#define _SC_CLK_TCK 39 /* New, variable version */ +#define _SC_ATEXIT_MAX 40 +#define _SC_THREADS 41 +#define _SC_SEMAPHORES 42 +#define _SC_BARRIERS 43 +#define _SC_TIMERS 44 +#define _SC_SPIN_LOCKS 45 +#define _SC_READER_WRITER_LOCKS 46 +#define _SC_GETGR_R_SIZE_MAX 47 +#define _SC_GETPW_R_SIZE_MAX 48 +#define _SC_CLOCK_SELECTION 49 + +/* configurable system strings */ +#define _CS_PATH 1 + +#endif /* !_SYS_UNISTD_H_ */ diff --git a/StdLib/Include/time.h b/StdLib/Include/time.h index 386629cc6b..8c7b8e1422 100644 --- a/StdLib/Include/time.h +++ b/StdLib/Include/time.h @@ -33,11 +33,11 @@ if Daylight Saving Time is not in effect, and negative if the information is not available. - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -69,6 +69,39 @@ #undef _EFI_TIME_T #endif +/** Value added to tm_year to get the full year value. TM_YEAR_BASE + 110 --> 2010 +**/ +#define TM_YEAR_BASE 1900 + +/** Values for the tm_wday member of struct tm. + @{ +**/ +#define TM_SUNDAY 0 +#define TM_MONDAY 1 +#define TM_TUESDAY 2 +#define TM_WEDNESDAY 3 +#define TM_THURSDAY 4 +#define TM_FRIDAY 5 +#define TM_SATURDAY 6 +/** @} **/ + +/** Values for the tm_mon member of struct tm. + @{ +**/ +#define TM_JANUARY 0 +#define TM_FEBRUARY 1 +#define TM_MARCH 2 +#define TM_APRIL 3 +#define TM_MAY 4 +#define TM_JUNE 5 +#define TM_JULY 6 +#define TM_AUGUST 7 +#define TM_SEPTEMBER 8 +#define TM_OCTOBER 9 +#define TM_NOVEMBER 10 +#define TM_DECEMBER 11 +/** @} **/ + /** A structure holding the components of a calendar time, called the broken-down time. The first nine (9) members are as mandated by the C95 standard. Additional fields have been added for EFI support. @@ -115,7 +148,7 @@ double EFIAPI difftime(time_t time1, time_t time0); same encoding as that of the values returned by the time function. The original values of the tm_wday and tm_yday components of the structure are ignored, and the original values of the other components are not - restricted to the ranges indicated above.270) On successful completion, + restricted to the ranges indicated above. On successful completion, the values of the tm_wday and tm_yday components of the structure are set appropriately, and the other components are set to represent the specified calendar time, but with their values forced to the ranges indicated above; @@ -128,25 +161,50 @@ double EFIAPI difftime(time_t time1, time_t time0); **/ time_t EFIAPI 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’s best approximation + of 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 Conversion Functions ########################## */ -/** +/** The asctime function converts the broken-down time in the structure pointed + to by timeptr into a string in the form + Sun Sep 16 01:03:52 1973\n\0 + + @return The asctime function returns a pointer to the string. **/ char * EFIAPI asctime(const struct tm *timeptr); -/** +/** The ctime function converts the calendar time pointed to by timer to local + time in the form of a string. It is equivalent to asctime(localtime(timer)) + + @return The ctime function returns the pointer returned by the asctime + function with that broken-down time as argument. **/ char * EFIAPI ctime(const time_t *timer); -/** +/** The gmtime function converts the calendar time pointed to by timer into a + brokendown time, expressed as UTC. + + @return The gmtime function returns a pointer to the broken-down time, + or a null pointer if the specified time cannot be converted to UTC. **/ struct tm * EFIAPI gmtime(const time_t *timer); -/** +/** The localtime function converts the calendar time pointed to by timer into + a broken-down time, expressed as local time. + + @return The localtime function returns a pointer to the broken-down time, + or a null pointer if the specified time cannot be converted to + local time. **/ struct tm * EFIAPI localtime(const time_t *timer); @@ -304,6 +362,9 @@ size_t EFIAPI strftime( char * __restrict s, size_t maxsize, const char * __restrict format, const struct tm * __restrict timeptr); +char *strptime(const char *, const char * format, struct tm*); + + /* ################# Implementation Functions ########################### */ clock_t EFIAPI __getCPS(void); diff --git a/StdLib/Include/unistd.h b/StdLib/Include/unistd.h new file mode 100644 index 0000000000..fc8d7381b7 --- /dev/null +++ b/StdLib/Include/unistd.h @@ -0,0 +1,170 @@ +/** @file + + Copyright (c) 2010 - 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 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. + +**/ +#ifndef _UNISTD_H_ +#define _UNISTD_H_ + +//#include +//#include +//#include +//#include +#include +#include + +#define F_ULOCK 0 +#define F_LOCK 1 +#define F_TLOCK 2 +#define F_TEST 3 + + +__BEGIN_DECLS +int rename(const char *, const char *); + +// Networking +long gethostid(void); +int gethostname(char *, size_t); +int getdomainname(char *, size_t); +int setdomainname(const char *, size_t); +int sethostid(long); +int sethostname(const char *, size_t); + +// For Future implementation +__dead void _exit(int) __attribute__((__noreturn__)); +ssize_t pread(int, void *, size_t, off_t); +ssize_t pwrite(int, const void *, size_t, off_t); +int syscall(int, ...); +int dup(int); +pid_t fork(void); + +// The following *nix functions are not implemented +unsigned int alarm(unsigned int); +int chown(const char *, uid_t, gid_t); +size_t confstr(int, char *, size_t); +int execl(const char *, const char *, ...); +int execle(const char *, const char *, ...); +int execlp(const char *, const char *, ...); +int execv(const char *, char * const *); +int execve(const char *, char * const *, char * const *); +int execvp(const char *, char * const *); +long fpathconf(int, int); +gid_t getegid(void); +uid_t geteuid(void); +gid_t getgid(void); +int getgroups(int, gid_t []); +__aconst char *getlogin(void); +pid_t getpgrp(void); +pid_t getpid(void); +pid_t getppid(void); +uid_t getuid(void); +int link(const char *, const char *); +long pathconf(const char *, int); +int pause(void); +int pipe(int *); +int setgid(gid_t); +int setpgid(pid_t, pid_t); +pid_t setsid(void); +int setuid(uid_t); +unsigned int sleep(unsigned int); +long sysconf(int); +pid_t tcgetpgrp(int); +int tcsetpgrp(int, pid_t); +__aconst char *ttyname(int); + +int getopt(int, char * const [], const char *); + +extern char *optarg; /* getopt(3) external variables */ +extern int opterr; +extern int optind; +extern int optopt; +extern int optreset; /* getopt(3) external variable */ +extern char *suboptarg; /* getsubopt(3) external variable */ + +int setegid(gid_t); +int seteuid(uid_t); +int fdatasync(int); +int fsync(int); +int ttyname_r(int, char *, size_t); +int chroot(const char *); +int nice(int); +__aconst char *crypt(const char *, const char *); +int encrypt(char *, int); +char *getpass(const char *); +pid_t getsid(pid_t); + +#ifndef intptr_t +typedef __intptr_t intptr_t; +#define intptr_t __intptr_t +#endif + +int brk(void *); +int fchdir(int); +int fchown(int, uid_t, gid_t); +int getdtablesize(void); +__pure int getpagesize(void); /* legacy */ +pid_t getpgid(pid_t); +int lchown(const char *, uid_t, gid_t); +int lockf(int, int, off_t); +ssize_t readlink(const char * __restrict, char * __restrict, size_t); +void *sbrk(intptr_t); +int setregid(gid_t, gid_t); +int setreuid(uid_t, uid_t); +void swab(const void *, void *, size_t); +int symlink(const char *, const char *); +void sync(void); +useconds_t ualarm(useconds_t, useconds_t); +int usleep(useconds_t); +pid_t vfork(void) __RENAME(__vfork14); + +/* + * Implementation-defined extensions + */ +int acct(const char *); +int closefrom(int); +int des_cipher(const char *, char *, long, int); +int des_setkey(const char *); +void endusershell(void); +int exect(const char *, char * const *, char * const *); +int fchroot(int); +int fsync_range(int, int, off_t, off_t); +int getgrouplist(const char *, gid_t, gid_t *, int *); +int getgroupmembership(const char *, gid_t, gid_t *, int, int *); +mode_t getmode(const void *, mode_t); +int getsubopt(char **, char * const *, char **); +__aconst char *getusershell(void); +int initgroups(const char *, gid_t); +int iruserok(uint32_t, int, const char *, const char *); +int issetugid(void); +int nfssvc(int, void *); +int profil(char *, size_t, u_long, u_int); +void psignal(unsigned int, const char *); +int rcmd(char **, int, const char *, const char *, const char *, int *); +int revoke(const char *); +int rresvport(int *); +int ruserok(const char *, int, const char *, const char *); +int setgroups(int, const gid_t *); +int setlogin(const char *); +void *setmode(const char *); +int setrgid(gid_t); +int setruid(uid_t); +void setusershell(void); +void strmode(mode_t, char *); +__aconst char *strsignal(int); +int swapctl(int, void *, int); +quad_t __syscall(quad_t, ...); +int undelete(const char *); +int rcmd_af(char **, int, const char *, const char *, const char *, int *, int); +int rresvport_af(int *, int); +int iruserok_sa(const void *, int, int, const char *, const char *); + +__END_DECLS + +#endif /* !_UNISTD_H_ */ diff --git a/StdLib/Include/wchar.h b/StdLib/Include/wchar.h index 360bdacc32..c42594787d 100644 --- a/StdLib/Include/wchar.h +++ b/StdLib/Include/wchar.h @@ -506,11 +506,23 @@ size_t wcsftime(wchar_t * __restrict s, size_t maxsize, const wchar_t * __restri **/ wint_t btowc(int c); -/** +/** The wctob function determines whether c corresponds to a member of the extended + character set whose multibyte character representation is a single byte when in the initial + shift state. + + @Returns The wctob function returns EOF if c does not correspond to a multibyte + character with length one in the initial shift state. Otherwise, it + returns the single-byte representation of that character as an + unsigned char converted to an int. **/ int wctob(wint_t c); -/** +/** If ps is not a null pointer, the mbsinit function determines whether the + pointed-to mbstate_t object describes an initial conversion state. + + @Returns The mbsinit function returns nonzero if ps is a null pointer + or if the pointed-to object describes an initial conversion + state; otherwise, it returns zero. **/ int mbsinit(const mbstate_t *ps); @@ -532,7 +544,33 @@ size_t wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps); **/ size_t mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t len, mbstate_t * __restrict ps); -/** +/** The wcsrtombs function converts a sequence of wide characters from the array + indirectly pointed to by src into a sequence of corresponding multibyte + characters that begins in the conversion state described by the object + pointed to by ps. If dst is not a null pointer, the converted characters + are then stored into the array pointed to by dst. Conversion continues + up to and including a terminating null wide character, which is also + stored. Conversion stops earlier in two cases: when a wide character is + reached that does not correspond to a valid multibyte character, or + (if dst is not a null pointer) when the next multibyte character would + exceed the limit of len total bytes to be stored into the array pointed + to by dst. Each conversion takes place as if by a call to the wcrtomb + function.) + + If dst is not a null pointer, the pointer object pointed to by src is + assigned either a null pointer (if conversion stopped due to reaching + a terminating null wide character) or the address just past the last wide + character converted (if any). If conversion stopped due to reaching a + terminating null wide character, the resulting state described is the + initial conversion state. + + @Returns If conversion stops because a wide character is reached that + does not correspond to a valid multibyte character, an + encoding error occurs: the wcsrtombs function stores the + value of the macro EILSEQ in errno and returns (size_t)(-1); + the conversion state is unspecified. Otherwise, it returns + the number of bytes in the resulting multibyte character + sequence, not including the terminating null character (if any). **/ size_t wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len, mbstate_t * __restrict ps); diff --git a/StdLib/Include/wctype.h b/StdLib/Include/wctype.h index 9aa89ef541..3df726a353 100644 --- a/StdLib/Include/wctype.h +++ b/StdLib/Include/wctype.h @@ -1,6 +1,15 @@ -/* $NetBSD: wctype.h,v 1.6 2005/02/03 04:39:32 perry Exp $ */ +/** @file + Wide character classification functions and macros. + + Copyright (c) 2010 - 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 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)1999 Citrus Project, * All rights reserved. * @@ -26,17 +35,19 @@ * SUCH DAMAGE. * * citrus Id: wctype.h,v 1.4 2000/12/21 01:50:21 itojun Exp - */ + NetBSD: wctype.h,v 1.6 2005/02/03 04:39:32 perry Exp +**/ #ifndef _WCTYPE_H_ #define _WCTYPE_H_ #include #include -#ifdef _BSD_WINT_T_ -typedef _BSD_WINT_T_ wint_t; -#undef _BSD_WINT_T_ +#ifdef _EFI_WINT_T + typedef _EFI_WINT_T wint_t; + #undef _BSD_WINT_T_ + #undef _EFI_WINT_T #endif #ifdef _BSD_WCTRANS_T_ diff --git a/StdLib/LibC/CRT/Gcc.c b/StdLib/LibC/CRT/Gcc.c index 01fbe79dc9..cbf4ec273f 100644 --- a/StdLib/LibC/CRT/Gcc.c +++ b/StdLib/LibC/CRT/Gcc.c @@ -14,7 +14,6 @@ **/ #include -#include #include #include @@ -22,175 +21,175 @@ // Shift Datum left by Count bits. // =========================================================================== -//int __ashlsi3(int Datum, int Count) -//{ -// DebugPrint(DEBUG_INFO, "%a:\n", __func__); -// return (int) LShiftU64 ((UINT64)Datum, (UINTN)Count); -//} +int __ashlsi3(int Datum, int Count) +{ + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (int) LShiftU64 ((UINT64)Datum, (UINTN)Count); +} -INT64 __ashldi3(INT64 Datum, int Count) +long __ashldi3(long Datum, int Count) { - DebugPrint(DEBUG_INFO, "%a:\n", __func__); - return LShiftU64 (Datum, (UINTN)Count); + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (long) LShiftU64 ((UINT64)Datum, (UINTN)Count); } -//long long __ashlti3(long long Datum, int Count) -//{ -// DebugPrint(DEBUG_INFO, "%a:\n", __func__); -// return (long long) LShiftU64 ((UINT64)Datum, (UINTN)Count); -//} +long long __ashlti3(long long Datum, int Count) +{ + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (long long) LShiftU64 ((UINT64)Datum, (UINTN)Count); +} // Arithmetically shift Datum right by Count bits. // =========================================================================== -//int __ashrsi3(int Datum, int Count) -//{ -// DebugPrint(DEBUG_INFO, "%a:\n", __func__); -// return (int) ARShiftU64 ((UINT64) Datum, (UINTN)Count); -//} +int __ashrsi3(int Datum, int Count) +{ + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (int) ARShiftU64 ((UINT64) Datum, (UINTN)Count); +} -INT64 __ashrdi3(INT64 Datum, int Count) +long __ashrdi3(long Datum, int Count) { - DebugPrint(DEBUG_INFO, "%a:\n", __func__); - return ARShiftU64 ( Datum, (UINTN)Count); + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (long) ARShiftU64 ((UINT64) Datum, (UINTN)Count); } -//long long __ashrti3(long long Datum, int Count) -//{ -// DebugPrint(DEBUG_INFO, "%a:\n", __func__); -// return (long long) ARShiftU64 ((UINT64) Datum, (UINTN)Count); -//} +long long __ashrti3(long long Datum, int Count) +{ + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (long long) ARShiftU64 ((UINT64) Datum, (UINTN)Count); +} // Return the quotient of the signed division of Dividend and Divisor // =========================================================================== -//int __divsi3(int Dividend, int Divisor) -//{ -// DebugPrint(DEBUG_INFO, "%a:\n", __func__); -// return (int) DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, NULL); -//} +int __divsi3(int Dividend, int Divisor) +{ + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (int) DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, NULL); +} INT64 __divdi3(INT64 Dividend, INT64 Divisor) { INT64 Quotient; Quotient = DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, NULL); - DebugPrint(DEBUG_INFO, "%a: %Ld / %Ld = %Ld\n", __func__, Dividend, Divisor, Quotient); + DEBUG((DEBUG_INFO, "%a: %Ld / %Ld = %Ld\n", __func__, Dividend, Divisor, Quotient)); return Quotient; } -//long long __divti3(long long Dividend, long long Divisor) -//{ -// DebugPrint(DEBUG_INFO, "%a:\n", __func__); -// return (long long) DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, NULL); -//} +long long __divti3(long long Dividend, long long Divisor) +{ + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (long long) DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, NULL); +} // Logically shift Datum right by Count bits // =========================================================================== -//int __lshrsi3(int Datum, int Count) -//{ -// DebugPrint(DEBUG_INFO, "%a:\n", __func__); -// return (int) RShiftU64 ((UINT64) Datum, (UINTN)Count); -//} +int __lshrsi3(int Datum, int Count) +{ + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (int) RShiftU64 ((UINT64) Datum, (UINTN)Count); +} -INT64 __lshrdi3(INT64 Datum, int Count) +long __lshrdi3(int Datum, int Count) { - DebugPrint(DEBUG_INFO, "%a:\n", __func__); - return RShiftU64 ( Datum, (UINTN)Count); + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (long) RShiftU64 ((UINT64) Datum, (UINTN)Count); } -//long long __lshrti3(int Datum, int Count) -//{ -// DebugPrint(DEBUG_INFO, "%a:\n", __func__); -// return (long long) RShiftU64 ((UINT64) Datum, (UINTN)Count); -//} +long long __lshrti3(int Datum, int Count) +{ + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (long long) RShiftU64 ((UINT64) Datum, (UINTN)Count); +} // Return the remainder of the signed division of Dividend and Divisor // =========================================================================== -//int __modsi3(int Dividend, int Divisor) -//{ -// INT64 Remainder; +int __modsi3(int Dividend, int Divisor) +{ + INT64 Remainder; -// (void) DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, &Remainder); -// DebugPrint(DEBUG_INFO, "modsi3: %d %% %d = %d\n", Dividend, Divisor, (int)Remainder); + (void) DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, &Remainder); + DEBUG((DEBUG_INFO, "modsi3: %d %% %d = %d\n", Dividend, Divisor, (int)Remainder)); -// return (int) Remainder; -//} + return (int) Remainder; +} INT64 __moddi3(INT64 Dividend, INT64 Divisor) { INT64 Remainder; (void) DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, &Remainder); - DebugPrint(DEBUG_INFO, "moddi3: %Ld %% %Ld = %Ld\n", (INT64)Dividend, (INT64)Divisor, Remainder); + DEBUG((DEBUG_INFO, "moddi3: %Ld %% %Ld = %Ld\n", (INT64)Dividend, (INT64)Divisor, Remainder)); return Remainder; } -//long long __modti3(long long Dividend, long long Divisor) -//{ -// INT64 Remainder; +long long __modti3(long long Dividend, long long Divisor) +{ + INT64 Remainder; -// (void) DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, &Remainder); -// DebugPrint(DEBUG_INFO, "modti3: %Ld %% %Ld = %Ld\n", (INT64)Dividend, (INT64)Divisor, Remainder); + (void) DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, &Remainder); + DEBUG((DEBUG_INFO, "modti3: %Ld %% %Ld = %Ld\n", (INT64)Dividend, (INT64)Divisor, Remainder)); -// return (long long) Remainder; -//} + return (long long) Remainder; +} // These functions return the product of the Multiplicand and Multiplier. // =========================================================================== -//long long __multi3(long long Multiplicand, long long Multiplier) -//{ -// DebugPrint(DEBUG_INFO, "%a:\n", __func__); -// return (long long) MultS64x64 ((INT64)Multiplicand, (INT64)Multiplier); -//} +long long __multi3(long long Multiplicand, long long Multiplier) +{ + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (long long) MultS64x64 ((INT64)Multiplicand, (INT64)Multiplier); +} // Return the quotient of the unsigned division of a and b. // =========================================================================== -//unsigned int __udivsi3(unsigned int Dividend, unsigned int Divisor) -//{ -// DebugPrint(DEBUG_INFO, "%a:\n", __func__); -// return (int) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, NULL); -//} +unsigned int __udivsi3(unsigned int Dividend, unsigned int Divisor) +{ + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (int) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, NULL); +} -UINT64 __udivdi3(UINT64 Dividend, UINT64 Divisor) +unsigned long __udivdi3(unsigned long Dividend, unsigned long Divisor) { - DebugPrint(DEBUG_INFO, "%a:\n", __func__); - return DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, NULL); + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (long) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, NULL); } -//unsigned long long __udivti3(unsigned long long Dividend, unsigned long long Divisor) -//{ -// DebugPrint(DEBUG_INFO, "%a:\n", __func__); -// return (long long) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, NULL); -//} +unsigned long long __udivti3(unsigned long long Dividend, unsigned long long Divisor) +{ + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + return (long long) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, NULL); +} // =========================================================================== -//unsigned int __umodsi3(unsigned int Dividend, unsigned int Divisor) -//{ -// UINT64 Remainder; +unsigned int __umodsi3(unsigned int Dividend, unsigned int Divisor) +{ + UINT64 Remainder; -// DebugPrint(DEBUG_INFO, "%a:\n", __func__); -// (void) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, &Remainder); + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + (void) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, &Remainder); -// return (unsigned int) Remainder; -//} + return (unsigned int) Remainder; +} -UINT64 __umoddi3(UINT64 Dividend, UINT64 Divisor) +unsigned long __umoddi3(unsigned long Dividend, unsigned long Divisor) { UINT64 Remainder; - DebugPrint(DEBUG_INFO, "%a:\n", __func__); + DEBUG((DEBUG_INFO, "%a:\n", __func__)); (void) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, &Remainder); - return Remainder; + return (unsigned long) Remainder; } -//unsigned long long __umodti3(unsigned long long Dividend, unsigned long long Divisor) -//{ -// UINT64 Remainder; +unsigned long long __umodti3(unsigned long long Dividend, unsigned long long Divisor) +{ + UINT64 Remainder; -// DebugPrint(DEBUG_INFO, "%a:\n", __func__); -// (void) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, &Remainder); + DEBUG((DEBUG_INFO, "%a:\n", __func__)); + (void) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, &Remainder); -// return (unsigned long long) Remainder; -//} + return (unsigned long long) Remainder; +} diff --git a/StdLib/LibC/LibC.inf b/StdLib/LibC/LibC.inf index 4af3ffe45e..451b9b0e64 100644 --- a/StdLib/LibC/LibC.inf +++ b/StdLib/LibC/LibC.inf @@ -104,6 +104,7 @@ LibStdLib LibStdio LibString + DevConsole ################################################################ # diff --git a/StdLib/LibC/Main/Main.c b/StdLib/LibC/Main/Main.c index 0336d8b36a..47103ce388 100644 --- a/StdLib/LibC/Main/Main.c +++ b/StdLib/LibC/Main/Main.c @@ -4,7 +4,7 @@ All of the global data in the gMD structure is initialized to 0, NULL, or SIG_DFL; as appropriate. - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 that accompanies this distribution. The full text of the license may be found at @@ -24,10 +24,12 @@ #include #include +#include #include #include +#include -extern int main( int, wchar_t**); +extern int main( int, char**); extern int __sse2_available; struct __MainData *gMD; @@ -38,6 +40,75 @@ void __main() ; } +static +void +FinalCleanup( void ) +{ + int i; + + /* 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 ); + } +} + +/* Create mbcs versions of the Argv strings. */ +static +char ** +ArgvConvert(UINTN Argc, CHAR16 **Argv) +{ + size_t AVsz; /* Size of a single nArgv string */ + UINTN count; + char **nArgv; + char *string; + INTN nArgvSize; /* Cumulative size of narrow Argv[i] */ + + nArgvSize = Argc; + /* Determine space needed for narrow Argv strings. */ + for(count = 0; count < Argc; ++count) { + AVsz = wcstombs(NULL, Argv[count], ARG_MAX); + if(AVsz < 0) { + Print(L"ABORTING: Argv[%d] contains an unconvertable character.\n", count); + exit(EXIT_FAILURE); + /* Not Reached */ + } + nArgvSize += AVsz; + } + + /* Reserve space for the converted strings. */ + gMD->NCmdLine = (char *)AllocateZeroPool(nArgvSize+1); + if(gMD->NCmdLine == NULL) { + Print(L"ABORTING: Insufficient memory.\n"); + exit(EXIT_FAILURE); + /* Not Reached */ + } + + /* Convert Argument Strings. */ + nArgv = gMD->NArgV; + string = gMD->NCmdLine; + for(count = 0; count < Argc; ++count) { + nArgv[count] = string; + AVsz = wcstombs(string, Argv[count], nArgvSize); + string[AVsz] = 0; /* NULL terminate the argument */ + string += AVsz + 1; + nArgvSize -= AVsz + 1; + if(nArgvSize < 0) { + Print(L"ABORTING: Internal Argv[%d] conversion error.\n", count); + exit(EXIT_FAILURE); + /* Not Reached */ + } + } + return gMD->NArgV; +} + INTN EFIAPI ShellAppMain ( @@ -45,10 +116,10 @@ ShellAppMain ( IN CHAR16 **Argv ) { + struct __filedes *mfd; + char **nArgv; INTN ExitVal; INTN i; - struct __filedes *mfd; - FILE *fp; ExitVal = (INTN)RETURN_SUCCESS; gMD = AllocateZeroPool(sizeof(struct __MainData)); @@ -61,10 +132,11 @@ ShellAppMain ( _fltused = 1; errno = 0; EFIerrno = 0; + gMD->FinalCleanup = &FinalCleanup; #ifdef NT32dvm - gMD->ClocksPerSecond = 0; // For NT32 only - gMD->AppStartTime = 0; // For NT32 only + gMD->ClocksPerSecond = 1; // For NT32 only + gMD->AppStartTime = 1; // For NT32 only #else gMD->ClocksPerSecond = (clock_t)GetPerformanceCounterProperties( NULL, NULL); gMD->AppStartTime = (clock_t)GetPerformanceCounter(); @@ -76,27 +148,28 @@ ShellAppMain ( mfd[i].MyFD = (UINT16)i; } - // Open stdin, stdout, stderr - fp = freopen("stdin:", "r", stdin); - if(fp != NULL) { - fp = freopen("stdout:", "w", stdout); - if(fp != NULL) { - fp = freopen("stderr:", "w", stderr); + i = open("stdin:", O_RDONLY, 0444); + if(i == 0) { + i = open("stdout:", O_WRONLY, 0222); + if(i == 1) { + i = open("stderr:", O_WRONLY, 0222); } } - if(fp == NULL) { + if(i != 2) { Print(L"ERROR Initializing Standard IO: %a.\n %r\n", strerror(errno), EFIerrno); } - ExitVal = (INTN)main( (int)Argc, (wchar_t **)Argv); - - if (gMD->cleanup != NULL) { - gMD->cleanup(); + /* Create mbcs versions of the Argv strings. */ + nArgv = ArgvConvert(Argc, Argv); + if(nArgv == NULL) { + ExitVal = (INTN)RETURN_INVALID_PARAMETER; } + else { + ExitVal = (INTN)main( (int)Argc, nArgv); } - if(gMD != NULL) { - FreePool( gMD ); } + exit((int)ExitVal); + /* Not Reached */ return ExitVal; } diff --git a/StdLib/LibC/StdLib/Environs.c b/StdLib/LibC/StdLib/Environs.c index 5d1584ddea..8472d0ef4c 100644 --- a/StdLib/LibC/StdLib/Environs.c +++ b/StdLib/LibC/StdLib/Environs.c @@ -6,11 +6,11 @@ - exit(int status) - _Exit(int status) - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -92,30 +92,27 @@ atexit(void (*handler)(void)) void exit(int status) { - int i = gMD->num_atexit; + 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 (gMD->cleanup != NULL) { - gMD->cleanup(); + if (CleanUp != NULL) { + CleanUp(); + } } _Exit(status); } -typedef -EFI_STATUS -(EFIAPI *ExitFuncPtr)( - IN EFI_HANDLE ImageHandle, - IN EFI_STATUS ExitStatus, - IN UINTN ExitDataSize, - IN CHAR16 *ExitData OPTIONAL -) __noreturn; - /** The _Exit function causes normal program termination to occur and control to be returned to the host environment. @@ -133,16 +130,16 @@ void _Exit(int status) { RETURN_STATUS ExitVal = (RETURN_STATUS)status; - ExitFuncPtr ExitFunc; if( ExitVal == EXIT_FAILURE) { ExitVal = RETURN_ABORTED; } - ExitFunc = (ExitFuncPtr)gBS->Exit; + if(gMD->FinalCleanup != NULL) { + gMD->FinalCleanup(); // gMD does not exist when this returns. + } - //gBS->Exit(gImageHandle, ExitVal, 0, NULL); /* abort() */ - ExitFunc(gImageHandle, ExitVal, 0, NULL); /* abort() */ + gBS->Exit(gImageHandle, ExitVal, 0, NULL); /* abort() */ } /** If string is a null pointer, the system function determines whether the @@ -206,3 +203,98 @@ char *getenv(const char *name) return retval; } + + +/** + Add or update a variable in the environment list + + @param name Address of a zero terminated name string + @param value Address of a zero terminated value string + @param rewrite TRUE allows overwriting existing values + + @retval Returns 0 upon success + @retval Returns -1 upon failure, sets errno with more information + + Errors + + EINVAL - name is NULL or points to a zero length string + EALREADY - name already set and rewrite set to FALSE + ENODEV - Unable to set non-volatile version of environment variable + ENOMEM - Unable to set volatile version of environment variable + ENOTSUP - Variable storage not supported + +**/ +int +setenv ( + register const char * name, + register const char * value, + int rewrite + ) +{ + CONST CHAR16 * HostName; + int retval; + EFI_STATUS Status; + CHAR16 * UName; + CHAR16 * UValue; + + // + // Assume failure + // + retval = -1; + + // + // Validate the inputs + // + errno = EINVAL; + if (( NULL != name ) && ( 0 != *name )) { + // + // Get the storage locations for the unicode strings + // + UName = &gMD->UString[0]; + UValue = &gMD->UString2[0]; + + // + // Convert the strings + // + AsciiStrToUnicodeStr ( name, UName ); + AsciiStrToUnicodeStr ( value, UValue ); + + // + // Determine if the string is already present + // + errno = EALREADY; + HostName = ShellGetEnvironmentVariable ( UName ); + if ( rewrite || ( NULL == HostName )) { + // + // Support systems that don't have non-volatile memory + // + errno = ENOMEM; + Status = ShellSetEnvironmentVariable ( UName, UValue, TRUE ); + if ( EFI_ERROR ( Status )) { + if ( EFI_UNSUPPORTED == Status ) { + errno = ENOTSUP; + } + } + else { + // + // Permanently set the environment variable + // + errno = ENODEV; + Status = ShellSetEnvironmentVariable ( UName, UValue, FALSE ); + if ( !EFI_ERROR ( Status )) { + // + // Success + // + errno = 0; + retval = 0; + } + } + } + } + + // + // Return the operation status + // + return retval; +} + diff --git a/StdLib/LibC/Stdio/Stdio.inf b/StdLib/LibC/Stdio/Stdio.inf index 56eaae3291..9d2adef1f6 100644 --- a/StdLib/LibC/Stdio/Stdio.inf +++ b/StdLib/LibC/Stdio/Stdio.inf @@ -70,6 +70,9 @@ vprintf.c # vsprintf.c # + snprintf.c + vsnprintf.c + # Wide character functions fgetwc.c # fgetws.c # diff --git a/StdLib/LibC/Stdio/clrerr.c b/StdLib/LibC/Stdio/clrerr.c index bda0d04ce8..469dc8c96a 100644 --- a/StdLib/LibC/Stdio/clrerr.c +++ b/StdLib/LibC/Stdio/clrerr.c @@ -1,7 +1,7 @@ /** @file Implementation of clearerr as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 that accompanies this distribution. The full text of the license may be found at @@ -47,6 +47,7 @@ #include #include +#include #include "reentrant.h" #include "local.h" @@ -55,9 +56,10 @@ void clearerr(FILE *fp) { - //_DIAGASSERT(fp != NULL); - + _DIAGASSERT(fp != NULL); + if(fp != NULL) { FLOCKFILE(fp); __sclearerr(fp); FUNLOCKFILE(fp); + } } diff --git a/StdLib/LibC/Stdio/fclose.c b/StdLib/LibC/Stdio/fclose.c index 3745e20f94..1ce28bcab4 100644 --- a/StdLib/LibC/Stdio/fclose.c +++ b/StdLib/LibC/Stdio/fclose.c @@ -1,7 +1,7 @@ /** @file Implementation of fclose as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 that accompanies this distribution. The full text of the license may be found at @@ -59,6 +59,10 @@ fclose(FILE *fp) int r; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } if (fp->_flags == 0) { /* not open! */ errno = EBADF; diff --git a/StdLib/LibC/Stdio/feof.c b/StdLib/LibC/Stdio/feof.c index 70b5e5090e..7850e39268 100644 --- a/StdLib/LibC/Stdio/feof.c +++ b/StdLib/LibC/Stdio/feof.c @@ -2,7 +2,7 @@ Implementation of a subroutine version of the macro feof, as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 that accompanies this distribution. The full text of the license may be found at @@ -48,6 +48,7 @@ #include #include +#include #include "reentrant.h" #include "local.h" @@ -59,6 +60,10 @@ feof(FILE *fp) int r; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } FLOCKFILE(fp); r = __sfeof(fp); diff --git a/StdLib/LibC/Stdio/ferror.c b/StdLib/LibC/Stdio/ferror.c index 5641b48038..4a3996fadd 100644 --- a/StdLib/LibC/Stdio/ferror.c +++ b/StdLib/LibC/Stdio/ferror.c @@ -2,7 +2,7 @@ Implementation of a subroutine version of the macro ferror, as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 that accompanies this distribution. The full text of the license may be found at @@ -48,6 +48,7 @@ #include #include +#include #include "reentrant.h" #include "local.h" @@ -59,6 +60,10 @@ ferror(FILE *fp) int r; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } FLOCKFILE(fp); r = __sferror(fp); diff --git a/StdLib/LibC/Stdio/fflush.c b/StdLib/LibC/Stdio/fflush.c index fd21e37a13..5a4d62468e 100644 --- a/StdLib/LibC/Stdio/fflush.c +++ b/StdLib/LibC/Stdio/fflush.c @@ -1,11 +1,11 @@ /** @file Implementation of fflush as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -87,6 +87,10 @@ __sflush(FILE *fp) int t; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } t = fp->_flags; if ((t & __SWR) == 0) diff --git a/StdLib/LibC/Stdio/fgetc.c b/StdLib/LibC/Stdio/fgetc.c index b6e1a258ba..aee896fea5 100644 --- a/StdLib/LibC/Stdio/fgetc.c +++ b/StdLib/LibC/Stdio/fgetc.c @@ -1,11 +1,11 @@ /** @file Implementation of fgetc as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -58,8 +58,14 @@ fgetc(FILE *fp) _DIAGASSERT(fp != NULL); + if(fp != NULL) { FLOCKFILE(fp); r = __sgetc(fp); FUNLOCKFILE(fp); + } + else { + r = EOF; + errno = ENOSTR; + } return r; } diff --git a/StdLib/LibC/Stdio/fgetpos.c b/StdLib/LibC/Stdio/fgetpos.c index f076718278..61d6f756d0 100644 --- a/StdLib/LibC/Stdio/fgetpos.c +++ b/StdLib/LibC/Stdio/fgetpos.c @@ -1,11 +1,11 @@ /** @file Implementation of fgetpos as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -56,5 +56,10 @@ fgetpos(FILE *fp, fpos_t *pos) _DIAGASSERT(fp != NULL); _DIAGASSERT(pos != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } + return((*pos = (off_t)ftello(fp)) == (off_t)-1); } diff --git a/StdLib/LibC/Stdio/fgets.c b/StdLib/LibC/Stdio/fgets.c index cf107ab867..cb07154ada 100644 --- a/StdLib/LibC/Stdio/fgets.c +++ b/StdLib/LibC/Stdio/fgets.c @@ -1,11 +1,11 @@ /** @file Implementation of fgets as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -48,6 +48,7 @@ #include #include #include +#include #include "reentrant.h" #include "local.h" @@ -65,8 +66,10 @@ fgets(char *buf, int n, FILE *fp) _DIAGASSERT(buf != NULL); _DIAGASSERT(fp != NULL); - if (n <= 0) /* sanity check */ + if ((fp == NULL) || (n <= 0)) { /* sanity check */ + errno = EINVAL; return (NULL); + } FLOCKFILE(fp); _SET_ORIENTATION(fp, -1); diff --git a/StdLib/LibC/Stdio/fgetstr.c b/StdLib/LibC/Stdio/fgetstr.c index 7364d3b891..9e898f3263 100644 --- a/StdLib/LibC/Stdio/fgetstr.c +++ b/StdLib/LibC/Stdio/fgetstr.c @@ -1,6 +1,13 @@ -/* $NetBSD: fgetstr.c,v 1.4 2006/11/24 19:46:58 christos Exp $ */ +/* + Copyright (c) 2010 - 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 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,20 +37,20 @@ * 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: fgetstr.c,v 1.4 2006/11/24 19:46:58 christos Exp $ + fgetline.c 8.1 (Berkeley) 6/4/93 +*/ + +/*- */ #include #include -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)fgetline.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: fgetstr.c,v 1.4 2006/11/24 19:46:58 christos Exp $"); -#endif -#endif /* LIBC_SCCS and not lint */ #include "namespace.h" #include +#include #include #include #include @@ -66,6 +73,10 @@ __slbexpand(FILE *fp, size_t newsize) ++newsize; #endif _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (-1); + } if ((size_t)fp->_lb._size >= newsize) return (0); @@ -92,6 +103,10 @@ __fgetstr(FILE *fp, size_t *lenp, int sep) _DIAGASSERT(fp != NULL); _DIAGASSERT(lenp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (NULL); + } /* make sure there is input */ if (fp->_r <= 0 && __srefill(fp)) { diff --git a/StdLib/LibC/Stdio/fgetwc.c b/StdLib/LibC/Stdio/fgetwc.c index 548192390d..f2159d7e41 100644 --- a/StdLib/LibC/Stdio/fgetwc.c +++ b/StdLib/LibC/Stdio/fgetwc.c @@ -1,4 +1,13 @@ /*- + Copyright (c) 2010 - 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 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)2001 Citrus Project, * All rights reserved. * @@ -46,6 +55,10 @@ __fgetwc_unlock(FILE *fp) size_t size; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = ENOSTR; + return WEOF; + } _SET_ORIENTATION(fp, 1); wcio = WCIO_GET(fp); @@ -91,6 +104,10 @@ fgetwc(FILE *fp) wint_t r; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (WEOF); + } FLOCKFILE(fp); r = __fgetwc_unlock(fp); diff --git a/StdLib/LibC/Stdio/fgetws.c b/StdLib/LibC/Stdio/fgetws.c index 0113557965..44a885ac54 100644 --- a/StdLib/LibC/Stdio/fgetws.c +++ b/StdLib/LibC/Stdio/fgetws.c @@ -1,6 +1,13 @@ -/* $NetBSD: fgetws.c,v 1.2 2006/07/03 17:06:36 tnozaki Exp $ */ +/* + Copyright (c) 2010 - 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 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) 2002 Tim J. Robbins. * All rights reserved. * @@ -27,13 +34,11 @@ * * Original version ID: * FreeBSD: src/lib/libc/stdio/fgetws.c,v 1.4 2002/09/20 13:25:40 tjr Exp - * - */ + + $NetBSD: fgetws.c,v 1.2 2006/07/03 17:06:36 tnozaki Exp $ +*/ #include #include -#if defined(LIB_SCCS) && !defined(lint) -__RCSID("$NetBSD: fgetws.c,v 1.2 2006/07/03 17:06:36 tnozaki Exp $"); -#endif #include #include @@ -54,6 +59,10 @@ fgetws( _DIAGASSERT(fp != NULL); _DIAGASSERT(ws != NULL); + if(fp == NULL) { + errno = EINVAL; + return (NULL); + } FLOCKFILE(fp); _SET_ORIENTATION(fp, 1); diff --git a/StdLib/LibC/Stdio/fileno.c b/StdLib/LibC/Stdio/fileno.c index b9468c7cfc..779cbd8682 100644 --- a/StdLib/LibC/Stdio/fileno.c +++ b/StdLib/LibC/Stdio/fileno.c @@ -1,6 +1,13 @@ -/* $NetBSD: fileno.c,v 1.12 2004/05/09 17:27:53 kleink Exp $ */ +/* + Copyright (c) 2010 - 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 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: fileno.c,v 1.12 2004/05/09 17:27:53 kleink Exp + fileno.c 8.1 (Berkeley) 6/4/93 +*/ #include #include -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)fileno.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: fileno.c,v 1.12 2004/05/09 17:27:53 kleink Exp $"); -#endif -#endif /* LIBC_SCCS and not lint */ #include "namespace.h" #include @@ -63,6 +66,10 @@ _fileno(fp) int r; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } FLOCKFILE(fp); r = __sfileno(fp); diff --git a/StdLib/LibC/Stdio/fparseln.c b/StdLib/LibC/Stdio/fparseln.c index c1ce12be2e..be1a42fb6b 100644 --- a/StdLib/LibC/Stdio/fparseln.c +++ b/StdLib/LibC/Stdio/fparseln.c @@ -1,6 +1,13 @@ -/* $NetBSD: fparseln.c,v 1.5 2004/06/20 22:20:15 jmc Exp $ */ - /* + Copyright (c) 2010 - 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 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) 1997 Christos Zoulas. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,12 +34,11 @@ * 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: fparseln.c,v 1.5 2004/06/20 22:20:15 jmc Exp +*/ #include #include -#if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: fparseln.c,v 1.5 2004/06/20 22:20:15 jmc Exp $"); -#endif /* LIBC_SCCS and not lint */ #include "namespace.h" @@ -107,6 +113,10 @@ fparseln(FILE *fp, size_t *size, size_t *lineno, const char str[3], int flags) char esc, con, nl, com; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (NULL); + } len = 0; buf = NULL; diff --git a/StdLib/LibC/Stdio/fprintf.c b/StdLib/LibC/Stdio/fprintf.c index ba6ec0c22e..7134c5c5e6 100644 --- a/StdLib/LibC/Stdio/fprintf.c +++ b/StdLib/LibC/Stdio/fprintf.c @@ -1,11 +1,11 @@ /** @file Implementation of fprintf as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -58,6 +58,10 @@ fprintf(FILE *fp, const char *fmt, ...) _DIAGASSERT(fp != NULL); _DIAGASSERT(fmt != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } va_start(ap, fmt); ret = vfprintf(fp, fmt, ap); diff --git a/StdLib/LibC/Stdio/fpurge.c b/StdLib/LibC/Stdio/fpurge.c index cc649eee49..48c5482a7c 100644 --- a/StdLib/LibC/Stdio/fpurge.c +++ b/StdLib/LibC/Stdio/fpurge.c @@ -1,6 +1,13 @@ -/* $NetBSD: fpurge.c,v 1.13 2003/08/07 16:43:24 agc Exp $ */ +/* + Copyright (c) 2010 - 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 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: fpurge.c,v 1.13 2003/08/07 16:43:24 agc Exp + fpurge.c 8.1 (Berkeley) 6/4/93 +*/ #include #include -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)fpurge.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: fpurge.c,v 1.13 2003/08/07 16:43:24 agc Exp $"); -#endif -#endif /* LIBC_SCCS and not lint */ #include #include @@ -59,6 +62,10 @@ fpurge(fp) { _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } if (fp->_flags == 0) { errno = EBADF; diff --git a/StdLib/LibC/Stdio/fputc.c b/StdLib/LibC/Stdio/fputc.c index b9ae5aa828..a7dfdef485 100644 --- a/StdLib/LibC/Stdio/fputc.c +++ b/StdLib/LibC/Stdio/fputc.c @@ -1,11 +1,11 @@ /** @file Implementation of fputc as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -58,8 +58,14 @@ fputc(int c, FILE *fp) _DIAGASSERT(fp != NULL); + if(fp != NULL) { FLOCKFILE(fp); r = __sputc(c, fp); FUNLOCKFILE(fp); + } + else { + r = EOF; + errno = ENOSTR; + } return r; } diff --git a/StdLib/LibC/Stdio/fputs.c b/StdLib/LibC/Stdio/fputs.c index 081ee1a099..56e622276a 100644 --- a/StdLib/LibC/Stdio/fputs.c +++ b/StdLib/LibC/Stdio/fputs.c @@ -1,11 +1,11 @@ /** @file Implementation of fputs as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -65,6 +65,10 @@ fputs(const char *s, FILE *fp) _DIAGASSERT(s != NULL); _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } if (s == NULL) s = "(null)"; diff --git a/StdLib/LibC/Stdio/fputwc.c b/StdLib/LibC/Stdio/fputwc.c index 49f6702227..8bbd407362 100644 --- a/StdLib/LibC/Stdio/fputwc.c +++ b/StdLib/LibC/Stdio/fputwc.c @@ -1,6 +1,13 @@ -/* $NetBSD: fputwc.c,v 1.4 2005/06/12 05:21:27 lukem Exp $ */ +/* + Copyright (c) 2010 - 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 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)2001 Citrus Project, * All rights reserved. * @@ -26,12 +33,11 @@ * SUCH DAMAGE. * * $Citrus$ - */ + +NetBSD: fputwc.c,v 1.4 2005/06/12 05:21:27 lukem Exp +*/ #include #include -#if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: fputwc.c,v 1.4 2005/06/12 05:21:27 lukem Exp $"); -#endif /* LIBC_SCCS and not lint */ #include #include @@ -53,6 +59,10 @@ __fputwc_unlock(wchar_t wc, FILE *fp) struct __siov iov; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (WEOF); + } /* LINTED we don't play with buf */ iov.iov_base = (void *)buf; @@ -91,6 +101,10 @@ fputwc(wchar_t wc, FILE *fp) wint_t r; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (WEOF); + } FLOCKFILE(fp); r = __fputwc_unlock(wc, fp); diff --git a/StdLib/LibC/Stdio/fputws.c b/StdLib/LibC/Stdio/fputws.c index ce373bb402..ddfc5ddd30 100644 --- a/StdLib/LibC/Stdio/fputws.c +++ b/StdLib/LibC/Stdio/fputws.c @@ -1,6 +1,13 @@ -/* $NetBSD: fputws.c,v 1.1 2003/03/07 07:11:37 tshiozak Exp $ */ +/* + Copyright (c) 2010 - 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 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) 2002 Tim J. Robbins. * All rights reserved. * @@ -27,12 +34,10 @@ * * Original version ID: * FreeBSD: src/lib/libc/stdio/fputws.c,v 1.4 2002/09/20 13:25:40 tjr Exp - */ + NetBSD: fputws.c,v 1.1 2003/03/07 07:11:37 tshiozak Exp +*/ #include #include -#if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: fputws.c,v 1.1 2003/03/07 07:11:37 tshiozak Exp $"); -#endif #include #include @@ -49,6 +54,10 @@ fputws( { _DIAGASSERT(fp != NULL); _DIAGASSERT(ws != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } FLOCKFILE(fp); _SET_ORIENTATION(fp, 1); diff --git a/StdLib/LibC/Stdio/fread.c b/StdLib/LibC/Stdio/fread.c index 21013d7ff4..7693ab3c06 100644 --- a/StdLib/LibC/Stdio/fread.c +++ b/StdLib/LibC/Stdio/fread.c @@ -1,11 +1,11 @@ /** @file Implementation of fread as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -61,6 +61,10 @@ fread(void *buf, size_t size, size_t count, FILE *fp) size_t total; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (0); + } /* * The ANSI standard requires a return value of 0 for a count * or a size of 0. Whilst ANSI imposes no such requirements on diff --git a/StdLib/LibC/Stdio/freopen.c b/StdLib/LibC/Stdio/freopen.c index 186ab9ad66..4d34497317 100644 --- a/StdLib/LibC/Stdio/freopen.c +++ b/StdLib/LibC/Stdio/freopen.c @@ -1,11 +1,11 @@ /** @file Implementation of freopen as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -73,6 +73,10 @@ freopen(const char *file, const char *mode, FILE *fp) _DIAGASSERT(file != NULL); _DIAGASSERT(mode != NULL); _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (NULL); + } if ((flags = __sflags(mode, &oflags)) == 0) { (void) fclose(fp); diff --git a/StdLib/LibC/Stdio/fseeko.c b/StdLib/LibC/Stdio/fseeko.c index 3c406eaec8..7fc7e42661 100644 --- a/StdLib/LibC/Stdio/fseeko.c +++ b/StdLib/LibC/Stdio/fseeko.c @@ -1,6 +1,13 @@ -/* $NetBSD: fseeko.c,v 1.5 2005/03/04 16:04:58 dsl Exp $ */ +/* + Copyright (c) 2010 - 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 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,15 +37,14 @@ * 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: fseeko.c,v 1.5 2005/03/04 16:04:58 dsl Exp */ //#include // REMOVE, For DEBUG only //#include // REMOVE, For DEBUG only #include #include -#if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: fseeko.c,v 1.5 2005/03/04 16:04:58 dsl Exp $"); -#endif /* LIBC_SCCS and not lint */ #include "namespace.h" #include @@ -72,6 +78,10 @@ fseeko(FILE *fp, off_t offset, int whence) int havepos; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return -1; + } #ifdef __GNUC__ /* This outrageous construct just to shut up a GCC warning. */ diff --git a/StdLib/LibC/Stdio/fvwrite.c b/StdLib/LibC/Stdio/fvwrite.c index fcbb256067..12773eff68 100644 --- a/StdLib/LibC/Stdio/fvwrite.c +++ b/StdLib/LibC/Stdio/fvwrite.c @@ -1,6 +1,13 @@ -/* $NetBSD: fvwrite.c,v 1.16.2.1 2007/05/07 19:49:09 pavel Exp $ */ +/* + Copyright (c) 2010 - 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 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: fvwrite.c,v 1.16.2.1 2007/05/07 19:49:09 pavel Exp + fvwrite.c 8.1 (Berkeley) 6/4/93 +*/ #include #include -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)fvwrite.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: fvwrite.c,v 1.16.2.1 2007/05/07 19:49:09 pavel Exp $"); -#endif -#endif /* LIBC_SCCS and not lint */ #include #include @@ -68,6 +71,10 @@ __sfvwrite(FILE *fp, struct __suio *uio) _DIAGASSERT(fp != NULL); _DIAGASSERT(uio != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } if ((len = uio->uio_resid) == 0) return (0); diff --git a/StdLib/LibC/Stdio/fwide.c b/StdLib/LibC/Stdio/fwide.c index b89b7a3811..4ba1423eb2 100644 --- a/StdLib/LibC/Stdio/fwide.c +++ b/StdLib/LibC/Stdio/fwide.c @@ -1,6 +1,13 @@ -/* $NetBSD: fwide.c,v 1.3 2005/06/12 05:21:27 lukem Exp $ */ +/* + Copyright (c) 2010 - 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 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)2001 Citrus Project, * All rights reserved. * @@ -26,14 +33,14 @@ * SUCH DAMAGE. * * $Citrus$ - */ + + NetBSD: fwide.c,v 1.3 2005/06/12 05:21:27 lukem Exp +*/ #include #include -#if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: fwide.c,v 1.3 2005/06/12 05:21:27 lukem Exp $"); -#endif /* LIBC_SCCS and not lint */ #include +#include #include #include #include "reentrant.h" @@ -45,6 +52,10 @@ fwide(FILE *fp, int mode) struct wchar_io_data *wcio; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (0); + } /* * this implementation use only -1, 0, 1 diff --git a/StdLib/LibC/Stdio/fwrite.c b/StdLib/LibC/Stdio/fwrite.c index 9416e67aea..c998e272b6 100644 --- a/StdLib/LibC/Stdio/fwrite.c +++ b/StdLib/LibC/Stdio/fwrite.c @@ -1,11 +1,11 @@ /** @file Implementation of fwrite as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -64,6 +64,11 @@ fwrite(const void *buf, size_t size, size_t count, FILE *fp) struct __siov iov; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (0); + } + /* * SUSv2 requires a return value of 0 for a count or a size of 0. */ diff --git a/StdLib/LibC/Stdio/getc.c b/StdLib/LibC/Stdio/getc.c index c0f367b892..755251eef7 100644 --- a/StdLib/LibC/Stdio/getc.c +++ b/StdLib/LibC/Stdio/getc.c @@ -1,11 +1,11 @@ /** @file Implementation of getc as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -63,6 +63,10 @@ getc(FILE *fp) int r; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = ENOSTR; + return (EOF); + } FLOCKFILE(fp); r = __sgetc(fp); @@ -75,6 +79,10 @@ getc_unlocked(FILE *fp) { _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = ENOSTR; + return EOF; + } return (__sgetc(fp)); } diff --git a/StdLib/LibC/Stdio/makebuf.c b/StdLib/LibC/Stdio/makebuf.c index 75c475c3a5..4e69be1275 100644 --- a/StdLib/LibC/Stdio/makebuf.c +++ b/StdLib/LibC/Stdio/makebuf.c @@ -1,11 +1,11 @@ /** @file Implementation of internal file buffer allocation functions. - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -74,6 +74,7 @@ __smakebuf(FILE *fp) _DIAGASSERT(fp != NULL); + if (fp != NULL) { if (fp->_flags & __SNBF) { fp->_bf._base = fp->_p = fp->_nbuf; fp->_bf._size = 1; @@ -93,6 +94,7 @@ __smakebuf(FILE *fp) if (couldbetty || isatty(fp->_file)) flags |= __SLBF; fp->_flags |= flags; + } } /* @@ -106,6 +108,9 @@ __swhatbuf(FILE *fp, size_t *bufsize, int *couldbetty) _DIAGASSERT(fp != NULL); _DIAGASSERT(bufsize != NULL); _DIAGASSERT(couldbetty != NULL); + if(fp == NULL) { + return (__SNPT); + } if (fp->_file < 0 || fstat(fp->_file, &st) < 0) { *couldbetty = 0; diff --git a/StdLib/LibC/Stdio/putc.c b/StdLib/LibC/Stdio/putc.c index 891e747a56..25f49f8646 100644 --- a/StdLib/LibC/Stdio/putc.c +++ b/StdLib/LibC/Stdio/putc.c @@ -2,11 +2,11 @@ Implementation of a subroutine version of the macro putc, as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -64,6 +64,10 @@ putc(int c, FILE *fp) int r; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } FLOCKFILE(fp); r = __sputc(c, fp); @@ -75,6 +79,10 @@ int putc_unlocked(int c, FILE *fp) { _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } return (__sputc(c, fp)); } diff --git a/StdLib/LibC/Stdio/refill.c b/StdLib/LibC/Stdio/refill.c index e2d162375b..953e8f674a 100644 --- a/StdLib/LibC/Stdio/refill.c +++ b/StdLib/LibC/Stdio/refill.c @@ -1,6 +1,13 @@ -/* $NetBSD: refill.c,v 1.13 2003/08/07 16:43:30 agc Exp $ */ +/* + Copyright (c) 2010 - 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 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,19 +37,15 @@ * 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: refill.c,v 1.13 2003/08/07 16:43:30 agc Exp + refill.c 8.1 (Berkeley) 6/4/93 +*/ #include // REMOVE, For DEBUG only #include // REMOVE, For DEBUG only #include #include -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)refill.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: refill.c,v 1.13 2003/08/07 16:43:30 agc Exp $"); -#endif -#endif /* LIBC_SCCS and not lint */ #include #include @@ -61,7 +64,11 @@ static int lflush(FILE *fp) { - //_DIAGASSERT(fp != NULL); + _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) return (__sflush(fp)); @@ -76,7 +83,11 @@ int __srefill(FILE *fp) { - //_DIAGASSERT(fp != NULL); + _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } /* make sure stdio is set up */ if (!__sdidinit) diff --git a/StdLib/LibC/Stdio/rewind.c b/StdLib/LibC/Stdio/rewind.c index 4f2ab041a2..5d1042152b 100644 --- a/StdLib/LibC/Stdio/rewind.c +++ b/StdLib/LibC/Stdio/rewind.c @@ -1,11 +1,11 @@ /** @file Implementation of rewind as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -56,8 +56,10 @@ rewind(FILE *fp) { _DIAGASSERT(fp != NULL); + if(fp != NULL) { FLOCKFILE(fp); (void) fseek(fp, 0L, SEEK_SET); __sclearerr(fp); FUNLOCKFILE(fp); + } } diff --git a/StdLib/LibC/Stdio/rget.c b/StdLib/LibC/Stdio/rget.c index ba97ac201b..74f73dcac4 100644 --- a/StdLib/LibC/Stdio/rget.c +++ b/StdLib/LibC/Stdio/rget.c @@ -1,11 +1,11 @@ /** @file Internal function to refill the buffer when getc() empties it. - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -61,10 +61,12 @@ __srget(FILE *fp) { _DIAGASSERT(fp != NULL); + if(fp != NULL) { _SET_ORIENTATION(fp, -1); if (__srefill(fp) == 0) { fp->_r--; return (*fp->_p++); + } } return (EOF); } diff --git a/StdLib/LibC/Stdio/setvbuf.c b/StdLib/LibC/Stdio/setvbuf.c index 3ea96ff6da..9e01ea9dc1 100644 --- a/StdLib/LibC/Stdio/setvbuf.c +++ b/StdLib/LibC/Stdio/setvbuf.c @@ -1,11 +1,11 @@ /** @file Implementation of setvbuf as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -67,6 +67,10 @@ setvbuf(FILE *fp, char *buf, int mode, size_t size) _DIAGASSERT(fp != NULL); /* buf may be NULL */ + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } /* * Verify arguments. The `int' limit on `size' is due to this diff --git a/StdLib/LibC/Stdio/stdio.c b/StdLib/LibC/Stdio/stdio.c index 005a4388df..de8963e574 100644 --- a/StdLib/LibC/Stdio/stdio.c +++ b/StdLib/LibC/Stdio/stdio.c @@ -2,11 +2,11 @@ Small standard I/O/seek/close functions. These maintain the `known seek offset' for seek optimisation. - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -65,6 +65,10 @@ __sread(void *cookie, char *buf, int n) _DIAGASSERT(fp != NULL); _DIAGASSERT(buf != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } ret = (int)read(fp->_file, buf, (size_t)n); /* if the read succeeded, update the current offset */ @@ -82,6 +86,10 @@ __swrite(void *cookie, char const *buf, int n) _DIAGASSERT(cookie != NULL); _DIAGASSERT(buf != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } if (fp->_flags & __SAPP) (void) lseek(fp->_file, (off_t)0, SEEK_END); @@ -96,6 +104,10 @@ __sseek(void *cookie, fpos_t offset, int whence) off_t ret; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } ret = lseek(fp->_file, (off_t)offset, whence); if (ret == -1L) @@ -112,6 +124,10 @@ __sclose(void *cookie) { _DIAGASSERT(cookie != NULL); + if(cookie == NULL) { + errno = EINVAL; + return (EOF); + } return (close(((FILE *)cookie)->_file)); } diff --git a/StdLib/LibC/Stdio/tmpfile.c b/StdLib/LibC/Stdio/tmpfile.c index bfcf77c49d..97040d58f2 100644 --- a/StdLib/LibC/Stdio/tmpfile.c +++ b/StdLib/LibC/Stdio/tmpfile.c @@ -68,8 +68,12 @@ tmpfile() //(void)sigprocmask(SIG_BLOCK, &set, &oset); fd = mkstemp(buf); - if (fd != -1) - (void)unlink(buf); + if (fd != -1) { + /* Changed from unlink(buf) because of differences between the behavior + of Unix and UEFI file systems. + */ + (void)DeleteOnClose(fd); + } //(void)sigprocmask(SIG_SETMASK, &oset, NULL); diff --git a/StdLib/LibC/Stdio/ungetc.c b/StdLib/LibC/Stdio/ungetc.c index e9d3807fcb..d8e1f3afc6 100644 --- a/StdLib/LibC/Stdio/ungetc.c +++ b/StdLib/LibC/Stdio/ungetc.c @@ -1,11 +1,11 @@ /** @file Implementation of ungetc as declared in . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -67,6 +67,10 @@ __submore(FILE *fp) unsigned char *p; _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } if (_UB(fp)._base == fp->_ubuf) { /* @@ -98,6 +102,10 @@ int ungetc(int c, FILE *fp) { _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } if (c == EOF) return (EOF); diff --git a/StdLib/LibC/Stdio/vfscanf.c b/StdLib/LibC/Stdio/vfscanf.c index 724fd2a747..861fb53301 100644 --- a/StdLib/LibC/Stdio/vfscanf.c +++ b/StdLib/LibC/Stdio/vfscanf.c @@ -1,11 +1,11 @@ /** @file Implementation of scanf internals for . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -44,14 +44,12 @@ FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.41 2007/01/09 00:28:07 imp Exp vfscanf.c 8.1 (Berkeley) 6/4/93 **/ -//#include // REMOVE, For DEBUG only -//#include // REMOVE, For DEBUG only - #include #include "namespace.h" #include #include +#include #include #include #include @@ -142,6 +140,10 @@ __svfscanf(FILE *fp, char const *fmt0, va_list ap) { int ret; + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } FLOCKFILE(fp); ret = __svfscanf_unlocked(fp, fmt0, ap); FUNLOCKFILE(fp); @@ -178,6 +180,10 @@ __svfscanf_unlocked(FILE *fp, const char *fmt0, va_list ap) _DIAGASSERT(fp != NULL); _DIAGASSERT(fmt0 != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } _SET_ORIENTATION(fp, -1); @@ -837,12 +843,12 @@ literal: goto match_failure; if ((flags & SUPPRESS) == 0) { if (flags & LONGDBL) { -/*dvm*/ long double **mp = (long double **)ap; + long double **mp = (long double **)ap; long double res = strtold(buf, &p); -/*dvm*/ *(*mp) = res; -/*dvm*/ ap += sizeof(long double *); -/*dvm*/ //*va_arg(ap, long double *) = res; + *(*mp) = res; + ap += sizeof(long double *); +/*???*/ //*va_arg(ap, long double *) = res; } else if (flags & LONG) { double res = strtod(buf, &p); *va_arg(ap, double *) = res; @@ -989,6 +995,11 @@ parsefloat(FILE *fp, char *buf, char *end) char decpt = *localeconv()->decimal_point; _Bool gotmantdig = 0, ishex = 0; + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } + /* * We set commit = p whenever the string we have read so far * constitutes a valid representation of a floating point diff --git a/StdLib/LibC/Stdio/vfwprintf.c b/StdLib/LibC/Stdio/vfwprintf.c index bf31ddb664..3c5332ac4a 100644 --- a/StdLib/LibC/Stdio/vfwprintf.c +++ b/StdLib/LibC/Stdio/vfwprintf.c @@ -164,6 +164,10 @@ __sbprintf(FILE *fp, const CHAR_T *fmt, va_list ap) _DIAGASSERT(fp != NULL); _DIAGASSERT(fmt != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } _FILEEXT_SETUP(&fake, &fakeext); @@ -229,6 +233,10 @@ __sprint(FILE *fp, struct __suio *uio) _DIAGASSERT(fp != NULL); _DIAGASSERT(uio != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } if (uio->uio_resid == 0) { uio->uio_iovcnt = 0; @@ -544,6 +552,10 @@ WDECL(vf,printf)(FILE * __restrict fp, const CHAR_T * __restrict fmt0, va_list a { int ret; + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } FLOCKFILE(fp); ret = WDECL(__vf,printf_unlocked)(fp, fmt0, ap); FUNLOCKFILE(fp); @@ -801,6 +813,10 @@ WDECL(__vf,printf_unlocked)(FILE *fp, const CHAR_T *fmt0, va_list ap) _DIAGASSERT(fp != NULL); _DIAGASSERT(fmt0 != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } _SET_ORIENTATION(fp, -1); diff --git a/StdLib/LibC/Stdio/vsnprintf.c b/StdLib/LibC/Stdio/vsnprintf.c index b2a2f63a91..23385ba0d8 100644 --- a/StdLib/LibC/Stdio/vsnprintf.c +++ b/StdLib/LibC/Stdio/vsnprintf.c @@ -54,11 +54,7 @@ __weak_alias(vsnprintf,_vsnprintf) #endif int -vsnprintf(str, n, fmt, ap) - char *str; - size_t n; - const char *fmt; - _BSD_VA_LIST_ ap; +vsnprintf(char *str, size_t n, const char *fmt, _BSD_VA_LIST_ ap) { int ret; FILE f; @@ -81,7 +77,7 @@ vsnprintf(str, n, fmt, ap) f._bf._size = f._w = 0; } else { f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._w = n - 1; + f._bf._size = f._w = (int)(n - 1); } ret = __vfprintf_unlocked(&f, fmt, ap); *f._p = 0; diff --git a/StdLib/LibC/Stdio/wbuf.c b/StdLib/LibC/Stdio/wbuf.c index 8482a18e87..888be1ea3b 100644 --- a/StdLib/LibC/Stdio/wbuf.c +++ b/StdLib/LibC/Stdio/wbuf.c @@ -1,6 +1,13 @@ -/* $NetBSD: wbuf.c,v 1.13 2003/08/07 16:43:35 agc Exp $ */ +/* + Copyright (c) 2010 - 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 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: wbuf.c,v 1.13 2003/08/07 16:43:35 agc Exp + wbuf.c 8.1 (Berkeley) 6/4/93 +*/ #include #include -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)wbuf.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: wbuf.c,v 1.13 2003/08/07 16:43:35 agc Exp $"); -#endif -#endif /* LIBC_SCCS and not lint */ #include #include @@ -58,6 +61,10 @@ __swbuf(int c, FILE *fp) int n; //_DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (EOF); + } _SET_ORIENTATION(fp, -1); diff --git a/StdLib/LibC/Stdio/wsetup.c b/StdLib/LibC/Stdio/wsetup.c index c1077bc9df..b8fc06449e 100644 --- a/StdLib/LibC/Stdio/wsetup.c +++ b/StdLib/LibC/Stdio/wsetup.c @@ -1,6 +1,13 @@ -/* $NetBSD: wsetup.c,v 1.11 2003/08/07 16:43:35 agc Exp $ */ +/* + Copyright (c) 2010 - 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 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: wsetup.c,v 1.11 2003/08/07 16:43:35 agc Exp + wsetup.c 8.1 (Berkeley) 6/4/93 +*/ #include #include -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)wsetup.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: wsetup.c,v 1.11 2003/08/07 16:43:35 agc Exp $"); -#endif -#endif /* LIBC_SCCS and not lint */ #include #include @@ -58,6 +61,10 @@ __swsetup(FILE *fp) { _DIAGASSERT(fp != NULL); + if(fp == NULL) { + errno = EINVAL; + return (-1); + } /* make sure stdio is set up */ if (!__sdidinit) diff --git a/StdLib/LibC/String/Copying.c b/StdLib/LibC/String/Copying.c index 2d5200e3c5..18498d6f87 100644 --- a/StdLib/LibC/String/Copying.c +++ b/StdLib/LibC/String/Copying.c @@ -1,7 +1,7 @@ /** @file Copying Functions for . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 that accompanies this distribution. The full text of the license may be found at @@ -10,8 +10,6 @@ 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 - #include #include #include @@ -21,6 +19,11 @@ #include #include +/** Do not define memcpy for IPF+GCC builds. + For IPF, using a GCC compiler, the memcpy function is converted to + CopyMem by objcpy during build. +**/ +#if !(defined(MDE_CPU_IPF) && defined(__GNUC__)) /** The memcpy function copies n characters from the object pointed to by s2 into the object pointed to by s1. @@ -33,6 +36,7 @@ memcpy(void * __restrict s1, const void * __restrict s2, size_t n) { return CopyMem( s1, s2, n); } +#endif /* !(defined(MDE_CPU_IPF) && defined(__GCC)) */ /** The memmove function copies n characters from the object pointed to by s2 into the object pointed to by s1. Copying takes place as if the n diff --git a/StdLib/LibC/String/String.inf b/StdLib/LibC/String/String.inf index 1614b1cb11..b6ab660051 100644 --- a/StdLib/LibC/String/String.inf +++ b/StdLib/LibC/String/String.inf @@ -1,7 +1,7 @@ ## @file # Standard C library: Miscelaneous implementations. # -# Copyright (c) 2010, Intel Corporation. All rights reserved.
+# Copyright (c) 2010 - 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 @@ -32,6 +32,7 @@ Comparison.c Searching.c ErrorList.c + strncasecmp.c [Packages] StdLib/StdLib.dec diff --git a/StdLib/LibC/String/strncasecmp.c b/StdLib/LibC/String/strncasecmp.c new file mode 100644 index 0000000000..2519df94e4 --- /dev/null +++ b/StdLib/LibC/String/strncasecmp.c @@ -0,0 +1,80 @@ +/** @file + strncasecmp implementation + + 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 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, 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: strncasecmp.c,v 1.2 2007/06/04 18:19:27 christos Exp $ + strcasecmp.c 8.1 (Berkeley) 6/4/93 +**/ + +#include +#include + +#if !defined(_KERNEL) && !defined(_STANDALONE) +#include "namespace.h" +#include +#include +#include +#ifdef __weak_alias +__weak_alias(strcasecmp,_strcasecmp) +__weak_alias(strncasecmp,_strncasecmp) +#endif +#else +#include +#include +#endif + +int +strncasecmp(const char *s1, const char *s2, size_t n) +{ + + _DIAGASSERT(s1 != NULL); + _DIAGASSERT(s2 != NULL); + + if (n != 0) { + const unsigned char *us1 = (const unsigned char *)s1, + *us2 = (const unsigned char *)s2; + + do { + if (tolower(*us1) != tolower(*us2++)) + return (tolower(*us1) - tolower(*--us2)); + if (*us1++ == '\0') + break; + } while (--n != 0); + } + return (0); +} diff --git a/StdLib/LibC/Time/Time.c b/StdLib/LibC/Time/Time.c index 3192696f4a..5cb9347752 100644 --- a/StdLib/LibC/Time/Time.c +++ b/StdLib/LibC/Time/Time.c @@ -1,7 +1,7 @@ /** Definitions and Implementation for . - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 that accompanies this distribution. The full text of the license may be found at @@ -199,15 +199,15 @@ clock_t EFIAPI clock(void) { +#ifndef NT32dvm clock_t temp; -#ifdef NT32dvm - temp = 0; -#else temp = (clock_t)GetPerformanceCounter(); -#endif /* NT32dvm */ return temp - gMD->AppStartTime; +#else + return (clock_t)-1; +#endif /* NT32dvm */ } /** diff --git a/StdLib/LibC/Time/Time.inf b/StdLib/LibC/Time/Time.inf index 8bbb248bd1..6de494f8d4 100644 --- a/StdLib/LibC/Time/Time.inf +++ b/StdLib/LibC/Time/Time.inf @@ -1,7 +1,7 @@ ## @file # Standard C library: Time implementations. # -# Copyright (c) 2010, Intel Corporation. All rights reserved.
+# Copyright (c) 2010 - 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 @@ -29,7 +29,9 @@ Time.c ZoneProc.c strftime.c + strptime.c TimeEfi.c + gettimeofday.c [Packages] StdLib/StdLib.dec diff --git a/StdLib/LibC/Time/gettimeofday.c b/StdLib/LibC/Time/gettimeofday.c new file mode 100644 index 0000000000..1c379a6b97 --- /dev/null +++ b/StdLib/LibC/Time/gettimeofday.c @@ -0,0 +1,68 @@ +/** @file + gettimeofday implementation + + 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 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) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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 Institute 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 INSTITUTE 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 INSTITUTE 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. + + 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 +#include +#include +#include +#ifndef HAVE_GETTIMEOFDAY + + +/* + * Simple gettimeofday that only returns seconds. + */ +int +gettimeofday (struct timeval *tp, void *ignore) +{ + time_t t; + + t = time(NULL); + tp->tv_sec = t; + tp->tv_usec = 0; + return 0; +} +#endif diff --git a/StdLib/LibC/Time/strftime.c b/StdLib/LibC/Time/strftime.c index a9da3e2f7d..6a5e2a34af 100644 --- a/StdLib/LibC/Time/strftime.c +++ b/StdLib/LibC/Time/strftime.c @@ -52,7 +52,7 @@ #include "namespace.h" #include #include "tzfile.h" -#include +#include "TimeVals.h" #include "fcntl.h" #include "locale.h" diff --git a/StdLib/LibC/Time/strptime.c b/StdLib/LibC/Time/strptime.c new file mode 100644 index 0000000000..98ca5c6376 --- /dev/null +++ b/StdLib/LibC/Time/strptime.c @@ -0,0 +1,400 @@ +/** @file + strptime implementation + + 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 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) 1997, 1998, 2005, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Klaus Klein. + * Heavily optimised by David Laight + * + * 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. + + $NetBSD: strptime.c,v 1.28 2008/04/28 20:23:01 martin Exp $ + +**/ + +#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */ + #pragma warning ( disable : 4244 ) + #pragma warning ( disable : 4018 ) +#endif + +#include + +#include + +#include "namespace.h" +#include +#include "tzfile.h" +#include +#include + +#include + +#include +#include +#include + +#ifdef __weak_alias +__weak_alias(strptime,_strptime) +#endif + +#define _ctloc(x) (_CurrentTimeLocale->x) + +/* + * We do not implement alternate representations. However, we always + * check whether a given modifier is allowed for a certain conversion. + */ +#define ALT_E 0x01 +#define ALT_O 0x02 +#define LEGAL_ALT(x) { if (alt_format & ~(x)) return NULL; } + +static const unsigned char *conv_num(const unsigned char *, int *, unsigned int, unsigned int); +static const unsigned char *find_string(const unsigned char *, int *, const char * const *, + const char * const *, int); + + +char * +strptime(const char *buf, const char *fmt, struct tm *tm) +{ + unsigned char c; + const unsigned char *bp; + int alt_format, i, split_year = 0; + const char *new_fmt; + + bp = (const unsigned char *)buf; + + while (bp != NULL && (c = *fmt++) != '\0') { + /* Clear `alternate' modifier prior to new conversion. */ + alt_format = 0; + i = 0; + + /* Eat up white-space. */ + if (isspace(c)) { + while (isspace(*bp)) + bp++; + continue; + } + + if (c != '%') + goto literal; + + +again: switch (c = *fmt++) { + case '%': /* "%%" is converted to "%". */ +literal: + if (c != *bp++) + return NULL; + LEGAL_ALT(0); + continue; + + /* + * "Alternative" modifiers. Just set the appropriate flag + * and start over again. + */ + case 'E': /* "%E?" alternative conversion modifier. */ + LEGAL_ALT(0); + alt_format |= ALT_E; + goto again; + + case 'O': /* "%O?" alternative conversion modifier. */ + LEGAL_ALT(0); + alt_format |= ALT_O; + goto again; + + /* + * "Complex" conversion rules, implemented through recursion. + */ + case 'c': /* Date and time, using the locale's format. */ + new_fmt = _ctloc(d_t_fmt); + goto recurse; + + case 'D': /* The date as "%m/%d/%y". */ + new_fmt = "%m/%d/%y"; + LEGAL_ALT(0); + goto recurse; + + case 'F': /* The date as "%Y-%m-%d". */ + new_fmt = "%Y-%m-%d"; + LEGAL_ALT(0); + goto recurse; + + case 'R': /* The time as "%H:%M". */ + new_fmt = "%H:%M"; + LEGAL_ALT(0); + goto recurse; + + case 'r': /* The time in 12-hour clock representation. */ + new_fmt =_ctloc(t_fmt_ampm); + LEGAL_ALT(0); + goto recurse; + + case 'T': /* The time as "%H:%M:%S". */ + new_fmt = "%H:%M:%S"; + LEGAL_ALT(0); + goto recurse; + + case 'X': /* The time, using the locale's format. */ + new_fmt =_ctloc(t_fmt); + goto recurse; + + case 'x': /* The date, using the locale's format. */ + new_fmt =_ctloc(d_fmt); + recurse: + bp = (const unsigned char *)strptime((const char *)bp, + new_fmt, tm); + LEGAL_ALT(ALT_E); + continue; + + /* + * "Elementary" conversion rules. + */ + case 'A': /* The day of week, using the locale's form. */ + case 'a': + bp = find_string(bp, &tm->tm_wday, _ctloc(day), + _ctloc(abday), 7); + LEGAL_ALT(0); + continue; + + case 'B': /* The month, using the locale's form. */ + case 'b': + case 'h': + bp = find_string(bp, &tm->tm_mon, _ctloc(mon), + _ctloc(abmon), 12); + LEGAL_ALT(0); + continue; + + case 'C': /* The century number. */ + i = 20; + bp = conv_num(bp, &i, 0, 99); + + i = i * 100 - TM_YEAR_BASE; + if (split_year) + i += tm->tm_year % 100; + split_year = 1; + tm->tm_year = i; + LEGAL_ALT(ALT_E); + continue; + + case 'd': /* The day of month. */ + case 'e': + bp = conv_num(bp, &tm->tm_mday, 1, 31); + LEGAL_ALT(ALT_O); + continue; + + case 'k': /* The hour (24-hour clock representation). */ + LEGAL_ALT(0); + /* FALLTHROUGH */ + case 'H': + bp = conv_num(bp, &tm->tm_hour, 0, 23); + LEGAL_ALT(ALT_O); + continue; + + case 'l': /* The hour (12-hour clock representation). */ + LEGAL_ALT(0); + /* FALLTHROUGH */ + case 'I': + bp = conv_num(bp, &tm->tm_hour, 1, 12); + if (tm->tm_hour == 12) + tm->tm_hour = 0; + LEGAL_ALT(ALT_O); + continue; + + case 'j': /* The day of year. */ + i = 1; + bp = conv_num(bp, &i, 1, 366); + tm->tm_yday = i - 1; + LEGAL_ALT(0); + continue; + + case 'M': /* The minute. */ + bp = conv_num(bp, &tm->tm_min, 0, 59); + LEGAL_ALT(ALT_O); + continue; + + case 'm': /* The month. */ + i = 1; + bp = conv_num(bp, &i, 1, 12); + tm->tm_mon = i - 1; + LEGAL_ALT(ALT_O); + continue; + + case 'p': /* The locale's equivalent of AM/PM. */ + bp = find_string(bp, &i, _ctloc(am_pm), NULL, 2); + if (tm->tm_hour > 11) + return NULL; + tm->tm_hour += i * 12; + LEGAL_ALT(0); + continue; + + case 'S': /* The seconds. */ + bp = conv_num(bp, &tm->tm_sec, 0, 61); + LEGAL_ALT(ALT_O); + continue; + + case 'U': /* The week of year, beginning on sunday. */ + case 'W': /* The week of year, beginning on monday. */ + /* + * XXX This is bogus, as we can not assume any valid + * information present in the tm structure at this + * point to calculate a real value, so just check the + * range for now. + */ + bp = conv_num(bp, &i, 0, 53); + LEGAL_ALT(ALT_O); + continue; + + case 'w': /* The day of week, beginning on sunday. */ + bp = conv_num(bp, &tm->tm_wday, 0, 6); + LEGAL_ALT(ALT_O); + continue; + + case 'Y': /* The year. */ + i = TM_YEAR_BASE; /* just for data sanity... */ + bp = conv_num(bp, &i, 0, 9999); + tm->tm_year = i - TM_YEAR_BASE; + LEGAL_ALT(ALT_E); + continue; + + case 'y': /* The year within 100 years of the epoch. */ + /* LEGAL_ALT(ALT_E | ALT_O); */ + bp = conv_num(bp, &i, 0, 99); + + if (split_year) + /* preserve century */ + i += (tm->tm_year / 100) * 100; + else { + split_year = 1; + if (i <= 68) + i = i + 2000 - TM_YEAR_BASE; + else + i = i + 1900 - TM_YEAR_BASE; + } + tm->tm_year = i; + continue; + + case 'Z': + tzset(); + if (strncmp((const char *)bp, gmt, 3) == 0) { + tm->tm_isdst = 0; +#ifdef TM_GMTOFF + tm->TM_GMTOFF = 0; +#endif +#ifdef TM_ZONE + tm->TM_ZONE = gmt; +#endif + bp += 3; + } else { + const unsigned char *ep; + + ep = find_string(bp, &i, + (const char * const *)tzname, + NULL, 2); + if (ep != NULL) { + tm->tm_isdst = i; +#ifdef TM_GMTOFF + tm->TM_GMTOFF = -(timezone); +#endif +#ifdef TM_ZONE + tm->TM_ZONE = tzname[i]; +#endif + } + bp = ep; + } + continue; + + /* + * Miscellaneous conversions. + */ + case 'n': /* Any kind of white-space. */ + case 't': + while (isspace(*bp)) + bp++; + LEGAL_ALT(0); + continue; + + + default: /* Unknown/unsupported conversion. */ + return NULL; + } + } + + return __UNCONST(bp); +} + + +static const unsigned char * +conv_num(const unsigned char *buf, int *dest, unsigned int llim, unsigned int ulim) +{ + unsigned int result = 0; + unsigned char ch; + + /* The limit also determines the number of valid digits. */ + unsigned int rulim = ulim; + + ch = *buf; + if (ch < '0' || ch > '9') + return NULL; + + do { + result *= 10; + result += ch - '0'; + rulim /= 10; + ch = *++buf; + } while ((result * 10 <= ulim) && rulim && ch >= '0' && ch <= '9'); + + if (result < llim || result > ulim) + return NULL; + + *dest = result; + return buf; +} + +static const unsigned char * +find_string(const unsigned char *bp, int *tgt, const char * const *n1, + const char * const *n2, int c) +{ + int i; + size_t len; + + /* check full name - then abbreviated ones */ + for (; n1 != NULL; n1 = n2, n2 = NULL) { + for (i = 0; i < c; i++, n1++) { + len = strlen(*n1); + if (strncasecmp(*n1, (const char *)bp, len) == 0) { + *tgt = i; + return bp + len; + } + } + } + + /* Nothing matched */ + return NULL; +} diff --git a/StdLib/LibC/Time/tzfile.h b/StdLib/LibC/Time/tzfile.h index 11c20ebd39..f50ab669d2 100644 --- a/StdLib/LibC/Time/tzfile.h +++ b/StdLib/LibC/Time/tzfile.h @@ -1,11 +1,11 @@ /** @file Time Zone processing, declarations and macros. - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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. @@ -131,29 +131,6 @@ struct tzhead { #define SECSPERDAY ((LONG32)(SECSPERHOUR * HOURSPERDAY)) #define MONSPERYEAR 12 -#define TM_SUNDAY 0 -#define TM_MONDAY 1 -#define TM_TUESDAY 2 -#define TM_WEDNESDAY 3 -#define TM_THURSDAY 4 -#define TM_FRIDAY 5 -#define TM_SATURDAY 6 - -#define TM_JANUARY 0 -#define TM_FEBRUARY 1 -#define TM_MARCH 2 -#define TM_APRIL 3 -#define TM_MAY 4 -#define TM_JUNE 5 -#define TM_JULY 6 -#define TM_AUGUST 7 -#define TM_SEPTEMBER 8 -#define TM_OCTOBER 9 -#define TM_NOVEMBER 10 -#define TM_DECEMBER 11 - -#define TM_YEAR_BASE 1900 - #define EPOCH_YEAR 1970 #define EPOCH_WDAY TM_THURSDAY // Use this for 32-bit time_t //#define EPOCH_WDAY TM_SUNDAY // Use this for 64-bit time_t diff --git a/StdLib/LibC/Uefi/Console.c b/StdLib/LibC/Uefi/Console.c deleted file mode 100644 index 0c3a21cf45..0000000000 --- a/StdLib/LibC/Uefi/Console.c +++ /dev/null @@ -1,393 +0,0 @@ -/** @file - File abstractions of the console. - - Manipulates EFI_FILE_PROTOCOL abstractions for stdin, stdout, stderr. - - Copyright (c) 2010, 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 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 -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -static const CHAR16 * stdioNames[NUM_SPECIAL] = { - L"stdin:", L"stdout:", L"stderr:" -}; -static const int stdioFlags[NUM_SPECIAL] = { - O_RDONLY, // stdin - O_WRONLY, // stdout - O_WRONLY // stderr -}; - -static const int stdioMode[NUM_SPECIAL] = { - 0444, // stdin - 0222, // stdout - 0222 // stderr -}; - -static -EFI_STATUS -EFIAPI -ConClose( - IN EFI_FILE_PROTOCOL *This - ) -{ - ConInstance *Stream; - - Stream = BASE_CR(This, ConInstance, Abstraction); - // Quick check to see if Stream looks reasonable - if(Stream->Cookie != 0x62416F49) { // Cookie == 'IoAb' - return RETURN_INVALID_PARAMETER; // Looks like a bad This pointer - } - // Nothing to Flush. - // Mark the Stream as closed. - Stream->Dev = NULL; - - return RETURN_SUCCESS; -} - -static -EFI_STATUS -EFIAPI -ConDelete( - IN EFI_FILE_PROTOCOL *This - ) -{ - return RETURN_UNSUPPORTED; -} - -static -EFI_STATUS -EFIAPI -ConRead( - IN EFI_FILE_PROTOCOL *This, - IN OUT UINTN *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; - UINTN i; - - Stream = BASE_CR(This, ConInstance, Abstraction); - // Quick check to see if Stream looks reasonable - if(Stream->Cookie != 0x62416F49) { // Cookie == 'IoAb' - return RETURN_INVALID_PARAMETER; // Looks like a bad This pointer - } - if(Stream->Dev == NULL) { - // Can't read from an unopened Stream - return RETURN_DEVICE_ERROR; - } - if(Stream != &gMD->StdIo[0]) { - // Read only valid for stdin - return RETURN_UNSUPPORTED; - } - // 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 { - Status = gBS->WaitForEvent( 1, &Proto->WaitForKey, &Edex); - if(Status != EFI_SUCCESS) { - break; - } - Status = Proto->ReadKeyStroke(Proto, &Key); - if(Status != EFI_SUCCESS) { - break; - } - if(Key.ScanCode == SCAN_NULL) { - *OutPtr++ = Key.UnicodeChar; - ++i; - } - if(Key.UnicodeChar < 0x0020) { // If a control character, or a scan code - break; - } - } while(i < NumChar); - *BufferSize = i * sizeof(CHAR16); - return Status; -} - -/* Write a NULL terminated WCS to the EFI console. - - @param[in,out] BufferSize Number of bytes in Buffer. Set to zero if - the string couldn't be displayed. - @parem[in] Buffer The WCS string to be displayed - -*/ -static -EFI_STATUS -EFIAPI -ConWrite( - IN EFI_FILE_PROTOCOL *This, - IN OUT UINTN *BufferSize, - IN VOID *Buffer - ) -{ - EFI_STATUS Status; - EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto; - ConInstance *Stream; - CHAR16 *MyBuf; - UINTN NumChar; - - Stream = BASE_CR(This, ConInstance, Abstraction); - // Quick check to see if Stream looks reasonable - if(Stream->Cookie != 0x62416F49) { // Cookie == 'IoAb' - return RETURN_INVALID_PARAMETER; // Looks like a bad This pointer - } - if(Stream->Dev == NULL) { - // Can't write to an unopened Stream - return RETURN_DEVICE_ERROR; - } - if(Stream == &gMD->StdIo[0]) { - // Write is not valid for stdin - return RETURN_UNSUPPORTED; - } - // Everything is OK to do the write. - Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev; - MyBuf = (CHAR16 *)Buffer; - NumChar = *BufferSize; - - // Send MyBuf to the console - Status = Proto->OutputString( Proto, MyBuf); - // Depending on status, update BufferSize and return - if(Status != EFI_SUCCESS) { - *BufferSize = 0; // We don't really know how many characters made it out - } - else { - *BufferSize = NumChar; - Stream->NumWritten += NumChar; - } - return Status; -} - -static -EFI_STATUS -EFIAPI -ConGetPosition( - IN EFI_FILE_PROTOCOL *This, - OUT UINT64 *Position - ) -{ - ConInstance *Stream; - EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto; - XYoffset CursorPos; - - Stream = BASE_CR(This, ConInstance, Abstraction); - // Quick check to see if Stream looks reasonable - if(Stream->Cookie != 0x62416F49) { // Cookie == 'IoAb' - return RETURN_INVALID_PARAMETER; // Looks like a bad This pointer - } - if(Stream == &gMD->StdIo[0]) { - // This is stdin - *Position = Stream->NumRead; - } - else { - Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev; - CursorPos.XYpos.Column = (UINT32)Proto->Mode->CursorColumn; - CursorPos.XYpos.Row = (UINT32)Proto->Mode->CursorRow; - *Position = CursorPos.Offset; - } - return RETURN_SUCCESS; -} - -static -EFI_STATUS -EFIAPI -ConSetPosition( - IN EFI_FILE_PROTOCOL *This, - IN UINT64 Position - ) -{ - ConInstance *Stream; - EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto; - XYoffset CursorPos; - - Stream = BASE_CR(This, ConInstance, Abstraction); - // Quick check to see if Stream looks reasonable - if(Stream->Cookie != 0x62416F49) { // Cookie == 'IoAb' - return RETURN_INVALID_PARAMETER; // Looks like a bad This pointer - } - if(Stream->Dev == NULL) { - // Can't write to an unopened Stream - return RETURN_DEVICE_ERROR; - } - if(Stream == &gMD->StdIo[0]) { - // Seek is not valid for stdin - return RETURN_UNSUPPORTED; - } - // Everything is OK to do the final verification and "seek". - Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev; - CursorPos.Offset = Position; - - return Proto->SetCursorPosition(Proto, - (INTN)CursorPos.XYpos.Column, - (INTN)CursorPos.XYpos.Row); -} - -static -EFI_STATUS -EFIAPI -ConGetInfo( - IN EFI_FILE_PROTOCOL *This, - IN EFI_GUID *InformationType, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer - ) -{ - EFI_FILE_INFO *InfoBuf; - ConInstance *Stream; - - Stream = BASE_CR(This, ConInstance, Abstraction); - // Quick check to see if Stream looks reasonable - if((Stream->Cookie != 0x62416F49) || // Cookie == 'IoAb' - (Buffer == NULL)) - { - return RETURN_INVALID_PARAMETER; - } - if(*BufferSize < sizeof(EFI_FILE_INFO)) { - *BufferSize = sizeof(EFI_FILE_INFO); - return RETURN_BUFFER_TOO_SMALL; - } - // All of our parameters are correct, so fill in the information. - (void) ZeroMem(Buffer, sizeof(EFI_FILE_INFO)); - InfoBuf = (EFI_FILE_INFO *)Buffer; - InfoBuf->Size = sizeof(EFI_FILE_INFO); - InfoBuf->FileSize = 1; - InfoBuf->PhysicalSize = 1; - *BufferSize = sizeof(EFI_FILE_INFO); - - return RETURN_SUCCESS; -} - -static -EFI_STATUS -EFIAPI -ConSetInfo( - IN EFI_FILE_PROTOCOL *This, - IN EFI_GUID *InformationType, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - return RETURN_UNSUPPORTED; -} - -static -EFI_STATUS -EFIAPI -ConFlush( - IN EFI_FILE_PROTOCOL *This - ) -{ - return RETURN_SUCCESS; -} - -EFI_STATUS -EFIAPI -ConOpen( - IN EFI_FILE_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **NewHandle, - IN CHAR16 *FileName, - IN UINT64 OpenMode, // Ignored - IN UINT64 Attributes // Ignored - ) -{ - ConInstance *Stream; - EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto; - UINTN Columns; - UINTN Rows; - int i; - - if((NewHandle == NULL) || - (FileName == NULL)) - { - return RETURN_INVALID_PARAMETER; - } - // Process FileName - for(i = 0; i < NUM_SPECIAL; ++i) { - if(StrCmp( stdioNames[i], FileName) == 0) { - break; - } - } - if(i >= NUM_SPECIAL) { - return RETURN_NO_MAPPING; - } - // Get pointer to instance. - Stream = &gMD->StdIo[i]; - if(Stream->Dev == NULL) { - // If this stream has been closed, then - // Initialize instance. - Stream->Cookie = 0x62416F49; - Stream->NumRead = 0; - Stream->NumWritten = 0; - switch(i) { - case 0: - Stream->Dev = gST->ConIn; - break; - case 1: - Stream->Dev = gST->ConOut; - break; - case 2: - if(gST->StdErr == NULL) { - Stream->Dev = gST->ConOut; - } - else { - Stream->Dev = gST->StdErr; - } - break; - default: - return RETURN_VOLUME_CORRUPTED; // This is a "should never happen" case. - } - Stream->Abstraction.Revision = 0x00010000; - Stream->Abstraction.Open = &ConOpen; - Stream->Abstraction.Close = &ConClose; - Stream->Abstraction.Delete = &ConDelete; - Stream->Abstraction.Read = &ConRead; - Stream->Abstraction.Write = &ConWrite; - Stream->Abstraction.GetPosition = &ConGetPosition; - Stream->Abstraction.SetPosition = &ConSetPosition; - Stream->Abstraction.GetInfo = &ConGetInfo; - Stream->Abstraction.SetInfo = &ConSetInfo; - Stream->Abstraction.Flush = &ConFlush; - // Get additional information if this is an Output stream - if(i != 0) { - Proto = Stream->Dev; - Stream->ConOutMode = Proto->Mode->Mode; - if( Proto->QueryMode(Proto, Stream->ConOutMode, &Columns, &Rows) != RETURN_SUCCESS) { - Stream->Dev = NULL; // Mark this stream as closed - return RETURN_INVALID_PARAMETER; - } - Stream->MaxConXY.XYpos.Column = (UINT32)Columns; - Stream->MaxConXY.XYpos.Row = (UINT32)Rows; - } - } - // Save NewHandle and return. - *NewHandle = &Stream->Abstraction; - - return RETURN_SUCCESS; -} diff --git a/StdLib/LibC/Uefi/Devices/Console/daConsole.c b/StdLib/LibC/Uefi/Devices/Console/daConsole.c new file mode 100644 index 0000000000..c579959081 --- /dev/null +++ b/StdLib/LibC/Uefi/Devices/Console/daConsole.c @@ -0,0 +1,558 @@ +/** @file + Abstract device driver for the UEFI Console. + + Manipulates abstractions for stdin, stdout, stderr. + + Copyright (c) 2010 - 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 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 +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static const CHAR16* const +stdioNames[NUM_SPECIAL] = { + L"stdin:", L"stdout:", L"stderr:" +}; + +static const int stdioFlags[NUM_SPECIAL] = { + O_RDONLY, // stdin + O_WRONLY, // stdout + O_WRONLY // stderr +}; + +static DeviceNode *ConNode[NUM_SPECIAL]; +static ConInstance *ConInstanceList; + +ssize_t +WideTtyCvt( CHAR16 *dest, const char *buf, size_t n) +{ + UINTN i; + wint_t wc; + + for(i = 0; i < n; ++i) { + wc = btowc(*buf++); + if( wc == 0) { + break; + }; + if(wc < 0) { + wc = BLOCKELEMENT_LIGHT_SHADE; + } + if(wc == L'\n') { + *dest++ = L'\r'; + } + *dest++ = (CHAR16)wc; + } + *dest = 0; + return (ssize_t)i; +} + +static +int +EFIAPI +da_ConClose( + IN struct __filedes *filp +) +{ + ConInstance *Stream; + + 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 File Descriptor pointer + } + gMD->StdIo[Stream->InstanceNum] = NULL; // Mark the stream as closed + return RETURN_SUCCESS; +} + +static +off_t +EFIAPI +da_ConSeek( + struct __filedes *filp, + off_t Position, + int whence ///< Ignored by Console +) +{ + ConInstance *Stream; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto; + XYoffset CursorPos; + + 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) { + // Seek is not valid for stdin + EFIerrno = RETURN_UNSUPPORTED; + return -1; + } + // Everything is OK to do the final verification and "seek". + Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev; + CursorPos.Offset = Position; + + EFIerrno = Proto->SetCursorPosition(Proto, + (INTN)CursorPos.XYpos.Column, + (INTN)CursorPos.XYpos.Row); + + if(RETURN_ERROR(EFIerrno)) { + return -1; + } + else { + return Position; + } +} + +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 + the string couldn't be displayed. + @param[in] Buffer The WCS string to be displayed + + @return The number of characters written. +*/ +static +ssize_t +EFIAPI +da_ConWrite( + IN struct __filedes *filp, + IN off_t *Position, + IN size_t BufferSize, + IN const void *Buffer + ) +{ + EFI_STATUS Status; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto; + ConInstance *Stream; + ssize_t NumChar; + //XYoffset CursorPos; + + 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) { + // Write is not valid for stdin + EFIerrno = RETURN_UNSUPPORTED; + return -1; + } + // Everything is OK to do the write. + Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev; + + // Convert string from MBCS to WCS and translate \n to \r\n. + NumChar = WideTtyCvt(gMD->UString, (const char *)Buffer, BufferSize); + //if(NumChar > 0) { + // BufferSize = (size_t)(NumChar * sizeof(CHAR16)); + //} + BufferSize = NumChar; + + //if( Position != NULL) { + // CursorPos.Offset = (UINT64)*Position; + + // Status = Proto->SetCursorPosition(Proto, + // (INTN)CursorPos.XYpos.Column, + // (INTN)CursorPos.XYpos.Row); + // if(RETURN_ERROR(Status)) { + // return -1; + // } + //} + + // Send the Unicode buffer to the console + Status = Proto->OutputString( Proto, gMD->UString); + // Depending on status, update BufferSize and return + if(RETURN_ERROR(Status)) { + BufferSize = 0; // We don't really know how many characters made it out + } + else { + //BufferSize = NumChar; + Stream->NumWritten += NumChar; + } + EFIerrno = Status; + return BufferSize; +} + +/** 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. + st_physsize 1 for stdin, 0 if QueryMode error, else max X and Y coordinates for the current mode. + st_curpos 0 for stdin, current X & Y coordinates for stdout and stderr + st_blksize Set to 1 since this is a character device + + All other members of the stat structure are left unchanged. +**/ +static +int +EFIAPI +da_ConStat( + struct __filedes *filp, + struct stat *Buffer, + void *Something + ) +{ + ConInstance *Stream; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto; + XYoffset CursorPos; + INT32 OutMode; + UINTN ModeCol; + UINTN ModeRow; + +// ConGetInfo + Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction); + // Quick check to see if Stream looks reasonable + if ((Stream->Cookie != CON_COOKIE) || // Cookie == 'IoAb' + (Buffer == NULL)) + { + EFIerrno = RETURN_INVALID_PARAMETER; + return -1; + } + // All of our parameters are correct, so fill in the information. + Buffer->st_blksize = 1; + +// ConGetPosition + if(Stream->InstanceNum == STDIN_FILENO) { + // This is stdin + Buffer->st_curpos = 0; + Buffer->st_size = (off_t)Stream->NumRead; + Buffer->st_physsize = 1; + } + else { + Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev; + CursorPos.XYpos.Column = (UINT32)Proto->Mode->CursorColumn; + CursorPos.XYpos.Row = (UINT32)Proto->Mode->CursorRow; + Buffer->st_curpos = (off_t)CursorPos.Offset; + Buffer->st_size = (off_t)Stream->NumWritten; + + OutMode = Proto->Mode->Mode; + EFIerrno = Proto->QueryMode(Proto, (UINTN)OutMode, &ModeCol, &ModeRow); + if(RETURN_ERROR(EFIerrno)) { + Buffer->st_physsize = 0; + } + else { + CursorPos.XYpos.Column = (UINT32)ModeCol; + CursorPos.XYpos.Row = (UINT32)ModeRow; + Buffer->st_physsize = (off_t)CursorPos.Offset; + } + } + return 0; +} + +static +int +EFIAPI +da_ConIoctl( + struct __filedes *filp, + ULONGN cmd, + void *argp + ) +{ + return -EPERM; +} + +/** Open an abstract Console Device. +**/ +int +EFIAPI +da_ConOpen( + struct __filedes *filp, + void *DevInstance, + wchar_t *Path, // Not used for console devices + wchar_t *Flags // Not used for console devices + ) +{ + ConInstance *Stream; + + if((filp == NULL) || + (DevInstance == NULL)) + { + EFIerrno = RETURN_INVALID_PARAMETER; + return -1; + } + Stream = (ConInstance *)DevInstance; + // 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; + filp->f_iflags |= (S_IFREG | _S_IFCHR | _S_ICONSOLE); + filp->f_offset = 0; + filp->f_ops = &Stream->Abstraction; + + return 0; +} + +#include +/* Returns a bit mask describing which operations could be completed immediately. + + (POLLIN | POLLRDNORM) A Unicode character is available to read + (POLLIN) A ScanCode is ready. + (POLLOUT) The device is ready for output - always set on stdout and stderr. + +*/ +static +short +EFIAPI +da_ConPoll( + struct __filedes *filp, + short events + ) +{ + EFI_SIMPLE_TEXT_INPUT_PROTOCOL *Proto; + ConInstance *Stream; + EFI_STATUS Status = RETURN_SUCCESS; + short RdyMask = 0; + + 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 POLLNVAL; // Looks like a bad filp pointer + } + if(Stream->InstanceNum == 0) { + // Only input is supported for this device + Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev; + if((Stream->UnGetKey.UnicodeChar == CHAR_NULL) && (Stream->UnGetKey.ScanCode == SCAN_NULL)) { + Status = Proto->ReadKeyStroke(Proto, &Stream->UnGetKey); + if(Status == RETURN_SUCCESS) { + RdyMask = POLLIN; + if(Stream->UnGetKey.UnicodeChar != CHAR_NULL) { + RdyMask |= POLLRDNORM; + } + } + else { + Stream->UnGetKey.ScanCode = SCAN_NULL; + Stream->UnGetKey.UnicodeChar = CHAR_NULL; + } + } + } + else if(Stream->InstanceNum < NUM_SPECIAL) { // Not 0, is it 1 or 2? + // Only output is supported for this device + RdyMask = POLLOUT; + } + else { + RdyMask = POLLERR; // Not one of the standard streams + } + EFIerrno = Status; + + return (RdyMask & (events | POLL_RETONLY)); +} + +/** Construct the Console stream devices: stdin, stdout, stderr. + + Allocate the instance structure and populate it with the information for + each stream device. +**/ +RETURN_STATUS +EFIAPI +__Cons_construct( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + ConInstance *Stream; + RETURN_STATUS Status = RETURN_SUCCESS; + int i; + + ConInstanceList = (ConInstance *)AllocateZeroPool(NUM_SPECIAL * sizeof(ConInstance)); + if(ConInstanceList == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + + for( i = 0; i < NUM_SPECIAL; ++i) { + // Get pointer to instance. + Stream = &ConInstanceList[i]; + + Stream->Cookie = CON_COOKIE; + Stream->InstanceNum = i; + + switch(i) { + case STDIN_FILENO: + Stream->Dev = SystemTable->ConIn; + break; + case STDOUT_FILENO: + Stream->Dev = SystemTable->ConOut; + break; + case STDERR_FILENO: + if(SystemTable->StdErr == NULL) { + Stream->Dev = SystemTable->ConOut; + } + else { + Stream->Dev = SystemTable->StdErr; + } + break; + default: + return RETURN_VOLUME_CORRUPTED; // This is a "should never happen" case. + } + + Stream->Abstraction.fo_close = &da_ConClose; + Stream->Abstraction.fo_read = &da_ConRead; + Stream->Abstraction.fo_write = &da_ConWrite; + Stream->Abstraction.fo_stat = &da_ConStat; + Stream->Abstraction.fo_lseek = &da_ConSeek; + Stream->Abstraction.fo_fcntl = &fnullop_fcntl; + Stream->Abstraction.fo_ioctl = &da_ConIoctl; + Stream->Abstraction.fo_poll = &da_ConPoll; + Stream->Abstraction.fo_flush = &fnullop_flush; + Stream->Abstraction.fo_delete = &fbadop_delete; + Stream->Abstraction.fo_mkdir = &fbadop_mkdir; + Stream->Abstraction.fo_rmdir = &fbadop_rmdir; + Stream->Abstraction.fo_rename = &fbadop_rename; + + Stream->NumRead = 0; + Stream->NumWritten = 0; + Stream->UnGetKey.ScanCode = SCAN_NULL; + Stream->UnGetKey.UnicodeChar = CHAR_NULL; + + if(Stream->Dev == NULL) { + continue; // No device for this stream. + } + ConNode[i] = __DevRegister(stdioNames[i], NULL, &da_ConOpen, Stream, 1, sizeof(ConInstance), stdioFlags[i]); + if(ConNode[i] == NULL) { + Status = EFIerrno; + break; + } + Stream->Parent = ConNode[i]; + } + return Status; +} + +RETURN_STATUS +EFIAPI +__Cons_deconstruct( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + int i; + + for(i = 0; i < NUM_SPECIAL; ++i) { + if(ConNode[i] != NULL) { + FreePool(ConNode[i]); + } + } + if(ConInstanceList != NULL) { + FreePool(ConInstanceList); + } + + return RETURN_SUCCESS; +} + +/* ######################################################################### */ +#if 0 /* Not implemented for Console */ + +static +int +EFIAPI +da_ConCntl( + struct __filedes *filp, + UINT32, + void *, + void * + ) +{ +} + +static +int +EFIAPI +da_ConFlush( + struct __filedes *filp + ) +{ + return 0; +} +#endif /* Not implemented for Console */ diff --git a/StdLib/LibC/Uefi/Devices/UefiShell/daShell.c b/StdLib/LibC/Uefi/Devices/UefiShell/daShell.c new file mode 100644 index 0000000000..37870e8384 --- /dev/null +++ b/StdLib/LibC/Uefi/Devices/UefiShell/daShell.c @@ -0,0 +1,650 @@ +/** @file + Abstract device driver for the UEFI Shell-hosted environment. + + In a Shell-hosted environment, this is the driver that is called + when no other driver matches. + + 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 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. + +**/ +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static +int +EFIAPI +da_ShellClose( + IN struct __filedes *Fp +) +{ + EFIerrno = ShellCloseFile( (SHELL_FILE_HANDLE *)&Fp->devdata); + if(RETURN_ERROR(EFIerrno)) { + return -1; + } + return 0; +} + +static +int +EFIAPI +da_ShellDelete( + struct __filedes *filp + ) +{ + RETURN_STATUS Status; + + Status = ShellDeleteFile( (SHELL_FILE_HANDLE *)&filp->devdata); + if(Status != RETURN_SUCCESS) { + errno = EFI2errno(Status); + EFIerrno = Status; + return -1; + } + return 0; +} + +static +off_t +EFIAPI +da_ShellSeek( + struct __filedes *filp, + off_t offset, + int whence +) +{ + __off_t CurPos = -1; + RETURN_STATUS Status = RETURN_SUCCESS; + SHELL_FILE_HANDLE FileHandle; + + FileHandle = (SHELL_FILE_HANDLE)filp->devdata; + + if(whence != SEEK_SET) { + // We are doing a relative seek + if(whence == SEEK_END) { + // seeking relative to EOF, so position there first. + Status = ShellSetFilePosition( FileHandle, 0xFFFFFFFFFFFFFFFFULL); + } + if(Status == RETURN_SUCCESS) { + // Now, determine our current position. + Status = ShellGetFilePosition( FileHandle, (UINT64 *)&CurPos); + } + } + else { + CurPos = 0; // offset is an absolute position for SEEK_SET + if(offset < 0) { + Status = RETURN_INVALID_PARAMETER; + } + } + if(Status == RETURN_SUCCESS) { + /* CurPos now indicates the point we are seeking from, so seek... */ + Status = ShellSetFilePosition( FileHandle, (UINT64)(CurPos + offset)); + if(Status == RETURN_SUCCESS) { + // Now, determine our final position. + Status = ShellGetFilePosition( FileHandle, (UINT64 *)&CurPos); + } + } + if(Status != RETURN_SUCCESS) { + if(Status == EFI_UNSUPPORTED) { + errno = EISDIR; + } + else { + errno = EFI2errno(Status); + } + EFIerrno = Status; + CurPos = EOF; + } + return CurPos; +} + +/** The directory path is created with the access permissions specified by + perms. + + The directory is closed after it is created. + + @retval 0 The directory was created successfully. + @retval -1 An error occurred and an error code is stored in errno. +**/ +static +int +EFIAPI +da_ShellMkdir( + const char *path, + __mode_t perms + ) +{ + SHELL_FILE_HANDLE FileHandle; + RETURN_STATUS Status; + EFI_FILE_INFO *FileInfo; + wchar_t *NewPath; + int retval = -1; + + // Convert name from MBCS to WCS and change '/' to '\\' + NewPath = NormalizePath( path); + + if(NewPath != NULL) { + Status = ShellCreateDirectory( NewPath, &FileHandle); + if(Status == RETURN_SUCCESS) { + FileInfo = ShellGetFileInfo( FileHandle); + Status = RETURN_ABORTED; // In case ShellGetFileInfo() failed + if(FileInfo != NULL) { + FileInfo->Attribute = Omode2EFI(perms); + Status = ShellSetFileInfo( FileHandle, FileInfo); + FreePool(FileInfo); + if(Status == RETURN_SUCCESS) { + (void)ShellCloseFile(&FileHandle); + retval = 0; + } + } + } + errno = EFI2errno(Status); + EFIerrno = Status; + free(NewPath); + } + return retval; +} + +static +ssize_t +EFIAPI +da_ShellRead( + IN OUT struct __filedes *filp, + IN OUT off_t *offset, + IN size_t BufferSize, + OUT VOID *Buffer +) +{ + ssize_t BufSize; + SHELL_FILE_HANDLE FileHandle; + RETURN_STATUS Status; + + if(offset != NULL) { + BufSize = (ssize_t)da_ShellSeek(filp, *offset, SEEK_SET); + if(BufSize >= 0) { + filp->f_offset = BufSize; + } + } + + BufSize = (ssize_t)BufferSize; + FileHandle = (SHELL_FILE_HANDLE)filp->devdata; + + Status = ShellReadFile( FileHandle, (UINTN *)&BufSize, Buffer); + if(Status != RETURN_SUCCESS) { + EFIerrno = Status; + errno = EFI2errno(Status); + if(Status == RETURN_BUFFER_TOO_SMALL) { + BufSize = -BufSize; + } + else { + BufSize = -1; + } + } + else { + filp->f_offset += BufSize; // Advance to where we want to read next. + } + return BufSize; +} + +static +ssize_t +EFIAPI +da_ShellWrite( + IN struct __filedes *filp, + IN off_t *offset, + IN size_t BufferSize, + IN const void *Buffer + ) +{ + ssize_t BufSize; + SHELL_FILE_HANDLE FileHandle; + RETURN_STATUS Status; + off_t Position = 0; + int How = SEEK_SET; + + + if((offset != NULL) || (filp->Oflags & O_APPEND)) { + if(filp->Oflags & O_APPEND) { + Position = 0; + How = SEEK_END; + } + else { + Position = *offset; + How = SEEK_SET; + } + BufSize = (ssize_t)da_ShellSeek(filp, Position, How); + if(BufSize >= 0) { + filp->f_offset = BufSize; + } + } + + BufSize = (ssize_t)BufferSize; + FileHandle = (SHELL_FILE_HANDLE)filp->devdata; + + Status = ShellWriteFile( FileHandle, (UINTN *)&BufSize, (void *)Buffer); + + if(Status != RETURN_SUCCESS) { + EFIerrno = Status; + errno = EFI2errno(Status); + if(Status == EFI_UNSUPPORTED) { + errno = EISDIR; + } + BufSize = -1; + } + else { + filp->f_offset += BufSize; // Advance to where we want to write next. + } + + return BufSize; +} + +static +int +EFIAPI +da_ShellStat( + struct __filedes *filp, + struct stat *statbuf, + void *Something + ) +{ + SHELL_FILE_HANDLE FileHandle; + EFI_FILE_INFO *FileInfo = NULL; + UINT64 Attributes; + RETURN_STATUS Status; + mode_t newmode; + + FileHandle = (SHELL_FILE_HANDLE)filp->devdata; + + FileInfo = ShellGetFileInfo( FileHandle); + + if(FileInfo != NULL) { + // Got the info, now populate statbuf with it + statbuf->st_blksize = S_BLKSIZE; + statbuf->st_size = FileInfo->FileSize; + statbuf->st_physsize = FileInfo->PhysicalSize; + statbuf->st_birthtime = Efi2Time( &FileInfo->CreateTime); + statbuf->st_atime = Efi2Time( &FileInfo->LastAccessTime); + statbuf->st_mtime = Efi2Time( &FileInfo->ModificationTime); + Attributes = FileInfo->Attribute; + newmode = (mode_t)(Attributes << S_EFISHIFT) | S_ACC_READ; + if((Attributes & EFI_FILE_DIRECTORY) == 0) { + newmode |= _S_IFREG; + if((Attributes & EFI_FILE_READ_ONLY) == 0) { + newmode |= S_ACC_WRITE; + } + } + else { + newmode |= _S_IFDIR; + } + statbuf->st_mode = newmode; + Status = RETURN_SUCCESS; + } + else { + Status = RETURN_DEVICE_ERROR; + } + errno = EFI2errno(Status); + EFIerrno = Status; + + if(FileInfo != NULL) { + FreePool(FileInfo); // Release the buffer allocated by the GetInfo function + } + return errno? -1 : 0; +} + +static +int +EFIAPI +da_ShellIoctl( + struct __filedes *filp, + ULONGN cmd, + void *argp ///< May be a pointer or a value + ) +{ + return 0; +} + +/** Open an abstract Shell File. +**/ +int +EFIAPI +da_ShellOpen( + struct __filedes *filp, + void *DevInstance, + wchar_t *Path, + wchar_t *Flags + ) +{ + UINT64 OpenMode; + UINT64 Attributes; + SHELL_FILE_HANDLE FileHandle; + GenericInstance *Gip; + char *NPath; + RETURN_STATUS Status; + int oflags; + + EFIerrno = RETURN_SUCCESS; + + //Attributes = Omode2EFI(mode); + Attributes = 0; + + // Convert oflags to Attributes + oflags = filp->Oflags; + OpenMode = Oflags2EFI(oflags); + if(OpenMode == 0) { + errno = EINVAL; + return -1; + } + + /* 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. + + !!!!!!!!! Change this to use ShellSetFileInfo() to actually truncate the file + !!!!!!!!! instead of deleting and re-creating it. + */ + if((oflags & O_TRUNC) || ((oflags & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT))) { + Status = ShellIsFile( Path ); + if(Status == RETURN_SUCCESS) { + // The file exists + if(oflags & O_TRUNC) { + NPath = AllocateZeroPool(1024); + if(NPath == NULL) { + errno = ENOMEM; + EFIerrno = RETURN_OUT_OF_RESOURCES; + return -1; + } + wcstombs(NPath, Path, 1024); + // 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. + } + FreePool(NPath); + } + else if((oflags & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT)) { + errno = EEXIST; + EFIerrno = RETURN_ACCESS_DENIED; + filp->f_iflags = 0; // Release our reservation on this FD + return -1; + } + } + } + + // Call the EFI Shell's Open function + Status = ShellOpenFileByName( Path, &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; + } + // Successfully got a regular File + filp->f_iflags |= S_IFREG; + + // Update the info in the fd + filp->devdata = (void *)FileHandle; + + Gip = (GenericInstance *)DevInstance; + filp->f_offset = 0; + filp->f_ops = &Gip->Abstraction; +// filp->devdata = FileHandle; + + return 0; +} + +#include +/* Returns a bit mask describing which operations could be completed immediately. + + For now, assume the file system, via the shell, is always ready. + + (POLLIN | POLLRDNORM) The file system is ready to be read. + (POLLOUT) The file system is ready for output. + +*/ +static +short +EFIAPI +da_ShellPoll( + struct __filedes *filp, + short events + ) +{ + UINT32 RdyMask; + short retval = 0; + + RdyMask = (UINT32)filp->Oflags; + + switch(RdyMask & O_ACCMODE) { + case O_RDONLY: + retval = (POLLIN | POLLRDNORM); + break; + + case O_WRONLY: + retval = POLLOUT; + break; + + case O_RDWR: + retval = (POLLIN | POLLRDNORM | POLLOUT); + break; + + default: + retval = POLLERR; + break; + } + return (retval & (events | POLL_RETONLY)); +} + +static +int +EFIAPI +da_ShellRename( + const char *from, + const char *to + ) +{ + RETURN_STATUS Status; + EFI_FILE_INFO *NewFileInfo; + EFI_FILE_INFO *OldFileInfo; + char *NewFn; + int OldFd; + SHELL_FILE_HANDLE FileHandle; + + // Open old file + OldFd = open(from, O_RDWR, 0); + if(OldFd >= 0) { + FileHandle = (SHELL_FILE_HANDLE)gMD->fdarray[OldFd].devdata; + + NewFileInfo = malloc(sizeof(EFI_FILE_INFO) + PATH_MAX); + if(NewFileInfo != NULL) { + 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)); + FreePool(OldFileInfo); + // 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); + // Copy the new file name into our new file info buffer + wcsncpy(NewFileInfo->FileName, gMD->UString, wcslen(gMD->UString)+1); + // Apply the new file name + Status = ShellSetFileInfo(FileHandle, NewFileInfo); + free(NewFileInfo); + if(Status == EFI_SUCCESS) { + // File has been successfully renamed. We are DONE! + return 0; + } + errno = EFI2errno( Status ); + EFIerrno = Status; + } + else { + errno = EIO; + } + } + else { + errno = ENOMEM; + } + } + return -1; +} + +static +int +EFIAPI +da_ShellRmdir( + struct __filedes *filp + ) +{ + SHELL_FILE_HANDLE FileHandle; + RETURN_STATUS Status = RETURN_SUCCESS; + EFI_FILE_INFO *FileInfo = NULL; + int Count = 0; + BOOLEAN NoFile = FALSE; + + errno = 0; // Make it easier to see if we have an error later + + FileHandle = (SHELL_FILE_HANDLE)filp->devdata; + + FileInfo = ShellGetFileInfo(FileHandle); + if(FileInfo != NULL) { + if((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0) { + errno = ENOTDIR; + } + else { + // See if the directory has any entries other than ".." and ".". + FreePool(FileInfo); // Free up the buffer from ShellGetFileInfo() + Status = ShellFindFirstFile( FileHandle, &FileInfo); + if(Status == RETURN_SUCCESS) { + ++Count; + while(Count < 3) { + Status = ShellFindNextFile( FileHandle, FileInfo, &NoFile); + if(Status == RETURN_SUCCESS) { + if(NoFile) { + break; + } + ++Count; + } + else { + Count = 99; + } + } + FreePool(FileInfo); // Free buffer from ShellFindFirstFile() + if(Count < 3) { + // Directory is empty + Status = ShellDeleteFile( &FileHandle); + if(Status == RETURN_SUCCESS) { + EFIerrno = RETURN_SUCCESS; + return 0; + /* ######## SUCCESSFUL RETURN ######## */ + } + } + else { + if(Count == 99) { + errno = EIO; + } + else { + errno = ENOTEMPTY; + } + } + } + } + } + else { + errno = EIO; + } + EFIerrno = Status; + if(errno == 0) { + errno = EFI2errno( Status ); + } + return -1; +} + +/** Construct an instance of the abstract Shell device. + + Allocate the instance structure and populate it with the information for + the device. +**/ +RETURN_STATUS +EFIAPI +__ctor_DevShell( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + GenericInstance *Stream; + DeviceNode *Node; + RETURN_STATUS Status; + + Stream = (GenericInstance *)AllocateZeroPool(sizeof(GenericInstance)); + if(Stream == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + + Stream->Cookie = CON_COOKIE; + Stream->InstanceNum = 1; + Stream->Dev = NULL; + Stream->Abstraction.fo_close = &da_ShellClose; + Stream->Abstraction.fo_read = &da_ShellRead; + Stream->Abstraction.fo_write = &da_ShellWrite; + Stream->Abstraction.fo_fcntl = &fnullop_fcntl; + 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_delete = &da_ShellDelete; + Stream->Abstraction.fo_rmdir = &da_ShellRmdir; + Stream->Abstraction.fo_mkdir = &da_ShellMkdir; + Stream->Abstraction.fo_rename = &da_ShellRename; + Stream->Abstraction.fo_lseek = &da_ShellSeek; + + Node = __DevRegister(NULL, NULL, &da_ShellOpen, Stream, 1, sizeof(GenericInstance), O_RDWR); + Status = EFIerrno; + Stream->Parent = Node; + + return Status; +} + +RETURN_STATUS +EFIAPI +__dtor_DevShell( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + if(daDefaultDevice != NULL) { + if(daDefaultDevice->InstanceList != NULL) { + FreePool(daDefaultDevice->InstanceList); + } + FreePool(daDefaultDevice); + } + return RETURN_SUCCESS; +} diff --git a/StdLib/LibC/Uefi/Devices/Utility/DevGenisis.c b/StdLib/LibC/Uefi/Devices/Utility/DevGenisis.c new file mode 100644 index 0000000000..2bdb33ac53 --- /dev/null +++ b/StdLib/LibC/Uefi/Devices/Utility/DevGenisis.c @@ -0,0 +1,139 @@ +/** @file + Device Abstraction: device creation utility functions. + + 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 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 +#include +#include + +#include + +#include +#include +#include +#include +#include + +LIST_ENTRY daDeviceList = INITIALIZE_LIST_HEAD_VARIABLE(daDeviceList); +DeviceNode *daDefaultDevice = NULL; ///< Device to use if nothing else found +DeviceNode *daRootDevice = NULL; ///< Device containing the root file system +DeviceNode *daCurrentDevice = NULL; ///< Device currently being accessed + +/* Commonly used fileops + fnullop_* Does nothing and returns success. + fbadop_* Does nothing and returns EPERM +*/ +int fnullop_fcntl (struct __filedes *filp, UINT32 Cmd, void *p3, void *p4) +{ return 0; } + +short fnullop_poll (struct __filedes *filp, short Events) +{ + return ((POLLIN | POLLRDNORM | POLLOUT) & Events); +} + +int fnullop_flush (struct __filedes *filp) +{ return 0; } + +int fbadop_stat (struct __filedes *filp, struct stat *StatBuf, void *Buf) +{ return -EPERM; } + +int fbadop_ioctl (struct __filedes *filp, ULONGN Cmd, void *argp) +{ return -EPERM; } + +int fbadop_delete (struct __filedes *filp) +{ return -EPERM; } + +int fbadop_mkdir (const char *path, __mode_t perms) +{ return -EPERM; } + +int fbadop_rename (const char *from, const char *to) +{ return -EPERM; } + +int fbadop_rmdir (struct __filedes *filp) +{ return -EPERM; } + +/** Add a new device to the device list. + If both DevName and DevProto are NULL, register this as the Default device. + + @param DevName Name of the device to add. + @param DevProto Pointer to the GUID identifying the protocol associated with this device. + If DevProto is NULL, startup code will not try to find instances + of this device. + @param OpenFunc Pointer to the device's Open function. + @param InstanceList Optional pointer to the device's initialized instance list. + If InstanceList is NULL, the application startup code will + scan for instances of the protocol identified by DevProto and + populate the InstanceList in the order those protocols are found. + @param NumInstance Number of instances in InstanceList. + @param Modes Bit-mapped flags indicating operations (R, W, RW, ...) permitted to this device. + +**/ +DeviceNode * +EFIAPI +__DevRegister( + IN const CHAR16 *DevName, + IN GUID *DevProto, + IN FO_OPEN OpenFunc, + IN void *InstanceList, + IN int NumInstance, + IN UINT32 InstanceSize, + IN UINT32 Modes + ) +{ + DeviceNode *Node; + GenericInstance *GIp; + char *GenPtr; + int i; + + /* Validate parameters */ + if(((DevName == NULL) && (DevProto != NULL)) || + (OpenFunc == NULL)) { + EFIerrno = RETURN_INVALID_PARAMETER; + return NULL; + } + Node = (DeviceNode *)AllocateZeroPool(sizeof(DeviceNode)); + if(Node == NULL) { + EFIerrno = RETURN_OUT_OF_RESOURCES; + return NULL; + } + + Node->DevName = DevName; + Node->DevProto = DevProto; + Node->InstanceList = InstanceList; + Node->OpenFunc = OpenFunc; + Node->InstanceSize = InstanceSize; + Node->NumInstances = NumInstance; + Node->OpModes = Modes; + + /* Update the Parent member of each element of the InstanceList */ + if(InstanceList != NULL) { + GenPtr = InstanceList; + + for(i = 0; i < NumInstance; ++i) { // Iterate through each element of InstanceList + GIp = (GenericInstance *)GenPtr; + GIp->Parent = Node; // Initializing the Parent member & InstanceNum + //GIp->InstanceNum = i; + GenPtr += InstanceSize; + } + } + if(DevName == NULL) { + if(daDefaultDevice != NULL) { + EFIerrno = RETURN_INVALID_PARAMETER; + return NULL; + } + daDefaultDevice = Node; + } + else { + (void) InsertTailList(&daDeviceList, &Node->DevList); + } + EFIerrno = RETURN_SUCCESS; + return Node; +} diff --git a/StdLib/LibC/Uefi/Devices/Utility/DevSearch.c b/StdLib/LibC/Uefi/Devices/Utility/DevSearch.c new file mode 100644 index 0000000000..b0fc7bacd1 --- /dev/null +++ b/StdLib/LibC/Uefi/Devices/Utility/DevSearch.c @@ -0,0 +1,112 @@ +/** @file + Device Abstraction: Search device list for a matching device. + + 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 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 +#include +#include + +#include + +#include +#include +#include +#include + +/** Find a DeviceNode matching DevName or DevProto, or both. + + If DevName is NULL, then the device name is not used in the search. + If DevProto is NULL, then the protocol GUID is not used in the search. + If both are NULL, then INVALID_PARAMETER is returned. + If both DevName and DevProto are specified, then both must match. + If both are specified but only one matches, then DEVICE_ERROR is returned. + + @param DevName Name of the Device Abstraction to find. + @param DevProto GUID of the Protocol associated with the Device Abstraction. + @param Node Pointer to the pointer to receive the found Device Node's address. + + @retval RETURN_SUCCESS The desired Device Node was found. + @retval RETURN_INVALID_PARAMETER Both DevName and DevProto are NULL or Node is NULL. + @retval RETURN_DEVICE_ERROR DevName matched but DevProto did not. + @retval RETURN_NOT_FOUND The desired device was not found. +**/ +EFI_STATUS +EFIAPI +__DevSearch( + IN CHAR16 *DevName, + IN GUID *DevProto, + OUT DeviceNode **Node + ) +{ + RETURN_STATUS Status = RETURN_NOT_FOUND; + DeviceNode *WorkNode; + INT32 DevMatched; + + if(((DevName == NULL) && (DevProto == NULL)) || (Node == NULL)) { + Status = RETURN_INVALID_PARAMETER; + } + else { + if(IsListEmpty((LIST_ENTRY *)&daDeviceList)) { + Status = RETURN_NOT_FOUND; + } + else { + /* Traverse the list of Device Nodes hunting for a match */ + WorkNode = (DeviceNode *)GetFirstNode((LIST_ENTRY *)&daDeviceList); + do { + /* Use DevMatched to keep track of the three match conditions. */ + DevMatched = 0; + if(DevName != NULL) { + ++DevMatched; + if(wcsncmp(DevName, WorkNode->DevName, wcslen(WorkNode->DevName)) == 0) { + ++DevMatched; + } + } + /* At this point, DevMatched has one of the following values: + 0 DevName == NULL, no name comparison + 1 DevName did not match WorkNode's name + 2 DevName MATCHED + */ + if((DevMatched != 1) && (DevProto != NULL) && (WorkNode->DevProto != NULL)) { + /* Only bother with the GUID comparison if: + * There was NOT a name mismatch + * DevProto is NOT NULL -- there is a GUID to compare + * WorkNode->DevProto is NOT NULL + */ + if(CompareGuid(DevProto, WorkNode->DevProto)) { + // GUIDs matched, we found it + Status = RETURN_SUCCESS; + *Node = WorkNode; + break; + } + else { + // GUIDs did not match + if(DevMatched == 2) { + // Name matched, GUID did not! + Status = RETURN_DEVICE_ERROR; + break; // Don't try any more, we have an internal problem + } + } + } + else { + if(DevMatched == 2) { + // Device Name matched, GUIDs skipped + Status = RETURN_SUCCESS; + *Node = WorkNode; + break; + } + } + // Check the next device in the list + WorkNode = (DeviceNode *)GetNextNode(&daDeviceList, (LIST_ENTRY *)WorkNode); + } while(&daDeviceList != (LIST_ENTRY *)WorkNode); + } + } + return Status; +} diff --git a/StdLib/LibC/Uefi/Devices/Utility/Path.c b/StdLib/LibC/Uefi/Devices/Utility/Path.c new file mode 100644 index 0000000000..92bb1a20b7 --- /dev/null +++ b/StdLib/LibC/Uefi/Devices/Utility/Path.c @@ -0,0 +1,382 @@ +/** @file + Device Abstraction: Path manipulation utilities. + + 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 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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +/** Identify the type of path pointed to by Path. + + Paths are classified based upon their initial character sequences. + ^\\ Absolute Path + ^\. Relative Path + ^[^:\\]: Mapping Path + .* Relative Path + + Mapping paths are broken into two parts at the ':'. The part to the left of the ':' + is the Map Name, pointed to by Path, and the part to the right of the ':' is pointed + to by NewPath. + + If Path was not a Mapping Path, then NewPath is set to Path. + + @param[in] Path Pointer to the path to be classified. + @param[out] NewPath Pointer to the path portion of a mapping path. + @param[out] Length Length of the Map Name portion of the path. + + @retval PathAbsolute Path is an absolute path. NewPath points to the first '\'. + @retval PathRelative Path is a relative path. NewPath = Path. + @retval PathMapping Path is a mapping path. NewPath points to the character following ':'. + @retval PathError Path is NULL. +**/ +PATH_CLASS +EFIAPI +ClassifyPath( + IN wchar_t * Path, + OUT wchar_t ** NewPath, + OUT int * const Length + ) +{ + size_t MapLen; + + if(Path == NULL) { + return PathError; // Bad parameter + } + if(NewPath != NULL) { + *NewPath = Path; // Setup default condition + } + if((*Path == L'\\') || (*Path == L'\0')) { + return PathAbsolute; + } + if(*Path == L'.') { + return PathRelative; + } + /* The easy stuff has been done, now see if this is a mapping path. + See if there is a ':' in Path that isn't the first character and is before + any '\\' characters. + */ + MapLen = wcscspn(Path, L"\\:"); + if(Length != NULL) { + *Length = (int)MapLen; + } + /* MapLen == 0 means that the first character is a ':' + == PathLen means that there are no '\\' or ':' + Otherwise, Path[MapLen] == ':' for a mapping path + or '\\' for a relative path. + */ + if(MapLen == 0) { + return PathError; + } + if(Path[MapLen] == L':') { + if(NewPath != NULL) { + *NewPath = &Path[MapLen + 1]; // Point to character after then ':'. Might be '\0'. + } + return PathMapping; + } + return PathRelative; +} + +/* Normalize a narrow-character path and produce a wide-character path + that has forward slashes replaced with backslashes. + Backslashes are directory separators in UEFI File Paths. + + It is the caller's responsibility to eventually free() the returned buffer. + + @param[in] path A pointer to the narrow-character path to be normalized. + + @return A pointer to a buffer containing the normalized, wide-character, path. +*/ +wchar_t * +NormalizePath( const char *path) +{ + wchar_t *temp; + wchar_t *OldPath; + wchar_t *NewPath; + size_t Length; + + OldPath = AsciiStrToUnicodeStr(path, gMD->UString); + Length = wcslen(OldPath) + 1; + + NewPath = calloc(Length, sizeof(wchar_t)); + if(NewPath != NULL) { + temp = NewPath; + for( ; *OldPath; ++OldPath) { + if(*OldPath == L'/') { + *temp = L'\\'; + } + else { + *temp = *OldPath; + } + ++temp; + } + } + else { + errno = ENOMEM; + EFIerrno = RETURN_OUT_OF_RESOURCES; + } + return NewPath; +} + +/** Process a wide character string representing a Mapping Path and extract the instance number. + + The instance number is the sequence of decimal digits immediately to the left + of the ":" in the Map Name portion of a Mapping Path. + + This function is called with a pointer to beginning of the Map Name. + Thus Path[Length] must be a ':' and Path[Length - 1] must be a decimal digit. + If either of these are not true, an instance value of 0 is returned. + + If Path is NULL, an instance value of 0 is returned. + + @param[in] Path Points to the beginning of a Mapping Path + @param[in] Length Number of valid characters to the left of the ':' + + @return Returns either 0 or the value of the contiguous digits to the left of the ':'. +**/ +int +EFIAPI +PathInstance( + const wchar_t *Path, + int Length + ) +{ + wchar_t *temp; + int instance = 0; + + if((Path != NULL) && (Path[Length] == L':') && (Length > 0)) { + for(temp = __UNCONST(&Path[Length - 1]); Length > 0; --Length) { + if(!iswdigit(*temp)) { + break; + } + --temp; + } + instance = (int)wcstol(temp+1, NULL, 10); + } + return instance; +} + +/** Transform a relative path into an absolute path. + + If Path is NULL, return NULL. + Otherwise, pre-pend the CWD to Path then process the resulting path to: + - Replace "/./" with "/" + - Replace "//../" with "/" + - Do not allow one to back up past the root, "/" + + Also sets the Current Working Device to the Root Device. + + Path must be a previously allocated buffer. PathAdjust will + allocate a new buffer to hold the results of the transformation + and free Path. A pointer to the newly allocated buffer is returned. + + @param[in] Path A pointer to the path to be transformed. This buffer + will always be freed. + + @return A pointer to a buffer containing the transformed path. +**/ +wchar_t * +EFIAPI +PathAdjust( + wchar_t *Path + ) +{ + wchar_t *NewPath; + + NewPath = calloc(PATH_MAX, sizeof(wchar_t)); + if(NewPath != NULL) { + wmemcpy(NewPath, Path, PATH_MAX); + } + else { + errno = ENOMEM; + } + free(Path); + return NewPath; +} + +/** Replace the leading portion of Path with any aliases. + + Aliases are read from /etc/fstab. If there is an associated device, the + Current Working Device is set to that device. + + Path must be a previously allocated buffer. PathAlias will + allocate a new buffer to hold the results of the transformation + then free Path. A pointer to the newly allocated buffer is returned. + + @param[in] Path A pointer to the original, unaliased, path. This + buffer is always freed. + @param[out] Node Filled in with a pointer to the Device Node describing + the device abstraction associated with this path. + + @return A pointer to a buffer containing the aliased path. +**/ +wchar_t * +EFIAPI +PathAlias( + wchar_t *Path, + DeviceNode **Node + ) +{ + wchar_t *NewPath; + + NewPath = calloc(PATH_MAX, sizeof(wchar_t)); + if(NewPath != NULL) { + wmemcpy(NewPath, Path, PATH_MAX); + } + else { + errno = ENOMEM; + } + free(Path); + *Node = NULL; + return NewPath; +} + +/** Parse a path producing the target device, device instance, and file path. + + @param[in] path + @param[out] FullPath + @param[out] DevNode + @param[out] Which + + @retval RETURN_SUCCESS The path was parsed successfully. + @retval RETURN_NOT_FOUND The path does not map to a valid device. + @retval RETURN_OUT_OF_RESOURCES Insufficient memory to calloc a MapName buffer. + The errno variable is set to ENOMEM. + @retval RETURN_INVALID_PARAMETER The path parameter is not valid. + The errno variable is set to EINVAL. +**/ +RETURN_STATUS +EFIAPI +ParsePath( + IN const char *path, + OUT wchar_t **FullPath, + OUT DeviceNode **DevNode, + OUT int *Which + ) +{ + int MapLen; + PATH_CLASS PathClass; + wchar_t *NewPath; + wchar_t *WPath = NULL; + wchar_t *MPath = NULL; + DeviceNode *Node = NULL; + RETURN_STATUS Status = RETURN_NOT_FOUND; + int Instance = 0; + BOOLEAN ReMapped; + + ReMapped = FALSE; + + // Convert name from MBCS to WCS and change '/' to '\\' + WPath = NormalizePath( path); + PathClass = ClassifyPath(WPath, &NewPath, &MapLen); + +reclassify: + switch(PathClass) { + case PathMapping: + if(!ReMapped) { + if((NewPath == NULL) || (*NewPath == L'\0')) { /* Nothing after the ':' */ + PathClass = PathAbsolute; + } + else { + Instance = PathInstance(WPath, MapLen); + PathClass = ClassifyPath(NewPath, NULL, NULL); + } + ReMapped = TRUE; + if(WPath[MapLen] == L':') { + // Get the Map Name, including the trailing ':'. */ + MPath = calloc(MapLen+2, sizeof(wchar_t)); + if(MPath != NULL) { + wmemcpy(MPath, WPath, MapLen+2); + } + else { + errno = ENOMEM; + Status = RETURN_OUT_OF_RESOURCES; + break; // Exit the switch(PathClass) statement. + } + } + if(WPath != NewPath) { + /* Shift the RHS of the path down to the start of the buffer. */ + wmemmove(WPath, NewPath, wcslen(NewPath)+1); + NewPath = WPath; + } + goto reclassify; + } + /* Fall through to PathError if Remapped. + This means that the path looked like "foo:bar:something". + */ + + case PathError: + errno = EINVAL; + Status = RETURN_INVALID_PARAMETER; + break; + + case PathRelative: + /* Transform a relative path into an Absolute path. + Prepends CWD and handles ./ and ../ entries. + It is the caller's responsibility to free the space + allocated to WPath. + */ + WPath = PathAdjust(NewPath); // WPath was malloc()ed by PathAdjust + + case PathAbsolute: + /* Perform any path aliasing. For example: /dev/foo -> { node.foo, "" } + The current volume and directory are updated in the path as needed. + It is the caller's responsibility to free the space + allocated to WPath. + */ + Status = RETURN_SUCCESS; + WPath = PathAlias(WPath, &Node); // PathAlias frees its argument and malloc()s a new one. + break; + } + if(!RETURN_ERROR(Status)) { + *FullPath = WPath; + *Which = Instance; + + /* At this point, WPath is an absolute path, + MPath is either NULL or points to the Map Name, + and Instance is the instance number. + */ + if(MPath == NULL) { + /* This is NOT a mapped path. */ + if(Node == NULL) { + Node = daDefaultDevice; + } + if(Node != NULL) { + Status = RETURN_SUCCESS; + } + } + else { + /* This is a mapped path. */ + Status = __DevSearch( MPath, NULL, &Node); + if(Status == RETURN_NOT_FOUND) { + Node = daDefaultDevice; + + if(Node != NULL) { + Status = RETURN_SUCCESS; + } + } + } + if(DevNode != NULL) { + *DevNode = Node; + } + } + if(MPath != NULL) { + free(MPath); // We don't need this any more. + } + return Status; +} diff --git a/StdLib/LibC/Uefi/Devices/daConsole.inf b/StdLib/LibC/Uefi/Devices/daConsole.inf new file mode 100644 index 0000000000..17865e4fec --- /dev/null +++ b/StdLib/LibC/Uefi/Devices/daConsole.inf @@ -0,0 +1,63 @@ +## @file +# Standard C library: Console Device Abstraction. +# +# 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DevConsole + FILE_GUID = 42c078ef-14a8-4e30-9329-6f12d796e54a + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + LIBRARY_CLASS = DevConsole + CONSTRUCTOR = __Cons_construct + DESTRUCTOR = __Cons_deconstruct + +# +# VALID_ARCHITECTURES = IA32 X64 IPF +# + +[Sources] + Console/daConsole.c + +[Packages] + StdLib/StdLib.dec + StdLibPrivateInternalFiles/DoNotUse.dec + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + MemoryAllocationLib + UefiBootServicesTableLib + LibC + LibWchar + LibUefi + DevUtility + +[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- diff --git a/StdLib/LibC/Uefi/Devices/daShell.inf b/StdLib/LibC/Uefi/Devices/daShell.inf new file mode 100644 index 0000000000..7b56f37363 --- /dev/null +++ b/StdLib/LibC/Uefi/Devices/daShell.inf @@ -0,0 +1,63 @@ +## @file +# Standard C library: Shell-Hosted Device Abstraction. +# +# When this library is included in an application, it creates the default device. +# This allows every device type not recognized to be passed to the shell for processing. +# +# 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DevShell + FILE_GUID = 42c078ef-14a8-4e30-9329-6f12d796e54a + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + LIBRARY_CLASS = DevShell + CONSTRUCTOR = __ctor_DevShell + DESTRUCTOR = __dtor_DevShell + +# +# VALID_ARCHITECTURES = IA32 X64 IPF +# + +[Sources] + UefiShell/daShell.c + +[Packages] + StdLib/StdLib.dec + StdLibPrivateInternalFiles/DoNotUse.dec + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + BaseLib + MemoryAllocationLib + UefiBootServicesTableLib + LibC + LibString + LibStdLib + 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- diff --git a/StdLib/LibC/Uefi/Devices/daUtility.inf b/StdLib/LibC/Uefi/Devices/daUtility.inf new file mode 100644 index 0000000000..53daad28ac --- /dev/null +++ b/StdLib/LibC/Uefi/Devices/daUtility.inf @@ -0,0 +1,56 @@ +## @file +# Standard C library: Console Device Abstraction. +# +# 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DevUtility + FILE_GUID = 42c078ef-14a8-4e30-9329-6f12d796e54a + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + LIBRARY_CLASS = DevUtility + +# +# VALID_ARCHITECTURES = IA32 X64 IPF +# + +[Sources] + Utility/DevGenisis.c + Utility/DevSearch.c + Utility/Path.c + +[Packages] + StdLib/StdLib.dec + StdLibPrivateInternalFiles/DoNotUse.dec + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + MemoryAllocationLib + 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- diff --git a/StdLib/LibC/Uefi/SysCalls.c b/StdLib/LibC/Uefi/SysCalls.c index 624d45878e..b3ca5b89b4 100644 --- a/StdLib/LibC/Uefi/SysCalls.c +++ b/StdLib/LibC/Uefi/SysCalls.c @@ -13,6 +13,7 @@ **/ #include #include +#include #include #include #include @@ -23,40 +24,22 @@ #include #include #include +#include #include #include +#include #include #include #include -#include "SysEfi.h" +#include +#include +#include #include #include // Library/include/extern.h: Private to implementation -#include - -/* Macros only used in this file. */ -// Parameters for the ValidateFD function. -#define VALID_OPEN 1 -#define VALID_CLOSED 0 -#define VALID_DONT_CARE -1 - +#include /* EFI versions of BSD system calls used in stdio */ -/* Normalize path so that forward slashes are replaced with backslashes. - Backslashes are required for UEFI. -*/ -static void -NormalizePath( const CHAR16 *path) -{ - CHAR16 *temp; - - for( temp = (CHAR16 *)path; *temp; ++temp) { - if(*temp == L'/') { - *temp = L'\\'; - } - } -} - /* Validate that fd refers to a valid file descriptor. IsOpen is interpreted as follows: - Positive fd must be OPEN @@ -66,15 +49,18 @@ NormalizePath( const CHAR16 *path) @retval TRUE fd is VALID @retval FALSE fd is INVALID */ -static BOOLEAN +BOOLEAN ValidateFD( int fd, int IsOpen) { + struct __filedes *filp; BOOLEAN retval = FALSE; if((fd >= 0) && (fd < OPEN_MAX)) { + filp = &gMD->fdarray[fd]; retval = TRUE; if(IsOpen >= 0) { - retval = (BOOLEAN)(gMD->fdarray[fd].State != 0); // TRUE if OPEN + retval = (BOOLEAN)((filp->f_iflags != 0) && // TRUE if OPEN + FILE_IS_USABLE(filp)); // and Usable (not Larval or Closing) if(IsOpen == VALID_CLOSED) { retval = (BOOLEAN)!retval; // We want TRUE if CLOSED } @@ -91,7 +77,7 @@ ValidateFD( int fd, int IsOpen) @return Returns -1 if there are no free FDs. Otherwise returns the found fd. */ -static int +int FindFreeFD( int MinFd ) { struct __filedes *Mfd; @@ -102,8 +88,8 @@ FindFreeFD( int MinFd ) // Get an available fd for(i=MinFd; i < OPEN_MAX; ++i) { - if(Mfd[i].State == 0) { - Mfd[i].State = S_ISYSTEM; // Temporarily mark this fd as reserved + if(Mfd[i].f_iflags == 0) { + Mfd[i].f_iflags = FIF_LARVAL; // Temporarily mark this fd as reserved fd = i; break; } @@ -111,6 +97,22 @@ FindFreeFD( int MinFd ) return fd; } +/* Mark that an open file is to be deleted when closed. */ +int +DeleteOnClose(int fd) +{ + int retval = 0; + + if(ValidateFD( fd, VALID_OPEN)) { + gMD->fdarray[fd].f_iflags |= FIF_DELCLOSE; + } + else { + errno = EBADF; + retval = -1; + } + return retval; +} + /** The isatty() function tests whether fildes, an open file descriptor, is associated with a terminal device. @@ -119,15 +121,14 @@ FindFreeFD( int MinFd ) EBADF if fildes is not a valid open FD. **/ int -isatty (int fildes) +isatty (int fd) { int retval = 0; - EFI_FILE_HANDLE FileHandle; + struct __filedes *Fp; - if(ValidateFD( fildes, VALID_OPEN)) { - FileHandle = gMD->fdarray[fildes].FileHandle; - retval = (FileHandle >= &gMD->StdIo[0].Abstraction) && - (FileHandle <= &gMD->StdIo[2].Abstraction); + if(ValidateFD( fd, VALID_OPEN)) { + Fp = &gMD->fdarray[fd]; + retval = Fp->f_iflags & _S_ITTY; } else { errno = EBADF; @@ -138,16 +139,19 @@ isatty (int fildes) static BOOLEAN IsDupFd( int fd) { - EFI_FILE_HANDLE FileHandle; + void * DevData; + const struct fileops *FileOps; int i; BOOLEAN Ret = FALSE; if(ValidateFD( fd, VALID_OPEN )) { - FileHandle = gMD->fdarray[fd].FileHandle; + FileOps = gMD->fdarray[fd].f_ops; + DevData = gMD->fdarray[fd].devdata; for(i=0; i < OPEN_MAX; ++i) { if(i == fd) continue; - if(gMD->fdarray[i].State != 0) { // TRUE if fd is OPEN - if(gMD->fdarray[i].FileHandle == FileHandle) { + if(ValidateFD( i, VALID_OPEN )) { // TRUE if fd is valid and OPEN + if((gMD->fdarray[i].f_ops == FileOps) + &&(gMD->fdarray[i].devdata == DevData )) { Ret = TRUE; break; } @@ -160,36 +164,37 @@ IsDupFd( int fd) static int _closeX (int fd, int NewState) { - struct __filedes *Mfd; - RETURN_STATUS Status; + struct __filedes *Fp; int retval = 0; - Status = EFIerrno = RETURN_SUCCESS; // In case of error before the EFI call. - // Verify my pointers and get my FD. if(ValidateFD( fd, VALID_OPEN )) { - Mfd = &gMD->fdarray[fd]; - // Check if there are duplicates using this FileHandle + Fp = &gMD->fdarray[fd]; + // Check if there are other users of this FileHandle + if(Fp->RefCount == 1) { // There should be no other users if(! IsDupFd(fd)) { // Only do the close if no one else is using the FileHandle - if(isatty(fd)) { - Status = Mfd->FileHandle->Close( Mfd->FileHandle); + if(Fp->f_iflags & FIF_DELCLOSE) { + /* Handle files marked "Delete on Close". */ + if(Fp->f_ops->fo_delete != NULL) { + retval = Fp->f_ops->fo_delete(Fp); + } } else { - Status = ShellCloseFile( (SHELL_FILE_HANDLE *)&Mfd->FileHandle); + retval = Fp->f_ops->fo_close( Fp); } } - Mfd->State = NewState; // Close this FD or reserve it - if(Status != RETURN_SUCCESS) { - errno = EFI2errno(Status); - EFIerrno = Status; - retval = -1; + Fp->f_iflags = NewState; // Close this FD or reserve it + Fp->RefCount = 0; // No one using this FD + } + else { + --Fp->RefCount; /* One less user of this FD */ } } else { // Bad FD - errno = EBADF; retval = -1; + errno = EBADF; } return retval; } @@ -210,41 +215,28 @@ close (int fd) return _closeX(fd, 0); } -/* Wide character version of unlink */ +/** +**/ int -Uunlink (const wchar_t *Path) +unlink (const char *path) { - EFI_FILE_HANDLE FileHandle; - RETURN_STATUS Status; + struct __filedes *Fp; + int fd; + int retval = -1; EFIerrno = RETURN_SUCCESS; - NormalizePath( Path); - // We can only delete open files. - Status = ShellOpenFileByName( Path, (SHELL_FILE_HANDLE *)&FileHandle, 3, 0); - if(Status != RETURN_SUCCESS) { - errno = EFI2errno(Status); - EFIerrno = Status; - return -1; + fd = open(path, O_WRONLY, 0); + if(fd >= 0) { + Fp = &gMD->fdarray[fd]; + + if(Fp->f_ops->fo_delete != NULL) { + retval = Fp->f_ops->fo_delete(Fp); } - Status = ShellDeleteFile( (SHELL_FILE_HANDLE *)&FileHandle); - if(Status != RETURN_SUCCESS) { - errno = EFI2errno(Status); - EFIerrno = Status; - return -1; + Fp->f_iflags = 0; // Close this FD + Fp->RefCount = 0; // No one using this FD } - return 0; -} - -/** -**/ -int -unlink (const char *path) -{ - // Convert path from MBCS to WCS - (void)AsciiStrToUnicodeStr( path, gMD->UString); - - return Uunlink(gMD->UString); + return retval; } /** The fcntl() function shall perform the operations described below on open @@ -366,23 +358,23 @@ fcntl (int fildes, int cmd, ...) break; //case F_SETFL: case F_SETFD: - retval = MyFd->State; - break; - case F_SETOWN: - retval = MyFd->SocProc; - MyFd->SocProc = va_arg(p3, int); + retval = MyFd->f_iflags; break; + //case F_SETOWN: + // retval = MyFd->SocProc; + // MyFd->SocProc = va_arg(p3, int); + // break; case F_GETFD: //retval = MyFd->Oflags; - retval = MyFd->State; + retval = MyFd->f_iflags; break; case F_GETFL: - //retval = MyFd->State; + //retval = MyFd->f_iflags; retval = MyFd->Oflags; break; - case F_GETOWN: - retval = MyFd->SocProc; - break; + //case F_GETOWN: + // retval = MyFd->SocProc; + // break; default: errno = EINVAL; break; @@ -441,9 +433,10 @@ dup2 (int fildes, int fildes2) retval = fildes2; if( fildes != fildes2) { if(ValidateFD( fildes2, VALID_DONT_CARE)) { - gMD->fdarray[fildes2].State = S_ISYSTEM; // Mark the file closed, but reserved + gMD->fdarray[fildes2].f_iflags = FIF_LARVAL; // Mark the file closed, but reserved (void)memcpy(&gMD->fdarray[fildes2], // Duplicate fildes into fildes2 &gMD->fdarray[fildes], sizeof(struct __filedes)); + gMD->fdarray[fildes2].MyFD = (UINT16)fildes2; } else { errno = EBADF; @@ -486,53 +479,21 @@ dup2 (int fildes, int fildes2) indicate the error. **/ __off_t -lseek (int fildes, __off_t offset, int how) +lseek (int fd, __off_t offset, int how) { __off_t CurPos = -1; - RETURN_STATUS Status = RETURN_SUCCESS; - EFI_FILE_HANDLE FileHandle; +// RETURN_STATUS Status = RETURN_SUCCESS; + struct __filedes *filp; EFIerrno = RETURN_SUCCESS; // In case of error without an EFI call if( how == SEEK_SET || how == SEEK_CUR || how == SEEK_END) { - if(ValidateFD( fildes, VALID_OPEN)) { + if(ValidateFD( fd, VALID_OPEN)) { + filp = &gMD->fdarray[fd]; // Both of our parameters have been verified as valid - FileHandle = gMD->fdarray[fildes].FileHandle; - CurPos = 0; - if(isatty(fildes)) { - Status = FileHandle->SetPosition( FileHandle, offset); - CurPos = offset; - } - else { - if(how != SEEK_SET) { - // We are doing a relative seek - if(how == SEEK_END) { - // seeking relative to EOF, so position there first. - Status = ShellSetFilePosition( (SHELL_FILE_HANDLE)FileHandle, 0xFFFFFFFFFFFFFFFFULL); - } - if(Status == RETURN_SUCCESS) { - // Now, determine our current position. - Status = ShellGetFilePosition( (SHELL_FILE_HANDLE)FileHandle, (UINT64 *)&CurPos); - } - } - if(Status == RETURN_SUCCESS) { - /* CurPos now indicates the point we are seeking from, so seek... */ - Status = ShellSetFilePosition( (SHELL_FILE_HANDLE)FileHandle, (UINT64)(CurPos + offset)); - if(Status == RETURN_SUCCESS) { - // Now, determine our final position. - Status = ShellGetFilePosition( (SHELL_FILE_HANDLE)FileHandle, (UINT64 *)&CurPos); - } - } - if(Status != RETURN_SUCCESS) { - EFIerrno = Status; - CurPos = -1; - if(Status == EFI_UNSUPPORTED) { - errno = EISDIR; - } - else { - errno = EFI2errno(Status); - } - } + CurPos = filp->f_ops->fo_lseek( filp, offset, how); + if(CurPos >= 0) { + filp->f_offset = CurPos; } } else { @@ -551,37 +512,35 @@ lseek (int fildes, __off_t offset, int how) The directory is closed after it is created. @retval 0 The directory was created successfully. - @retval -1 An error occurred and an error code is stored in errno. + @retval -1 An error occurred and error codes are stored in errno and EFIerrno. **/ int mkdir (const char *path, __mode_t perms) { - EFI_FILE_HANDLE FileHandle; + wchar_t *NewPath; + DeviceNode *Node; + char *GenI; RETURN_STATUS Status; - EFI_FILE_INFO *FileInfo; - - // Convert name from MBCS to WCS - (void)AsciiStrToUnicodeStr( path, gMD->UString); - NormalizePath( gMD->UString); + int Instance = 0; + int retval = 0; -//Print(L"%a( \"%s\", 0x%8X)\n", __func__, gMD->UString, perms); - Status = ShellCreateDirectory( gMD->UString, (SHELL_FILE_HANDLE *)&FileHandle); + Status = ParsePath(path, &NewPath, &Node, &Instance); if(Status == RETURN_SUCCESS) { - FileInfo = ShellGetFileInfo( FileHandle); - if(FileInfo != NULL) { - FileInfo->Attribute = Omode2EFI(perms); - Status = ShellSetFileInfo( FileHandle, FileInfo); - FreePool(FileInfo); - if(Status == RETURN_SUCCESS) { - (void)ShellCloseFile((SHELL_FILE_HANDLE *)&FileHandle); - return 0; + GenI = Node->InstanceList; + if(GenI == NULL) { + errno = EPERM; + retval = -1; } + else { + GenI += (Instance * Node->InstanceSize); + retval = ((GenericInstance *)GenI)->Abstraction.fo_mkdir( path, perms); + } + free(NewPath); } + else { + retval = -1; } - errno = EFI2errno(Status); - EFIerrno = Status; - - return -1; + return retval; } /** Open a file. @@ -608,112 +567,215 @@ 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 *name, int oflags, int mode) +open (const char *path, int oflags, int mode) { - EFI_FILE_HANDLE FileHandle; - struct __filedes *Mfd; + wchar_t *NewPath; + DeviceNode *Node; + char *GenI = NULL; + struct __filedes *filp; + int Instance = 0; RETURN_STATUS Status; UINT64 OpenMode; - UINT64 Attributes; int fd = -1; - UINT32 NewState; + int doresult; - EFIerrno = RETURN_SUCCESS; - Mfd = gMD->fdarray; - - // Convert name from MBCS to WCS - (void)AsciiStrToUnicodeStr( name, gMD->UString); - NormalizePath( gMD->UString); - - // Convert oflags to Attributes - OpenMode = Oflags2EFI(oflags); - if(OpenMode == 0) { - errno = EINVAL; - return -1; + Status = ParsePath(path, &NewPath, &Node, &Instance); + if(Status == RETURN_SUCCESS) { + if((Node != NULL) && + ((GenI = Node->InstanceList) == NULL)) { + errno = EPERM; } - - //Attributes = Omode2EFI(mode); - Attributes = 0; - + else { // Could add a test to see if the file name begins with a period. // If it does, then add the HIDDEN flag to Attributes. // Get an available fd - fd = FindFreeFD( 0 ); + fd = FindFreeFD( VALID_CLOSED ); if( fd < 0 ) { // All available FDs are in use errno = EMFILE; return -1; } + 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); + if(doresult < 0) { + filp->f_iflags = 0; // Release this FD + fd = -1; // Indicate an error + } + else { + // Re-use OpenMode in order to build our final f_iflags value + OpenMode = ( mode & S_ACC_READ ) ? S_ACC_READ : 0; + OpenMode |= ( mode & S_ACC_WRITE ) ? S_ACC_WRITE : 0; - Status = ConOpen( NULL, &FileHandle, gMD->UString, OpenMode, Attributes); - if(Status == RETURN_NO_MAPPING) { - // Not a console device, how about a regular file device? - - /* 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. - - !!!!!!!!! Change this to use ShellSetFileInfo() to actually truncate the file - !!!!!!!!! instead of deleting and re-creating it. - */ - if((oflags & O_TRUNC) || ((oflags & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT))) { - Status = ShellIsFile( gMD->UString ); - if(Status == RETURN_SUCCESS) { - // The file exists - if(oflags & O_TRUNC) { - // We do a truncate by deleting the existing file and creating a new one. - if(Uunlink(gMD->UString) != 0) { - Mfd[fd].State = 0; // Release our reservation on this FD - return -1; // errno and EFIerrno are already set. + filp->f_iflags |= (UINT32)OpenMode; + ++filp->RefCount; + FILE_SET_MATURE(filp); + } } + free(NewPath); } - else if(oflags & (O_EXCL | O_CREAT)) { - errno = EEXIST; - EFIerrno = Status; - Mfd[fd].State = 0; // Release our reservation on this FD + // return the fd of our now open file + return fd; +} + + +/** + Poll a list of file descriptors. + + The ::poll routine waits for up to timeout milliseconds for an event + to occur on one or more of the file descriptors listed. The event + types of interested are specified for each file descriptor in the events + field. The actual event detected is returned in the revents field of + the array. The + POSIX + documentation is available online. + + @param [in] pfd Address of an array of pollfd structures. + + @param [in] nfds Number of elements in the array of pollfd structures. + + @param [in] timeout Length of time in milliseconds to wait for the event + + @returns The number of file descriptors with detected events. Zero + indicates that the call timed out and -1 indicates an error. + + **/ +int +poll ( + struct pollfd * pfd, + nfds_t nfds, + int timeout + ) +{ + struct __filedes * pDescriptor; + struct pollfd * pEnd; + struct pollfd * pPollFD; + int SelectedFDs; + EFI_STATUS Status; + EFI_EVENT Timer; + UINT64 TimerTicks; + + // + // Create the timer for the timeout + // + Timer = NULL; + Status = EFI_SUCCESS; + if ( INFTIM != timeout ) { + Status = gBS->CreateEvent ( EVT_TIMER, + TPL_NOTIFY, + NULL, + NULL, + &Timer ); + if ( !EFI_ERROR ( Status )) { + // + // Start the timeout timer + // + TimerTicks = timeout; + TimerTicks *= 1000 * 10; + Status = gBS->SetTimer ( Timer, + TimerRelative, + TimerTicks ); + } + else { + SelectedFDs = -1; + errno = ENOMEM; + } + } + if ( !EFI_ERROR ( Status )) { + // + // Poll until an event is detected or the timer fires + // + SelectedFDs = 0; + errno = 0; + do { + // + // Poll the list of file descriptors + // + pPollFD = pfd; + pEnd = &pPollFD [ nfds ]; + while ( pEnd > pPollFD ) { + // + // Validate the file descriptor + // + if ( !ValidateFD ( pPollFD->fd, VALID_OPEN )) { + errno = EINVAL; return -1; } + + // + // Poll the device or file + // + pDescriptor = &gMD->fdarray [ pPollFD->fd ]; + pPollFD->revents = pDescriptor->f_ops->fo_poll ( pDescriptor, + pPollFD->events ); + + // + // Determine if this file descriptor detected an event + // + if ( 0 != pPollFD->revents ) { + // + // Select this descriptor + // + SelectedFDs += 1; + } + + // + // Set the next file descriptor + // + pPollFD += 1; } + + // + // Check for timeout + // + if ( NULL != Timer ) { + Status = gBS->CheckEvent ( Timer ); + if ( EFI_SUCCESS == Status ) { + // + // Timeout + // + break; + } + else if ( EFI_NOT_READY == Status ) { + Status = EFI_SUCCESS; } - // Call the EFI Shell's Open function - Status = ShellOpenFileByName( gMD->UString, (SHELL_FILE_HANDLE *)&FileHandle, OpenMode, Attributes); - if(RETURN_ERROR(Status)) { - Mfd[fd].State = 0; // Release our reservation on this FD - // Set errno based upon Status - errno = EFI2errno(Status); - EFIerrno = Status; - return -1; } - // Successfully got a regular File - NewState = S_IFREG; + } while (( 0 == SelectedFDs ) + && ( EFI_SUCCESS == Status )); + // + // Stop the timer + // + if ( NULL != Timer ) { + gBS->SetTimer ( Timer, + TimerCancel, + 0 ); } - else if(Status != RETURN_SUCCESS) { - // Set errno based upon Status - errno = EFI2errno(Status); - EFIerrno = Status; - return -1; } else { - // Succesfully got a Console stream - NewState = S_IFREG | _S_ITTY | _S_IFCHR; + SelectedFDs = -1; + errno = EAGAIN; } - // Update the info in the fd - Mfd[fd].FileHandle = FileHandle; - Mfd[fd].Oflags = oflags; - Mfd[fd].Omode = mode; + // + // Release the timer + // + if ( NULL != Timer ) { + gBS->CloseEvent ( Timer ); + } - // Re-use OpenMode in order to build our final State value - OpenMode = ( mode & S_ACC_READ ) ? S_ACC_READ : 0; - OpenMode |= ( mode & S_ACC_WRITE ) ? S_ACC_WRITE : 0; + // + // Return the number of selected file system descriptors + // + return SelectedFDs; +} - Mfd[fd].State = NewState | (UINT32)OpenMode; - // return the fd of our now open file - return fd; -} /** The rename() function changes the name of a file. The old argument points to the pathname of the file to be renamed. The new @@ -745,168 +807,54 @@ open (const char *name, int oflags, int mode) shall be changed or created. **/ int -rename (const char *old, const char *new) -{ - // UINT64 InfoSize; - // RETURN_STATUS Status; - // EFI_FILE_INFO *NewFileInfo = NULL; - // EFI_FILE_INFO *OldFileInfo; - // char *Newfn; - // int OldFd; - - //// Open old file - // OldFd = open(old, O_RDONLY, 0); - // if(OldFd >= 0) { - // NewFileInfo = malloc(sizeof(EFI_FILE_INFO) + PATH_MAX); - // if(NewFileInfo != NULL) { - // 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)); - // FreePool(OldFileInfo); - // // Strip off all but the file name portion of new - // NewFn = strrchr(new, '/'); - // if(NewFn == NULL) { - // NewFn = strrchr(new '\\'); - // if(NewFn == NULL) { - // NewFn = new; - // } - // } - // // Convert new name from MBCS to WCS - // (void)AsciiStrToUnicodeStr( NewFn, gMD->UString); - // // Copy the new file name into our new file info buffer - // wcsncpy(NewFileInfo->FileName, gMD->UString, wcslen(gMD->UString)+1); - // // Apply the new file name - // Status = ShellSetFileInfo(FileHandle); - // if(Status == EFI_SUCCESS) { - // // File has been successfully renamed. We are DONE! - // return 0; - // } - // errno = EFI2errno( Status ); - // EFIerrno = Status; - // } - // else { - // errno = EIO; - // } - // } - // else { - // errno = ENOMEM; - // } - // } - return -1; -} - -/** -**/ -int -rmdir (const char *path) +EFIAPI +rename( + const char *from, + const char *to + ) { - EFI_FILE_HANDLE FileHandle; - RETURN_STATUS Status; - EFI_FILE_INFO *FileInfo = NULL; - int Count = 0; - BOOLEAN NoFile = FALSE; - - errno = 0; // Make it easier to see if we have an error later - - // Convert name from MBCS to WCS - (void)AsciiStrToUnicodeStr( path, gMD->UString); - NormalizePath( gMD->UString); - -//Print(L"%a( \"%s\")\n", __func__, gMD->UString); - Status = ShellOpenFileByName( gMD->UString, (SHELL_FILE_HANDLE *)&FileHandle, - (EFI_FILE_MODE_READ || EFI_FILE_MODE_WRITE), 0); + wchar_t *FromPath; + DeviceNode *FromNode; + char *GenI; + int Instance = 0; + RETURN_STATUS Status; + int retval = -1; + + Status = ParsePath(from, &FromPath, &FromNode, &Instance); if(Status == RETURN_SUCCESS) { - FileInfo = ShellGetFileInfo( (SHELL_FILE_HANDLE)FileHandle); - if(FileInfo != NULL) { - if((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0) { - errno = ENOTDIR; + GenI = FromNode->InstanceList; + if(GenI == NULL) { + errno = EPERM; + retval = -1; } else { - // See if the directory has any entries other than ".." and ".". - FreePool(FileInfo); // Free up the buffer from ShellGetFileInfo() - Status = ShellFindFirstFile( (SHELL_FILE_HANDLE)FileHandle, &FileInfo); - if(Status == RETURN_SUCCESS) { - ++Count; - while(Count < 3) { - Status = ShellFindNextFile( (SHELL_FILE_HANDLE)FileHandle, FileInfo, &NoFile); - if(Status == RETURN_SUCCESS) { - if(NoFile) { - break; + GenI += (Instance * FromNode->InstanceSize); + retval = ((GenericInstance *)GenI)->Abstraction.fo_rename( from, to); } - ++Count; - } - else { - Count = 99; + free(FromPath); } - } - FreePool(FileInfo); // Free buffer from ShellFindFirstFile() - if(Count < 3) { - // Directory is empty - Status = ShellDeleteFile( (SHELL_FILE_HANDLE *)&FileHandle); - if(Status == RETURN_SUCCESS) { - EFIerrno = RETURN_SUCCESS; - return 0; - /* ######## SUCCESSFUL RETURN ######## */ - } - } - else { - if(Count == 99) { - errno = EIO; - } - else { - errno = ENOTEMPTY; - } - } - } - } - } - else { - errno = EIO; - } - } - EFIerrno = Status; - if(errno == 0) { - errno = EFI2errno( Status ); - } - return -1; + return retval; } -/* Internal File Info. worker function for stat and fstat. */ -static -EFI_STATUS -_EFI_FileInfo( EFI_FILE_INFO *FileInfo, struct stat *statbuf) +/** +**/ +int +EFIAPI +rmdir( + const char *path + ) { - UINT64 Attributes; - RETURN_STATUS Status; - mode_t newmode; - - if(FileInfo != NULL) { - // Got the info, now populate statbuf with it - statbuf->st_blksize = S_BLKSIZE; - statbuf->st_size = FileInfo->Size; - statbuf->st_physsize = FileInfo->PhysicalSize; - statbuf->st_birthtime = Efi2Time( &FileInfo->CreateTime); - statbuf->st_atime = Efi2Time( &FileInfo->LastAccessTime); - statbuf->st_mtime = Efi2Time( &FileInfo->ModificationTime); - Attributes = FileInfo->Attribute; - newmode = (mode_t)(Attributes << S_EFISHIFT) | S_ACC_READ; - if((Attributes & EFI_FILE_DIRECTORY) == 0) { - newmode |= _S_IFREG; - if((Attributes & EFI_FILE_READ_ONLY) == 0) { - statbuf->st_mode |= S_ACC_WRITE; + struct __filedes *filp; + int fd; + int retval = -1; + + fd = open(path, O_RDWR, 0); + if(fd >= 0) { + filp = &gMD->fdarray[fd]; + + retval = filp->f_ops->fo_rmdir(filp); } - } - else { - newmode |= _S_IFDIR; - } - statbuf->st_mode = newmode; - Status = RETURN_SUCCESS; - } - else { - Status = RETURN_DEVICE_ERROR; - } - return Status; + return retval; } /** The fstat() function obtains information about an open file associated @@ -935,7 +883,7 @@ _EFI_FileInfo( EFI_FILE_INFO *FileInfo, struct stat *statbuf) - st_gid Set to zero. - st_nlink Set to one. - @param[in] fildes File descriptor as returned from open(). + @param[in] fd File descriptor as returned from open(). @param[out] statbuf Buffer in which the file status is put. @retval 0 Successful Completion. @@ -943,37 +891,19 @@ _EFI_FileInfo( EFI_FILE_INFO *FileInfo, struct stat *statbuf) identify the error. **/ int -fstat (int fildes, struct stat *statbuf) +fstat (int fd, struct stat *statbuf) { - EFI_FILE_HANDLE FileHandle; - RETURN_STATUS Status = RETURN_SUCCESS; - EFI_FILE_INFO *FileInfo = NULL; - UINTN FinfoSize = sizeof(EFI_FILE_INFO); + int retval = -1; + struct __filedes *filp; - if(ValidateFD( fildes, VALID_OPEN)) { - FileHandle = gMD->fdarray[fildes].FileHandle; - if(isatty(fildes)) { - FileInfo = AllocateZeroPool(FinfoSize); - if(FileInfo != NULL) { - Status = FileHandle->GetInfo( FileHandle, 0, &FinfoSize, FileInfo); + if(ValidateFD( fd, VALID_OPEN)) { + filp = &gMD->fdarray[fd]; + retval = filp->f_ops->fo_stat(filp, statbuf, NULL); } else { - Status = RETURN_OUT_OF_RESOURCES; + errno = EBADF; } - } - else { - FileInfo = ShellGetFileInfo( FileHandle); - } - Status = _EFI_FileInfo( FileInfo, statbuf); - } - errno = EFI2errno(Status); - EFIerrno = Status; - - if(FileInfo != NULL) { - FreePool(FileInfo); // Release the buffer allocated by the GetInfo function - } - - return errno? -1 : 0; + return retval; } /** Obtains information about the file pointed to by path. @@ -988,26 +918,17 @@ fstat (int fildes, struct stat *statbuf) int stat (const char *path, void *statbuf) { - EFI_FILE_HANDLE FileHandle; - RETURN_STATUS Status; - EFI_FILE_INFO *FileInfo; - - errno = 0; // Make it easier to see if we have an error later - - // Convert name from MBCS to WCS - (void)AsciiStrToUnicodeStr( path, gMD->UString); - NormalizePath( gMD->UString); - - Status = ShellOpenFileByName( gMD->UString, (SHELL_FILE_HANDLE *)&FileHandle, EFI_FILE_MODE_READ, 0ULL); - if(Status == RETURN_SUCCESS) { - FileInfo = ShellGetFileInfo( FileHandle); - Status = _EFI_FileInfo( FileInfo, (struct stat *)statbuf); - (void)ShellCloseFile( (SHELL_FILE_HANDLE *)&FileHandle); + int fd; + int retval = -1; + struct __filedes *filp; + + fd = open(path, O_RDONLY, 0); + if(fd >= 0) { + filp = &gMD->fdarray[fd]; + retval = filp->f_ops->fo_stat( filp, statbuf, NULL); + close(fd); } - errno = EFI2errno(Status); - EFIerrno = Status; - - return errno? -1 : 0; + return retval; } /** Same as stat since EFI doesn't have symbolic links. **/ @@ -1017,6 +938,33 @@ lstat (const char *path, struct stat *statbuf) return stat(path, statbuf); } +/** Control a device. +**/ +int +ioctl( + int fd, + unsigned long request, + ... + ) +{ + int retval = -1; + struct __filedes *filp; + va_list argp; + + va_start(argp, request); + + if(ValidateFD( fd, VALID_OPEN)) { + filp = &gMD->fdarray[fd]; + retval = filp->f_ops->fo_ioctl(filp, request, argp); + } + else { + errno = EBADF; + } + va_end(argp); + + return retval; +} + /** Read from a file. The read() function shall attempt to read nbyte bytes from the file @@ -1083,59 +1031,22 @@ lstat (const char *path, struct stat *statbuf) ssize_t read (int fildes, void *buf, size_t nbyte) { + struct __filedes *filp; ssize_t BufSize; - EFI_FILE_HANDLE FileHandle; - RETURN_STATUS Status; BufSize = (ssize_t)nbyte; if(ValidateFD( fildes, VALID_OPEN)) { - FileHandle = gMD->fdarray[fildes].FileHandle; - if(isatty(fildes)) { - Status = FileHandle->Read( FileHandle, (UINTN *)&BufSize, buf); - } - else { - Status = ShellReadFile( FileHandle, (UINTN *)&BufSize, buf); - } - if(Status != RETURN_SUCCESS) { - EFIerrno = Status; - errno = EFI2errno(Status); - if(Status == RETURN_BUFFER_TOO_SMALL) { - BufSize = -BufSize; - } - else { - BufSize = -1; - } - } + filp = &gMD->fdarray[fildes]; + + BufSize = filp->f_ops->fo_read(filp, &filp->f_offset, nbyte, buf); } else { errno = EBADF; + BufSize = -EBADF; } return BufSize; } -ssize_t -WideTtyCvt( CHAR16 *dest, const char *buf, size_t n) -{ - UINTN i; - wint_t wc; - - for(i = 0; i < n; ++i) { - wc = btowc(*buf++); - if( wc == 0) { - break; - }; - if(wc < 0) { - wc = BLOCKELEMENT_LIGHT_SHADE; - } - if(wc == L'\n') { - *dest++ = L'\r'; - } - *dest++ = (CHAR16)wc; - } - *dest = 0; - return (ssize_t)i; -} - /** Write data to a file. This function writes the specified number of bytes to the file at the current @@ -1159,40 +1070,62 @@ WideTtyCvt( CHAR16 *dest, const char *buf, size_t n) QUESTION: Should writes to stdout or stderr always succeed? **/ ssize_t -write (int fildes, const void *buf, size_t n) +write (int fd, const void *buf, size_t nbyte) { + struct __filedes *filp; ssize_t BufSize; - EFI_FILE_HANDLE FileHandle; - RETURN_STATUS Status = RETURN_SUCCESS; - ssize_t UniBufSz; +// EFI_FILE_HANDLE FileHandle; +// RETURN_STATUS Status = RETURN_SUCCESS; + + BufSize = (ssize_t)nbyte; - BufSize = (ssize_t)n; + if(ValidateFD( fd, VALID_OPEN)) { + filp = &gMD->fdarray[fd]; - if(ValidateFD( fildes, VALID_OPEN)) { - FileHandle = gMD->fdarray[fildes].FileHandle; - if(isatty(fildes)) { - // Convert string from MBCS to WCS and translate \n to \r\n. - UniBufSz = WideTtyCvt(gMD->UString, (const char *)buf, n); - if(UniBufSz > 0) { - BufSize = (ssize_t)(UniBufSz * sizeof(CHAR16)); - Status = FileHandle->Write( FileHandle, (UINTN *)&BufSize, (void *)gMD->UString); - BufSize = (ssize_t)n; // Always pretend all was output - } + BufSize = filp->f_ops->fo_write(filp, &filp->f_offset, nbyte, buf); } else { - Status = ShellWriteFile( FileHandle, (UINTN *)&BufSize, (void *)buf); - } - if(Status != RETURN_SUCCESS) { - EFIerrno = Status; - errno = EFI2errno(Status); - if(Status == EFI_UNSUPPORTED) { - errno = EISDIR; + errno = EBADF; + BufSize = -EBADF; } - BufSize = -1; + return BufSize; +} + +/** Gets the current working directory. + + The getcwd() function shall place an absolute pathname of the current + working directory in the array pointed to by buf, and return buf. The + pathname copied to the array shall contain no components that are + symbolic links. The size argument is the size in bytes of the character + array pointed to by the buf argument. + + @param[in,out] buf The buffer to fill. + @param[in] size The number of bytes in buffer. + + @retval NULL The function failed. + @retval NULL Buf was NULL. + @retval NULL Size was 0. + @return buf The function completed successfully. See errno for info. +**/ +char +*getcwd (char *buf, size_t size) +{ + CONST CHAR16 *Cwd; + + if (size == 0 || buf == NULL) { + errno = EINVAL; + return NULL; } + + Cwd = ShellGetCurrentDir(NULL); + if (Cwd == NULL) { + errno = EACCES; + return NULL; } - else { - errno = EBADF; + if (size < ((StrLen (Cwd) + 1) * sizeof (CHAR8))) { + errno = ERANGE; + return (NULL); } - return BufSize; + + return (UnicodeStrToAsciiStr(Cwd, buf)); } diff --git a/StdLib/LibC/Uefi/SysEfi.h b/StdLib/LibC/Uefi/SysEfi.h deleted file mode 100644 index fa9dc38cdd..0000000000 --- a/StdLib/LibC/Uefi/SysEfi.h +++ /dev/null @@ -1,37 +0,0 @@ -/** @file - Declarations local to the Uefi SysCalls module of the Standard C Library. - - Copyright (c) 2010, 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 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. - -**/ -#ifndef _SYSEFI_H -#define _SYSEFI_H -#include - -#define EFI_FILE_MODE_MASK ( EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE ) -#define OMODE_MASK 0xFFFF00UL -#define OMODE_SHIFT 8 - -#define S_ACC_READ ( S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH ) -#define S_ACC_WRITE ( S_IWUSR | S_IWGRP | S_IWOTH ) -#define S_ACC_MASK ( S_IRWXU | S_IRWXG | S_IRWXO ) - -UINT64 -Oflags2EFI( int oflags); - -UINT64 -Omode2EFI( int mode); - -/* Converts the first several EFI status values into the appropriate errno value. -*/ -int -EFI2errno( RETURN_STATUS Status); - -#endif /* _SYSEFI_H */ diff --git a/StdLib/LibC/Uefi/Uefi.inf b/StdLib/LibC/Uefi/Uefi.inf index ca6437abe0..084d6c4fc3 100644 --- a/StdLib/LibC/Uefi/Uefi.inf +++ b/StdLib/LibC/Uefi/Uefi.inf @@ -1,7 +1,7 @@ ## @file # Standard C library: UEFI "system calls". # -# Copyright (c) 2010, Intel Corporation. All rights reserved.
+# Copyright (c) 2010 - 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 @@ -28,7 +28,6 @@ [Sources] SysCalls.c Xform.c - Console.c [Packages] StdLib/StdLib.dec @@ -47,3 +46,4 @@ LibLocale LibString LibTime + DevUtility diff --git a/StdLib/LibC/Uefi/Xform.c b/StdLib/LibC/Uefi/Xform.c index 21eff6fb9d..6b15da3563 100644 --- a/StdLib/LibC/Uefi/Xform.c +++ b/StdLib/LibC/Uefi/Xform.c @@ -1,7 +1,7 @@ /** @file Value transformations between stdio and the UEFI environment. - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 that accompanies this distribution. The full text of the license may be found at @@ -18,7 +18,7 @@ #include #include -#include "SysEfi.h" +#include /** Translate the Open flags into a Uefi Open Modes value. @@ -44,6 +44,10 @@ Oflags2EFI( int oflags ) // Build the Open Modes flags = (UINT64)((oflags & O_ACCMODE) + 1); // Handle the Read/Write flags + if(flags & EFI_FILE_MODE_WRITE) { // Asking for write only? + // EFI says the only two RW modes are read-only and read+write. + flags = EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE; + } if(oflags & (O_CREAT | O_TRUNC)) { // Now add the Create flag. // Also added if O_TRUNC set since we will need to create a new file. // We just set the flags here since the only valid EFI mode with create diff --git a/StdLib/LibC/Wchar/ConsDecons.c b/StdLib/LibC/Wchar/ConsDecons.c index ab139405fc..534d3e3b08 100644 --- a/StdLib/LibC/Wchar/ConsDecons.c +++ b/StdLib/LibC/Wchar/ConsDecons.c @@ -5,19 +5,17 @@ two wide characters the same way as two integers of the underlying integer type designated by wchar_t. - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 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 -#include -#include -#include +#include #include @@ -36,11 +34,17 @@ __wchar_construct( IN EFI_SYSTEM_TABLE *SystemTable ) { + EFI_STATUS Status; + if( __wchar_bitmap == NULL) { __wchar_bitmap_size = (WCHAR_MAX + 8) / 8U; - __wchar_bitmap = AllocatePool(__wchar_bitmap_size); - if( __wchar_bitmap == NULL) { - EFIerrno = RETURN_OUT_OF_RESOURCES; + + Status = SystemTable->BootServices->AllocatePool( + EfiBootServicesData, __wchar_bitmap_size, (VOID **)&__wchar_bitmap); + ASSERT(__wchar_bitmap != NULL); + if (EFI_ERROR (Status)) { + __wchar_bitmap = NULL; + EFIerrno = Status; errno = ENOMEM; return EFIerrno; } @@ -56,9 +60,12 @@ __wchar_deconstruct( IN EFI_SYSTEM_TABLE *SystemTable ) { + EFI_STATUS Status = RETURN_SUCCESS; + if( __wchar_bitmap != NULL) { - FreePool( __wchar_bitmap); + Status = SystemTable->BootServices->FreePool( __wchar_bitmap); + ASSERT_EFI_ERROR (Status); __wchar_bitmap = NULL; } - return RETURN_SUCCESS; + return Status; } diff --git a/StdLib/LibC/Wchar/Searching.c b/StdLib/LibC/Wchar/Searching.c index c345dfe838..12556bd757 100644 --- a/StdLib/LibC/Wchar/Searching.c +++ b/StdLib/LibC/Wchar/Searching.c @@ -5,7 +5,7 @@ two wide characters the same way as two integers of the underlying integer type designated by wchar_t. - Copyright (c) 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 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 that accompanies this distribution. The full text of the license may be found at @@ -86,12 +86,14 @@ size_t wcscspn(const wchar_t *s1, const wchar_t *s2) const wchar_t *str; UINT8 bit; int index; + size_t s1len; if(*s1 == 0) return 0; + s1len = wcslen(s1); BuildBitmap( __wchar_bitmap, s2, __wchar_bitmap_size); - for(str = s1; ; str++) { + for(str = s1; str < &s1[s1len] ; str++) { index = WHICH8(*str); bit = WHICH_BIT(*str); if ((__wchar_bitmap[index] & bit) != 0) diff --git a/StdLib/LibC/Wchar/Wchar.inf b/StdLib/LibC/Wchar/Wchar.inf index 427d615742..5a88233600 100644 --- a/StdLib/LibC/Wchar/Wchar.inf +++ b/StdLib/LibC/Wchar/Wchar.inf @@ -52,7 +52,7 @@ # 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 +# /Oi- is required for Microsoft VC++ to allow "intrinsic" functions to be # defined in this library. # [BuildOptions] diff --git a/StdLib/StdLib.dsc b/StdLib/StdLib.dsc index 3024b02a20..3f71d41e30 100644 --- a/StdLib/StdLib.dsc +++ b/StdLib/StdLib.dsc @@ -87,6 +87,12 @@ LibSignal|StdLib/LibC/Signal/Signal.inf LibNetUtil|StdLib/LibC/NetUtil/NetUtil.inf + # Libraries for device abstractions within the Standard C Library + # Applications should not directly access any functions defined in these libraries. + DevUtility|StdLib/LibC/Uefi/Devices/daUtility.inf + DevConsole|StdLib/LibC/Uefi/Devices/daConsole.inf + DevShell|StdLib/LibC/Uefi/Devices/daShell.inf + [LibraryClasses.IA32] TimerLib|PerformancePkg/Library/DxeTscTimerLib/DxeTscTimerLib.inf ## Comment out the above line and un-comment the line below for running under Nt32 emulation. @@ -148,6 +154,11 @@ StdLib/LibC/Signal/Signal.inf StdLib/LibC/NetUtil/NetUtil.inf +# Device Abstractions within the Standard C Library +# Applications should not directly access any functions defined in these libraries. + StdLib/LibC/Uefi/Devices/daUtility.inf + StdLib/LibC/Uefi/Devices/daConsole.inf + StdLib/LibC/Uefi/Devices/daShell.inf ################################################################ #