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

📄 storage.c

📁 用于移动设备上的java虚拟机源代码
💻 C
字号:
/* * @(#)storage.c	1.29 02/07/24 @(#) * * Copyright (c) 1998-2002 Sun Microsystems, Inc.  All rights reserved. * PROPRIETARY/CONFIDENTIAL * Use is subject to license terms. *//*========================================================================= * MIDP Reference implementation *========================================================================= * SYSTEM:    MIDP RI * SUBSYSTEM: File Storage. * FILE:      storage.c * OVERVIEW:  Manage storage for internal API's. See storage.h *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#include <stdio.h>#include <string.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#include <kni.h>#include <midpMalloc.h>#include <storage.h>#include <configuration.h>static void ensureStorageRoot(char** ppszError);static void initTotalSpace();static int getUsedSpace();static char* getLastError(char* pszFunction);static char* getLastFileError(char* pszFunction, char* pszFile);#ifndef _S_IREAD#define _S_IREAD 0444#endif#ifndef _S_IWRITE#define _S_IWRITE 0220#endif/* O_BINARY not defined in sys/fcntl.h on solaris platform */#ifndef O_BINARY#define O_BINARY 0#endif/* * Name of the storage directory. */#define APP_DIR "appdb"#ifdef UNIX#   include <dirent.h>#   define MKDIR_MODE S_IRWXU|S_IRWXG|S_IRWXO#   define MKDIR(x) mkdir(x, MKDIR_MODE)#   define COMMIT(x)#   define TRUNCATE_FILE(x,y) ftruncate(x,y)    static char *FILESEP = "/";    static char *PATHSEP = ":";#else    /*     * Use compatibility functions defined in MIDP. Because of name conflicts     * between global.h and windows.h, we repeat the essential stuff defined     * in the file MIDP/src/win32/native/dirent.h here.     */    /* begin dirent.h digest */    struct dirent {        char d_name[1];    };    typedef struct {        char internal_data[1];    } DIR;    DIR *opendir(const char *dirname);    struct dirent *readdir(DIR *dirp);    int closedir(DIR *dirp);    /* end dirent.h digest */#   define MKDIR(x) _mkdir(x)#   define COMMIT(x) _commit(x)#   define TRUNCATE_FILE(x,y) _chsize(x,y)    static char *FILESEP = "\\";    static char *PATHSEP = ";";#endif /* UNIX */#ifdef DEBUG_PRINT#   define DEBUGP(x)  printf x#else#   define DEBUGP(x)  #endif /*DEBUG_PRINT*//* Local variables */#define DEFAULT_TOTAL_SPACE (4 * 1024 * 1024) /* 4 Meg. */static int totalSpace = 0;static char *systemDirAndSep;static char *systemDir;#define MAX_ERROR_LEN 159static char errorBuffer[MAX_ERROR_LEN + 1] = {0};char* getFileSeparator() {    return FILESEP;}/* * The function is provided for development platforms so we can manage * local files outside of the RI simulated storage. */char* getPathSeparator() {    return PATHSEP;}/* * Prefixing the system directory for storage, APP_DIR, with midp_home. * * "+1" is for null terminator. */void initializeStorage(char *midp_home) {    systemDirAndSep = (char *) midpMalloc(strlen(midp_home) + 2*strlen(FILESEP) + strlen(APP_DIR) + 1);    systemDir = (char *) midpMalloc(strlen(midp_home) + strlen(FILESEP) + strlen(APP_DIR) + 1);    /*     * If no memory can be allocated, exit.     */    if (!systemDirAndSep || !systemDir) {        fprintf(stderr, "Error: out of memory.\n");        exit(-1);    }    strcpy(systemDir, midp_home);    strcat(systemDir, FILESEP);    strcat(systemDir, APP_DIR);    strcpy(systemDirAndSep, systemDir);    strcat(systemDirAndSep, FILESEP);}/* * free native resources. */void finalizeStorage() {    midpFree(systemDirAndSep);    midpFree(systemDir);}char* getStorageRoot() {    return systemDirAndSep;}void storageFreeError(char* pszError) {    /*     * This is a place holder, so that an implemenation, like a debuggable     * one can create dynamic error messages.     */    if (NULL == pszError) {        return;    }}/* * Creates the storage root directory of a file if nessecary. */static void ensureStorageRoot(char** ppszError) {    struct stat stat_buf;    *ppszError = NULL;    if (0 == stat(systemDir, &stat_buf)) {        DEBUGP(("storage root %s exists\n", systemDir));        /* dir exists */        return;    }    DEBUGP(("creating storage root %s\n", systemDir));    if (MKDIR(systemDir) < 0) {        *ppszError = getLastError("ensureStorageRoot");        return;    }}int storageOpen(char** ppszError, char* pszAsciiFilename, int ioMode) {    int flags = O_BINARY;    int creationMode = 0;    int handle;    *ppszError = NULL;    if (strlen(pszAsciiFilename) > MAX_FILENAME_LENGTH) {        *ppszError = "filename too long";        return -1;    }    if (OPEN_READ == ioMode) {        DEBUGP(("opening for read only %s\n", pszAsciiFilename));        flags |= O_RDONLY;    } else {        ensureStorageRoot(ppszError);        if (*ppszError != NULL) {            return -1;        }        if (!storageFileExists(pszAsciiFilename)) {            flags |= O_CREAT;            creationMode = _S_IREAD | _S_IWRITE;        } else if (OPEN_READ_WRITE_TRUNCATE == ioMode) {            flags |= O_TRUNC;        }        if (OPEN_WRITE == ioMode) {            DEBUGP(("opening write only %s\n", pszAsciiFilename));            flags |= O_WRONLY;        } else {            DEBUGP(("opening read write %s\n", pszAsciiFilename));            flags |= O_RDWR;        }    }    handle = open(pszAsciiFilename, flags, creationMode);    DEBUGP(("storageOpen allocated file_desc %d\n", handle));    if (-1 == handle) {        *ppszError = getLastFileError("storageOpen()", pszAsciiFilename);        return -1;    }#ifdef DEBUG_PRINT    if (creationMode != 0) {        DEBUGP(("created %s\n", pszAsciiFilename));    }#endif    return handle;}void storageClose(char** ppszError, int handle) {    int status;    *ppszError = NULL;    status = close(handle);    DEBUGP(("storageClose on file_desc %d returns %d\n", handle, status));    if (status < 0) {        *ppszError = getLastError("storageClose()");    }}int storageRead(char** ppszError, int handle, char* buffer, int length) {    int bytesRead;    *ppszError = NULL;    if (0 == length) {        return 0;    }    bytesRead = read(handle, buffer, length);  #ifdef DEBUG_STREAM    fprintf(stdout, "storageRead on fd %d res = %d\n", handle, bytesRead);#endif    if (-1 == bytesRead) {        *ppszError = getLastError("storageRead()");    } else if (0 == bytesRead) {        /* end of file in java is -1 */        bytesRead = -1;    }    return bytesRead;}void storageWrite(char** ppszError, int handle, char* buffer, int length) {    int bytesWritten;    *ppszError = NULL;    bytesWritten = write(handle, buffer, length);    COMMIT(handle); /* force flush of the write to disk */#ifdef DEBUG_STREAM    fprintf(stdout, "storageWrite on fd %d res = %d\n", handle, bytesWritten);#endif    if (-1 == bytesWritten) {        *ppszError = getLastError("storageWrite()");        return;    }    if (bytesWritten != length) {        *ppszError = "storage full";        return;    }}void storagePosition(char** ppszError, int handle, long absolutePosition) {    long newPosition;    newPosition = lseek(handle, absolutePosition, SEEK_SET);#ifdef DEBUG_STREAM    fprintf(stdout, "storagePostion on fd %d res = %d\n", handle, newPosition);#endif    if (-1 == newPosition) {        *ppszError = getLastError("storagePosition()");        return;    }    *ppszError = NULL;}int storageSizeOf(char** ppszError,  int handle) {    struct stat stat_buf;    if (fstat(handle, &stat_buf) < 0) {        *ppszError = getLastError("storageSizeOf()");        return 0;    }    *ppszError = NULL;    return stat_buf.st_size;}void storageTruncate(char** ppszError, int handle, int size) {    int rv;    rv = TRUNCATE_FILE(handle, size);    if (rv == -1) {	*ppszError = getLastError("storageTruncate()");    } else {	*ppszError = NULL;    }    /* DEBUGP(("storageTruncate got rv %d\n", rv)); */}int storageGetFreeSpace() {    int freeSpace;    if (totalSpace == 0) {        initTotalSpace();    }    freeSpace = totalSpace - getUsedSpace();    /* DEBUGP(("Free space = %d\n", freeSpace)); */    return freeSpace;}int storageFileExists(char* pszAsciiFilename) {    struct stat stat_buf;    int status;    status = stat(pszAsciiFilename, &stat_buf);    if (status < 0) {        DEBUGP(("storage file %s does not exist\n", pszAsciiFilename));        return 0;    }    DEBUGP(("storage file %s exists\n", pszAsciiFilename));    return 1;}void storageDeleteFile(char** ppszError, char* pszAsciiFilename) {    DEBUGP(("trying to delete %s\n", pszAsciiFilename));    if (unlink(pszAsciiFilename) < 0) {        *ppszError = getLastFileError("storageDeleteFile", pszAsciiFilename);        return;    }    DEBUGP(("deleted %s\n", pszAsciiFilename));    *ppszError = NULL;}void storageRenameFile(char** ppszError, char* pszOldFilename,                       char* pszNewFilename) {    DEBUGP(("renaming %s to %s\n", pszOldFilename, pszNewFilename));    if (!storageFileExists(pszOldFilename)) {        *ppszError = "The file to be renamed does not exist.";    }    if (storageFileExists(pszNewFilename)) {        storageDeleteFile(ppszError, pszNewFilename);        if (*ppszError != NULL) {            return;        }    }    if (rename(pszOldFilename, pszNewFilename) < 0) {        *ppszError = getLastFileError("storageRename", pszNewFilename);        return;    }    *ppszError = NULL;}static void initTotalSpace() {    /*     * Initialize total space     */    char * env;    env = getInternalProp("system.jam_space");    if (env == NULL) {        totalSpace = DEFAULT_TOTAL_SPACE;        return;    }    totalSpace = atoi(env);    if (totalSpace < 4000) {          totalSpace = 4000;        fprintf(stderr, "total storage space set to minimum: %d\n",                totalSpace);    }}static int getUsedSpace() {    DIR *dir;      int size;     struct dirent *de;    struct stat stat_buf;     char filename[MAX_FILENAME_LENGTH + 1];     int rootLen;    int exists;    dir = opendir(systemDir);    if (dir == NULL) {        DEBUGP(("getSpaceUsed couldn't open dir %s\n", systemDir));	return 0;    }        size = 0;    strcpy(filename, systemDirAndSep);    rootLen = strlen(filename);    for (de = readdir(dir); de != NULL;             de = readdir(dir), filename[rootLen] = 0) {        if (strcmp(de->d_name, ".") == 0 ||                 strcmp(de->d_name, "..") == 0) {            continue;        }        strncat(filename, de->d_name, sizeof (filename) - 1 - rootLen);	exists = stat(filename, &stat_buf);	if (exists != -1 && !S_ISDIR(stat_buf.st_mode)) {	    size += stat_buf.st_size;	}    }    closedir(dir);    return size;}static char* getLastError(char* pszFunction) {    char* temp;    temp = strerror(errno);    if (temp == NULL) {        return "Unspecifed Error";    }    strcpy(errorBuffer, pszFunction);    strcat(errorBuffer, ": ");    strncat(errorBuffer, temp, MAX_ERROR_LEN - 2 - strlen(pszFunction));    return errorBuffer;}static char* getLastFileError(char* pszFunction, char* pszFile) {    char* temp;    int charsLeft;    temp = strerror(errno);    if (temp == NULL) {        return "Unspecifed Error";    }    strcpy(errorBuffer, pszFunction);    strcat(errorBuffer, ": ");    charsLeft = MAX_ERROR_LEN - strlen(errorBuffer);    strncat(errorBuffer, temp, charsLeft);    charsLeft = MAX_ERROR_LEN - strlen(errorBuffer);    strncat(errorBuffer, ", ", charsLeft);    charsLeft = MAX_ERROR_LEN - strlen(errorBuffer);    strncat(errorBuffer, pszFile, charsLeft);    return errorBuffer;}static int savedRootLength = 0;static int savedMatchLength = 0;static DIR* savedDirectory = NULL;static char savedFilename[MAX_FILENAME_LENGTH + 1];/* * this returns a static buffer an has static state for *  getNextFileThatStartsWith */char* getFirstFileThatStartsWith(char* string) {    char* tmp;    if (savedDirectory != NULL) {        closedir(savedDirectory);        savedDirectory = NULL;    }    /*     * find the root dir     */    tmp = strrchr(string, *getFileSeparator());    if (NULL == tmp) {        return NULL;    }    savedRootLength = tmp - string + 1;    savedMatchLength = strlen(string + savedRootLength);         /*     * break up the filename at the parent separator, but put back the     * separator after we create the parent directory     */    *tmp = '\0';    savedDirectory = opendir(string);    *tmp = *getFileSeparator();    return getNextFileThatStartsWith(string);}/* * call getFirstFileThatStartsWith first, to set up the shared state * needed for this function */char* getNextFileThatStartsWith(char* string) {    char* match;    struct dirent *de;    char* filename = NULL;    if (NULL == savedDirectory) {        return NULL;    }    match = string + savedRootLength;    /* find the first match file not "." or ".." */    for (de = readdir(savedDirectory); de != NULL;         de = readdir(savedDirectory)) {        filename = de->d_name;        if (strcmp(filename, ".") == 0 ||            strcmp(filename, "..") == 0) {            continue;        }        if (strncmp(filename, match, savedMatchLength) == 0) {            break;        }    }    if (NULL == de) {        closedir(savedDirectory);        savedDirectory = NULL;        return NULL;    }    if ((savedRootLength + strlen(filename) + 1) > sizeof (savedFilename)) {        closedir(savedDirectory);        savedDirectory = NULL;        return NULL;    }    memcpy(savedFilename, string, savedRootLength);    strcpy(savedFilename + savedRootLength, filename);    return savedFilename;}

⌨️ 快捷键说明

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