From 0c1992fbccd139e9d3bb730c19a79847c6a5a246 Mon Sep 17 00:00:00 2001 From: darylm503 Date: Wed, 30 Nov 2011 00:52:45 +0000 Subject: StdLib: Add isDirSep character classification macro and function. Implement several Posix functions and clean up EfiSysCall.h. Align file mode handling with UEFI file protocol flags. Include/ctype.h: Function declaration and Macro definition of isDirSep Include/unistd.h: Declarations added from EfiSysCall.h Include/utime.h: New file. For the Posix utime() function. Include/sys/_ctype.h: Update character class bit maps. Include/sys/EfiSysCall.h: Move declarations to unistd.h Include/sys/fcntl.h: Improve comments. Add UEFI-specific macros. Include/sys/filio.h: Remove declarations for unsupported file ioctls. Include/sys/stat.h: Fix flags. Add macros and declarations. Include/sys/time.h: Add declarations for new functions Tm2Efi() and Time2Efi(). Include/sys/types.h: Use EFI-specific instead of BSD-specific definitions for typedefs. Include/sys/unistd.h: Delete inappropriate content. Guard macro definitions. LibC/Locale/setlocale.c LibC/Stdio/{fdopen.c, findfp.c, fopen.c, freopen.c, gettemp.c, makebuf.c, mktemp.c, remove.c, stdio.c, tempnam.c, tmpfile.c, tmpnam.c} LibC/Time/{itimer.c, ZoneProc.c} LibC/Uefi/SysCalls.c LibC/Uefi/Devices/Console/daConsole.c LibC/Uefi/Devices/UefiShell/daShell.c PosixLib/Gen/readdir.c Include unistd.h instead of EfiSysCall.h LibC/Ctype/CClass.c: Character classification function implementation for isDirSep. LibC/Ctype/iCtype.c: Update character classification and case conversion tables. LibC/Time/TimeEfi.c: Improve comments. Implement new functions Tm2Efi() and Time2Efi(). LibC/Uefi/StubFunctions.c: Add missing include. Cosmetic changes to declarations. LibC/Uefi/SysCalls.c: Add support function for utime(). LibC/Uefi/Uefi.inf: Add LibGen library class dependency. LibC/Uefi/Xform.c: Enhance Omode2EFI(). LibC/Uefi/Devices/UefiShell/daShell.c: Enhance da_ShellMkdir. Implement da_ShellIoctl to set file times. PosixLib/Gen/access.c: New file. Implement the access() function. PosixLib/Gen/dirname.c: Enhance to use isDirSep and differentiate between the device, path, and filename components of UEFI Shell-style paths. PosixLib/Gen/utime.c: New file. Implement the utime() function. PosixLib/Gen/LibGen.inf: Change MODULE_TYPE. Add new files. Signed-off-by: darylm503 Reviewed-by: geekboy15a Reviewed-by: jljusten Reviewed-by: Rahul Khana Reviewed-by: leegrosenbaum git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12800 6f19259b-4bc3-4df7-8a09-765794883524 --- StdLib/PosixLib/Gen/LibGen.inf | 2 + StdLib/PosixLib/Gen/access.c | 118 +++++++++++++++++++++++++++++++++++++++++ StdLib/PosixLib/Gen/dirname.c | 39 ++++++++++---- StdLib/PosixLib/Gen/readdir.c | 2 - StdLib/PosixLib/Gen/utime.c | 73 +++++++++++++++++++++++++ 5 files changed, 221 insertions(+), 13 deletions(-) create mode 100644 StdLib/PosixLib/Gen/access.c create mode 100644 StdLib/PosixLib/Gen/utime.c (limited to 'StdLib/PosixLib') diff --git a/StdLib/PosixLib/Gen/LibGen.inf b/StdLib/PosixLib/Gen/LibGen.inf index 0a2ab188fd..5a54686f6e 100644 --- a/StdLib/PosixLib/Gen/LibGen.inf +++ b/StdLib/PosixLib/Gen/LibGen.inf @@ -31,6 +31,8 @@ opendir.c closedir.c readdir.c + access.c + utime.c [Packages] MdePkg/MdePkg.dec diff --git a/StdLib/PosixLib/Gen/access.c b/StdLib/PosixLib/Gen/access.c new file mode 100644 index 0000000000..3031e4f942 --- /dev/null +++ b/StdLib/PosixLib/Gen/access.c @@ -0,0 +1,118 @@ +/** @file + Implementation of the Posix access() function. + + Copyright (c) 2011, Intel Corporation. All rights reserved.
+ This program and the accompanying materials are licensed and made available under + the terms and conditions of the BSD License 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 + +/** Save some typing later on. */ +#define GOOD_MODE (F_OK | X_OK | W_OK | R_OK) + +/** Determine accessibility of a file. + The access() function checks the file, named by the pathname pointed to by + the Path argument, for accessibility according to the bit pattern contained + in Mode. + + The value of Mode is either the bitwise-inclusive OR of the access + permissions to be checked (R_OK, W_OK, X_OK) or the existence test (F_OK). + + If Path ends in '/' or '\\', the target must be a directory, otherwise it doesn't matter. + A file is executable if it is NOT a directory and it ends in ".efi". + + @param[in] Path Path or name of the file to be checked. + @param[in] Mode Access permissions to check for. + + @retval 0 Successful completion. + @retval -1 File is not accessible with the given Mode. The error condition + is indicated by errno. Values of errno specific to the access + function include: EACCES, ENOENT, ENOTDIR, ENAMETOOLONG +**/ +int +access( + const char *Path, + int Mode + ) +{ + struct stat FileStat; + int retval = -1; + size_t PLength; + uint32_t WantDir; + uint32_t DirMatch; + + if((Path == NULL) || ((Mode & ~GOOD_MODE) != 0)) { + errno = EINVAL; + } + else { + PLength = strlen(Path); + if(PLength > PATH_MAX) { + errno = ENAMETOOLONG; + } + else { + retval = stat(Path, &FileStat); + if(retval == 0) { + /* Path exists. FileStat now holds valid information. */ + WantDir = isDirSep(Path[PLength - 1]); // Does Path end in '/' or '\\' ? + DirMatch = (! WantDir && (! S_ISDIR(FileStat.st_mode))); + + /* Test each permission individually. */ + do { + if(Mode == F_OK) { /* Existence test. */ + if(DirMatch) { /* This is a directory or file as desired. */ + retval = 0; + } + else { + /* Indicate why we failed the test. */ + errno = (WantDir) ? ENOTDIR : EISDIR; + } + break; /* F_OK does not combine with any other tests. */ + } + if(Mode & R_OK) { + if((FileStat.st_mode & READ_PERMS) == 0) { + /* No read permissions. + For UEFI, everything should have READ permissions. + */ + errno = EDOOFUS; /* Programming Error. */ + break; + } + } + if(Mode & W_OK) { + if((FileStat.st_mode & WRITE_PERMS) == 0) { + /* No write permissions. */ + errno = EACCES; /* Writing is not OK. */ + break; + } + } + if(Mode & X_OK) { + /* In EDK II, executable files end in ".efi" */ + if(strcmp(&Path[PLength-4], ".efi") != 0) { + /* File is not an executable. */ + errno = EACCES; + break; + } + } + retval = 0; + } while(FALSE); + } + else { + /* File or path does not exist. */ + errno = ENOENT; + } + } + } + return retval; +} diff --git a/StdLib/PosixLib/Gen/dirname.c b/StdLib/PosixLib/Gen/dirname.c index 7fb4d39a0f..eb924d435c 100644 --- a/StdLib/PosixLib/Gen/dirname.c +++ b/StdLib/PosixLib/Gen/dirname.c @@ -1,5 +1,14 @@ /** @file + 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) 1997, 2002 The NetBSD Foundation, Inc. * All rights reserved. * @@ -30,19 +39,17 @@ NetBSD: dirname.c,v 1.10 2008/05/10 22:39:40 christos Exp */ #include - #include -//#include "namespace.h" -//#include #include +#include #include #ifdef __weak_alias __weak_alias(dirname,_dirname) #endif -#if !HAVE_DIRNAME +#ifdef HAVE_DIRNAME char * dirname(char *path) { @@ -60,24 +67,34 @@ dirname(char *path) /* Strip trailing slashes, if any. */ lastp = path + strlen(path) - 1; - while (lastp != path && *lastp == '/') + while (lastp != path && isDirSep(*lastp)) lastp--; /* Terminate path at the last occurence of '/'. */ do { - if (*lastp == '/') { + if (isDirSep(*lastp)) { /* Strip trailing slashes, if any. */ - while (lastp != path && *lastp == '/') + while (lastp != path && isDirSep(*lastp)) lastp--; - /* ...and copy the result into the result buffer. */ + /* ...and copy the result into the result buffer. + We make sure that there will be room for the terminating NUL + and for a final '/', if necessary. + */ len = (lastp - path) + 1 /* last char */; - if (len > (PATH_MAX - 1)) - len = PATH_MAX - 1; + if (len > (PATH_MAX - 2)) + len = PATH_MAX - 2; memcpy(result, path, len); + if(*lastp == ':') { /* Have we stripped off all except the Volume name? */ + if(isDirSep(lastp[1])) { /* Was ...":/"... so we want the root of the volume. */ + result[len++] = '/'; + } + else { + result[len++] = '.'; + } + } result[len] = '\0'; - return (result); } } while (--lastp >= path); diff --git a/StdLib/PosixLib/Gen/readdir.c b/StdLib/PosixLib/Gen/readdir.c index b8ad0af2a3..13c4eaec07 100644 --- a/StdLib/PosixLib/Gen/readdir.c +++ b/StdLib/PosixLib/Gen/readdir.c @@ -54,8 +54,6 @@ #include #include -#include - /* * get next entry in a directory. */ diff --git a/StdLib/PosixLib/Gen/utime.c b/StdLib/PosixLib/Gen/utime.c new file mode 100644 index 0000000000..9cb8b5b50b --- /dev/null +++ b/StdLib/PosixLib/Gen/utime.c @@ -0,0 +1,73 @@ +/** @file + Set file access and modification times. + + 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. + * + * 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: utime.c,v 1.12 2003/08/07 16:42:59 agc Exp + utime.c 8.1 (Berkeley) 6/4/93 + */ +#include +#include + +#include "namespace.h" +#include + +#include +#include +#include +#include + +int +utime( + const char *path, + const struct utimbuf *times + ) +{ + struct timeval tv[2], *tvp; + + _DIAGASSERT(path != NULL); + + if (times == (struct utimbuf *) NULL) + tvp = NULL; + else { + tv[0].tv_sec = times->actime; + tv[1].tv_sec = times->modtime; + tv[0].tv_usec = tv[1].tv_usec = 0; + tvp = tv; + } + return (utimes(path, tvp)); +} -- cgit v1.2.3