[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    nspluginscan fork() patch (the attachment)
From:       Ilya Konstantinov <kde-core-devel () future ! galanet ! net>
Date:       2001-09-02 18:46:39
[Download RAW message or body]

And now, the attachment itself :)

["nspluginscan_fork.patch" (text/plain)]

Index: pluginscan.cpp
===================================================================
RCS file: /home/kde/kdebase/nsplugins/pluginscan.cpp,v
retrieving revision 1.31
diff -u -3 -d -p -r1.31 pluginscan.cpp
--- pluginscan.cpp	2001/04/26 15:24:22	1.31
+++ pluginscan.cpp	2001/09/02 18:38:55
@@ -23,6 +23,10 @@
 
 */
 
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+              
 #include <qdir.h>
 #include <qfile.h>
 #include <qtextstream.h>
@@ -188,94 +192,148 @@ void scanDirectory( QString dir, QString
         kdDebug(1433) << "Checking library " << absFile << endl;
 
         // open the library and ask for the mimetype
-        kdDebug(1433) << " - opening" << absFile << endl;
-        KLibrary *_handle = KLibLoader::self()->library( absFile.latin1() );
+        kdDebug(1433) << " - opening " << absFile << endl;
+        
+        // fork, so that a crash in the plugin won't stop the scanning of other plugins
+        int pipes[2];
+        if (pipe(pipes) != 0) break;
+        FILE *read_pipe = fdopen(pipes[0], "r");
+        FILE *write_pipe = fdopen(pipes[1], "w"); 
+        int loader_pid = fork();
+        
+        if (loader_pid == 0) {
 
-        if (!_handle) {
-            kdDebug(1433) << " - open failed, skipping " << endl;
-            continue;
-        }
+           KLibrary *_handle = KLibLoader::self()->library( absFile.latin1() );
+           if (!_handle) {
+               kdDebug(1433) << " - open failed, skipping " << endl;
+               exit(1);
+           }
 
-        // ask for name and description
-        QString name = i18n("Unnamed plugin");
-        QString description;
+           // create a QDataStream for our IPC pipe (to send plugin info back to the parent)
+           QFile stream_file;
+           stream_file.open(IO_WriteOnly, write_pipe);
+           QDataStream stream(&stream_file);
 
-        NPError (*func_GetValue)(void *, NPPVariable, void *) =
-            (NPError(*)(void *, NPPVariable, void *))
-            _handle->symbol("NP_GetValue");
-        if ( func_GetValue ) {
+           // ask for name and description
+           QString name = i18n("Unnamed plugin");
+           QString description;
 
-            // get name
-            char *buf = 0;
-            NPError err = func_GetValue( 0, NPPVpluginNameString,
-                                         (void*)&buf );
-            if ( err==NPERR_NO_ERROR )
-                name = QString::fromLatin1( buf );
-            kdDebug() << "name = " << name << endl;
+           NPError (*func_GetValue)(void *, NPPVariable, void *) =
+               (NPError(*)(void *, NPPVariable, void *))
+               _handle->symbol("NP_GetValue");
+           if ( func_GetValue ) {
 
-            // get name
-            NPError nperr = func_GetValue( 0, NPPVpluginDescriptionString,
-                                         (void*)&buf );
-            if ( nperr==NPERR_NO_ERROR )
-                description = QString::fromLatin1( buf );
-            kdDebug() << "description = " << description << endl;
-        }
+               // get name
+               char *buf = 0;
+               NPError err = func_GetValue( 0, NPPVpluginNameString,
+                                            (void*)&buf );
+               if ( err==NPERR_NO_ERROR )
+                   name = QString::fromLatin1( buf );
+               kdDebug() << "name = " << name << endl;
 
-        // get mime description function pointer
-        char* (*func_GetMIMEDescription)() =
-            (char *(*)())_handle->symbol("NP_GetMIMEDescription");
-        if ( !func_GetMIMEDescription ) {
-            kdDebug(1433) << " - no GetMIMEDescription, skipping" << endl;
-            KLibLoader::self()->unloadLibrary( absFile.latin1() );
-            continue;
-        }
+               // get name
+               NPError nperr = func_GetValue( 0, NPPVpluginDescriptionString,
+                                            (void*)&buf );
+               if ( nperr==NPERR_NO_ERROR )
+                   description = QString::fromLatin1( buf );
+               kdDebug() << "description = " << description << endl;
+           }
 
-        // ask for mime information
-        QString mimeInfo = func_GetMIMEDescription();
-        if ( mimeInfo.isEmpty() ) {
-            kdDebug(1433) << " - no mime info returned, skipping" << endl;
-            KLibLoader::self()->unloadLibrary( absFile.latin1() );
-            continue;
-        }
+           // get mime description function pointer
+           char* (*func_GetMIMEDescription)() =
+               (char *(*)())_handle->symbol("NP_GetMIMEDescription");
+           if ( !func_GetMIMEDescription ) {
+               kdDebug(1433) << " - no GetMIMEDescription, skipping" << endl;
+               KLibLoader::self()->unloadLibrary( absFile.latin1() );
+               exit(1);
+           }
 
-        // remove version info, as it is not used at the moment
-        QRegExp versionRegExp(";version=[^:]*:");
-        mimeInfo.replace( versionRegExp, ":");
+           // ask for mime information
+           QString mimeInfo = func_GetMIMEDescription();
+           if ( mimeInfo.isEmpty() ) {
+               kdDebug(1433) << " - no mime info returned, skipping" << endl;
+               KLibLoader::self()->unloadLibrary( absFile.latin1() );
+               exit(1);
+           }
 
-        // note the plugin name
-        cache << "[" << absFile << "]" << endl;
+           // remove version info, as it is not used at the moment
+           QRegExp versionRegExp(";version=[^:]*:");
+           mimeInfo.replace( versionRegExp, ":");
+           
+           // return the gathered info to the parent
+           stream << name;
+           stream << description;
+           stream << mimeInfo;
+           
+           // unload plugin lib
+           kdDebug(1433) << " - unloading plugin" << endl;
+           KLibLoader::self()->unloadLibrary( absFile.latin1() );
+           exit(0);
 
-        // get mime types from string
-        QStringList types = QStringList::split( ';', mimeInfo );
-        QStringList::Iterator type;
-        for ( type=types.begin(); type!=types.end(); ++type ) {
+        } else if (loader_pid == -1) {
 
-            kdDebug(1433) << " - type=" << *type << endl;
+	   // unable to fork
 
-            // write into type cache
-            QStringList tokens = QStringList::split(':', *type, TRUE);
-            QStringList::Iterator token;
-            token = tokens.begin();
-            cache << (*token).lower();
-            ++token;
-            for ( ; token!=tokens.end(); ++token )
-                cache << ":" << *token;
-            cache << endl;
+        } else {
 
-            // append type to MIME type list
-            if ( !mimeInfoList.contains( *type ) )
-                mimeInfoList.append( name + ":" + *type );
-        }
+           // the parent process waits for the child to exit (or die)
+           int status;
+           waitpid(loader_pid, &status, 0);
+           
+           // if exited correctly and exit status == 0
+           if ((WIFEXITED(status) != 0) && (WEXITSTATUS(status) == 0)) {
+              
+              // create a QDataStream for our IPC pipe (to get info gathered by the child)
+              QFile stream_file;
+              stream_file.open(IO_ReadOnly, read_pipe);
+              QDataStream stream(&stream_file);
+           
+              if (!stream.atEnd()) {
+                 QString name, description, mimeInfo;
+                 stream >> name;
+                 stream >> description;
+                 stream >> mimeInfo;
+                 
+                 // note the plugin name
+                 cache << "[" << absFile << "]" << endl;
 
-        // register plugin for javascript
-        registerPlugin( name, description, files[i], mimeInfo );
+                 // get mime types from string
+                 QStringList types = QStringList::split( ';', mimeInfo );
+                 QStringList::Iterator type;
+                 for ( type=types.begin(); type!=types.end(); ++type ) {
 
-        // unload plugin lib
-        kdDebug(1433) << " - unloading  plugin" << endl;
-        KLibLoader::self()->unloadLibrary( absFile.latin1() );
+                    kdDebug(1433) << " - type=" << *type << endl;
+
+                    // write into type cache
+                    QStringList tokens = QStringList::split(':', *type, TRUE);
+                    QStringList::Iterator token;
+                    token = tokens.begin();
+                    cache << (*token).lower();
+                    ++token;
+                    for ( ; token!=tokens.end(); ++token )
+                        cache << ":" << *token;
+                    cache << endl;
+
+                    // append type to MIME type list
+                    if ( !mimeInfoList.contains( *type ) )
+                        mimeInfoList.append( name + ":" + *type );
+                 }
+
+                 // register plugin for javascript
+                 registerPlugin( name, description, files[i], mimeInfo );
+
+              }
+           }
+
+        }
+        
+        fclose(read_pipe);
+        fclose(write_pipe);
     }
 
     // iterate over all sub directories
+    // NOTE: Mozilla doesn't iterate over subdirectories of the plugin dir.
+    // We still do (as Netscape 4 did).
     QDir dirs( dir, QString::null, QDir::Name|QDir::IgnoreCase, QDir::Dirs );
     if ( !dirs.exists() )
       return;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic