2 * libdpkg - Debian packaging suite library routines
3 * file.c - file handling functions
5 * Copyright © 1994, 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2008-2012 Guillem Jover <guillem@debian.org>
8 * This is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 #include <sys/types.h>
32 #include <dpkg/dpkg.h>
33 #include <dpkg/i18n.h>
34 #include <dpkg/pager.h>
35 #include <dpkg/fdio.h>
36 #include <dpkg/buffer.h>
37 #include <dpkg/file.h>
40 * Check whether a filename is executable.
42 * @param filename The filename to check.
45 file_is_exec(const char *filename
)
49 if (stat(filename
, &st
) < 0)
52 if (!S_ISREG(st
.st_mode
))
55 return st
.st_mode
& 0111;
59 * Copy file ownership and permissions from one file to another.
61 * @param src The source filename.
62 * @param dst The destination filename.
65 file_copy_perms(const char *src
, const char *dst
)
69 if (stat(src
, &stab
) == -1) {
72 ohshite(_("unable to stat source file '%.250s'"), src
);
75 if (chown(dst
, stab
.st_uid
, stab
.st_gid
) == -1)
76 ohshite(_("unable to change ownership of target file '%.250s'"),
79 if (chmod(dst
, (stab
.st_mode
& ~S_IFMT
)) == -1)
80 ohshite(_("unable to set mode of target file '%.250s'"), dst
);
84 file_slurp_fd(int fd
, const char *filename
, struct varbuf
*vb
,
85 struct dpkg_error
*err
)
89 if (fstat(fd
, &st
) < 0)
90 return dpkg_put_errno(err
, _("cannot stat %s"), filename
);
92 if (!S_ISREG(st
.st_mode
))
93 return dpkg_put_error(err
, _("%s is not a regular file"),
99 varbuf_init(vb
, st
.st_size
);
100 if (fd_read(fd
, vb
->buf
, st
.st_size
) < 0)
101 return dpkg_put_errno(err
, _("cannot read %s"), filename
);
102 vb
->used
= st
.st_size
;
108 file_slurp(const char *filename
, struct varbuf
*vb
, struct dpkg_error
*err
)
115 fd
= open(filename
, O_RDONLY
);
117 return dpkg_put_errno(err
, _("cannot open %s"), filename
);
119 rc
= file_slurp_fd(fd
, filename
, vb
, err
);
127 file_lock_setup(struct flock
*fl
, short type
)
130 fl
->l_whence
= SEEK_SET
;
137 * Unlock a previously locked file.
140 file_unlock(int lockfd
, const char *lockfile
, const char *lockdesc
)
145 internerr("%s (%s) fd is %d < 0", lockdesc
, lockfile
, lockfd
);
147 file_lock_setup(&fl
, F_UNLCK
);
149 if (fcntl(lockfd
, F_SETLK
, &fl
) == -1)
150 ohshite(_("unable to unlock %s"), lockdesc
);
154 file_unlock_cleanup(int argc
, void **argv
)
156 int lockfd
= *(int *)argv
[0];
157 const char *lockfile
= argv
[1];
158 const char *lockdesc
= argv
[2];
160 file_unlock(lockfd
, lockfile
, lockdesc
);
164 * Check if a file has a lock acquired.
166 * @param lockfd The file descriptor for the lock.
167 * @param filename The file name associated to the file descriptor.
170 file_is_locked(int lockfd
, const char *filename
)
174 file_lock_setup(&fl
, F_WRLCK
);
176 if (fcntl(lockfd
, F_GETLK
, &fl
) == -1)
177 ohshit(_("unable to check file '%s' lock status"), filename
);
179 if (fl
.l_type
== F_WRLCK
&& fl
.l_pid
!= getpid())
188 * @param lockfd The pointer to the lock file descriptor. It must be allocated
189 * statically as its addresses is passed to a cleanup handler.
190 * @param flags The lock flags specifying what type of locking to perform.
191 * @param filename The name of the file to lock.
192 * @param desc The description of the file to lock.
195 file_lock(int *lockfd
, enum file_lock_flags flags
, const char *filename
,
201 setcloexec(*lockfd
, filename
);
203 file_lock_setup(&fl
, F_WRLCK
);
205 if (flags
== FILE_LOCK_WAIT
)
210 if (fcntl(*lockfd
, lock_cmd
, &fl
) == -1) {
213 if (errno
!= EACCES
&& errno
!= EAGAIN
)
214 ohshite(_("unable to lock %s"), desc
);
216 warnmsg
= _("Note: removing the lock file is always wrong, "
217 "can damage the locked area\n"
218 "and the entire system. "
219 "See <https://wiki.debian.org/Teams/Dpkg/FAQ#db-lock>.");
221 file_lock_setup(&fl
, F_WRLCK
);
222 if (fcntl(*lockfd
, F_GETLK
, &fl
) == -1)
223 ohshit(_("%s was locked by another process\n%s"),
226 ohshit(_("%s was locked by another process with pid %d\n%s"),
227 desc
, fl
.l_pid
, warnmsg
);
230 push_cleanup(file_unlock_cleanup
, ~0, 3, lockfd
, filename
, desc
);
234 file_show(const char *filename
)
237 struct dpkg_error err
;
240 if (filename
== NULL
)
241 internerr("filename is NULL");
243 fd
= open(filename
, O_RDONLY
);
245 ohshite(_("cannot open file %s"), filename
);
247 pager
= pager_spawn(_("pager to show file"));
248 rc
= fd_fd_copy(fd
, STDOUT_FILENO
, -1, &err
);
253 if (rc
< 0 && err
.syserrno
!= EPIPE
) {
254 errno
= err
.syserrno
;
255 ohshite(_("cannot write file %s into the pager"), filename
);