]>
Commit | Line | Data |
---|---|---|
5bced64c MY |
1 | /* |
2 | * lsfd-fifo.c - handle associations opening fifo objects | |
3 | * | |
4 | * Copyright (C) 2021 Red Hat, Inc. All rights reserved. | |
5 | * Written by Masatake YAMATO <yamato@redhat.com> | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it would be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software Foundation, | |
19 | * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | */ | |
21 | ||
5bced64c MY |
22 | #include "lsfd.h" |
23 | ||
5211d5a1 MY |
24 | struct fifo { |
25 | struct file file; | |
26 | struct ipc_endpoint endpoint; | |
27 | }; | |
28 | ||
29 | struct fifo_ipc { | |
30 | struct ipc ipc; | |
31 | ino_t ino; | |
32 | }; | |
33 | ||
34 | static inline char *fifo_xstrendpoint(struct file *file) | |
35 | { | |
36 | char *str = NULL; | |
37 | xasprintf(&str, "%d,%s,%d%c%c", | |
38 | file->proc->pid, file->proc->command, file->association, | |
39 | (file->mode & S_IRUSR)? 'r': '-', | |
40 | (file->mode & S_IWUSR)? 'w': '-'); | |
41 | return str; | |
42 | } | |
43 | ||
5bced64c | 44 | static bool fifo_fill_column(struct proc *proc __attribute__((__unused__)), |
f54225c4 | 45 | struct file *file, |
5bced64c MY |
46 | struct libscols_line *ln, |
47 | int column_id, | |
48 | size_t column_index) | |
49 | { | |
50 | char *str = NULL; | |
51 | ||
52 | switch(column_id) { | |
53 | case COL_TYPE: | |
54 | if (scols_line_set_data(ln, column_index, "FIFO")) | |
55 | err(EXIT_FAILURE, _("failed to add output data")); | |
56 | return true; | |
618db964 | 57 | case COL_SOURCE: |
a500de34 MY |
58 | if (major(file->stat.st_dev) == 0 |
59 | && strncmp(file->name, "pipe:", 5) == 0) { | |
e0dc84da | 60 | str = xstrdup("pipefs"); |
a500de34 MY |
61 | break; |
62 | } | |
63 | return false; | |
5211d5a1 MY |
64 | case COL_ENDPOINTS: { |
65 | struct fifo *this = (struct fifo *)file; | |
66 | struct list_head *e; | |
e62d5873 | 67 | foreach_endpoint(e, this->endpoint) { |
55c857ae | 68 | char *estr; |
5211d5a1 MY |
69 | struct fifo *other = list_entry(e, struct fifo, endpoint.endpoints); |
70 | if (this == other) | |
71 | continue; | |
72 | if (str) | |
73 | xstrputc(&str, '\n'); | |
74 | estr = fifo_xstrendpoint(&other->file); | |
75 | xstrappend(&str, estr); | |
76 | free(estr); | |
77 | } | |
78 | if (!str) | |
79 | return false; | |
80 | break; | |
81 | } | |
5bced64c MY |
82 | default: |
83 | return false; | |
84 | } | |
85 | ||
86 | if (!str) | |
87 | err(EXIT_FAILURE, _("failed to add output data")); | |
88 | if (scols_line_refer_data(ln, column_index, str)) | |
89 | err(EXIT_FAILURE, _("failed to add output data")); | |
90 | return true; | |
91 | } | |
92 | ||
5211d5a1 MY |
93 | static unsigned int fifo_get_hash(struct file *file) |
94 | { | |
95 | return (unsigned int)(file->stat.st_ino % UINT_MAX); | |
96 | } | |
97 | ||
98 | static bool fifo_is_suitable_ipc(struct ipc *ipc, struct file *file) | |
99 | { | |
100 | return ((struct fifo_ipc *)ipc)->ino == file->stat.st_ino; | |
101 | } | |
102 | ||
54a06438 | 103 | static const struct ipc_class *fifo_get_ipc_class(struct file *file __attribute__((__unused__))) |
5211d5a1 | 104 | { |
54a06438 | 105 | static const struct ipc_class fifo_ipc_class = { |
79ec864e | 106 | .size = sizeof(struct fifo_ipc), |
5211d5a1 MY |
107 | .get_hash = fifo_get_hash, |
108 | .is_suitable_ipc = fifo_is_suitable_ipc, | |
109 | .free = NULL, | |
110 | }; | |
111 | return &fifo_ipc_class; | |
112 | } | |
113 | ||
114 | static void fifo_initialize_content(struct file *file) | |
115 | { | |
116 | struct fifo *fifo = (struct fifo *)file; | |
117 | struct ipc *ipc; | |
118 | unsigned int hash; | |
119 | ||
f9263edc | 120 | init_endpoint(&fifo->endpoint); |
5211d5a1 MY |
121 | ipc = get_ipc(file); |
122 | if (ipc) | |
123 | goto link; | |
124 | ||
79ec864e | 125 | ipc = new_ipc(fifo_get_ipc_class(file)); |
5211d5a1 MY |
126 | ((struct fifo_ipc *)ipc)->ino = file->stat.st_ino; |
127 | ||
128 | hash = fifo_get_hash(file); | |
129 | add_ipc(ipc, hash); | |
130 | link: | |
1c2ab17e | 131 | add_endpoint(&fifo->endpoint, ipc); |
5211d5a1 MY |
132 | } |
133 | ||
5bced64c MY |
134 | const struct file_class fifo_class = { |
135 | .super = &file_class, | |
5211d5a1 | 136 | .size = sizeof(struct fifo), |
5bced64c | 137 | .fill_column = fifo_fill_column, |
5211d5a1 | 138 | .initialize_content = fifo_initialize_content, |
5bced64c | 139 | .free_content = NULL, |
5211d5a1 | 140 | .get_ipc_class = fifo_get_ipc_class, |
5bced64c | 141 | }; |