2008-12-19 Rolf Bjarne Kvinge <RKvinge@novell.com>
[mono.git] / mono / io-layer / daemon.c
index 62aa75ce1f335d8a18b7e0fcbc90aa92ad9791c5..0f5ad38ab882c7136f58c7e02e21ca1e4594c979 100644 (file)
@@ -830,23 +830,11 @@ static void send_reply (GIOChannel *channel, WapiHandleResponse *resp)
        _wapi_daemon_response (g_io_channel_unix_get_fd (channel), resp);
 }
 
-/*
- * process_new:
- * @channel: The client making the request
- * @channel_data: Our data for this channel
- * @type: type to init handle to
- *
- * Find a free handle and initialize it to 'type', increase refcnt and
- * send back a reply to the client.
- */
-static void process_new (GIOChannel *channel, ChannelData *channel_data,
-                        WapiHandleType type)
+static guint32 new_handle_with_shared_check (WapiHandleType type)
 {
-       guint32 handle;
-       WapiHandleResponse resp={0};
-       
-       handle=_wapi_handle_new_internal (type);
-       if(handle==0) {
+       guint32 handle = 0;
+
+       while ((handle = _wapi_handle_new_internal (type)) == 0) {
                /* Try and allocate a new shared segment, and have
                 * another go
                 */
@@ -871,15 +859,34 @@ static void process_new (GIOChannel *channel, ChannelData *channel_data,
                                        channels[i].open_handles=_wapi_g_renew0 (channels[i].open_handles, old_len, new_len);
                                }
                        }
-
-                       handle=_wapi_handle_new_internal (type);
                } else {
                        /* Map failed.  Just return 0 meaning "out of
                         * handles"
                         */
+                       break;
                }
        }
        
+       return(handle);
+}
+
+/*
+ * process_new:
+ * @channel: The client making the request
+ * @channel_data: Our data for this channel
+ * @type: type to init handle to
+ *
+ * Find a free handle and initialize it to 'type', increase refcnt and
+ * send back a reply to the client.
+ */
+static void process_new (GIOChannel *channel, ChannelData *channel_data,
+                        WapiHandleType type)
+{
+       guint32 handle;
+       WapiHandleResponse resp={0};
+       
+       handle = new_handle_with_shared_check (type);
+       
        /* handle might still be set to 0.  This is handled at the
         * client end
         */
@@ -1064,11 +1071,11 @@ static void process_process_fork (GIOChannel *channel, ChannelData *channel_data
         * client must check if either handle is 0 and take
         * appropriate error handling action.
         */
-       process_handle=_wapi_handle_new_internal (WAPI_HANDLE_PROCESS);
+       process_handle = new_handle_with_shared_check (WAPI_HANDLE_PROCESS);
        ref_handle (daemon_channel_data, process_handle);
        ref_handle (channel_data, process_handle);
        
-       thread_handle=_wapi_handle_new_internal (WAPI_HANDLE_THREAD);
+       thread_handle = new_handle_with_shared_check (WAPI_HANDLE_THREAD);
        ref_handle (daemon_channel_data, thread_handle);
        ref_handle (channel_data, thread_handle);
        
@@ -1097,6 +1104,16 @@ static void process_process_fork (GIOChannel *channel, ChannelData *channel_data
                cmd=_wapi_handle_scratch_lookup (process_fork.cmd);
                dir=_wapi_handle_scratch_lookup (process_fork.dir);
                env=_wapi_handle_scratch_lookup_string_array (process_fork.env);
+
+               _wapi_lookup_handle (GUINT_TO_POINTER (process_handle),
+                                    WAPI_HANDLE_PROCESS,
+                                    (gpointer *)&process_handle_data,
+                                    NULL);
+
+               _wapi_lookup_handle (GUINT_TO_POINTER (thread_handle),
+                                    WAPI_HANDLE_THREAD,
+                                    (gpointer *)&thread_handle_data,
+                                    NULL);
                
                ret=g_shell_parse_argv (cmd, NULL, &argv, &gerr);
                if(ret==FALSE) {
@@ -1109,16 +1126,6 @@ static void process_process_fork (GIOChannel *channel, ChannelData *channel_data
                        g_message (G_GNUC_PRETTY_FUNCTION ": forking");
 #endif
 
-                       _wapi_lookup_handle (GUINT_TO_POINTER (process_handle),
-                                            WAPI_HANDLE_PROCESS,
-                                            (gpointer *)&process_handle_data,
-                                            NULL);
-
-                       _wapi_lookup_handle (GUINT_TO_POINTER (thread_handle),
-                                            WAPI_HANDLE_THREAD,
-                                            (gpointer *)&thread_handle_data,
-                                            NULL);
-
                        /* Fork, exec cmd with args and optional env,
                         * and return the handles with pid and blank
                         * thread id
@@ -1207,12 +1214,20 @@ static void process_process_fork (GIOChannel *channel, ChannelData *channel_data
 
                /* store process name, based on the last section of the cmd */
                {
-                       char *slash=strrchr (argv[0], '/');
+                       char *slash;
                        
-                       if(slash!=NULL) {
-                               process_handle_data->proc_name=_wapi_handle_scratch_store (slash+1, strlen (slash+1));
+                       /* This should never fail, but it seems it can...
+                        */
+                       if (argv[0] != NULL) {
+                               slash=strrchr (argv[0], '/');
+                       
+                               if(slash!=NULL) {
+                                       process_handle_data->proc_name=_wapi_handle_scratch_store (slash+1, strlen (slash+1));
+                               } else {
+                                       process_handle_data->proc_name=_wapi_handle_scratch_store (argv[0], strlen (argv[0]));
+                               }
                        } else {
-                               process_handle_data->proc_name=_wapi_handle_scratch_store (argv[0], strlen (argv[0]));
+                               process_handle_data->proc_name = _wapi_handle_scratch_store (cmd, strlen(cmd));
                        }
                }
                
@@ -1246,7 +1261,7 @@ static void process_process_fork (GIOChannel *channel, ChannelData *channel_data
 
                resp.u.process_fork.pid=pid;
        }
-                       
+
        resp.u.process_fork.process_handle=process_handle;
        resp.u.process_fork.thread_handle=thread_handle;
 
@@ -1491,6 +1506,9 @@ void _wapi_daemon_main(gpointer data, gpointer scratch)
        /* Note that we've got the starting segment already */
        _wapi_shared_data[0]->num_segments=1;
        _wapi_shm_mapped_segments=1;
+
+       _wapi_fd_offset_table_size=getdtablesize ();
+       _wapi_shared_data[0]->fd_offset_table_size = _wapi_fd_offset_table_size;
        
        startup ();