⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 open.c

📁 log4cxx 0.10 unix下编译包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#include "apr_private.h"#include "apr_arch_file_io.h"#include "apr_file_io.h"#include "apr_general.h"#include "apr_strings.h"#include "apr_portable.h"#include "apr_thread_mutex.h"#if APR_HAVE_ERRNO_H#include <errno.h>#endif#include <winbase.h>#include <string.h>#if APR_HAVE_SYS_STAT_H#include <sys/stat.h>#endif#include "apr_arch_misc.h"#include "apr_arch_inherit.h"#if APR_HAS_UNICODE_FSapr_status_t utf8_to_unicode_path(apr_wchar_t* retstr, apr_size_t retlen,                                   const char* srcstr){    /* TODO: The computations could preconvert the string to determine     * the true size of the retstr, but that's a memory over speed     * tradeoff that isn't appropriate this early in development.     *     * Allocate the maximum string length based on leading 4      * characters of \\?\ (allowing nearly unlimited path lengths)      * plus the trailing null, then transform /'s into \\'s since     * the \\?\ form doesn't allow '/' path seperators.     *     * Note that the \\?\ form only works for local drive paths, and     * \\?\UNC\ is needed UNC paths.     */    apr_size_t srcremains = strlen(srcstr) + 1;    apr_wchar_t *t = retstr;    apr_status_t rv;    /* This is correct, we don't twist the filename if it is will     * definately be shorter than MAX_PATH.  It merits some      * performance testing to see if this has any effect, but there     * seem to be applications that get confused by the resulting     * Unicode \\?\ style file names, especially if they use argv[0]     * or call the Win32 API functions such as GetModuleName, etc.     * Not every application is prepared to handle such names.     *     * Note that a utf-8 name can never result in more wide chars     * than the original number of utf-8 narrow chars.     */    if (srcremains > MAX_PATH) {        if (srcstr[1] == ':' && (srcstr[2] == '/' || srcstr[2] == '\\')) {            wcscpy (retstr, L"\\\\?\\");            retlen -= 4;            t += 4;        }        else if ((srcstr[0] == '/' || srcstr[0] == '\\')              && (srcstr[1] == '/' || srcstr[1] == '\\')              && (srcstr[2] != '?')) {            /* Skip the slashes */            srcstr += 2;            srcremains -= 2;            wcscpy (retstr, L"\\\\?\\UNC\\");            retlen -= 8;            t += 8;        }    }    if (rv = apr_conv_utf8_to_ucs2(srcstr, &srcremains, t, &retlen)) {        return (rv == APR_INCOMPLETE) ? APR_EINVAL : rv;    }    if (srcremains) {        return APR_ENAMETOOLONG;    }    for (; *t; ++t)        if (*t == L'/')            *t = L'\\';    return APR_SUCCESS;}apr_status_t unicode_to_utf8_path(char* retstr, apr_size_t retlen,                                  const apr_wchar_t* srcstr){    /* Skip the leading 4 characters if the path begins \\?\, or substitute     * // for the \\?\UNC\ path prefix, allocating the maximum string     * length based on the remaining string, plus the trailing null.     * then transform \\'s back into /'s since the \\?\ form never     * allows '/' path seperators, and APR always uses '/'s.     */    apr_size_t srcremains = wcslen(srcstr) + 1;    apr_status_t rv;    char *t = retstr;    if (srcstr[0] == L'\\' && srcstr[1] == L'\\' &&         srcstr[2] == L'?'  && srcstr[3] == L'\\') {        if (srcstr[4] == L'U' && srcstr[5] == L'N' &&             srcstr[6] == L'C' && srcstr[7] == L'\\') {            srcremains -= 8;            srcstr += 8;            retstr[0] = '\\';            retstr[1] = '\\';            retlen -= 2;            t += 2;        }        else {            srcremains -= 4;            srcstr += 4;        }    }            if (rv = apr_conv_ucs2_to_utf8(srcstr, &srcremains, t, &retlen)) {        return rv;    }    if (srcremains) {        return APR_ENAMETOOLONG;    }    return APR_SUCCESS;}#endifvoid *res_name_from_filename(const char *file, int global, apr_pool_t *pool){#if APR_HAS_UNICODE_FS    IF_WIN_OS_IS_UNICODE    {        apr_wchar_t *wpre, *wfile, *ch;        apr_size_t n = strlen(file) + 1;        apr_size_t r, d;        apr_status_t rv;        if (apr_os_level >= APR_WIN_2000) {            if (global)                wpre = L"Global\\";            else                wpre = L"Local\\";        }        else            wpre = L"";        r = wcslen(wpre);        if (n > 256 - r) {            file += n - 256 - r;            n = 256;            /* skip utf8 continuation bytes */            while ((*file & 0xC0) == 0x80) {                ++file;                --n;            }        }        wfile = apr_palloc(pool, (r + n) * sizeof(apr_wchar_t));        wcscpy(wfile, wpre);        d = n;        if (rv = apr_conv_utf8_to_ucs2(file, &n, wfile + r, &d)) {            return NULL;        }        for (ch = wfile + r; *ch; ++ch) {            if (*ch == ':' || *ch == '/' || *ch == '\\')                *ch = '_';        }        return wfile;    }#endif#if APR_HAS_ANSI_FS    ELSE_WIN_OS_IS_ANSI    {        char *nfile, *ch;        apr_size_t n = strlen(file) + 1;#if !APR_HAS_UNICODE_FS        apr_status_t rv;        apr_size_t r, d;        char *pre;        if (apr_os_level >= APR_WIN_2000) {            if (global)                pre = "Global\\";            else                pre = "Local\\";        }        else            pre = "";        r = strlen(pre);        if (n > 256 - r) {            file += n - 256 - r;            n = 256;        }        nfile = apr_palloc(pool, (r + n) * sizeof(apr_wchar_t));        memcpy(nfile, pre, r);        memcpy(nfile + r, file, n);#else        const apr_size_t r = 0;        if (n > 256) {            file += n - 256;            n = 256;        }        nfile = apr_pmemdup(pool, file, n);#endif        for (ch = nfile + r; *ch; ++ch) {            if (*ch == ':' || *ch == '/' || *ch == '\\')                *ch = '_';        }        return nfile;    }#endif}apr_status_t file_cleanup(void *thefile){    apr_file_t *file = thefile;    apr_status_t flush_rv = APR_SUCCESS;    if (file->filehand != INVALID_HANDLE_VALUE) {        /* In order to avoid later segfaults with handle 'reuse',         * we must protect against the case that a dup2'ed handle         * is being closed, and invalidate the corresponding StdHandle          */        if (file->filehand == GetStdHandle(STD_ERROR_HANDLE)) {            SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE);        }        if (file->filehand == GetStdHandle(STD_OUTPUT_HANDLE)) {            SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE);        }        if (file->filehand == GetStdHandle(STD_INPUT_HANDLE)) {            SetStdHandle(STD_INPUT_HANDLE, INVALID_HANDLE_VALUE);        }        if (file->buffered) {            /* XXX: flush here is not mutex protected */            flush_rv = apr_file_flush((apr_file_t *)thefile);        }        CloseHandle(file->filehand);        file->filehand = INVALID_HANDLE_VALUE;    }    if (file->pOverlapped && file->pOverlapped->hEvent) {        CloseHandle(file->pOverlapped->hEvent);        file->pOverlapped = NULL;    }    return flush_rv;}APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new, const char *fname,                                   apr_int32_t flag, apr_fileperms_t perm,                                   apr_pool_t *pool){    HANDLE handle = INVALID_HANDLE_VALUE;    DWORD oflags = 0;    DWORD createflags = 0;    DWORD attributes = 0;    DWORD sharemode = FILE_SHARE_READ | FILE_SHARE_WRITE;    apr_status_t rv;    if (flag & APR_READ) {        oflags |= GENERIC_READ;    }    if (flag & APR_WRITE) {        oflags |= GENERIC_WRITE;    }    if (flag & APR_WRITEATTRS) {        oflags |= FILE_WRITE_ATTRIBUTES;    }    if (apr_os_level >= APR_WIN_NT)         sharemode |= FILE_SHARE_DELETE;    if (flag & APR_CREATE) {        if (flag & APR_EXCL) {            /* only create new if file does not already exist */            createflags = CREATE_NEW;        } else if (flag & APR_TRUNCATE) {            /* truncate existing file or create new */            createflags = CREATE_ALWAYS;        } else {            /* open existing but create if necessary */            createflags = OPEN_ALWAYS;        }    } else if (flag & APR_TRUNCATE) {        /* only truncate if file already exists */        createflags = TRUNCATE_EXISTING;    } else {        /* only open if file already exists */        createflags = OPEN_EXISTING;    }    if ((flag & APR_EXCL) && !(flag & APR_CREATE)) {        return APR_EACCES;    }           if (flag & APR_DELONCLOSE) {        attributes |= FILE_FLAG_DELETE_ON_CLOSE;    }    if (flag & APR_OPENLINK) {       attributes |= FILE_FLAG_OPEN_REPARSE_POINT;    }    /* Without READ or WRITE, we fail unless apr called apr_file_open     * internally with the private APR_OPENINFO flag.     *     * With the APR_OPENINFO flag on NT, use the option flag     * FILE_FLAG_BACKUP_SEMANTICS to allow us to open directories.     * See the static resolve_ident() fn in file_io/win32/filestat.c

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -