Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/ipc/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 3 kB image not shown  

Quelle  msgutil.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * linux/ipc/msgutil.c
 * Copyright (C) 1999, 2004 Manfred Spraul
 */


#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/security.h>
#include <linux/slab.h>
#include <linux/ipc.h>
#include <linux/msg.h>
#include <linux/ipc_namespace.h>
#include <linux/utsname.h>
#include <linux/proc_ns.h>
#include <linux/uaccess.h>
#include <linux/sched.h>

#include "util.h"

DEFINE_SPINLOCK(mq_lock);

/*
 * The next 2 defines are here bc this is the only file
 * compiled when either CONFIG_SYSVIPC and CONFIG_POSIX_MQUEUE
 * and not CONFIG_IPC_NS.
 */

struct ipc_namespace init_ipc_ns = {
 .ns.count = REFCOUNT_INIT(1),
 .user_ns = &init_user_ns,
 .ns.inum = PROC_IPC_INIT_INO,
#ifdef CONFIG_IPC_NS
 .ns.ops = &ipcns_operations,
#endif
};

struct msg_msgseg {
 struct msg_msgseg *next;
 /* the next part of the message follows immediately */
};

#define DATALEN_MSG ((size_t)PAGE_SIZE-sizeof(struct msg_msg))
#define DATALEN_SEG ((size_t)PAGE_SIZE-sizeof(struct msg_msgseg))

static kmem_buckets *msg_buckets __ro_after_init;

static int __init init_msg_buckets(void)
{
 msg_buckets = kmem_buckets_create("msg_msg", SLAB_ACCOUNT,
       sizeof(struct msg_msg),
       DATALEN_MSG, NULL);

 return 0;
}
subsys_initcall(init_msg_buckets);

static struct msg_msg *alloc_msg(size_t len)
{
 struct msg_msg *msg;
 struct msg_msgseg **pseg;
 size_t alen;

 alen = min(len, DATALEN_MSG);
 msg = kmem_buckets_alloc(msg_buckets, sizeof(*msg) + alen, GFP_KERNEL);
 if (msg == NULL)
  return NULL;

 msg->next = NULL;
 msg->security = NULL;

 len -= alen;
 pseg = &msg->next;
 while (len > 0) {
  struct msg_msgseg *seg;

  cond_resched();

  alen = min(len, DATALEN_SEG);
  seg = kmalloc(sizeof(*seg) + alen, GFP_KERNEL_ACCOUNT);
  if (seg == NULL)
   goto out_err;
  *pseg = seg;
  seg->next = NULL;
  pseg = &seg->next;
  len -= alen;
 }

 return msg;

out_err:
 free_msg(msg);
 return NULL;
}

struct msg_msg *load_msg(const void __user *src, size_t len)
{
 struct msg_msg *msg;
 struct msg_msgseg *seg;
 int err = -EFAULT;
 size_t alen;

 msg = alloc_msg(len);
 if (msg == NULL)
  return ERR_PTR(-ENOMEM);

 alen = min(len, DATALEN_MSG);
 if (copy_from_user(msg + 1, src, alen))
  goto out_err;

 for (seg = msg->next; seg != NULL; seg = seg->next) {
  len -= alen;
  src = (char __user *)src + alen;
  alen = min(len, DATALEN_SEG);
  if (copy_from_user(seg + 1, src, alen))
   goto out_err;
 }

 err = security_msg_msg_alloc(msg);
 if (err)
  goto out_err;

 return msg;

out_err:
 free_msg(msg);
 return ERR_PTR(err);
}
#ifdef CONFIG_CHECKPOINT_RESTORE
struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst)
{
 struct msg_msgseg *dst_pseg, *src_pseg;
 size_t len = src->m_ts;
 size_t alen;

 if (src->m_ts > dst->m_ts)
  return ERR_PTR(-EINVAL);

 alen = min(len, DATALEN_MSG);
 memcpy(dst + 1, src + 1, alen);

 for (dst_pseg = dst->next, src_pseg = src->next;
      src_pseg != NULL;
      dst_pseg = dst_pseg->next, src_pseg = src_pseg->next) {

  len -= alen;
  alen = min(len, DATALEN_SEG);
  memcpy(dst_pseg + 1, src_pseg + 1, alen);
 }

 dst->m_type = src->m_type;
 dst->m_ts = src->m_ts;

 return dst;
}
#else
struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst)
{
 return ERR_PTR(-ENOSYS);
}
#endif
int store_msg(void __user *dest, struct msg_msg *msg, size_t len)
{
 size_t alen;
 struct msg_msgseg *seg;

 alen = min(len, DATALEN_MSG);
 if (copy_to_user(dest, msg + 1, alen))
  return -1;

 for (seg = msg->next; seg != NULL; seg = seg->next) {
  len -= alen;
  dest = (char __user *)dest + alen;
  alen = min(len, DATALEN_SEG);
  if (copy_to_user(dest, seg + 1, alen))
   return -1;
 }
 return 0;
}

void free_msg(struct msg_msg *msg)
{
 struct msg_msgseg *seg;

 security_msg_msg_free(msg);

 seg = msg->next;
 kfree(msg);
 while (seg != NULL) {
  struct msg_msgseg *tmp = seg->next;

  cond_resched();
  kfree(seg);
  seg = tmp;
 }
}

Messung V0.5
C=98 H=75 G=87

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.