(root)/
util-linux-2.39/
sys-utils/
ipcmk.c
       1  /*
       2   *  ipcmk.c - used to create ad-hoc IPC segments
       3   *
       4   *  Copyright (C) 2008 Hayden A. James (hayden.james@gmail.com)
       5   *  Copyright (C) 2008 Karel Zak <kzak@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 will 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 along
      18   * with this program; if not, write to the Free Software Foundation, Inc.,
      19   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      20   */
      21  
      22  #include <errno.h>
      23  #include <getopt.h>
      24  #include <stddef.h>
      25  #include <stdio.h>
      26  #include <stdlib.h>
      27  #include <sys/ipc.h>
      28  #include <sys/msg.h>
      29  #include <sys/sem.h>
      30  #include <sys/shm.h>
      31  #include <sys/time.h>
      32  
      33  #include "c.h"
      34  #include "nls.h"
      35  #include "randutils.h"
      36  #include "strutils.h"
      37  #include "closestream.h"
      38  
      39  static int create_shm(size_t size, int permission)
      40  {
      41  	key_t key;
      42  
      43  	ul_random_get_bytes(&key, sizeof(key));
      44  	return shmget(key, size, permission | IPC_CREAT);
      45  }
      46  
      47  static int create_msg(int permission)
      48  {
      49  	key_t key;
      50  
      51  	ul_random_get_bytes(&key, sizeof(key));
      52  	return msgget(key, permission | IPC_CREAT);
      53  }
      54  
      55  static int create_sem(int nsems, int permission)
      56  {
      57  	key_t key;
      58  
      59  	ul_random_get_bytes(&key, sizeof(key));
      60  	return semget(key, nsems, permission | IPC_CREAT);
      61  }
      62  
      63  static void __attribute__((__noreturn__)) usage(void)
      64  {
      65  	FILE *out = stdout;
      66  	fputs(USAGE_HEADER, out);
      67  	fprintf(out, _(" %s [options]\n"), program_invocation_short_name);
      68  
      69  	fputs(USAGE_SEPARATOR, out);
      70  	fputs(_("Create various IPC resources.\n"), out);
      71  
      72  	fputs(USAGE_OPTIONS, out);
      73  	fputs(_(" -M, --shmem <size>       create shared memory segment of size <size>\n"), out);
      74  	fputs(_(" -S, --semaphore <number> create semaphore array with <number> elements\n"), out);
      75  	fputs(_(" -Q, --queue              create message queue\n"), out);
      76  	fputs(_(" -p, --mode <mode>        permission for the resource (default is 0644)\n"), out);
      77  
      78  	fputs(USAGE_SEPARATOR, out);
      79  	printf(USAGE_HELP_OPTIONS(26));
      80  
      81  	fputs(USAGE_ARGUMENTS, out);
      82  	printf(USAGE_ARG_SIZE(_("<size>")));
      83  
      84  	printf(USAGE_MAN_TAIL("ipcmk(1)"));
      85  
      86  	exit(EXIT_SUCCESS);
      87  }
      88  
      89  int main(int argc, char **argv)
      90  {
      91  	int permission = 0644;
      92  	int opt;
      93  	size_t size = 0;
      94  	int nsems = 0;
      95  	int ask_shm = 0, ask_msg = 0, ask_sem = 0;
      96  	static const struct option longopts[] = {
      97  		{"shmem", required_argument, NULL, 'M'},
      98  		{"semaphore", required_argument, NULL, 'S'},
      99  		{"queue", no_argument, NULL, 'Q'},
     100  		{"mode", required_argument, NULL, 'p'},
     101  		{"version", no_argument, NULL, 'V'},
     102  		{"help", no_argument, NULL, 'h'},
     103  		{NULL, 0, NULL, 0}
     104  	};
     105  
     106  	setlocale(LC_ALL, "");
     107  	bindtextdomain(PACKAGE, LOCALEDIR);
     108  	textdomain(PACKAGE);
     109  	close_stdout_atexit();
     110  
     111  	while((opt = getopt_long(argc, argv, "hM:QS:p:Vh", longopts, NULL)) != -1) {
     112  		switch(opt) {
     113  		case 'M':
     114  			size = strtosize_or_err(optarg, _("failed to parse size"));
     115  			ask_shm = 1;
     116  			break;
     117  		case 'Q':
     118  			ask_msg = 1;
     119  			break;
     120  		case 'S':
     121  			nsems = strtos32_or_err(optarg, _("failed to parse elements"));
     122  			ask_sem = 1;
     123  			break;
     124  		case 'p':
     125  		{
     126  			char *end = NULL;
     127  			errno = 0;
     128  			permission = strtoul(optarg, &end, 8);
     129  			if (errno || optarg == end || (end && *end))
     130  				err(EXIT_FAILURE, _("failed to parse mode"));
     131  			break;
     132  		}
     133  		case 'h':
     134  			usage();
     135  		case 'V':
     136  			print_version(EXIT_SUCCESS);
     137  		default:
     138  			errtryhelp(EXIT_FAILURE);
     139  		}
     140  	}
     141  
     142  	if(!ask_shm && !ask_msg && !ask_sem) {
     143  		warnx(_("bad usage"));
     144  		errtryhelp(EXIT_FAILURE);
     145  	}
     146  	if (ask_shm) {
     147  		int shmid;
     148  		if (-1 == (shmid = create_shm(size, permission)))
     149  			err(EXIT_FAILURE, _("create share memory failed"));
     150  		else
     151  			printf(_("Shared memory id: %d\n"), shmid);
     152  	}
     153  
     154  	if (ask_msg) {
     155  		int msgid;
     156  		if (-1 == (msgid = create_msg(permission)))
     157  			err(EXIT_FAILURE, _("create message queue failed"));
     158  		else
     159  			printf(_("Message queue id: %d\n"), msgid);
     160  	}
     161  
     162  	if (ask_sem) {
     163  		int semid;
     164  		if (-1 == (semid = create_sem(nsems, permission)))
     165  			err(EXIT_FAILURE, _("create semaphore failed"));
     166  		else
     167  			printf(_("Semaphore id: %d\n"), semid);
     168  	}
     169  
     170  	return EXIT_SUCCESS;
     171  }