lynx-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

lynx-dev LYCgi.c patches


From: Klaus Weide
Subject: lynx-dev LYCgi.c patches
Date: Tue, 29 Dec 1998 12:50:13 -0600 (CST)

If the exec for a lynxcgi script fails, very strange things can
happen.  To reproduce, try a shell script which is missing the "#!"
line, or a file with permissions like -rw-r-xr-x owned by the user
running lynx.  (More fun with -trace, be warned that the tracelog file
may fill up the disk with garbage.)  Main problem is that the child
doesn't exit.


Patches against 2.8.2dev.12.

* Changes for handling lynxcgi: handle failure of execve(), by showing
  the system error and then _exit()ing the child process.  Make sure
  REQUEST_METHOD is always set.  Added checks for EINTR and other
  errors from read().

*** lynx2-8-2.orig/src/LYCgi.c  Sat Dec 26 14:50:01 1998
--- lynx2-8-2/src/LYCgi.c       Tue Dec 29 12:26:53 1998
***************
*** 354,359 ****
--- 354,361 ----
                        LYNX_NAME, LYNX_VERSION);
                add_environment_value(server_software);
            }
+           fflush(stdout);
+           fflush(stderr);
  
            if ((pid = fork()) > 0) { /* The good, */
                int chars, total_chars;
***************
*** 402,412 ****
                }
  
                HTReadProgress(total_chars = 0, 0);
!               while((chars = read(fd2[0], buf, sizeof(buf))) > 0) {
                    HTReadProgress(total_chars += chars, 0);
                    CTRACE(tfp, "LYNXCGI: Rx: %.*s\n", chars, buf);
                    (*target->isa->put_block)(target, buf, chars);
                }
  #if !HAVE_WAITPID
                while (wait(&wstatus) != pid)
                    ; /* do nothing */
--- 404,439 ----
                }
  
                HTReadProgress(total_chars = 0, 0);
!               while((chars = read(fd2[0], buf, sizeof(buf))) != 0) {
!                   if (chars < 0) {
! #ifdef EINTR
!                       if (errno == EINTR)
!                           continue;
! #endif /* EINTR */
! #ifdef ERESTARTSYS
!                       if (errno == ERESTARTSYS)
!                           continue;
! #endif /* ERESTARTSYS */
!                       if (TRACE) {
!                           perror("LYNXCGI: read() of CGI output failed");
!                       }
!                       break;
!                   }
                    HTReadProgress(total_chars += chars, 0);
                    CTRACE(tfp, "LYNXCGI: Rx: %.*s\n", chars, buf);
                    (*target->isa->put_block)(target, buf, chars);
                }
+ 
+               if (chars < 0 && total_chars == 0) {
+                   status = HT_NOT_LOADED;
+                   (*target->isa->_abort)(target, NULL);
+                   target = NULL;
+               } else if (chars != 0) {
+                   status = HT_PARTIAL_CONTENT;
+               } else {
+                   status = HT_LOADED;
+               }
+ 
  #if !HAVE_WAITPID
                while (wait(&wstatus) != pid)
                    ; /* do nothing */
***************
*** 424,435 ****
                }
  #endif /* !HAVE_WAITPID */
                close(fd2[0]);
-               status = HT_LOADED;
  
            } else if (pid == 0) { /* The Bad, */
                char **argv = NULL;
                int argv_cnt = 3; /* name, one arg and terminator */
                char **cur_argv = NULL;
  
                /* Set up output pipe */
                close(fd2[0]);
--- 451,462 ----
                }
  #endif /* !HAVE_WAITPID */
                close(fd2[0]);
  
            } else if (pid == 0) { /* The Bad, */
                char **argv = NULL;
                int argv_cnt = 3; /* name, one arg and terminator */
                char **cur_argv = NULL;
+               int exec_errno;
  
                /* Set up output pipe */
                close(fd2[0]);
***************
*** 497,503 ****
                    /* Data for a get/search form */
                    if (is_www_index) {
                        add_environment_value("REQUEST_METHOD=SEARCH");
!                   } else if (!anAnchor->isHEAD) {
                        add_environment_value("REQUEST_METHOD=GET");
                    }
  
--- 524,530 ----
                    /* Data for a get/search form */
                    if (is_www_index) {
                        add_environment_value("REQUEST_METHOD=SEARCH");
!                   } else if (!anAnchor->isHEAD && !anAnchor->post_data) {
                        add_environment_value("REQUEST_METHOD=GET");
                    }
  
***************
*** 523,528 ****
--- 550,557 ----
                        }
                        cp++;
                    }
+               } else if (!anAnchor->isHEAD && !anAnchor->post_data) {
+                   add_environment_value("REQUEST_METHOD=GET");
                }
                *cur_argv = NULL;       /* Terminate argv */
                argv[0] = pgm;
***************
*** 557,565 ****
--- 586,607 ----
                /* End WebSter Mods  -jkt */
  
                execve(argv[0], argv, env);
+               exec_errno = errno;
                if (TRACE) {
                    perror("LYNXCGI: execve failed");
                }
+               printf("Content-Type: text/plain\r\n\r\n");
+               if (!anAnchor->isHEAD) {
+                   printf("exec of %s failed", pgm);
+ #ifdef HAVE_STRERROR          
+                   printf(": %s.\r\n", strerror(exec_errno));
+ #else
+                   printf(". System errno is %d.\r\n", exec_errno);
+ #endif /* HAVE_STRERROR */
+               }
+               fflush(stdout);
+               fflush(stderr);
+               _exit(1);
  
            } else {    /* and the Ugly */
                HTAlert(CONNECT_FAILED);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]