VirtualBox

Changeset 1108 in kBuild for trunk/src/kmk/kmkbuiltin


Ignore:
Timestamp:
Sep 23, 2007 8:33:10 AM (18 years ago)
Author:
bird
Message:

Added symlink link support (vista).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/kmkbuiltin/mscfakes.c

    r936 r1108  
    3131#include <io.h>
    3232#include <fcntl.h>
     33#include <sys/stat.h>
    3334#include "err.h"
    3435#include "mscfakes.h"
     36
     37#define timeval windows_timeval
     38#include <Windows.h>
     39#undef timeval
    3540
    3641
     
    5560    if (rc)
    5661    {
    57         int len = strlen(path);
     62        size_t len = strlen(path);
    5863        if (len > 0 && (path[len - 1] == '/' || path[len - 1] == '\\'))
    5964        {
     
    7378    if (rc)
    7479    {
    75         int len = strlen(path);
     80        size_t len = strlen(path);
    7681        if (len > 0 && (path[len - 1] == '/' || path[len - 1] == '\\'))
    7782        {
     
    126131
    127132
     133/** Unix to DOS. */
     134static char *fix_slashes(char *psz)
     135{
     136    char *pszRet = psz;
     137    for (; *psz; psz++)
     138        if (*psz == '/')
     139            *psz = '\\';
     140    return pszRet;
     141}
     142
     143
     144/** Calcs the SYMBOLIC_LINK_FLAG_DIRECTORY flag for CreatesymbolcLink.  */
     145static DWORD is_directory(const char *pszPath, const char *pszRelativeTo)
     146{
     147    size_t cchPath = strlen(pszPath);
     148    struct stat st;
     149    if (cchPath > 0 && pszPath[cchPath - 1] == '\\' || pszPath[cchPath - 1] == '/')
     150        return 1; /* SYMBOLIC_LINK_FLAG_DIRECTORY */
     151
     152    if (stat(pszPath, &st))
     153    {
     154        size_t cchRelativeTo = strlen(pszRelativeTo);
     155        char *psz = malloc(cchPath + cchRelativeTo + 4);
     156        memcpy(psz, pszRelativeTo, cchRelativeTo);
     157        memcpy(psz + cchRelativeTo, "\\", 1);
     158        memcpy(psz + cchRelativeTo + 1, pszPath, cchPath + 1);
     159        if (stat(pszPath, &st))
     160            st.st_mode = _S_IFREG;
     161        free(psz);
     162    }
     163
     164    return (st.st_mode & _S_IFMT) == _S_IFDIR ? 1 : 0;
     165}
     166
     167
    128168int symlink(const char *pszDst, const char *pszLink)
    129169{
     170    static BOOL (WINAPI *s_pfnCreateSymbolicLinkA)(LPCSTR, LPCSTR, DWORD) = 0;
     171    static BOOL s_fTried = FALSE;
     172
     173    if (!s_fTried)
     174    {
     175        HMODULE hmod = LoadLibrary("KERNEL32.DLL");
     176        if (hmod)
     177            *(FARPROC *)&s_pfnCreateSymbolicLinkA = GetProcAddress(hmod, "CreateSymbolicLinkA");
     178        s_fTried = TRUE;
     179    }
     180
     181    if (s_pfnCreateSymbolicLinkA)
     182    {
     183        char *pszDstCopy = fix_slashes(strdup(pszDst));
     184        char *pszLinkCopy = fix_slashes(strdup(pszLink));
     185        BOOL fRc = s_pfnCreateSymbolicLinkA(pszLinkCopy, pszDstCopy,
     186                                            is_directory(pszDstCopy, pszLinkCopy));
     187        DWORD err = GetLastError();
     188        free(pszDstCopy);
     189        free(pszLinkCopy);
     190        if (fRc)
     191            return 0;
     192        switch (err)
     193        {
     194            case ERROR_NOT_SUPPORTED:       errno = ENOSYS; break;
     195            case ERROR_ALREADY_EXISTS:
     196            case ERROR_FILE_EXISTS:         errno = EEXIST; break;
     197            case ERROR_DIRECTORY:           errno = ENOTDIR; break;
     198            case ERROR_ACCESS_DENIED:
     199            case ERROR_PRIVILEGE_NOT_HELD:  errno = EPERM; break;
     200            default:                        errno = EINVAL; break;
     201        }
     202        return -1;
     203    }
     204
    130205    errno = ENOSYS;
    131206    err(1, "symlink() is not implemented on windows!");
     
    160235    for (i = 0; i < count; i++)
    161236    {
    162         int cb = write(fd, vector[i].iov_base, vector[i].iov_len);
     237        int cb = (int)write(fd, vector[i].iov_base, (int)vector[i].iov_len);
    163238        if (cb < 0)
    164239            return -1;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette