OSDN Git Service

Eliminate use of sigframe and sigthread throughout.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / sem.cc
1 /* sem.cc: XSI IPC interface for Cygwin.
2
3    Copyright 2003 Red Hat, Inc.
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11 #include "winsup.h"
12 #include "cygerrno.h"
13 #include <signal.h>
14 #ifdef USE_SERVER
15 #include <sys/types.h>
16 #include <stdio.h>
17 #include <unistd.h>
18 #include <stdarg.h>
19
20 #include "sigproc.h"
21
22 #include "cygserver_ipc.h"
23 #include "cygserver_sem.h"
24
25 /*
26  * client_request_sem Constructors
27  */
28
29 client_request_sem::client_request_sem (int semid,
30                                         int semnum,
31                                         int cmd,
32                                         union semun *arg)
33   : client_request (CYGSERVER_REQUEST_SEM, &_parameters, sizeof (_parameters))
34 {
35   _parameters.in.semop = SEMOP_semctl;
36   ipc_set_proc_info (_parameters.in.ipcblk);
37
38    _parameters.in.ctlargs.semid = semid;
39    _parameters.in.ctlargs.semnum = semnum;
40    _parameters.in.ctlargs.cmd = cmd;
41    _parameters.in.ctlargs.arg = arg;
42
43   msglen (sizeof (_parameters.in));
44 }
45
46 client_request_sem::client_request_sem (key_t key,
47                                         int nsems,
48                                         int semflg)
49   : client_request (CYGSERVER_REQUEST_SEM, &_parameters, sizeof (_parameters))
50 {
51   _parameters.in.semop = SEMOP_semget;
52   ipc_set_proc_info (_parameters.in.ipcblk);
53
54   _parameters.in.getargs.key = key;
55   _parameters.in.getargs.nsems = nsems;
56   _parameters.in.getargs.semflg = semflg;
57
58   msglen (sizeof (_parameters.in));
59 }
60
61 client_request_sem::client_request_sem (int semid,
62                                         struct sembuf *sops,
63                                         size_t nsops)
64   : client_request (CYGSERVER_REQUEST_SEM, &_parameters, sizeof (_parameters))
65 {
66   _parameters.in.semop = SEMOP_semop;
67   ipc_set_proc_info (_parameters.in.ipcblk);
68
69   _parameters.in.opargs.semid = semid;
70   _parameters.in.opargs.sops = sops;
71   _parameters.in.opargs.nsops = nsops;
72
73   msglen (sizeof (_parameters.in));
74 }
75 #endif /* USE_SERVER */
76
77 /*
78  * XSI semaphore API.  These are exported by the DLL.
79  */
80
81 extern "C" int
82 semctl (int semid, int semnum, int cmd, ...)
83 {
84 #ifdef USE_SERVER
85   union semun arg = {0};
86   if (cmd == IPC_STAT || cmd == IPC_SET || cmd == IPC_INFO || cmd == SEM_INFO
87       || cmd == GETALL || cmd == SETALL || cmd == SETVAL)
88     {
89       va_list ap;
90       va_start (ap, cmd);
91       arg = va_arg (ap, union semun);
92       va_end (ap);
93     }
94   syscall_printf ("semctl (semid = %d, semnum = %d, cmd = %d, arg.val = 0x%x)",
95                   semid, semnum, cmd, arg.val);
96   if ((cmd == IPC_STAT || cmd == IPC_SET)
97       && __check_null_invalid_struct_errno (arg.buf, sizeof (struct semid_ds)))
98     return -1;
99   if (cmd == IPC_INFO)
100     {
101       /* semid == 0: Request for seminfo struct. */
102       if (!semid
103           && __check_null_invalid_struct_errno (arg.buf, sizeof (struct seminfo)))
104           return -1;
105       /* Otherwise, request semid entries from internal semid_ds array. */
106       if (semid)
107         if (__check_null_invalid_struct_errno (arg.buf, semid * sizeof (struct semid_ds)))
108           return -1;
109     }
110   if (cmd == SEM_INFO
111       && __check_null_invalid_struct_errno (arg.buf, sizeof (struct sem_info)))
112     return -1;
113   client_request_sem request (semid, semnum, cmd, &arg);
114   if (request.make_request () == -1 || request.retval () == -1)
115     {
116       syscall_printf ("-1 [%d] = semctl ()", request.error_code ());
117       set_errno (request.error_code ());
118       if (request.error_code () == ENOSYS)
119         raise (SIGSYS);
120       return -1;
121     }
122   return request.retval ();
123 #else
124   set_errno (ENOSYS);
125   raise (SIGSYS);
126   return -1;
127 #endif
128 }
129
130 extern "C" int
131 semget (key_t key, int nsems, int semflg)
132 {
133 #ifdef USE_SERVER
134   syscall_printf ("semget (key = %U, nsems = %d, semflg = 0x%x)",
135                   key, nsems, semflg);
136   client_request_sem request (key, nsems, semflg);
137   if (request.make_request () == -1 || request.retval () == -1)
138     {
139       syscall_printf ("-1 [%d] = semctl ()", request.error_code ());
140       set_errno (request.error_code ());
141       if (request.error_code () == ENOSYS)
142         raise (SIGSYS);
143       return -1;
144     }
145   return request.retval ();
146 #else
147   set_errno (ENOSYS);
148   raise (SIGSYS);
149   return -1;
150 #endif
151 }
152
153 extern "C" int
154 semop (int semid, struct sembuf *sops, size_t nsops)
155 {
156 #ifdef USE_SERVER
157   syscall_printf ("semop (semid = %d, sops = %p, nsops = %d)",
158                   semid, sops, nsops);
159   if (__check_null_invalid_struct_errno (sops, nsops * sizeof (struct sembuf)))
160     return -1;
161   client_request_sem request (semid, sops, nsops);
162   if (request.make_request () == -1 || request.retval () == -1)
163     {
164       syscall_printf ("-1 [%d] = semctl ()", request.error_code ());
165       set_errno (request.error_code ());
166       if (request.error_code () == ENOSYS)
167         raise (SIGSYS);
168       return -1;
169     }
170   return request.retval ();
171 #else
172   set_errno (ENOSYS);
173   raise (SIGSYS);
174   return -1;
175 #endif
176 }