[BACK]Return to scp.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/scp.c between version 1.166 and 1.167

version 1.166, 2010/07/01 13:06:59 version 1.167, 2010/09/22 22:58:51
Line 104 
Line 104 
   
 int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout);  int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout);
   
 void bwlimit(int);  
   
 /* Struct for addargs */  /* Struct for addargs */
 arglist args;  arglist args;
   
 /* Bandwidth limit */  /* Bandwidth limit */
 off_t limit_rate = 0;  long long limit_kbps = 0;
   struct bwlimit bwlimit;
   
 /* Name of current file being transferred. */  /* Name of current file being transferred. */
 char *curfile;  char *curfile;
Line 302 
Line 301 
 main(int argc, char **argv)  main(int argc, char **argv)
 {  {
         int ch, fflag, tflag, status, n;          int ch, fflag, tflag, status, n;
         double speed;          char *targ, **newargv;
         char *targ, *endp, **newargv;          const char *errstr;
         extern char *optarg;          extern char *optarg;
         extern int optind;          extern int optind;
   
Line 350 
Line 349 
                         addargs(&args, "-oBatchmode yes");                          addargs(&args, "-oBatchmode yes");
                         break;                          break;
                 case 'l':                  case 'l':
                         speed = strtod(optarg, &endp);                          limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024,
                         if (speed <= 0 || *endp != '\0')                              &errstr);
                           if (errstr != NULL)
                                 usage();                                  usage();
                         limit_rate = speed * 1024;                          limit_kbps *= 1024; /* kbps */
                           bandwidth_limit_init(&bwlimit, limit_kbps, COPY_BUFLEN);
                         break;                          break;
                 case 'p':                  case 'p':
                         pflag = 1;                          pflag = 1;
Line 452 
Line 453 
         exit(errs != 0);          exit(errs != 0);
 }  }
   
 /*  /* Callback from atomicio6 to update progress meter and limit bandwidth */
  * atomicio-like wrapper that also applies bandwidth limits and updates  static int
  * the progressmeter counter.  scpio(void *_cnt, size_t s)
  */  
 static size_t  
 scpio(ssize_t (*f)(int, void *, size_t), int fd, void *_p, size_t l, off_t *c)  
 {  {
         u_char *p = (u_char *)_p;          off_t *cnt = (off_t *)_cnt;
         size_t offset;  
         ssize_t r;  
         struct pollfd pfd;  
   
         pfd.fd = fd;          *cnt += s;
         pfd.events = f == read ? POLLIN : POLLOUT;          if (limit_kbps > 0)
         for (offset = 0; offset < l;) {                  bandwidth_limit(&bwlimit, s);
                 r = f(fd, p + offset, l - offset);          return 0;
                 if (r == 0) {  
                         errno = EPIPE;  
                         return offset;  
                 }  
                 if (r < 0) {  
                         if (errno == EINTR)  
                                 continue;  
                         if (errno == EAGAIN) {  
                                 (void)poll(&pfd, 1, -1); /* Ignore errors */  
                                 continue;  
                         }  
                         return offset;  
                 }  
                 offset += (size_t)r;  
                 *c += (off_t)r;  
                 if (limit_rate)  
                         bwlimit(r);  
         }  
         return offset;  
 }  }
   
 void  void
Line 728 
Line 704 
                                 (void)atomicio(vwrite, remout, bp->buf, amt);                                  (void)atomicio(vwrite, remout, bp->buf, amt);
                                 continue;                                  continue;
                         }                          }
                         if (scpio(vwrite, remout, bp->buf, amt,                          if (atomicio6(vwrite, remout, bp->buf, amt, scpio,
                             &statbytes) != amt)                              &statbytes) != amt)
                                 haderr = errno;                                  haderr = errno;
                 }                  }
Line 803 
Line 779 
 }  }
   
 void  void
 bwlimit(int amount)  
 {  
         static struct timeval bwstart, bwend;  
         static int lamt, thresh = 16384;  
         u_int64_t waitlen;  
         struct timespec ts, rm;  
   
         if (!timerisset(&bwstart)) {  
                 gettimeofday(&bwstart, NULL);  
                 return;  
         }  
   
         lamt += amount;  
         if (lamt < thresh)  
                 return;  
   
         gettimeofday(&bwend, NULL);  
         timersub(&bwend, &bwstart, &bwend);  
         if (!timerisset(&bwend))  
                 return;  
   
         lamt *= 8;  
         waitlen = (double)1000000L * lamt / limit_rate;  
   
         bwstart.tv_sec = waitlen / 1000000L;  
         bwstart.tv_usec = waitlen % 1000000L;  
   
         if (timercmp(&bwstart, &bwend, >)) {  
                 timersub(&bwstart, &bwend, &bwend);  
   
                 /* Adjust the wait time */  
                 if (bwend.tv_sec) {  
                         thresh /= 2;  
                         if (thresh < 2048)  
                                 thresh = 2048;  
                 } else if (bwend.tv_usec < 10000) {  
                         thresh *= 2;  
                         if (thresh > COPY_BUFLEN * 4)  
                                 thresh = COPY_BUFLEN * 4;  
                 }  
   
                 TIMEVAL_TO_TIMESPEC(&bwend, &ts);  
                 while (nanosleep(&ts, &rm) == -1) {  
                         if (errno != EINTR)  
                                 break;  
                         ts = rm;  
                 }  
         }  
   
         lamt = 0;  
         gettimeofday(&bwstart, NULL);  
 }  
   
 void  
 sink(int argc, char **argv)  sink(int argc, char **argv)
 {  {
         static BUF buffer;          static BUF buffer;
Line 1049 
Line 971 
                                 amt = size - i;                                  amt = size - i;
                         count += amt;                          count += amt;
                         do {                          do {
                                 j = scpio(read, remin, cp, amt, &statbytes);                                  j = atomicio6(read, remin, cp, amt,
                                       scpio, &statbytes);
                                 if (j == 0) {                                  if (j == 0) {
                                         run_err("%s", j != EPIPE ?                                          run_err("%s", j != EPIPE ?
                                             strerror(errno) :                                              strerror(errno) :

Legend:
Removed from v.1.166  
changed lines
  Added in v.1.167