Implemented aborting on exit of child process of --gnokiid
[gnokii.git] / gnokii / gnokii.c
index df3ce22..e6692ab 100644 (file)
@@ -20,6 +20,8 @@
 #include <ctype.h>
 #include <time.h>
 #include <sys/stat.h>
+#include <limits.h>
+#include <errno.h>
 
 #ifdef UCLINUX
 /* <getopt.h> or "getopt.h" would include insufficient getopt.h from uClinux */
@@ -948,7 +950,7 @@ static int usage(void)
 
 #ifdef UCLINUX
   fprintf(stdout, _(
-"          gnokii --gnokiid [--debug]\n"
+"          gnokii --gnokiid [--debug] [<child to run> [<child args>...]]\n"
   ));
 #endif
 
@@ -1232,7 +1234,7 @@ int main(int argc, char *argv[])
 #endif /* UCLINUX */
 
 #ifdef UCLINUX
-    { OPT_GNOKIID,           0, 1, 0 },
+    { OPT_GNOKIID,           0, INT_MAX, 0 },
 #endif /* UCLINUX */
 
     { 0, 0, 0, 0 },
@@ -1280,6 +1282,7 @@ int main(int argc, char *argv[])
 
     for(i = 2; i < argc; i++)
       nargv[i-2] = argv[i];
+               nargv[argc-2] = NULL;   /* required by gnokiid() for execv(3) */
        
     if(checkargs(c, gals, nargc)) {
 
@@ -4116,6 +4119,12 @@ int monitormode(int argc, char *argv[])
 
 #ifdef UCLINUX
 
+static void gnokiid_SIGCHLD(int signo)
+{
+       fprintf (stderr, _("Child process exited, aborting...\n"));
+       exit(2);
+}
+
 static int gnokiid(int argc, char *argv[])
 {
        bool    DebugMode;  /* When true, run in debug mode */
@@ -4129,17 +4138,16 @@ static int gnokiid(int argc, char *argv[])
        DebugMode = false;
        if(argc>0)
        {
-               if( strcmp(argv[0],"--debug" ))
+               if( !strcmp(argv[0],"--debug" ))
                {
-                       usage();
-                       return -1;
-               }
-               else
                        DebugMode = true;
+                       argv++;
+                       argc--;
+               }
        }
 
 #ifdef DEBUG
-  fprintf (stderr, _("Entering gnokiid mode...\n"));
+  fprintf (stderr, _("Initializing gnokiid mode...\n"));
 #endif
 
        if (CFG_ReadConfig(&Model, &Port, &Initlength, &Connection, &BinDir, true) < 0)
@@ -4148,6 +4156,33 @@ static int gnokiid(int argc, char *argv[])
   if (VM_Initialise(Model, Port, Initlength, GCT_FBUS, BinDir, DebugMode, true, ""/*SynchronizeTime*/) == false)
                return (-1);
 
+       if (argc>0) {
+#ifdef DEBUG
+               fprintf (stderr, _("Spawning gnokiid startup child process \"%s\"...\n"), *argv);
+#endif
+               signal(SIGCHLD,gnokiid_SIGCHLD);
+               errno=0;
+               switch (vfork()) {
+                       case -1: /* vfork() failure */
+                               fprintf (stderr, _("vfork() failed! (%s)\n"),strerror(errno));
+                               return -1;
+                       case 0: /* child */
+                               execv(*argv,argv);
+                               fprintf (stderr, _("Spawn of child process failed! (%s)\n"),strerror(errno));
+                               _exit(9);
+                               break;
+                       default: /* parent */
+                               /* PASSTHRU */
+                               break;
+                       }
+               }
+
+#ifdef DEBUG
+  fprintf (stderr, _("Entering gnokiid virtual modem main loop...\n"));
+#endif
+
+       VM_ThreadLoop();
+
        VM_Terminate();
 
   return 0;
@@ -7762,32 +7797,32 @@ int binringtoneconvert(int argc, char *argv[])
            w=w*2;
            if (w>z && (w/2)<=z) {
              switch (m) {
-               case 1:fprintf(file,_("16"));break;\r
-               case 2:fprintf(file,_("8"));break;\r
-               case 3:fprintf(file,_("4"));break;\r
-               case 4:fprintf(file,_("2"));break;\r
-               case 5:fprintf(file,_("1"));break;\r
+               case 1:fprintf(file,_("16"));break;
+               case 2:fprintf(file,_("8"));break;
+               case 3:fprintf(file,_("4"));break;
+               case 4:fprintf(file,_("2"));break;
+               case 5:fprintf(file,_("1"));break;
              }
              break;
            }
          }
          if (z>w) fprintf(file,_("1"));
          pause=false;
-          switch (GSM_GetNote(j)) {\r
-            case Note_C  :fprintf(file,_("c"));break;\r
-            case Note_Cis:fprintf(file,_("c#"));break;\r
-            case Note_D  :fprintf(file,_("d"));break;\r
-            case Note_Dis:fprintf(file,_("d#"));break;\r
-            case Note_E  :fprintf(file,_("e"));break;\r
-            case Note_F  :fprintf(file,_("f"));break;\r
-            case Note_Fis:fprintf(file,_("f#"));break;\r
-            case Note_G  :fprintf(file,_("g"));break;\r
-            case Note_Gis:fprintf(file,_("g#"));break;\r
-            case Note_A  :fprintf(file,_("a"));break;\r
-            case Note_Ais:fprintf(file,_("a#"));break;\r
-            case Note_H  :fprintf(file,_("h"));break;\r
-            default      :pause=true;fprintf(file,_("p"));break; //Pause ?\r
-          }\r
+          switch (GSM_GetNote(j)) {
+            case Note_C  :fprintf(file,_("c"));break;
+            case Note_Cis:fprintf(file,_("c#"));break;
+            case Note_D  :fprintf(file,_("d"));break;
+            case Note_Dis:fprintf(file,_("d#"));break;
+            case Note_E  :fprintf(file,_("e"));break;
+            case Note_F  :fprintf(file,_("f"));break;
+            case Note_Fis:fprintf(file,_("f#"));break;
+            case Note_G  :fprintf(file,_("g"));break;
+            case Note_Gis:fprintf(file,_("g#"));break;
+            case Note_A  :fprintf(file,_("a"));break;
+            case Note_Ais:fprintf(file,_("a#"));break;
+            case Note_H  :fprintf(file,_("h"));break;
+            default      :pause=true;fprintf(file,_("p"));break; //Pause ?
+          }
          w=deflen*1.5;
          for (m=0;m<6;m++) {
            w=w*2;
@@ -7932,11 +7967,11 @@ int setsimlock()
     fprintf(stderr,_("Error getting simlock info\n"));GSM->Terminate();return -1;
   }
   /* Opening all locks (we must check, if we can open them) */
-  NULL_SendMessageSequence\r(50, &CurrentMagicError, 10, 0x40,openbuffer0);
-  openbuffer[4]=1;NULL_SendMessageSequence\r(50, &CurrentMagicError, 10, 0x40,openbuffer);
-  openbuffer[4]=2;NULL_SendMessageSequence\r(50, &CurrentMagicError, 10, 0x40,openbuffer);
-  openbuffer[4]=4;NULL_SendMessageSequence\r(50, &CurrentMagicError, 10, 0x40,openbuffer);
-  openbuffer[4]=8;NULL_SendMessageSequence\r(50, &CurrentMagicError, 10, 0x40,openbuffer);
+  NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer0);
+  openbuffer[4]=1;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
+  openbuffer[4]=2;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
+  openbuffer[4]=4;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
+  openbuffer[4]=8;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
   if (GSM->SimlockInfo(&siml)!=GE_NONE) {
     fprintf(stderr,_("Error getting simlock info\n"));GSM->Terminate();return -1;
   }
@@ -7985,13 +8020,13 @@ int setsimlock()
   }  
   /* Closing simlock with given values */
   closebuffer[4]=1+2+4+8;
-  NULL_SendMessageSequence\r(50, &CurrentMagicError, 20, 0x40,closebuffer);  
+  NULL_SendMessageSequence(50, &CurrentMagicError, 20, 0x40,closebuffer);  
   /* Opening all locks */
-  NULL_SendMessageSequence\r(50, &CurrentMagicError, 10, 0x40,openbuffer0);
-  openbuffer[4]=1;NULL_SendMessageSequence\r(50, &CurrentMagicError, 10, 0x40,openbuffer);
-  openbuffer[4]=2;NULL_SendMessageSequence\r(50, &CurrentMagicError, 10, 0x40,openbuffer);
-  openbuffer[4]=4;NULL_SendMessageSequence\r(50, &CurrentMagicError, 10, 0x40,openbuffer);
-  openbuffer[4]=8;NULL_SendMessageSequence\r(50, &CurrentMagicError, 10, 0x40,openbuffer);
+  NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer0);
+  openbuffer[4]=1;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
+  openbuffer[4]=2;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
+  openbuffer[4]=4;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
+  openbuffer[4]=8;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
   GSM->Reset(0x03);
   GSM->Terminate();
   return 0;
@@ -8091,7 +8126,7 @@ int geteeprom()
     
     if ((i/256)!=((i-1)/256)) fprintf(stderr,_("."));
     
-    if (NULL_SendMessageSequence(50, &CurrentMagicError, 9, 0x40,buffer)!=GE_NONE)\r      break;
+    if (NULL_SendMessageSequence(50, &CurrentMagicError, 9, 0x40,buffer)!=GE_NONE)       break;
 
     i=i+0x10;
   }