*
* Copyright (C) 2008 Hayden A. James (hayden.james@gmail.com)
* Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * 2025 Prasanna Paithankar <paithankarprasanna@gmail.com>
+ * - Added POSIX IPC support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
-#include <mqueue.h>
#include <sys/sem.h>
-#include <semaphore.h>
#include <sys/shm.h>
+#include <sys/time.h>
+
+#ifdef HAVE_MQUEUE_H
+#include <mqueue.h>
+#endif
+
+#ifdef HAVE_SEMAPHORE_H
+#include <semaphore.h>
+#endif
+
+#ifdef HAVE_SYS_MMAN_H
#include <sys/stat.h>
#include <sys/mman.h>
-#include <sys/time.h>
+#endif
#include "c.h"
#include "nls.h"
return shmget(key, size, permission | IPC_CREAT);
}
+#ifndef HAVE_SYS_MMAN_H
+static int create_posix_shm(const char *name __attribute__((__unused__)),
+ size_t size __attribute__((__unused__)),
+ int permission __attribute__((__unused__)))
+{
+ warnx(_("POSIX shared memory is not supported"));
+ return -1;
+}
+#else
static int create_posix_shm(const char *name, size_t size, int permission)
{
int shmfd;
printf(_("POSIX shared memory name: %s\n"), name);
return 0;
}
+#endif
static int create_msg(int permission)
{
return msgget(key, permission | IPC_CREAT);
}
+#ifndef HAVE_MQUEUE_H
+static int create_posix_msg(const char *name __attribute__((__unused__)),
+ int permission __attribute__((__unused__)))
+{
+ warnx(_("POSIX message queue is not supported"));
+ return -1;
+}
+#else
static int create_posix_msg(const char *name, int permission)
{
- if (-1 == mq_open(name, O_RDWR | O_CREAT, permission, NULL))
+ mqd_t mqd;
+
+ if (-1 == (mqd = mq_open(name, O_RDWR | O_CREAT, permission, NULL)))
return -1;
+
+ mq_close(mqd);
printf(_("POSIX message queue name: %s\n"), name);
return 0;
}
+#endif
static int create_sem(int nsems, int permission)
{
return semget(key, nsems, permission | IPC_CREAT);
}
+#ifndef HAVE_SEMAPHORE_H
+static int create_posix_sem(const char *name __attribute__((__unused__)),
+ int permission __attribute__((__unused__)))
+{
+ warnx(_("POSIX semaphore is not supported"));
+ return -1;
+}
+#else
static int create_posix_sem(const char *name, int permission)
{
sem_t *sem;
printf(_("POSIX semaphore name: %s\n"), name);
return 0;
}
+#endif
static void __attribute__((__noreturn__)) usage(void)
{
}
/* POSIX IPC */
+ #ifdef HAVE_MQUEUE_H
FILE *f;
f = fopen(_PATH_PROC_POSIX_IPC_MSGMNI, "r");
lim->msgmax_posix = 0;
fclose(f);
}
+ #endif
return 0;
}
}
}
+#ifndef HAVE_SYS_MMAN_H
+int posix_ipc_shm_get_info(const char *name __attribute__((unused)),
+ struct posix_shm_data **shmds __attribute__((unused)))
+{
+ warnx(_("POSIX shared memory is not supported"));
+ return -1;
+}
+#else
int posix_ipc_shm_get_info(const char *name, struct posix_shm_data **shmds)
{
DIR *d;
struct posix_shm_data *p;
struct dirent *de;
+ d = opendir(_PATH_DEV_SHM);
+ if (!d) {
+ warnx(_("cannot open %s"), _PATH_DEV_SHM);
+ return -1;
+ }
+
p = *shmds = xcalloc(1, sizeof(struct posix_shm_data));
p->next = NULL;
- d = opendir(_PATH_DEV_SHM);
- if (!d)
- err(EXIT_FAILURE, _("cannot open %s"), _PATH_DEV_SHM);
-
while ((de = readdir(d)) != NULL) {
if ((de->d_name[0] == '.' && de->d_name[1] == '\0') ||
(de->d_name[0] == '.' && de->d_name[1] == '.' &&
continue;
struct stat st;
- char path[PATH_MAX];
- snprintf(path, sizeof(path), "%s/%s", _PATH_DEV_SHM, de->d_name);
- if (stat(path, &st) < 0)
+ if (fstatat(dirfd(d), de->d_name, &st, 0) < 0)
continue;
-
- memset(path, 0, sizeof(path));
- path[0] = '/';
- strcat(path, de->d_name);
- p->name = xstrdup(path);
+ p->name = xstrdup(de->d_name);
p->cuid = st.st_uid;
p->cgid = st.st_gid;
p->size = st.st_size;
p->mtime = st.st_mtime;
if (name != NULL) {
- if (strcmp(name, path) == 0) {
+ if (strcmp(name, p->name) == 0) {
i = 1;
break;
}
closedir(d);
return i;
}
+#endif
void posix_ipc_shm_free_info(struct posix_shm_data *shmds)
{
}
}
+#ifndef HAVE_SEMAPHORE_H
+int posix_ipc_sem_get_info(const char *name __attribute__((__unused__)),
+ struct posix_sem_data **semds __attribute__((__unused__)))
+{
+ warnx(_("POSIX semaphore is not supported"));
+ return -1;
+}
+#else
int posix_ipc_sem_get_info(const char *name, struct posix_sem_data **semds)
{
DIR *d;
struct posix_sem_data *p;
struct dirent *de;
+ d = opendir(_PATH_DEV_SHM);
+ if (!d) {
+ warnx(_("cannot open %s"), _PATH_DEV_SHM);
+ return -1;
+ }
+
p = *semds = xcalloc(1, sizeof(struct posix_sem_data));
p->next = NULL;
- d = opendir(_PATH_DEV_SHM);
- if (!d)
- err(EXIT_FAILURE, _("cannot open %s"), _PATH_DEV_SHM);
-
while ((de = readdir(d)) != NULL) {
if ((de->d_name[0] == '.' && de->d_name[1] == '\0') ||
(de->d_name[0] == '.' && de->d_name[1] == '.' &&
continue;
struct stat st;
- char path[PATH_MAX];
- snprintf(path, sizeof(path), "%s/%s", _PATH_DEV_SHM, de->d_name);
- if (stat(path, &st) < 0)
+ if (fstatat(dirfd(d), de->d_name, &st, 0) < 0)
continue;
sem_t *sem = sem_open(de->d_name + 4, 0);
continue;
sem_getvalue(sem, &p->sval);
sem_close(sem);
-
- memset(path, 0, sizeof(path));
- path[0] = '/';
- strcat(path, de->d_name + 4);
- p->sname = xstrdup(path);
+ p->sname = xstrdup(de->d_name + 4);
p->cuid = st.st_uid;
p->cgid = st.st_gid;
p->mode = st.st_mode;
p->mtime = st.st_mtime;
if (name != NULL) {
- if (strcmp(name, path) == 0) {
+ if (strcmp(name, p->sname) == 0) {
i = 1;
break;
}
closedir(d);
return i;
}
+#endif
void posix_ipc_sem_free_info(struct posix_sem_data *semds)
{
}
}
+#ifndef HAVE_MQUEUE_H
+int posix_ipc_msg_get_info(const char *name __attribute__((unused)),
+ struct posix_msg_data **msgds __attribute__((unused)))
+{
+ warnx(_("POSIX message queues are not supported"));
+ return -1;
+}
+#else
int posix_ipc_msg_get_info(const char *name, struct posix_msg_data **msgds)
{
FILE *f;
struct posix_msg_data *p;
struct dirent *de;
- p = *msgds = xcalloc(1, sizeof(struct msg_data));
- p->next = NULL;
-
if (access(_PATH_DEV_MQUEUE, F_OK) != 0) {
warnx(_("%s does not seem to be mounted. Use 'mount -t mqueue none %s' to mount it."), _PATH_DEV_MQUEUE, _PATH_DEV_MQUEUE);
return -1;
}
+ if (name && name[0] != '/') {
+ warnx(_("mqueue name must start with '/': %s"), name);
+ return -1;
+ }
+
d = opendir(_PATH_DEV_MQUEUE);
if (!d) {
warnx(_("cannot open %s"), _PATH_DEV_MQUEUE);
return -1;
}
+ p = *msgds = xcalloc(1, sizeof(struct msg_data));
+ p->next = NULL;
+
while ((de = readdir(d)) != NULL) {
if ((de->d_name[0] == '.' && de->d_name[1] == '\0') ||
(de->d_name[0] == '.' && de->d_name[1] == '.' &&
continue;
struct stat st;
- char path[PATH_MAX];
- snprintf(path, sizeof(path), "%s/%s", _PATH_DEV_MQUEUE, de->d_name);
-
- int fd = open(path, O_RDONLY);
- if (fd < 0)
+ if (fstatat(dirfd(d), de->d_name, &st, 0) < 0)
continue;
- if (fstat(fd, &st) < 0) {
- close(fd);
+ int fd = openat(dirfd(d), de->d_name, O_RDONLY);
+ if (fd < 0)
continue;
- }
f = fdopen(fd, "r");
if (!f) {
continue;
}
fclose(f);
-
- memset(path, 0, sizeof(path));
- path[0] = '/';
- strcat(path, de->d_name);
- p->mname = xstrdup(path);
+ p->mname = strconcat("/", de->d_name);
- mqd_t mq = mq_open(path, O_RDONLY);
+ mqd_t mq = mq_open(p->mname, O_RDONLY);
struct mq_attr attr;
mq_getattr(mq, &attr);
p->q_qnum = attr.mq_curmsgs;
p->mtime = st.st_mtime;
if (name != NULL) {
- if (strcmp(name, path) == 0) {
+ if (strcmp(name, p->mname) == 0) {
i = 1;
break;
}
return i;
}
+#endif
void posix_ipc_msg_free_info(struct posix_msg_data *msgds)
{
*
* Copyright (C) 2015 Ondrej Oprala <ooprala@redhat.com>
* Copyright (C) 2015 Karel Zak <ooprala@redhat.com>
+ *
+ * 2025 Prasanna Paithankar <paithankarprasanna@gmail.com>
+ * - Added POSIX IPC support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
struct posix_sem_data *semds, *p;
char *arg = NULL;
- scols_table_set_name(tb, "posix-semaphores");
- if (posix_ipc_sem_get_info(name, &semds) < 1) {
- if (name)
- warnx(_("name %s not found"), name);
+ int retval = posix_ipc_sem_get_info(name, &semds);
+ if (retval == -1)
+ return;
+
+ if (retval < 1) {
+ if (name != NULL)
+ warnx(_("mqueue %s not found"), name);
return;
}
+
+ scols_table_set_name(tb, "posix-semaphores");
+
for (p = semds; p->next != NULL || name != NULL; p = p->next) {
size_t n;
warnx(_("mqueue %s not found"), name);
return;
}
+
scols_table_set_name(tb, "posix-messages");
for (p = msgds; p->next != NULL || name != NULL; p = p->next) {
global_set_data(ctl, tb, "MSGMNB", _("Default max size of System V queue (bytes)"), 0, lim.msgmnb, 0, 1);
}
+#ifndef HAVE_MQUEUE_H
+static void do_posix_msg_global(struct lsipc_control *ctl __attribute__((unused)), struct libscols_table *tb __attribute__((unused)))
+{
+ return;
+}
+#else
static void do_posix_msg_global(struct lsipc_control *ctl, struct libscols_table *tb)
{
struct posix_msg_data *pmsgds;
global_set_data(ctl, tb, "MQUMAX", _("Max size of POSIX message (bytes)"), 0, lim.msgmax_posix, 0, 1);
global_set_data(ctl, tb, "MQUMNB", _("Number of messages in POSIX message queue"), 0, lim.msgmnb_posix, 0, 0);
}
+#endif
static void do_shm(int id, struct lsipc_control *ctl, struct libscols_table *tb)
struct posix_shm_data *shmds, *p;
char *arg = NULL;
- if (posix_ipc_shm_get_info(name, &shmds) < 1) {
+ int retval = posix_ipc_shm_get_info(name, &shmds);
+ if (retval == -1)
+ return;
+
+ if (retval < 1) {
if (name != NULL)
warnx(_("shm %s not found"), name);
return;