[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