OpenCoverage

careadlinkat.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/coreutils/src/gnulib/lib/careadlinkat.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* Read symbolic links into a buffer without size limitation, relative to fd.-
2-
3 Copyright (C) 2001, 2003-2004, 2007, 2009-2018 Free Software Foundation,-
4 Inc.-
5-
6 This program is free software: you can redistribute it and/or modify-
7 it under the terms of the GNU General Public License as published by-
8 the Free Software Foundation; either version 3 of the License, or-
9 (at your option) any later version.-
10-
11 This program is distributed in the hope that it will be useful,-
12 but WITHOUT ANY WARRANTY; without even the implied warranty of-
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-
14 GNU General Public License for more details.-
15-
16 You should have received a copy of the GNU General Public License-
17 along with this program. If not, see <https://www.gnu.org/licenses/>. */-
18-
19/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */-
20-
21#include <config.h>-
22-
23#include "careadlinkat.h"-
24-
25#include <errno.h>-
26#include <limits.h>-
27#include <string.h>-
28#include <unistd.h>-
29-
30/* Define this independently so that stdint.h is not a prerequisite. */-
31#ifndef SIZE_MAX-
32# define SIZE_MAX ((size_t) -1)-
33#endif-
34-
35#ifndef SSIZE_MAX-
36# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))-
37#endif-
38-
39#include "allocator.h"-
40-
41/* Assuming the current directory is FD, get the symbolic link value-
42 of FILENAME as a null-terminated string and put it into a buffer.-
43 If FD is AT_FDCWD, FILENAME is interpreted relative to the current-
44 working directory, as in openat.-
45-
46 If the link is small enough to fit into BUFFER put it there.-
47 BUFFER's size is BUFFER_SIZE, and BUFFER can be null-
48 if BUFFER_SIZE is zero.-
49-
50 If the link is not small, put it into a dynamically allocated-
51 buffer managed by ALLOC. It is the caller's responsibility to free-
52 the returned value if it is nonnull and is not BUFFER. A null-
53 ALLOC stands for the standard allocator.-
54-
55 The PREADLINKAT function specifies how to read links. It operates-
56 like POSIX readlinkat()-
57 <http://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html>-
58 but can assume that its first argument is the same as FD.-
59-
60 If successful, return the buffer address; otherwise return NULL and-
61 set errno. */-
62-
63char *-
64careadlinkat (int fd, char const *filename,-
65 char *buffer, size_t buffer_size,-
66 struct allocator const *alloc,-
67 ssize_t (*preadlinkat) (int, char const *, char *, size_t))-
68{-
69 char *buf;-
70 size_t buf_size;-
71 size_t buf_size_max =-
72 SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
0x7fffffffffff... ((size_t) -1)Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • stdbuf
FALSEnever evaluated
0-2
73 char stack_buf[1024];-
74-
75 if (! alloc)
! allocDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • stdbuf
FALSEnever evaluated
0-2
76 alloc = &stdlib_allocator;
executed 2 times by 1 test: alloc = &stdlib_allocator;
Executed by:
  • stdbuf
2
77-
78 if (! buffer_size)
! buffer_sizeDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • stdbuf
FALSEnever evaluated
0-2
79 {-
80 /* Allocate the initial buffer on the stack. This way, in the-
81 common case of a symlink of small size, we get away with a-
82 single small malloc() instead of a big malloc() followed by a-
83 shrinking realloc(). */-
84 buffer = stack_buf;-
85 buffer_size = sizeof stack_buf;-
86 }
executed 2 times by 1 test: end of block
Executed by:
  • stdbuf
2
87-
88 buf = buffer;-
89 buf_size = buffer_size;-
90-
91 do-
92 {-
93 /* Attempt to read the link into the current buffer. */-
94 ssize_t link_length = preadlinkat (fd, filename, buf, buf_size);-
95 size_t link_size;-
96 if (link_length < 0)
link_length < 0Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • stdbuf
0-2
97 {-
98 /* On AIX 5L v5.3 and HP-UX 11i v2 04/09, readlink returns -1-
99 with errno == ERANGE if the buffer is too small. */-
100 int readlinkat_errno = errno;-
101 if (readlinkat_errno != ERANGE)
readlinkat_errno != 34Description
TRUEnever evaluated
FALSEnever evaluated
0
102 {-
103 if (buf != buffer)
buf != bufferDescription
TRUEnever evaluated
FALSEnever evaluated
0
104 {-
105 alloc->free (buf);-
106 errno = readlinkat_errno;-
107 }
never executed: end of block
0
108 return NULL;
never executed: return ((void *)0) ;
0
109 }-
110 }
never executed: end of block
0
111-
112 link_size = link_length;-
113-
114 if (link_size < buf_size)
link_size < buf_sizeDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • stdbuf
FALSEnever evaluated
0-2
115 {-
116 buf[link_size++] = '\0';-
117-
118 if (buf == stack_buf)
buf == stack_bufDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • stdbuf
FALSEnever evaluated
0-2
119 {-
120 char *b = (char *) alloc->allocate (link_size);-
121 buf_size = link_size;-
122 if (! b)
! bDescription
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • stdbuf
0-2
123 break;
never executed: break;
0
124 memcpy (b, buf, link_size);-
125 buf = b;-
126 }
executed 2 times by 1 test: end of block
Executed by:
  • stdbuf
2
127 else if (link_size < buf_size && buf != buffer && alloc->reallocate)
link_size < buf_sizeDescription
TRUEnever evaluated
FALSEnever evaluated
buf != bufferDescription
TRUEnever evaluated
FALSEnever evaluated
alloc->reallocateDescription
TRUEnever evaluated
FALSEnever evaluated
0
128 {-
129 /* Shrink BUF before returning it. */-
130 char *b = (char *) alloc->reallocate (buf, link_size);-
131 if (b)
bDescription
TRUEnever evaluated
FALSEnever evaluated
0
132 buf = b;
never executed: buf = b;
0
133 }
never executed: end of block
0
134-
135 return buf;
executed 2 times by 1 test: return buf;
Executed by:
  • stdbuf
2
136 }-
137-
138 if (buf != buffer)
buf != bufferDescription
TRUEnever evaluated
FALSEnever evaluated
0
139 alloc->free (buf);
never executed: alloc->free (buf);
0
140-
141 if (buf_size <= buf_size_max / 2)
buf_size <= buf_size_max / 2Description
TRUEnever evaluated
FALSEnever evaluated
0
142 buf_size *= 2;
never executed: buf_size *= 2;
0
143 else if (buf_size < buf_size_max)
buf_size < buf_size_maxDescription
TRUEnever evaluated
FALSEnever evaluated
0
144 buf_size = buf_size_max;
never executed: buf_size = buf_size_max;
0
145 else if (buf_size_max < SIZE_MAX)
buf_size_max < ((size_t) -1)Description
TRUEnever evaluated
FALSEnever evaluated
0
146 {-
147 errno = ENAMETOOLONG;-
148 return NULL;
never executed: return ((void *)0) ;
0
149 }-
150 else-
151 break;
never executed: break;
0
152 buf = (char *) alloc->allocate (buf_size);-
153 }
never executed: end of block
0
154 while (buf);
bufDescription
TRUEnever evaluated
FALSEnever evaluated
0
155-
156 if (alloc->die)
alloc->dieDescription
TRUEnever evaluated
FALSEnever evaluated
0
157 alloc->die (buf_size);
never executed: alloc->die (buf_size);
0
158 errno = ENOMEM;-
159 return NULL;
never executed: return ((void *)0) ;
0
160}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2