source: trunk/third/findutils/lib/xstat.in @ 18890

Revision 18890, 3.4 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18889, which included commits to RCS files with non-trunk default branches.
Line 
1/* @IGNORE@ -*- c -*- */
2/* @IGNORE@ This file is a template from which both stat.c and lstat.c
3   @IGNORE@ are generated. */
4/* Work around the bug in some systems whereby @xstat@ succeeds when
5   given the zero-length file name argument.  The @xstat@ from SunOS4.1.4
6   has this bug.
7   Copyright (C) 1997-2000 Free Software Foundation, Inc.
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2, or (at your option)
12   any later version.
13
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software Foundation,
21   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
23/* written by Jim Meyering */
24
25#include <config.h>
26
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <errno.h>
30#ifndef errno
31extern int errno;
32#endif
33@BEGIN_LSTAT_ONLY@
34
35#ifdef STAT_MACROS_BROKEN
36# undef S_ISLNK
37#endif
38#if !defined(S_ISLNK) && defined(S_IFLNK)
39# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
40#endif
41
42char *xmalloc ();
43
44/* lstat works different on Linux and Solaris systems.  POSIX (see
45   `pathname resolution' in the glossary) requires that programs like `ls'
46   take into consideration the fact that FILE has a trailing slash when
47   FILE is a symbolic link.  On Linux systems, the lstat function already
48   has the desired semantics (in treating `lstat("symlink/",sbuf)' just like
49   `lstat("symlink/.",sbuf)', but on Solaris it does not.
50
51   If FILE has a trailing slash and specifies a symbolic link,
52   then append a `.' to FILE and call lstat a second time.  */
53
54static int
55slash_aware_lstat (const char *file, struct stat *sbuf)
56{
57  size_t len;
58  char *new_file;
59
60  int lstat_result = lstat (file, sbuf);
61
62  if (lstat_result != 0 || !S_ISLNK (sbuf->st_mode))
63    return lstat_result;
64
65  len = strlen (file);
66  if (file[len - 1] != '/')
67    return lstat_result;
68
69  /* FILE refers to a symbolic link and the name ends with a slash.
70     Append a `.' to FILE and repeat the lstat call.  */
71
72  /* Add one for the `.' we might have to append, and one more
73     for the trailing NUL.  */
74  new_file = xmalloc (len + 1 + 1);
75  memcpy (new_file, file, len);
76  new_file[len] = '.';
77  new_file[len + 1] = 0;
78
79  lstat_result = lstat (new_file, sbuf);
80  free (new_file);
81
82  return lstat_result;
83}
84@END_LSTAT_ONLY@
85
86/* This is a wrapper for @xstat@(2).
87   If FILE is the empty string, fail with errno == ENOENT.
88   Otherwise, return the result of calling the real @xstat@.
89
90   This works around the bug in some systems whereby @xstat@ succeeds when
91   given the zero-length file name argument.  The @xstat@ from SunOS4.1.4
92   has this bug.  */
93@BEGIN_LSTAT_ONLY@
94
95/* This function also provides a version of lstat with consistent semantics
96   when FILE specifies a symbolic link and has a trailing slash.  */
97@END_LSTAT_ONLY@
98
99int
100rpl_@xstat@ (const char *file, struct stat *sbuf)
101{
102  if (file && *file == 0)
103    {
104      errno = ENOENT;
105      return -1;
106    }
107
108@BEGIN_LSTAT_ONLY@
109  return slash_aware_lstat (file, sbuf);
110@END_LSTAT_ONLY@
111@BEGIN_STAT_ONLY@
112  return stat (file, sbuf);
113@END_STAT_ONLY@
114}
Note: See TracBrowser for help on using the repository browser.