This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] Alpha IPC ctl fix


Hi!

Actually, I've missed that Alpha does not use ipc multiplexer, so IMHO this
is needed to get it working.
BTW: For some reason in 2.3.43-pre2 kernel appeared a patch which makes
IPC_64 always assumed on Alpha, which is IMHO very wrong and hopefully
will be removed again (that would mean no binary compatibility for IPC on
Alpha).
Anyone with an Alpha able to test it (should be applied on top of my 02-01
patch).

2000-02-08  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/unix/sysv/linux/alpha/msgctl.c: New file.
	* sysdeps/unix/sysv/linux/alpha/semctl.c: New file.
	* sysdeps/unix/sysv/linux/alpha/shmctl.c: New file.
	* sysdeps/unix/sysv/linux/alpha/syscalls.list (msgctl, semctl,
	shmctl): Make them EXTRA as __old_* and as GLIBC_2.0 symbols.
	* sysdeps/unix/sysv/linux/alpha/Makefile: Add oldmsgctl, oldsemctl
	and oldshmctl to sysdep-routines.

--- libc/sysdeps/unix/sysv/linux/alpha/msgctl.c.jj	Tue Feb  8 14:48:44 2000
+++ libc/sysdeps/unix/sysv/linux/alpha/msgctl.c	Tue Feb  8 14:54:21 2000
@@ -0,0 +1,120 @@
+/* Copyright (C) 1995, 1997, 1998, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <sys/msg.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <string.h>
+#include <sys/syscall.h>
+
+#include "kernel-features.h"
+
+struct __old_msqid_ds
+{
+  struct __old_ipc_perm msg_perm;	/* structure describing operation permission */
+  struct msg *__msg_first;		/* pointer to first message on queue */
+  struct msg *__msg_last;		/* pointer to last message on queue */
+  __time_t msg_stime;			/* time of last msgsnd command */
+  __time_t msg_rtime;			/* time of last msgrcv command */
+  __time_t msg_ctime;			/* time of last change */
+  struct wait_queue *__wwait;		/* ??? */
+  struct wait_queue *__rwait;		/* ??? */
+  unsigned short int __msg_cbytes;	/* current number of bytes on queue */
+  unsigned short int msg_qnum;		/* number of messages currently on queue */
+  unsigned short int msg_qbytes;	/* max number of bytes allowed on queue */
+  __ipc_pid_t msg_lspid;		/* pid of last msgsnd() */
+  __ipc_pid_t msg_lrpid;		/* pid of last msgrcv() */
+};
+
+/* Allows to control internal state and destruction of message queue
+   objects.  */
+int __new_msgctl (int, int, struct msqid_ds *);
+
+int
+__new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
+{
+#if __ASSUME_32BITUIDS > 0
+  return INLINE_SYSCALL (msgctl, 3, msqid, cmd | __IPC_64, buf);
+#else
+  switch (cmd) {
+    case MSG_STAT:
+    case IPC_STAT:
+    case IPC_SET:
+      break;
+    default:
+      return INLINE_SYSCALL (msgctl, 3, msqid, cmd, buf);
+  }
+
+  {
+    int save_errno = errno, result;
+    struct __old_msqid_ds old;
+
+    /* Unfortunately there is no way how to find out for sure whether
+       we should use old or new msgctl.  */
+    result = INLINE_SYSCALL (msgctl, 3, msqid, cmd | __IPC_64, buf);
+    if (result != -1 || errno != EINVAL)
+      return result;
+
+    __set_errno(save_errno);
+    if (cmd == IPC_SET)
+      {
+	old.msg_perm.uid = buf->msg_perm.uid;
+	old.msg_perm.gid = buf->msg_perm.gid;
+	old.msg_perm.mode = buf->msg_perm.mode;
+	old.msg_qbytes = buf->msg_qbytes;
+	if (old.msg_perm.uid != buf->msg_perm.uid ||
+	    old.msg_perm.gid != buf->msg_perm.gid ||
+	    old.msg_qbytes != buf->msg_qbytes)
+	  {
+	    __set_errno (EINVAL);
+	    return -1;
+	  }
+      }
+    result = INLINE_SYSCALL (msgctl, 3, msqid, cmd, &old);
+    if (result != -1 && cmd != IPC_SET)
+      {
+	memset(buf, 0, sizeof(*buf));
+	buf->msg_perm.__key = old.msg_perm.__key;
+	buf->msg_perm.uid = old.msg_perm.uid;
+	buf->msg_perm.gid = old.msg_perm.gid;
+	buf->msg_perm.cuid = old.msg_perm.cuid;
+	buf->msg_perm.cgid = old.msg_perm.cgid;
+	buf->msg_perm.mode = old.msg_perm.mode;
+	buf->msg_perm.__seq = old.msg_perm.__seq;
+	buf->msg_stime = old.msg_stime;
+	buf->msg_rtime = old.msg_rtime;
+	buf->msg_ctime = old.msg_ctime;
+	buf->__msg_cbytes = old.__msg_cbytes;
+	buf->msg_qnum = old.msg_qnum;
+	buf->msg_qbytes = old.msg_qbytes;
+	buf->msg_lspid = old.msg_lspid;
+	buf->msg_lrpid = old.msg_lrpid;
+      }
+    return result;
+  }
+#endif
+}
+
+#if defined PIC && DO_VERSIONING
+default_symbol_version (__new_msgctl, msgctl, GLIBC_2.2);
+#else
+weak_alias (__new_msgctl, msgctl);
+#endif
--- libc/sysdeps/unix/sysv/linux/alpha/semctl.c.jj	Tue Feb  8 14:48:44 2000
+++ libc/sysdeps/unix/sysv/linux/alpha/semctl.c	Tue Feb  8 15:01:32 2000
@@ -0,0 +1,132 @@
+/* Copyright (C) 1995, 1997, 1998, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <sys/sem.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <string.h>
+#include <sys/syscall.h>
+
+#include "kernel-features.h"
+
+struct __old_semid_ds
+{
+  struct __old_ipc_perm sem_perm;	/* operation permission struct */
+  __time_t sem_otime;			/* last semop() time */
+  __time_t sem_ctime;			/* last time changed by semctl() */
+  struct sem *__sembase;		/* ptr to first semaphore in array */
+  struct sem_queue *__sem_pending;	/* pending operations */
+  struct sem_queue *__sem_pending_last; /* last pending operation */
+  struct sem_undo *__undo;		/* ondo requests on this array */
+  unsigned short int sem_nsems;		/* number of semaphores in set */
+};
+
+/* Define a `union semun' suitable for Linux here.  */
+union semun
+{
+  int val;			/* value for SETVAL */
+  struct semid_ds *buf;		/* buffer for IPC_STAT & IPC_SET */
+  unsigned short int *array;	/* array for GETALL & SETALL */
+  struct seminfo *__buf;	/* buffer for IPC_INFO */
+};
+
+
+/* Return identifier for array of NSEMS semaphores associated with
+   KEY.  */
+int __new_semctl (int semid, int semnum, int cmd, ...);
+
+int
+__new_semctl (int semid, int semnum, int cmd, ...)
+{
+  union semun arg;
+  va_list ap;
+
+  va_start (ap, cmd);
+
+  /* Get the argument.  */
+  arg = va_arg (ap, union semun);
+
+  va_end (ap);
+
+#if __ASSUME_32BITUIDS > 0
+  return INLINE_SYSCALL (semctl, 4, semid, semnum, cmd | __IPC_64, &arg);
+#else
+  switch (cmd) {
+    case SEM_STAT:
+    case IPC_STAT:
+    case IPC_SET:
+      break;
+    default:
+      return INLINE_SYSCALL (semctl, 4, semid, semnum, cmd, &arg);
+  }
+
+  {
+    int save_errno = errno, result;
+    struct __old_semid_ds old;
+    struct semid_ds *buf;
+
+    /* Unfortunately there is no way how to find out for sure whether
+       we should use old or new semctl.  */
+    result = INLINE_SYSCALL (semctl, 4, semid, semnum, cmd | __IPC_64, &arg);
+    if (result != -1 || errno != EINVAL)
+      return result;
+
+    __set_errno(save_errno);
+    buf = arg.buf;
+    arg.buf = (struct semid_ds *)&old;
+    if (cmd == IPC_SET)
+      {
+	old.sem_perm.uid = buf->sem_perm.uid;
+	old.sem_perm.gid = buf->sem_perm.gid;
+	old.sem_perm.mode = buf->sem_perm.mode;
+	if (old.sem_perm.uid != buf->sem_perm.uid ||
+	    old.sem_perm.gid != buf->sem_perm.gid)
+	  {
+	    __set_errno (EINVAL);
+	    return -1;
+	  }
+      }
+    result = INLINE_SYSCALL (semctl, 4, semid, semnum, cmd, &arg);
+    if (result != -1 && cmd != IPC_SET)
+      {
+	memset(buf, 0, sizeof(*buf));
+	buf->sem_perm.__key = old.sem_perm.__key;
+	buf->sem_perm.uid = old.sem_perm.uid;
+	buf->sem_perm.gid = old.sem_perm.gid;
+	buf->sem_perm.cuid = old.sem_perm.cuid;
+	buf->sem_perm.cgid = old.sem_perm.cgid;
+	buf->sem_perm.mode = old.sem_perm.mode;
+	buf->sem_perm.__seq = old.sem_perm.__seq;
+	buf->sem_otime = old.sem_otime;
+	buf->sem_ctime = old.sem_ctime;
+	buf->sem_nsems = old.sem_nsems;
+      }
+    return result;
+  }
+#endif
+}
+
+#if defined PIC && DO_VERSIONING
+default_symbol_version (__new_semctl, semctl, GLIBC_2.2);
+#else
+weak_alias (__new_semctl, semctl);
+#endif
--- libc/sysdeps/unix/sysv/linux/alpha/shmctl.c.jj	Tue Feb  8 14:48:44 2000
+++ libc/sysdeps/unix/sysv/linux/alpha/shmctl.c	Tue Feb  8 15:04:18 2000
@@ -0,0 +1,137 @@
+/* Copyright (C) 1995, 1997, 1998, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <sys/shm.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <bits/wordsize.h>
+
+#include "kernel-features.h"
+
+struct __old_shmid_ds
+{
+  struct __old_ipc_perm shm_perm;	/* operation permission struct */
+  int shm_segsz;			/* size of segment in bytes */
+  __time_t shm_atime;			/* time of last shmat() */
+  __time_t shm_dtime;			/* time of last shmdt() */
+  __time_t shm_ctime;			/* time of last change by shmctl() */
+  __ipc_pid_t shm_cpid;			/* pid of creator */
+  __ipc_pid_t shm_lpid;			/* pid of last shmop */
+  unsigned short int shm_nattch;	/* number of current attaches */
+  unsigned short int __shm_npages;	/* size of segment (pages) */
+  unsigned long int *__shm_pages;	/* array of ptrs to frames -> SHMMAX */
+  struct vm_area_struct *__attaches;	/* descriptors for attaches */
+};
+
+struct __old_shminfo
+{
+  int shmmax;
+  int shmmin;
+  int shmmni;
+  int shmseg;
+  int shmall;
+};
+
+/* Provide operations to control over shared memory segments.  */
+int __new_shmctl (int, int, struct shmid_ds *);
+
+int
+__new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
+{
+#if __ASSUME_32BITUIDS > 0
+  return INLINE_SYSCALL (shmctl, 3, shmid, cmd | __IPC_64, buf);
+#else
+  switch (cmd) {
+    case SHM_STAT:
+    case IPC_STAT:
+    case IPC_SET:
+    case IPC_INFO:
+      break;
+    default:
+      return INLINE_SYSCALL (shmctl, 3, shmid, cmd, buf);
+  }
+
+  {
+    int save_errno = errno, result;
+    struct __old_shmid_ds old;
+
+    /* Unfortunately there is no way how to find out for sure whether
+       we should use old or new shmctl.  */
+    result = INLINE_SYSCALL (shmctl, 3, shmid, cmd | __IPC_64, buf);
+    if (result != -1 || errno != EINVAL)
+      return result;
+
+    __set_errno(save_errno);
+    if (cmd == IPC_SET)
+      {
+	old.shm_perm.uid = buf->shm_perm.uid;
+	old.shm_perm.gid = buf->shm_perm.gid;
+	old.shm_perm.mode = buf->shm_perm.mode;
+	if (old.shm_perm.uid != buf->shm_perm.uid ||
+	    old.shm_perm.gid != buf->shm_perm.gid)
+	  {
+	    __set_errno (EINVAL);
+	    return -1;
+	  }
+      }
+    result = INLINE_SYSCALL (shmctl, 3, shmid, cmd, &old);
+    if (result != -1 && (cmd == SHM_STAT || cmd == IPC_STAT))
+      {
+	memset(buf, 0, sizeof(*buf));
+	buf->shm_perm.__key = old.shm_perm.__key;
+	buf->shm_perm.uid = old.shm_perm.uid;
+	buf->shm_perm.gid = old.shm_perm.gid;
+	buf->shm_perm.cuid = old.shm_perm.cuid;
+	buf->shm_perm.cgid = old.shm_perm.cgid;
+	buf->shm_perm.mode = old.shm_perm.mode;
+	buf->shm_perm.__seq = old.shm_perm.__seq;
+	buf->shm_atime = old.shm_atime;
+	buf->shm_dtime = old.shm_dtime;
+	buf->shm_ctime = old.shm_ctime;
+	buf->shm_segsz = old.shm_segsz;
+	buf->shm_nattch = old.shm_nattch;
+	buf->shm_cpid = old.shm_cpid;
+	buf->shm_lpid = old.shm_lpid;
+      }
+    else if (result != -1 && cmd == IPC_INFO)
+      {
+	struct __old_shminfo *oldi = (struct __old_shminfo *)&old;
+	struct shminfo *i = (struct shminfo *)buf;
+
+	memset(i, 0, sizeof(*i));
+	i->shmmax = oldi->shmmax;
+	i->shmmin = oldi->shmmin;
+	i->shmmni = oldi->shmmni;
+	i->shmseg = oldi->shmseg;
+	i->shmall = oldi->shmall;
+      }
+    return result;
+  }
+#endif
+}
+
+#if defined PIC && DO_VERSIONING
+default_symbol_version (__new_shmctl, shmctl, GLIBC_2.2);
+#else
+weak_alias (__new_shmctl, shmctl);
+#endif
--- libc/sysdeps/unix/sysv/linux/alpha/syscalls.list.jj	Mon Jan  3 07:35:26 2000
+++ libc/sysdeps/unix/sysv/linux/alpha/syscalls.list	Tue Feb  8 14:58:45 2000
@@ -3,17 +3,17 @@
 # used to implement inb()/outb() etc.
 sethae		-	sethae		1	__sethae
 
-msgctl		-	msgctl		3	__msgctl	msgctl
+oldmsgctl	EXTRA	msgctl		3	__old_msgctl	msgctl@GLIBC_2.0
 msgget		-	msgget		2	__msgget	msgget
 msgrcv		-	msgrcv		5	__msgrcv	msgrcv
 msgsnd		-	msgsnd		4	__msgsnd	msgsnd
 shmat		-	osf_shmat	3	__shmat		shmat
-shmctl		-	shmctl		3	__shmctl	shmctl
+oldshmctl	EXTRA	shmctl		3	__old_shmctl	shmctl@GLIBC_2.0
 shmdt		-	shmdt		1	__shmdt		shmdt
 shmget		-	shmget		3	__shmget	shmget
 semop		-	semop		3	__semop		semop
 semget		-	semget		3	__semget	semget
-semctl		-	semctl		4	__semctl	semctl
+oldsemctl	EXTRA	semctl		4	__old_semctl	semctl@GLIBC_2.0
 
 osf_sigprocmask	-	osf_sigprocmask	2	__osf_sigprocmask
 sigstack	-	sigstack	2	sigstack
--- libc/sysdeps/unix/sysv/linux/alpha/Makefile.jj	Mon Jan 24 08:12:20 2000
+++ libc/sysdeps/unix/sysv/linux/alpha/Makefile	Tue Feb  8 14:59:19 2000
@@ -13,6 +13,9 @@ sysdep_routines += osf_select osf_gettim
 		   osf_getitimer osf_setitimer osf_utimes \
 		   osf_getrusage osf_wait4 old_adjtimex
 
+# Support old ipc control
+sysdep_routines += oldmsgctl oldsemctl oldshmctl
+
 CFLAGS-ioperm.c = -Wa,-mev6
 endif
 

Cheers,
    Jakub
___________________________________________________________________
Jakub Jelinek | jakub@redhat.com | http://sunsite.mff.cuni.cz/~jj
Linux version 2.3.42 on a sparc64 machine (1343.49 BogoMips)
___________________________________________________________________

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]