(root)/
util-linux-2.39/
misc-utils/
lsfd-fifo.c
       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  
      22  #include "xalloc.h"
      23  #include "nls.h"
      24  #include "libsmartcols.h"
      25  
      26  #include "lsfd.h"
      27  
      28  struct fifo {
      29  	struct file file;
      30  	struct ipc_endpoint endpoint;
      31  };
      32  
      33  struct fifo_ipc {
      34  	struct ipc ipc;
      35  	ino_t ino;
      36  };
      37  
      38  static inline char *fifo_xstrendpoint(struct file *file)
      39  {
      40  	char *str = NULL;
      41  	xasprintf(&str, "%d,%s,%d%c%c",
      42  		  file->proc->pid, file->proc->command, file->association,
      43  		  (file->mode & S_IRUSR)? 'r': '-',
      44  		  (file->mode & S_IWUSR)? 'w': '-');
      45  	return str;
      46  }
      47  
      48  static bool fifo_fill_column(struct proc *proc __attribute__((__unused__)),
      49  			     struct file *file,
      50  			     struct libscols_line *ln,
      51  			     int column_id,
      52  			     size_t column_index)
      53  {
      54  	char *str = NULL;
      55  
      56  	switch(column_id) {
      57  	case COL_TYPE:
      58  		if (scols_line_set_data(ln, column_index, "FIFO"))
      59  			err(EXIT_FAILURE, _("failed to add output data"));
      60  		return true;
      61  	case COL_SOURCE:
      62  		if (major(file->stat.st_dev) == 0
      63  		    && strncmp(file->name, "pipe:", 5) == 0) {
      64  			str = xstrdup("pipefs");
      65  			break;
      66  		}
      67  		return false;
      68  	case COL_ENDPOINTS: {
      69  		struct fifo *this = (struct fifo *)file;
      70  		struct list_head *e;
      71  		char *estr;
      72  		list_for_each_backwardly(e, &this->endpoint.ipc->endpoints) {
      73  			struct fifo *other = list_entry(e, struct fifo, endpoint.endpoints);
      74  			if (this == other)
      75  				continue;
      76  			if (str)
      77  				xstrputc(&str, '\n');
      78  			estr = fifo_xstrendpoint(&other->file);
      79  			xstrappend(&str, estr);
      80  			free(estr);
      81  		}
      82  		if (!str)
      83  			return false;
      84  		break;
      85  	}
      86  	default:
      87  		return false;
      88  	}
      89  
      90  	if (!str)
      91  		err(EXIT_FAILURE, _("failed to add output data"));
      92  	if (scols_line_refer_data(ln, column_index, str))
      93  		err(EXIT_FAILURE, _("failed to add output data"));
      94  	return true;
      95  }
      96  
      97  static unsigned int fifo_get_hash(struct file *file)
      98  {
      99  	return (unsigned int)(file->stat.st_ino % UINT_MAX);
     100  }
     101  
     102  static bool fifo_is_suitable_ipc(struct ipc *ipc, struct file *file)
     103  {
     104  	return ((struct fifo_ipc *)ipc)->ino == file->stat.st_ino;
     105  }
     106  
     107  static const struct ipc_class *fifo_get_ipc_class(struct file *file __attribute__((__unused__)))
     108  {
     109  	static const struct ipc_class fifo_ipc_class = {
     110  		.get_hash = fifo_get_hash,
     111  		.is_suitable_ipc = fifo_is_suitable_ipc,
     112  		.free = NULL,
     113  	};
     114  	return &fifo_ipc_class;
     115  }
     116  
     117  static void fifo_initialize_content(struct file *file)
     118  {
     119  	struct fifo *fifo = (struct fifo *)file;
     120  	struct ipc *ipc;
     121  	unsigned int hash;
     122  
     123  	INIT_LIST_HEAD(&fifo->endpoint.endpoints);
     124  	ipc = get_ipc(file);
     125  	if (ipc)
     126  		goto link;
     127  
     128  	ipc = xmalloc(sizeof(struct fifo_ipc));
     129  	ipc->class = fifo_get_ipc_class(file);
     130  	INIT_LIST_HEAD(&ipc->endpoints);
     131  	INIT_LIST_HEAD(&ipc->ipcs);
     132  	((struct fifo_ipc *)ipc)->ino = file->stat.st_ino;
     133  
     134  	hash = fifo_get_hash(file);
     135  	add_ipc(ipc, hash);
     136   link:
     137  	fifo->endpoint.ipc = ipc;
     138  	list_add(&fifo->endpoint.endpoints, &ipc->endpoints);
     139  }
     140  
     141  const struct file_class fifo_class = {
     142  	.super = &file_class,
     143  	.size = sizeof(struct fifo),
     144  	.fill_column = fifo_fill_column,
     145  	.initialize_content = fifo_initialize_content,
     146  	.free_content = NULL,
     147  	.get_ipc_class = fifo_get_ipc_class,
     148  };