OpenCoverage

force-link.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/coreutils/src/src/force-link.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* Implement ln -f "atomically"-
2-
3 Copyright 2017-2018 Free Software Foundation, Inc.-
4-
5 This program is free software: you can redistribute it and/or modify-
6 it under the terms of the GNU General Public License as published by-
7 the Free Software Foundation, either version 3 of the License, or-
8 (at your option) any later version.-
9-
10 This program is distributed in the hope that it will be useful,-
11 but WITHOUT ANY WARRANTY; without even the implied warranty of-
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-
13 GNU General Public License for more details.-
14-
15 You should have received a copy of the GNU General Public License-
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */-
17-
18/* Written by Paul Eggert. */-
19-
20/* A naive "ln -f A B" unlinks B and then links A to B. This module-
21 instead links A to a randomly-named temporary T in B's directory,-
22 and then renames T to B. This approach has a window with a-
23 randomly-named temporary, which is safer for many applications than-
24 a window where B does not exist. */-
25-
26#include <config.h>-
27#include "system.h"-
28-
29#include "force-link.h"-
30-
31#include <tempname.h>-
32-
33/* A basename pattern suitable for a temporary file. It should work-
34 even on file systems like FAT that support only short names.-
35 "Cu" is short for "Coreutils" or for "Changeable unstable",-
36 take your pick.... */-
37-
38static char const simple_pattern[] = "CuXXXXXX";-
39enum { x_suffix_len = sizeof "XXXXXX" - 1 };-
40-
41/* A size for smallish buffers containing file names. Longer file-
42 names can use malloc. */-
43-
44enum { smallsize = 256 };-
45-
46/* Return a template for a file in the same directory as DSTNAME.-
47 Use BUF if the template fits, otherwise use malloc and return NULL-
48 (setting errno) if unsuccessful. */-
49-
50static char *-
51samedir_template (char const *dstname, char buf[smallsize])-
52{-
53 ptrdiff_t dstdirlen = last_component (dstname) - dstname;-
54 size_t dsttmpsize = dstdirlen + sizeof simple_pattern;-
55 char *dsttmp;-
56 if (dsttmpsize <= smallsize)
dsttmpsize <= smallsizeDescription
TRUEevaluated 30 times by 3 tests
Evaluated by:
  • cp
  • ln
  • mv
FALSEnever evaluated
0-30
57 dsttmp = buf;
executed 30 times by 3 tests: dsttmp = buf;
Executed by:
  • cp
  • ln
  • mv
30
58 else-
59 {-
60 dsttmp = malloc (dsttmpsize);-
61 if (!dsttmp)
!dsttmpDescription
TRUEnever evaluated
FALSEnever evaluated
0
62 return dsttmp;
never executed: return dsttmp;
0
63 }
never executed: end of block
0
64 strcpy (mempcpy (dsttmp, dstname, dstdirlen), simple_pattern);-
65 return dsttmp;
executed 30 times by 3 tests: return dsttmp;
Executed by:
  • cp
  • ln
  • mv
30
66}-
67-
68-
69/* Auxiliaries for force_linkat. */-
70-
71struct link_arg-
72{-
73 int srcdir;-
74 char const *srcname;-
75 int dstdir;-
76 int flags;-
77};-
78-
79static int-
80try_link (char *dest, void *arg)-
81{-
82 struct link_arg *a = arg;-
83 return linkat (a->srcdir, a->srcname, a->dstdir, dest, a->flags);
executed 19 times by 3 tests: return linkat (a->srcdir, a->srcname, a->dstdir, dest, a->flags);
Executed by:
  • cp
  • ln
  • mv
19
84}-
85-
86/* Hard-link directory SRCDIR's file SRCNAME to directory DSTDIR's-
87 file DSTNAME, using linkat-style FLAGS to control the linking.-
88 If FORCE and DSTNAME already exists, replace it atomically. Return-
89 1 if successful and DSTNAME already existed,-
90 0 if successful and DSTNAME did not already exist, and-
91 -1 (setting errno) on failure. */-
92extern int-
93force_linkat (int srcdir, char const *srcname,-
94 int dstdir, char const *dstname, int flags, bool force)-
95{-
96 int r = linkat (srcdir, srcname, dstdir, dstname, flags);-
97 if (!force || r == 0 || errno != EEXIST)
!forceDescription
TRUEevaluated 30103 times by 2 tests
Evaluated by:
  • cp
  • ln
FALSEevaluated 37 times by 3 tests
Evaluated by:
  • cp
  • ln
  • mv
r == 0Description
TRUEevaluated 18 times by 3 tests
Evaluated by:
  • cp
  • ln
  • mv
FALSEevaluated 19 times by 3 tests
Evaluated by:
  • cp
  • ln
  • mv
(*__errno_location ()) != 17Description
TRUEnever evaluated
FALSEevaluated 19 times by 3 tests
Evaluated by:
  • cp
  • ln
  • mv
0-30103
98 return r;
executed 30121 times by 3 tests: return r;
Executed by:
  • cp
  • ln
  • mv
30121
99-
100 char buf[smallsize];-
101 char *dsttmp = samedir_template (dstname, buf);-
102 if (! dsttmp)
! dsttmpDescription
TRUEnever evaluated
FALSEevaluated 19 times by 3 tests
Evaluated by:
  • cp
  • ln
  • mv
0-19
103 return -1;
never executed: return -1;
0
104 struct link_arg arg = { srcdir, srcname, dstdir, flags };-
105 int err;-
106-
107 if (try_tempname_len (dsttmp, 0, &arg, try_link, x_suffix_len) != 0)
try_tempname_l...ffix_len) != 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • cp
FALSEevaluated 18 times by 3 tests
Evaluated by:
  • cp
  • ln
  • mv
1-18
108 err = errno;
executed 1 time by 1 test: err = (*__errno_location ()) ;
Executed by:
  • cp
1
109 else-
110 {-
111 err = renameat (dstdir, dsttmp, dstdir, dstname) == 0 ? 0 : errno;
renameat (dstd... dstname) == 0Description
TRUEevaluated 18 times by 3 tests
Evaluated by:
  • cp
  • ln
  • mv
FALSEnever evaluated
0-18
112 /* Unlink DSTTMP even if renameat succeeded, in case DSTTMP-
113 and DSTNAME were already the same hard link and renameat-
114 was a no-op. */-
115 unlinkat (dstdir, dsttmp, 0);-
116 }
executed 18 times by 3 tests: end of block
Executed by:
  • cp
  • ln
  • mv
18
117-
118 if (dsttmp != buf)
dsttmp != bufDescription
TRUEnever evaluated
FALSEevaluated 19 times by 3 tests
Evaluated by:
  • cp
  • ln
  • mv
0-19
119 free (dsttmp);
never executed: free (dsttmp);
0
120 if (!err)
!errDescription
TRUEevaluated 18 times by 3 tests
Evaluated by:
  • cp
  • ln
  • mv
FALSEevaluated 1 time by 1 test
Evaluated by:
  • cp
1-18
121 return 1;
executed 18 times by 3 tests: return 1;
Executed by:
  • cp
  • ln
  • mv
18
122 errno = err;-
123 return -1;
executed 1 time by 1 test: return -1;
Executed by:
  • cp
1
124}-
125-
126-
127/* Auxiliaries for force_symlinkat. */-
128-
129struct symlink_arg-
130{-
131 char const *srcname;-
132 int dstdir;-
133};-
134-
135static int-
136try_symlink (char *dest, void *arg)-
137{-
138 struct symlink_arg *a = arg;-
139 return symlinkat (a->srcname, a->dstdir, dest);
executed 11 times by 2 tests: return symlinkat (a->srcname, a->dstdir, dest);
Executed by:
  • cp
  • ln
11
140}-
141-
142/* Create a symlink containing SRCNAME in directory DSTDIR's file DSTNAME.-
143 If FORCE and DSTNAME already exists, replace it atomically. Return-
144 1 if successful and DSTNAME already existed,-
145 0 if successful and DSTNAME did not already exist, and-
146 -1 (setting errno) on failure. */-
147extern int-
148force_symlinkat (char const *srcname, int dstdir, char const *dstname,-
149 bool force)-
150{-
151 int r = symlinkat (srcname, dstdir, dstname);-
152 if (!force || r == 0 || errno != EEXIST)
!forceDescription
TRUEevaluated 651 times by 3 tests
Evaluated by:
  • cp
  • ln
  • mv
FALSEevaluated 57 times by 2 tests
Evaluated by:
  • cp
  • ln
r == 0Description
TRUEevaluated 46 times by 2 tests
Evaluated by:
  • cp
  • ln
FALSEevaluated 11 times by 2 tests
Evaluated by:
  • cp
  • ln
(*__errno_location ()) != 17Description
TRUEnever evaluated
FALSEevaluated 11 times by 2 tests
Evaluated by:
  • cp
  • ln
0-651
153 return r;
executed 697 times by 3 tests: return r;
Executed by:
  • cp
  • ln
  • mv
697
154-
155 char buf[smallsize];-
156 char *dsttmp = samedir_template (dstname, buf);-
157 if (!dsttmp)
!dsttmpDescription
TRUEnever evaluated
FALSEevaluated 11 times by 2 tests
Evaluated by:
  • cp
  • ln
0-11
158 return -1;
never executed: return -1;
0
159 struct symlink_arg arg = { srcname, dstdir };-
160 int err;-
161-
162 if (try_tempname_len (dsttmp, 0, &arg, try_symlink, x_suffix_len) != 0)
try_tempname_l...ffix_len) != 0Description
TRUEnever evaluated
FALSEevaluated 11 times by 2 tests
Evaluated by:
  • cp
  • ln
0-11
163 err = errno;
never executed: err = (*__errno_location ()) ;
0
164 else if (renameat (dstdir, dsttmp, dstdir, dstname) != 0)
renameat (dstd... dstname) != 0Description
TRUEnever evaluated
FALSEevaluated 11 times by 2 tests
Evaluated by:
  • cp
  • ln
0-11
165 {-
166 err = errno;-
167 unlinkat (dstdir, dsttmp, 0);-
168 }
never executed: end of block
0
169 else-
170 {-
171 /* Don't worry about renameat being a no-op, since DSTTMP is-
172 newly created. */-
173 err = 0;-
174 }
executed 11 times by 2 tests: end of block
Executed by:
  • cp
  • ln
11
175-
176 if (dsttmp != buf)
dsttmp != bufDescription
TRUEnever evaluated
FALSEevaluated 11 times by 2 tests
Evaluated by:
  • cp
  • ln
0-11
177 free (dsttmp);
never executed: free (dsttmp);
0
178 if (!err)
!errDescription
TRUEevaluated 11 times by 2 tests
Evaluated by:
  • cp
  • ln
FALSEnever evaluated
0-11
179 return 1;
executed 11 times by 2 tests: return 1;
Executed by:
  • cp
  • ln
11
180 errno = err;-
181 return -1;
never executed: return -1;
0
182}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2