Ignore:
Timestamp:
Sep 2, 2008, 11:50:04 PM (17 years ago)
Author:
bird
Message:

kmk: Made chmod build on windows. Some cleanup of the bsdisms.

File:
1 edited

Legend:

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

    r1321 r1710  
    4040
    4141
     42/**
     43 * Makes corrections to a directory path that ends with a trailing slash.
     44 *
     45 * @returns temporary buffer to free.
     46 * @param   ppszPath    The path pointer. This is updated when necessary.
     47 * @param   pfMustBeDir This is set if it must be a directory, otherwise it's cleared.
     48 */
     49static char *
     50msc_fix_path(const char **ppszPath, int *pfMustBeDir)
     51{
     52    const char *pszPath = *ppszPath;
     53    const char *psz;
     54    char *pszNew;
     55    *pfMustBeDir = 0;
     56
     57    /*
     58     * Skip any compusory trailing slashes
     59     */
     60    if (pszPath[0] == '/' || pszPath[0] == '\\')
     61    {
     62        if (   (pszPath[1] == '/' || pszPath[1] == '\\')
     63            &&  pszPath[2] != '/'
     64            &&  pszPath[2] != '\\')
     65            /* unc */
     66            pszPath += 2;
     67        else
     68            /* root slash(es) */
     69            pszPath++;
     70    }
     71    else if (   isalpha(pszPath[0])
     72             && pszPath[1] == ':')
     73    {
     74        if (pszPath[2] == '/' || pszPath[2] == '\\')
     75            /* drive w/ slash */
     76            pszPath += 3;
     77        else
     78            /* drive relative path. */
     79            pszPath += 2;
     80    }
     81    /* else: relative path, no skipping necessary. */
     82
     83    /*
     84     * Any trailing slashes to drop off?
     85     */
     86    psz = strchr(pszPath, '\0');
     87    if (pszPath <= psz)
     88        return NULL;
     89    if (   psz[-1] != '/'
     90        || psz[-1] != '\\')
     91        return NULL;
     92
     93    /* figure how many, make a copy and strip them off. */
     94    while (     psz > pszPath
     95           &&   (   psz[-1] == '/'
     96                 || psz[-1] == '\\'))
     97        psz--;
     98    pszNew = strdup(pszPath);
     99    pszNew[psz - pszPath] = '\0';
     100
     101    *pfMustBeDir = 1;
     102    *ppszPath = pszNew; /* use this one */
     103    return pszNew;
     104}
     105
     106
     107static int
     108msc_set_errno(DWORD dwErr)
     109{
     110    switch (dwErr)
     111    {
     112        default:
     113        case ERROR_INVALID_FUNCTION:        errno = EINVAL; break;
     114        case ERROR_FILE_NOT_FOUND:          errno = ENOENT; break;
     115        case ERROR_PATH_NOT_FOUND:          errno = ENOENT; break;
     116        case ERROR_TOO_MANY_OPEN_FILES:     errno = EMFILE; break;
     117        case ERROR_ACCESS_DENIED:           errno = EACCES; break;
     118        case ERROR_INVALID_HANDLE:          errno = EBADF; break;
     119        case ERROR_ARENA_TRASHED:           errno = ENOMEM; break;
     120        case ERROR_NOT_ENOUGH_MEMORY:       errno = ENOMEM; break;
     121        case ERROR_INVALID_BLOCK:           errno = ENOMEM; break;
     122        case ERROR_BAD_ENVIRONMENT:         errno = E2BIG; break;
     123        case ERROR_BAD_FORMAT:              errno = ENOEXEC; break;
     124        case ERROR_INVALID_ACCESS:          errno = EINVAL; break;
     125        case ERROR_INVALID_DATA:            errno = EINVAL; break;
     126        case ERROR_INVALID_DRIVE:           errno = ENOENT; break;
     127        case ERROR_CURRENT_DIRECTORY:       errno = EACCES; break;
     128        case ERROR_NOT_SAME_DEVICE:         errno = EXDEV; break;
     129        case ERROR_NO_MORE_FILES:           errno = ENOENT; break;
     130        case ERROR_LOCK_VIOLATION:          errno = EACCES; break;
     131        case ERROR_BAD_NETPATH:             errno = ENOENT; break;
     132        case ERROR_NETWORK_ACCESS_DENIED:   errno = EACCES; break;
     133        case ERROR_BAD_NET_NAME:            errno = ENOENT; break;
     134        case ERROR_FILE_EXISTS:             errno = EEXIST; break;
     135        case ERROR_CANNOT_MAKE:             errno = EACCES; break;
     136        case ERROR_FAIL_I24:                errno = EACCES; break;
     137        case ERROR_INVALID_PARAMETER:       errno = EINVAL; break;
     138        case ERROR_NO_PROC_SLOTS:           errno = EAGAIN; break;
     139        case ERROR_DRIVE_LOCKED:            errno = EACCES; break;
     140        case ERROR_BROKEN_PIPE:             errno = EPIPE; break;
     141        case ERROR_DISK_FULL:               errno = ENOSPC; break;
     142        case ERROR_INVALID_TARGET_HANDLE:   errno = EBADF; break;
     143        case ERROR_WAIT_NO_CHILDREN:        errno = ECHILD; break;
     144        case ERROR_CHILD_NOT_COMPLETE:      errno = ECHILD; break;
     145        case ERROR_DIRECT_ACCESS_HANDLE:    errno = EBADF; break;
     146        case ERROR_NEGATIVE_SEEK:           errno = EINVAL; break;
     147        case ERROR_SEEK_ON_DEVICE:          errno = EACCES; break;
     148        case ERROR_DIR_NOT_EMPTY:           errno = ENOTEMPTY; break;
     149        case ERROR_NOT_LOCKED:              errno = EACCES; break;
     150        case ERROR_BAD_PATHNAME:            errno = ENOENT; break;
     151        case ERROR_MAX_THRDS_REACHED:       errno = EAGAIN; break;
     152        case ERROR_LOCK_FAILED:             errno = EACCES; break;
     153        case ERROR_ALREADY_EXISTS:          errno = EEXIST; break;
     154        case ERROR_FILENAME_EXCED_RANGE:    errno = ENOENT; break;
     155        case ERROR_NESTING_NOT_ALLOWED:     errno = EAGAIN; break;
     156    }
     157
     158    return -1;
     159}
     160
    42161char *dirname(char *path)
    43162{
    44163    /** @todo later */
    45164    return path;
     165}
     166
     167
     168int lchmod(const char *pszPath, mode_t mode)
     169{
     170    int rc = 0;
     171    int fMustBeDir;
     172    char *pszPathFree = msc_fix_path(&pszPath, &fMustBeDir);
     173
     174    /*
     175     * Get the current attributes
     176     */
     177    DWORD fAttr = GetFileAttributes(pszPath);
     178    if (fAttr == INVALID_FILE_ATTRIBUTES)
     179        rc = msc_set_errno(GetLastError());
     180    else if (fMustBeDir & !(fAttr & FILE_ATTRIBUTE_DIRECTORY))
     181    {
     182        errno = ENOTDIR;
     183        rc = -1;
     184    }
     185    else
     186    {
     187        /*
     188         * Modify the attributes and try set them.
     189         */
     190        if (mode & _S_IWRITE)
     191            fAttr &= ~FILE_ATTRIBUTE_READONLY;
     192        else
     193            fAttr |= FILE_ATTRIBUTE_READONLY;
     194        if (!SetFileAttributes(pszPath, fAttr))
     195            rc = msc_set_errno(GetLastError());
     196    }
     197
     198    if (pszPathFree)
     199    {
     200        int saved_errno = errno;
     201        free(pszPathFree);
     202        errno = saved_errno;
     203    }
     204    return rc;
     205}
     206
     207
     208int msc_chmod(const char *pszPath, mode_t mode)
     209{
     210    int rc = 0;
     211    int saved_errno;
     212    int fMustBeDir;
     213    char *pszPathFree = msc_fix_path(&pszPath, &fMustBeDir);
     214
     215    /*
     216     * Get the current attributes.
     217     */
     218    DWORD fAttr = GetFileAttributes(pszPath);
     219    if (fAttr == INVALID_FILE_ATTRIBUTES)
     220        rc = msc_set_errno(GetLastError());
     221    else if (fMustBeDir & !(fAttr & FILE_ATTRIBUTE_DIRECTORY))
     222    {
     223        errno = ENOTDIR;
     224        rc = -1;
     225    }
     226    else if (fAttr & FILE_ATTRIBUTE_REPARSE_POINT)
     227    {
     228        errno = ENOSYS; /** @todo resolve symbolic link / rewrite to NtSetInformationFile. */
     229        rc = -1;
     230    }
     231    else
     232    {
     233        /*
     234         * Modify the attributes and try set them.
     235         */
     236        if (mode & _S_IWRITE)
     237            fAttr &= ~FILE_ATTRIBUTE_READONLY;
     238        else
     239            fAttr |= FILE_ATTRIBUTE_READONLY;
     240        if (!SetFileAttributes(pszPath, fAttr))
     241            rc = msc_set_errno(GetLastError());
     242    }
     243
     244    if (pszPathFree)
     245    {
     246        int saved_errno = errno;
     247        free(pszPathFree);
     248        errno = saved_errno;
     249    }
     250    return rc;
    46251}
    47252
Note: See TracChangeset for help on using the changeset viewer.