fdwalk should return 0 on an empty directory
[kopensolaris-gnu/glibc.git] / hurd / catch-exc.c
1 /* Copyright (C) 1994,95,96,97,2002 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18
19 #include <mach/exc_server.h>
20 #include <hurd/signal.h>
21 #include <assert.h>
22
23 /* Called by the microkernel when a thread gets an exception.  */
24
25 kern_return_t
26 _S_catch_exception_raise (mach_port_t port,
27                           thread_t thread,
28                           task_t task,
29 #ifdef EXC_MASK_ALL             /* New interface flavor.  */
30                           exception_type_t exception,
31                           exception_data_t code,
32                           mach_msg_type_number_t codeCnt
33 #else                           /* Vanilla Mach 3.0 interface.  */
34                           integer_t exception,
35                           integer_t code, integer_t subcode
36 #endif
37                           )
38 {
39   struct hurd_sigstate *ss;
40   int signo;
41   struct hurd_signal_detail d;
42
43   if (task != __mach_task_self ())
44     /* The sender wasn't the kernel.  */
45     return EPERM;
46
47   d.exc = exception;
48 #ifdef EXC_MASK_ALL
49   assert (codeCnt >= 2);
50   d.exc_code = code[0];
51   d.exc_subcode = code[1];
52 #else
53   d.exc_code = code;
54   d.exc_subcode = subcode;
55 #endif
56
57   /* Call the machine-dependent function to translate the Mach exception
58      codes into a signal number and subcode.  */
59   _hurd_exception2signal (&d, &signo);
60
61   /* Find the sigstate structure for the faulting thread.  */
62   __mutex_lock (&_hurd_siglock);
63   for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
64     if (ss->thread == thread)
65       break;
66   __mutex_unlock (&_hurd_siglock);
67   if (ss == NULL)
68     ss = _hurd_thread_sigstate (thread); /* Allocate a fresh one.  */
69
70   if (__spin_lock_locked (&ss->lock))
71     {
72       /* Loser.  The thread faulted with its sigstate lock held.  Its
73          sigstate data is now suspect.  So we reset the parts of it which
74          could cause trouble for the signal thread.  Anything else
75          clobbered therein will just hose this user thread, but it's
76          faulting already.
77
78          This is almost certainly a library bug: unless random memory
79          clobberation caused the sigstate lock to gratuitously appear held,
80          no code should do anything that can fault while holding the
81          sigstate lock.  */
82
83       __spin_unlock (&ss->critical_section_lock);
84       ss->context = NULL;
85       __spin_unlock (&ss->lock);
86     }
87
88   /* Post the signal.  */
89   _hurd_internal_post_signal (ss, signo, &d,
90                               MACH_PORT_NULL, MACH_MSG_TYPE_PORT_SEND,
91                               0);
92
93   return KERN_SUCCESS;
94 }
95
96 #ifdef EXC_MASK_ALL
97 /* XXX New interface flavor has additional RPCs that we could be using
98    instead.  These RPCs roll a thread_get_state/thread_set_state into
99    the message, so the signal thread ought to use these to save some calls.
100  */
101 kern_return_t
102 _S_catch_exception_raise_state (mach_port_t port,
103                                 exception_type_t exception,
104                                 exception_data_t code,
105                                 mach_msg_type_number_t codeCnt,
106                                 int *flavor,
107                                 thread_state_t old_state,
108                                 mach_msg_type_number_t old_stateCnt,
109                                 thread_state_t new_state,
110                                 mach_msg_type_number_t *new_stateCnt)
111 {
112   abort ();
113   return KERN_FAILURE;
114 }
115
116 kern_return_t
117 _S_catch_exception_raise_state_identity (mach_port_t exception_port,
118                                          thread_t thread,
119                                          task_t task,
120                                          exception_type_t exception,
121                                          exception_data_t code,
122                                          mach_msg_type_number_t codeCnt,
123                                          int *flavor,
124                                          thread_state_t old_state,
125                                          mach_msg_type_number_t old_stateCnt,
126                                          thread_state_t new_state,
127                                          mach_msg_type_number_t *new_stateCnt)
128 {
129   abort ();
130   return KERN_FAILURE;
131 }
132 #endif