File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libiconv / srclib / readlink.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 13:38:46 2021 UTC (3 years, 3 months ago) by misho
Branches: libiconv, MAIN
CVS tags: v1_16p0, HEAD
libiconv 1.16

    1: /* Stub for readlink().
    2:    Copyright (C) 2003-2007, 2009-2019 Free Software Foundation, Inc.
    3: 
    4:    This program is free software: you can redistribute it and/or modify
    5:    it under the terms of the GNU General Public License as published by
    6:    the Free Software Foundation; either version 3 of the License, or
    7:    (at your option) any later version.
    8: 
    9:    This program is distributed in the hope that it will be useful,
   10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12:    GNU General Public License for more details.
   13: 
   14:    You should have received a copy of the GNU General Public License
   15:    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
   16: 
   17: #include <config.h>
   18: 
   19: /* Specification.  */
   20: #include <unistd.h>
   21: 
   22: #include <errno.h>
   23: #include <string.h>
   24: #include <sys/stat.h>
   25: 
   26: #if !HAVE_READLINK
   27: 
   28: /* readlink() substitute for systems that don't have a readlink() function,
   29:    such as DJGPP 2.03 and mingw32.  */
   30: 
   31: ssize_t
   32: readlink (const char *name, char *buf _GL_UNUSED,
   33:           size_t bufsize _GL_UNUSED)
   34: {
   35:   struct stat statbuf;
   36: 
   37:   /* In general we should use lstat() here, not stat().  But on platforms
   38:      without symbolic links, lstat() - if it exists - would be equivalent to
   39:      stat(), therefore we can use stat().  This saves us a configure check.  */
   40:   if (stat (name, &statbuf) >= 0)
   41:     errno = EINVAL;
   42:   return -1;
   43: }
   44: 
   45: #else /* HAVE_READLINK */
   46: 
   47: # undef readlink
   48: 
   49: /* readlink() wrapper that uses correct types, for systems like cygwin
   50:    1.5.x where readlink returns int, and which rejects trailing slash,
   51:    for Solaris 9.  */
   52: 
   53: ssize_t
   54: rpl_readlink (const char *name, char *buf, size_t bufsize)
   55: {
   56: # if READLINK_TRAILING_SLASH_BUG
   57:   size_t len = strlen (name);
   58:   if (len && name[len - 1] == '/')
   59:     {
   60:       /* Even if name without the slash is a symlink to a directory,
   61:          both lstat() and stat() must resolve the trailing slash to
   62:          the directory rather than the symlink.  We can therefore
   63:          safely use stat() to distinguish between EINVAL and
   64:          ENOTDIR/ENOENT, avoiding extra overhead of rpl_lstat().  */
   65:       struct stat st;
   66:       if (stat (name, &st) == 0)
   67:         errno = EINVAL;
   68:       return -1;
   69:     }
   70: # endif /* READLINK_TRAILING_SLASH_BUG */
   71:   return readlink (name, buf, bufsize);
   72: }
   73: 
   74: #endif /* HAVE_READLINK */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>