1 /* __LICENSE_HEADER_BEGIN__ */
4 * Copyright (C) 2012 Emmanuel Roullit <emmanuel.roullit@gmail.com>
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 2 of the License, or (at
9 * your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22 /* __LICENSE_HEADER_END__ */
29 #include <sys/types.h>
33 #include <dabbacore/strlcpy.h>
35 #define PROC_FD_PATH "/proc/self/fd/"
37 int fd_to_path(const int fd
, char *path
, const size_t path_len
)
39 char proc_path
[PATH_MAX
], fdstr
[16];
40 struct stat fd_stat
, path_stat
;
42 struct dirent
*dir_entry
;
50 memset(&proc_path
, 0, sizeof(proc_path
));
51 memset(&fd_stat
, 0, sizeof(fd_stat
));
52 memset(&resolved_path
, 0, sizeof(resolved_path
));
53 memset(&path_stat
, 0, sizeof(path_stat
));
54 memset(&fdstr
, 0, sizeof(fdstr
));
56 if (snprintf(fdstr
, sizeof(fdstr
), "%i", fd
) <= 0)
59 dir
= opendir(PROC_FD_PATH
);
64 /* /proc/self/fd/<fdstr> is a symlink to the actual file */
65 for (dir_entry
= readdir(dir
); dir_entry
; dir_entry
= readdir(dir
)) {
66 if (strcmp(dir_entry
->d_name
, fdstr
) == 0)
76 (proc_path
, sizeof(proc_path
), PROC_FD_PATH
"%s",
77 dir_entry
->d_name
) <= 0) {
82 if (fstat(fd
, &fd_stat
) < 0 || stat(proc_path
, &path_stat
) < 0) {
87 /* filenames are not accurate, interface and inode ID need to checked too */
88 if (fd_stat
.st_dev
!= path_stat
.st_dev
89 || fd_stat
.st_ino
!= path_stat
.st_ino
) {
94 /* resolve /proc/self/fd/<fdstr> symlink now */
95 resolved_path
= realpath(proc_path
, NULL
);
102 strlcpy(path
, resolved_path
, path_len
);