]> git.saurik.com Git - apt.git/commitdiff
Signal safety
authorArch Librarian <arch@canonical.com>
Mon, 20 Sep 2004 16:53:05 +0000 (16:53 +0000)
committerArch Librarian <arch@canonical.com>
Mon, 20 Sep 2004 16:53:05 +0000 (16:53 +0000)
Author: jgg
Date: 1999-03-16 00:43:55 GMT
Signal safety

apt-pkg/acquire-worker.cc
apt-pkg/acquire.cc
apt-pkg/contrib/fileutl.cc
apt-pkg/contrib/strutl.cc
cmdline/acqprogress.cc

index 099a43e2ec214142ef878d047039cab7f20935a9..4c204041a1676a7287ee059e9200afe4e01f6208 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: acquire-worker.cc,v 1.19 1999/01/30 08:08:54 jgg Exp $
+// $Id: acquire-worker.cc,v 1.20 1999/03/16 00:43:55 jgg Exp $
 /* ######################################################################
 
    Acquire Worker 
 
 #include <sys/stat.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <wait.h>
 #include <stdio.h>
+#include <errno.h>
                                                                        /*}}}*/
 
 // Worker::Worker - Constructor for Queue startup                      /*{{{*/
@@ -130,6 +132,17 @@ bool pkgAcquire::Worker::Start()
       SetCloseExec(STDOUT_FILENO,false);
       SetCloseExec(STDIN_FILENO,false);      
       SetCloseExec(STDERR_FILENO,false);
+
+      signal(SIGPIPE,SIG_DFL);
+      signal(SIGQUIT,SIG_DFL);
+      signal(SIGINT,SIG_DFL);
+      signal(SIGWINCH,SIG_DFL);
+      signal(SIGCONT,SIG_DFL);
+      signal(SIGTSTP,SIG_DFL);
+      
+      // Close all of our FDs - just in case
+      for (int K = 3; K != 40; K++)
+        fcntl(K,F_SETFD,FD_CLOEXEC);
       
       const char *Args[2];
       Args[0] = Method.c_str();
@@ -433,7 +446,13 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
 /* */
 bool pkgAcquire::Worker::OutFdReady()
 {
-   int Res = write(OutFd,OutQueue.begin(),OutQueue.length());
+   int Res;
+   do
+   {
+      Res = write(OutFd,OutQueue.begin(),OutQueue.length());
+   }
+   while (Res < 0 && errno == EINTR);
+   
    if (Res <= 0)
       return MethodFailure();
 
index aadfe2efb0c94d3db996fd34b9f760fef6bb6fe2..80624f9d3341bbc209123b8ca9b94cecc10490ff 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: acquire.cc,v 1.28 1999/03/15 08:10:39 jgg Exp $
+// $Id: acquire.cc,v 1.29 1999/03/16 00:43:55 jgg Exp $
 /* ######################################################################
 
    Acquire - File Acquiration
@@ -297,7 +297,13 @@ bool pkgAcquire::Run()
       FD_ZERO(&WFds);
       SetFds(Highest,&RFds,&WFds);
       
-      int Res = select(Highest+1,&RFds,&WFds,0,&tv);
+      int Res;
+      do
+      {
+        Res = select(Highest+1,&RFds,&WFds,0,&tv);
+      }
+      while (Res < 0 && errno == EINTR);
+      
       if (Res < 0)
       {
         _error->Errno("select","Select has failed");
index a761794eefd4d4ad6764cc0d1a4d9fca99ed394f..a28dce6c07022f9b4421f4222f486d4d4fef4586 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: fileutl.cc,v 1.22 1999/03/15 08:10:39 jgg Exp $
+// $Id: fileutl.cc,v 1.23 1999/03/16 00:43:55 jgg Exp $
 /* ######################################################################
    
    File Utilities
@@ -38,14 +38,21 @@ bool CopyFile(FileFd &From,FileFd &To)
    
    // Buffered copy between fds
    unsigned char *Buf = new unsigned char[64000];
-   long Size;
-   while ((Size = read(From.Fd(),Buf,64000)) > 0)
+   unsigned long Size = From.Size();
+   while (Size != 0)
    {
-      if (To.Write(Buf,Size) == false)
+      unsigned long ToRead = Size;
+      if (Size > 64000)
+        ToRead = 64000;
+      
+      if (To.Read(Buf,ToRead) == false || 
+         To.Write(Buf,ToRead) == false)
       {
         delete [] Buf;
         return false;
       }
+      
+      Size -= ToRead;
    }
 
    delete [] Buf;
@@ -175,14 +182,28 @@ bool WaitFd(int Fd,bool write,unsigned long timeout)
    tv.tv_sec = timeout;
    tv.tv_usec = 0;
    if (write == true) 
-   {
-      if (select(Fd+1,0,&Set,0,(timeout != 0?&tv:0)) <= 0)
-         return false;
+   {      
+      int Res;
+      do
+      {
+        Res = select(Fd+1,0,&Set,0,(timeout != 0?&tv:0));
+      }
+      while (Res < 0 && errno == EINTR);
+      
+      if (Res <= 0)
+        return false;
    } 
    else 
    {
-      if (select(Fd+1,&Set,0,0,(timeout != 0?&tv:0)) <= 0)
-         return false;
+      int Res;
+      do
+      {
+        Res = select(Fd+1,&Set,0,0,(timeout != 0?&tv:0));
+      }
+      while (Res < 0 && errno == EINTR);
+      
+      if (Res <= 0)
+        return false;
    }
    
    return true;
@@ -239,16 +260,33 @@ FileFd::~FileFd()
                                                                        /*}}}*/
 // FileFd::Read - Read a bit of the file                               /*{{{*/
 // ---------------------------------------------------------------------
-/* */
+/* We are carefull to handle interruption by a signal while reading 
+   gracefully. */
 bool FileFd::Read(void *To,unsigned long Size)
 {
-   if (read(iFd,To,Size) != (signed)Size)
+   int Res;
+   errno = 0;
+   do
    {
-      Flags |= Fail;
-      return _error->Errno("read","Read error");
-   }   
+      Res = read(iFd,To,Size);
+      if (Res < 0 && errno == EINTR)
+        continue;
+      if (Res < 0)
+      {
+        Flags |= Fail;
+        return _error->Errno("read","Read error");
+      }
       
-   return true;
+      To = (char *)To + Res;
+      Size -= Res;
+   }
+   while (Res > 0 && Size > 0);
+   
+   if (Size == 0)
+      return true;
+   
+   Flags |= Fail;
+   return _error->Error("read, still have %u to read but none left",Size);
 }
                                                                        /*}}}*/
 // FileFd::Write - Write to the file                                   /*{{{*/
@@ -256,13 +294,29 @@ bool FileFd::Read(void *To,unsigned long Size)
 /* */
 bool FileFd::Write(const void *From,unsigned long Size)
 {
-   if (write(iFd,From,Size) != (signed)Size)
+   int Res;
+   errno = 0;
+   do
    {
-      Flags |= Fail;
-      return _error->Errno("write","Write error");
+      Res = write(iFd,From,Size);
+      if (Res < 0 && errno == EINTR)
+        continue;
+      if (Res < 0)
+      {
+        Flags |= Fail;
+        return _error->Errno("write","Write error");
+      }
+      
+      From = (char *)From + Res;
+      Size -= Res;
    }
+   while (Res > 0 && Size > 0);
    
-   return true;
+   if (Size == 0)
+      return true;
+   
+   Flags |= Fail;
+   return _error->Error("write, still have %u to write but couldn't",Size);
 }
                                                                        /*}}}*/
 // FileFd::Seek - Seek in the file                                     /*{{{*/
index a2464c9a36bb4b59413625be996632b405fa6bf9..8bbc6174d7cb8681c85bbe996ba5e5074814c364 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: strutl.cc,v 1.21 1999/03/15 08:10:39 jgg Exp $
+// $Id: strutl.cc,v 1.22 1999/03/16 00:43:55 jgg Exp $
 /* ######################################################################
 
    String Util - Some usefull string functions.
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <errno.h>
                                                                        /*}}}*/
 
 // strstrip - Remove white space from the front and back of a string   /*{{{*/
@@ -529,6 +530,8 @@ bool ReadMessages(int Fd, vector<string> &List)
    while (1)
    {
       int Res = read(Fd,End,sizeof(Buffer) - (End-Buffer));
+      if (Res < 0 && errno == EINTR)
+        continue;
       
       // Process is dead, this is kind of bad..
       if (Res == 0)
index 190dc5e8166b417421bd76371183d6ec1e504b6a..485679c1d706d90669d337a57247495147e14692 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: acqprogress.cc,v 1.10 1999/02/27 22:29:11 jgg Exp $
+// $Id: acqprogress.cc,v 1.11 1999/03/16 00:43:55 jgg Exp $
 /* ######################################################################
 
    Acquire Progress - Command line progress meter 
@@ -12,7 +12,9 @@
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/acquire-worker.h>
 #include <apt-pkg/strutl.h>
+
 #include <stdio.h>
+#include <signal.h>
                                                                        /*}}}*/
 
 // AcqTextStatus::AcqTextStatus - Constructor                          /*{{{*/
@@ -209,7 +211,13 @@ void AcqTextStatus::Pulse(pkgAcquire *Owner)
    if (Shown == false)
       snprintf(S,End-S," [Working]");
       
-   // Put in the ETA and cps meter
+   /* Put in the ETA and cps meter, block off signals to prevent strangeness
+      during resizing */
+   sigset_t Sigs,OldSigs;
+   sigemptyset(&Sigs);
+   sigaddset(&Sigs,SIGWINCH);
+   sigprocmask(SIG_BLOCK,&Sigs,&OldSigs);
+   
    if (CurrentCPS != 0)
    {      
       char Tmp[300];
@@ -224,7 +232,9 @@ void AcqTextStatus::Pulse(pkgAcquire *Owner)
       }      
    }
    Buffer[ScreenWidth] = 0;
-   
+   BlankLine[ScreenWidth] = 0;
+   sigprocmask(SIG_UNBLOCK,&OldSigs,0);
+
    // Draw the current status
    if (strlen(Buffer) == strlen(BlankLine))
       cout << '\r' << Buffer << flush;