1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
int
do_ipcctl(optype, arglast)
int optype;
int *arglast;
{
register STR **st = stack->ary_array;
register int sp = arglast[0];
STR *astr;
char *a;
int id, n, cmd, infosize, getinfo, ret;
id = (int)str_gnum(st[++sp]);
n = (optype == O_SEMCTL) ? (int)str_gnum(st[++sp]) : 0;
cmd = (int)str_gnum(st[++sp]);
astr = st[++sp];
infosize = 0;
getinfo = (cmd == IPC_STAT);
switch (optype)
{
#ifdef HAS_MSG
case O_MSGCTL:
if (cmd == IPC_STAT || cmd == IPC_SET)
infosize = sizeof(struct msqid_ds);
break;
#endif
#ifdef HAS_SHM
case O_SHMCTL:
if (cmd == IPC_STAT || cmd == IPC_SET)
infosize = sizeof(struct shmid_ds);
break;
#endif
#ifdef HAS_SEM
case O_SEMCTL:
if (cmd == IPC_STAT || cmd == IPC_SET)
infosize = sizeof(struct semid_ds);
else if (cmd == GETALL || cmd == SETALL)
{
struct semid_ds semds;
if (semctl(id, 0, IPC_STAT, &semds) == -1)
return -1;
getinfo = (cmd == GETALL);
infosize = semds.sem_nsems * sizeof(short);
/* "short" is technically wrong but much more portable
than guessing about u_?short(_t)? */
}
break;
#endif
#if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
default:
fatal("%s not implemented", opname[optype]);
#endif
}
if (infosize)
{
if (getinfo)
{
STR_GROW(astr, infosize+1);
a = str_get(astr);
}
else
{
a = str_get(astr);
if (astr->str_cur != infosize)
{
errno = EINVAL;
return -1;
}
}
}
else
{
int i = (int)str_gnum(astr);
a = (char *)i; /* ouch */
}
errno = 0;
switch (optype)
{
#ifdef HAS_MSG
case O_MSGCTL:
ret = msgctl(id, cmd, (struct msqid_ds *)a);
break;
#endif
#ifdef HAS_SEM
case O_SEMCTL:
ret = semctl(id, n, cmd, a);
break;
#endif
#ifdef HAS_SHM
case O_SHMCTL:
ret = shmctl(id, cmd, (struct shmid_ds *)a);
break;
#endif
}
if (getinfo && ret >= 0) {
astr->str_cur = infosize;
astr->str_ptr[infosize] = '\0';
}
return ret;
}
|