Can a pass-by-reference var be assigned to a local var?

Matthew Hagerty matthew at mundomateo.com
Wed Jul 2 10:54:18 PDT 2003


Greetings,

I was looking over the code for the tail command and found something that
seems wrong.  Below is the abbreviated code that highlights my concern. 
Basically, sb is defined in main() and passed to forward() (and reverse())
by reference.  Then in forward() sb2 is defined, and finally sb is set to
sb2.

Two things come to mind that don't seem right: 1. What happens to sb when
forward() returns?  It was pointing to sb2 which was a local var of
forward()...  and 2. The assignment *sbp = sb2 happens in a loop and could
be executed more than once, which seems to make the comparisons just prior
to the assignment usless 2 or more loop iterations.

Am I missing something?  It seems to me that instead of *sbp = sb2, it
should be done with memcpy() or something?  Any insight would be greatly
appreciated.

Thanks,
Matthew


In tail.c:

int
main(argc, argv)
  int argc;
  char *argv[];
{
  struct stat sb;
.
.
  if ((fp = fopen(fname, "r")) == NULL ||
    fstat(fileno(fp), &sb)) {
.
.
  if (rflag)
    reverse(fp, style, off, &sb);
  else
    forward(fp, style, off, &sb);
.
.
}

Then in forward.c:

void
forward(fp, style, off, sbp)
  FILE *fp;
  enum STYLE style;
  off_t off;
  struct stat *sbp;
{
  int ch, n, kq = -1;
  int action = USE_SLEEP;
  struct kevent ev[2];
  struct stat sb2;
  struct timespec ts;
.
.
    if (Fflag && fileno(fp) != STDIN_FILENO) {
      while (stat(fname, &sb2) != 0)
      /* file was rotated, wait until it reappears */
        (void)sleep(1);
      if (sb2.st_ino != sbp->st_ino ||
        sb2.st_dev != sbp->st_dev ||
        sb2.st_rdev != sbp->st_rdev ||
        sb2.st_nlink == 0) {
        fp = freopen(fname, "r", fp);
        if (fp == NULL) {
          ierr();
          return;
        } else {
          *sbp = sb2;
          action = ADD_EVENTS;
        }
      }
    }
.
.
}



More information about the freebsd-hackers mailing list