diff options
author | Arch Librarian <arch@canonical.com> | 2004-09-20 16:53:05 +0000 |
---|---|---|
committer | Arch Librarian <arch@canonical.com> | 2004-09-20 16:53:05 +0000 |
commit | b0db36b1ac7a93c147888aa98f9431e8bcc7d36e (patch) | |
tree | 0db564188095f9826ceb47156b1b4740a7fafb96 | |
parent | 78b558ca4dab74f113cec91362b055263baa8011 (diff) |
Signal safety
Author: jgg
Date: 1999-03-16 00:43:55 GMT
Signal safety
-rw-r--r-- | apt-pkg/acquire-worker.cc | 23 | ||||
-rw-r--r-- | apt-pkg/acquire.cc | 10 | ||||
-rw-r--r-- | apt-pkg/contrib/fileutl.cc | 92 | ||||
-rw-r--r-- | apt-pkg/contrib/strutl.cc | 5 | ||||
-rw-r--r-- | cmdline/acqprogress.cc | 16 |
5 files changed, 119 insertions, 27 deletions
diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc index 099a43e2e..4c204041a 100644 --- a/apt-pkg/acquire-worker.cc +++ b/apt-pkg/acquire-worker.cc @@ -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 @@ -24,9 +24,11 @@ #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(); diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index aadfe2efb..80624f9d3 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -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"); diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index a761794ee..a28dce6c0 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -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 /*{{{*/ diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index a2464c9a3..8bbc6174d 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -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) diff --git a/cmdline/acqprogress.cc b/cmdline/acqprogress.cc index 190dc5e81..485679c1d 100644 --- a/cmdline/acqprogress.cc +++ b/cmdline/acqprogress.cc @@ -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; |