Changeset 3772


Ignore:
Timestamp:
Mar 15, 2012, 9:25:39 PM (13 years ago)
Author:
bird
Message:

Backported r3769: Reimplemented _fullpath to avoid changing the current directory and such (hazardous in multithreaded apps). Fixes #237.

Location:
branches/libc-0.6/src/emx/src/lib/misc
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/libc-0.6/src/emx/src/lib/misc

  • branches/libc-0.6/src/emx/src/lib/misc/fullpath.c

    r1632 r3772  
    1 /* fullpath.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 * EMX _fullpath().
     4 */
    25
     6/*
     7 * Copyright (c) 2012 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
     8 *
     9 * This file is part of kLibC.
     10 *
     11 * kLibC is free software; you can redistribute it and/or
     12 * modify it under the terms of the GNU Lesser General Public
     13 * License as published by the Free Software Foundation; either
     14 * version 2.1 of the License, or (at your option) any later version.
     15 *
     16 * kLibC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     19 * Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public
     22 * License along with kLibC; if not, write to the Free Software
     23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     24 *
     25 */
     26
     27/*******************************************************************************
     28* Header Files                                                                 *
     29*******************************************************************************/
    330#include "libc-alias.h"
    4 #include <direct.h>
    5 #include <stdio.h>
    631#include <stdlib.h>
    732#include <string.h>
    833#include <errno.h>
    9 #include <sys/param.h>
    10 #include <emx/syscalls.h>
    11 #include <emx/io.h>
    12 #include <InnoTekLIBC/libc.h>
     34#include <InnoTekLIBC/backend.h>
     35#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_IO
     36#include <InnoTekLIBC/logstrict.h>
    1337
    14 int _fullpath (char *dst, const char *src, int size)
     38
     39/**
     40 * This is the PC version of realpath with an EMX twist.
     41 *
     42 * The EMX twist is the return value.  VisualAge for C++ and Visual C++ returns
     43 * a char pointer and allow dynamic buffer allocation.  EMX returns 0 or -1.
     44 *
     45 * @returns 0 on success, -1 on failure and errno is set.  ERANGE is used to
     46 *          indicate insufficient buffer space.
     47 * @param   pszDst            The destination buffer.
     48 * @param   pszSrc            The relative path.
     49 * @param   cbDst             The size of the destination buffer (including the
     50 *                            terminator character).
     51 */
     52int _fullpath(char *pszDst, const char *pszSrc, int cbDst)
    1553{
    16   char drive, cwd1[MAXPATHLEN+1], cwd2[MAXPATHLEN+1];
    17   char *temp = NULL, c, *r;
    18   int j, k, add_file;
    19 
    20   /* drive stuff. */
    21   drive = _fngetdrive (src);
    22   if (drive == 0)
    23     drive = _getdrive ();
    24   else
    25     src += 2;
    26 
    27   /* save the cwd of the drive */
    28   if (!_getdcwd(drive - 'A' + 1, cwd1, sizeof(cwd1)))
    29     goto failure2;
    30 
    31   /* try change to the specified path. */
    32   add_file = 0; k = 0;
    33   if (chdir (src) != 0)
     54    int rc = __libc_Back_fsPathResolve(pszSrc, pszDst, cbDst, __LIBC_BACKFS_FLAGS_RESOLVE_FULL_MAYBE);
     55    if (rc == 0)
    3456    {
    35       int i = strlen (src);
    36       temp = (char *)alloca (i+2+1);
    37       temp[0] = drive; temp[1] = ':';
    38       strcpy (temp+2, src);
    39 
    40       k = _getname (temp) - temp;
    41       if (k == 3)
    42         {
    43           c = temp[k];
    44           temp[k] = '\0';
    45           if (chdir (temp) != 0)
    46             goto failure;
    47           temp[k] = c;
    48         }
    49       else if (k > 3)
    50         {
    51           temp[k-1] = '\0';
    52           if (chdir (temp) != 0)
    53             goto failure;
    54         }
    55       add_file = 1;
     57        while ((pszDst = strchr(pszDst, '/')) != NULL)
     58            *pszDst++ = '\\';
     59        return 0;
    5660    }
    5761
    58   /* get the changed path. */
    59   r = _getdcwd(drive - 'A' + 1, cwd2, sizeof(cwd2));
    60   if (_chdir (cwd1) != 0 || r == NULL)
    61     goto failure;
     62    /* failed */
     63    errno = -rc;
     64    if (cbDst)
     65        *pszDst = '\0';
     66    return -1;
     67}
    6268
    63   if (strlen (cwd2)+1 > size)
    64   {
    65       errno = ERANGE;
    66       goto failure;
    67   }
    68   strcpy (dst, cwd2);
    69   if (add_file && temp[k] != 0)
    70     {
    71       j = strlen (dst);
    72       if (j+1+strlen (temp+k)+1 > size)
    73       {
    74           errno = ERANGE;
    75           goto failure;
    76       }
    77       if (!_trslash (dst, j, 0))
    78         dst[j++] = !__libc_gfNoUnix ? '/' : '\\';
    79       strcpy (dst+j, temp+k);
    80     }
    81 
    82   if (!__libc_gfNoUnix)
    83     _fnslashify (dst);
    84   return 0;
    85 
    86 failure:
    87   chdir(cwd1);
    88 failure2:
    89   dst[0] = '\0';
    90   return -1;
    91 }
Note: See TracChangeset for help on using the changeset viewer.