Пример #1
0
// Call to indicate the end of a delimited region.  We now know the length of
// the delimited region.  If we are not nested inside any other delimited
// regions, we can now emit all of the buffered data we accumulated.
static bool end_delim(upb_pb_encoder *e) {
  accumulate(e);
  size_t msglen = top(e)->msglen;

  if (e->top == e->stack) {
    // All lengths are now available, emit all buffered data.
    char buf[UPB_PB_VARINT_MAX_LEN];
    upb_pb_encoder_segment *s;
    const char *ptr = e->buf;
    for (s = e->segbuf; s <= e->segptr; s++) {
      size_t lenbytes = upb_vencode64(s->msglen, buf);
      putbuf(e, buf, lenbytes);
      putbuf(e, ptr, s->seglen);
      ptr += s->seglen;
    }

    e->ptr = e->buf;
    e->top = NULL;
  } else {
    // Need to keep buffering; propagate length info into enclosing submessages.
    --e->top;
    top(e)->msglen += msglen + upb_varint_size(msglen);
  }

  return true;
}
Пример #2
0
static int
syscall_write (int fd, const char *buffer, unsigned size) 
{
	struct file *f;

	/* if the FD is 1, write to STDOUT */
	if (fd == 1) {
		const int max_out = 256;
		int remained = size;

		while (remained > max_out) {
			putbuf(buffer, max_out);
			buffer += max_out;
			remained -= max_out;
		}
		putbuf(buffer, remained);
		
		// actuall size of bytes written is (size - i)
		return (int)size;
	}

	/* normal case */
	f = process_file_find (fd);
	if (f == NULL)
		return -1;
	return file_write(f, buffer, size);
}
Пример #3
0
int
fwormwrite(Device *d, Off b, void *c)
{
	Iobuf *p;
	Device *fdev;
	Devsize l;

	if(chatty > 1)
		fprint(2, "fworm write %lld\n", (Wideoff)b);
	fdev = FDEV(d);
	l = devsize(fdev);
	l -= l/(BUFSIZE*8) + 1;
	if(b >= l)
		panic("fworm: wbounds %lld", (Wideoff)b);
	l += b/(BUFSIZE*8);

	p = getbuf(fdev, l, Brd|Bmod|Bres);
	if(!p || checktag(p, Tvirgo, l))
		panic("fworm: checktag %lld", (Wideoff)l);
	l = b % (BUFSIZE*8);
	if((p->iobuf[l/8] & (1<<(l%8)))) {
		putbuf(p);
		fprint(2, "fworm: write %lld\n", (Wideoff)b);
		return 1;
	}
	p->iobuf[l/8] |= 1<<(l%8);
	putbuf(p);
	return devwrite(fdev, b, c);
}
Пример #4
0
long
indfetch(Iobuf *p, Dentry *d, long addr, long a, int itag, int tag)
{
	Iobuf *bp;

	if(!addr)
		return 0;
	bp = getbuf(p->dev, addr, Bread);
	if(!bp || checktag(bp, itag, d->qid.path)) {
		if(!bp) {
			print("ind fetch bp = 0\n");
			return 0;
		}
		print("ind fetch tag\n");
		putbuf(bp);
		return 0;
	}
	addr = ((long*)bp->iobuf)[a];
	if(!addr && tag) {
		addr = balloc(p->dev, tag, d->qid.path);
		if(addr) {
			((long*)bp->iobuf)[a] = addr;
			bp->flags |= Bmod;
			if(localfs || tag == Tdir)
				bp->flags |= Bimm;
			settag(bp, itag, d->qid.path);
		}
	}
	putbuf(bp);
	return addr;
}
Пример #5
0
void
sysexit(int status)
{
	// Print Process Termination Message
	// File Name	
	char* name = thread_current()->name;
	char* token, *save_ptr;
	token = strtok_r(name, " ", &save_ptr);
	putbuf (token, strlen(token));

	char* str1 = ": exit(";
	putbuf (str1, strlen(str1));

	// ExitStatus
	char strstatus[32];
	snprintf(strstatus, 32, "%d", status);
	putbuf (strstatus, strlen(strstatus));

	char* str2 = ")\n";
	putbuf (str2, strlen(str2));

	// EXIT Child Processes
	if(thread_current()->numchild > 0)
	{
		struct list_elem * e;
		while (!list_empty(&thread_current()->child_list))
		{
			e = list_pop_front(&thread_current()->child_list);
			struct childproc * childitem = list_entry (e, struct childproc, elem);
			if(!exit_remove(childitem->childid))
			{
				list_push_back(&ignore_list, &childitem->elem);
			}
			else
			{
				free(childitem);
			}
		}
	}

	// Save exit status
	struct exitstatus * es = (struct exitstatus *) malloc(sizeof(struct exitstatus));
	if(es != NULL && !ignore_remove(thread_current()->tid))
	{
		es->avail = true;
		es->status = status;
		es->childid = thread_current()->tid;
		list_push_back(&exit_list, &es->elem);

		struct list_elem * e;
		for (e = list_begin (&waitproc_list); e != list_end (&waitproc_list); e = list_next (e))
		{
			struct waitproc * item = list_entry (e, struct waitproc, elem);
			sema_up(&item->sema);	
		}
	}
Пример #6
0
Файл: sub.c Проект: npe9/harvey
/*
 * free the block at `addr' on dev.
 * if it's an indirect block (d [depth] > 0),
 * first recursively free all the blocks it names.
 *
 * ts->relblk is the block number within the file of this
 * block (or the first data block eventually pointed to via
 * this indirect block).
 */
void
buffree(Device *dev, Off addr, int d, Truncstate *ts)
{
	Iobuf *p;
	Off a;
	int i, pastlast;

	if(!addr)
		return;
	pastlast = (ts == nil? 1: ts->pastlast);
	/*
	 * if this is an indirect block, recurse and free any
	 * suitable blocks within it (possibly via further indirect blocks).
	 */
	if(d > 0) {
		d--;
		p = getbuf(dev, addr, Brd);
		if(p) {
			if (ts == nil)		/* common case: create */
				for(i=INDPERBUF-1; i>=0; i--) {
					a = ((Off *)p->iobuf)[i];
					buffree(dev, a, d, nil);
				}
			else			/* wstat truncation */
				for (i = 0; i < INDPERBUF; i++)
					truncfree(ts, dev, d, p, i);
			putbuf(p);
		}
	}
	if (!pastlast)
		return;
	/*
	 * having zeroed the pointer to this block, add it to the free list.
	 * stop outstanding i/o
	 */
	p = getbuf(dev, addr, Bprobe);
	if(p) {
		p->flags &= ~(Bmod|Bimm);
		putbuf(p);
	}
	/*
	 * dont put written worm
	 * blocks into free list
	 */
	if(dev->type == Devcw) {
		i = cwfree(dev, addr);
		if(i)
			return;
	}
	p = getbuf(dev, superaddr(dev), Brd|Bmod);
	if(!p || checktag(p, Tsuper, QPSUPER))
		panic("buffree: super block");
	addfree(dev, addr, (Superb*)p->iobuf);
	putbuf(p);
}
Пример #7
0
long
rel2abs(Iobuf *p, Dentry *d, long a, int tag, int putb)
{
	long addr, qpath;
	Device dev;

	if(a < 0) {
		print("dnodebuf: neg\n");
		return 0;
	}
	qpath = d->qid.path;
	dev = p->dev;
	if(a < NDBLOCK) {
		addr = d->dblock[a];
		if(!addr && tag) {
			addr = balloc(dev, tag, qpath);
			d->dblock[a] = addr;
			p->flags |= Bmod|Bimm;
		}
		if(putb)
			putbuf(p);
		return addr;
	}
	a -= NDBLOCK;
	if(a < INDPERBUF) {
		addr = d->iblock;
		if(!addr && tag) {
			addr = balloc(dev, Tind1, qpath);
			d->iblock = addr;
			p->flags |= Bmod|Bimm;
		}
		if(putb)
			putbuf(p);
		addr = indfetch(p, d, addr, a, Tind1, tag);
		return addr;
	}
	a -= INDPERBUF;
	if(a < INDPERBUF2) {
		addr = d->diblock;
		if(!addr && tag) {
			addr = balloc(dev, Tind2, qpath);
			d->diblock = addr;
			p->flags |= Bmod|Bimm;
		}
		if(putb)
			putbuf(p);
		addr = indfetch(p, d, addr, a/INDPERBUF, Tind2, Tind1);
		addr = indfetch(p, d, addr, a%INDPERBUF, Tind1, tag);
		return addr;
	}
	if(putb)
		putbuf(p);
	print("dnodebuf: trip indirect\n");
	return 0;
}
Пример #8
0
static void dopush(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
{
  int opcode;

  while (inch != EOF)
    {
      /* Search for a PUSHS opcode */

      if (inch != oPUSHS)
        {
          /* Its not PUSHS, just echo to the output file/buffer */

          putbuf(inch, poffProgHandle);

          /* Get the next byte from the input stream */

          opcode = inch;
          inch = poffGetProgByte(poffHandle);

          /* Check for an 8-bit argument */

          if ((opcode & o8) != 0)
            {
              /* Echo the 8-bit argument */

              putbuf(inch, poffProgHandle);
              inch = poffGetProgByte(poffHandle);
            }

          /* Check for a 16-bit argument */

          if ((opcode & o16) != 0)
            {
              /* Echo the 16-bit argument */

              putbuf(inch, poffProgHandle);
              inch = poffGetProgByte(poffHandle);
              putbuf(inch, poffProgHandle);
              inch = poffGetProgByte(poffHandle);
            }
        }
      else
        {
          /* We have found PUSHS.  No search for the next occurrence
           * of either and instruction that increments the string
           * stack or for the matching POPS
           */

          current_level++;
          dopop(poffHandle, poffProgHandle);
          current_level--;
        }
    }
}
Пример #9
0
int
doclri(File *f)
{
	Iobuf *p, *p1;
	Dentry *d, *d1;
	int err;

	err = 0;
	p = 0;
	p1 = 0;
	if(f->fs->dev->type == Devro) {
		err = Eronly;
		goto out;
	}
	/*
	 * check on parent directory of file to be deleted
	 */
	if(f->wpath == 0 || f->wpath->addr == f->addr) {
		err = Ephase;
		goto out;
	}
	p1 = getbuf(f->fs->dev, f->wpath->addr, Brd);
	d1 = getdir(p1, f->wpath->slot);
	if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
		err = Ephase;
		goto out;
	}

	accessdir(p1, d1, FWRITE, 0);
	putbuf(p1);
	p1 = 0;

	/*
	 * check on file to be deleted
	 */
	p = getbuf(f->fs->dev, f->addr, Brd);
	d = getdir(p, f->slot);

	/*
	 * do it
	 */
	memset(d, 0, sizeof(Dentry));
	settag(p, Tdir, QPNONE);
	freewp(f->wpath);
	freefp(f);

out:
	if(p1)
		putbuf(p1);
	if(p)
		putbuf(p);
	return err;
}
Пример #10
0
static
void
ckfreelist(Superb *sb)
{
	long a, lo, hi;
	int n, i;
	Iobuf *p;
	Fbuf *fb;


	strcpy(name, "free list");
	cprint("check %s\n", name);
	fb = &sb->fbuf;
	a = sbaddr;
	p = 0;
	lo = 0;
	hi = 0;
	for(;;) {
		n = fb->nfree;
		if(n < 0 || n > FEPERBUF) {
			cprint("check: nfree bad %ld\n", a);
			break;
		}
		for(i=1; i<n; i++) {
			a = fb->free[i];
			if(a && !fmark(a)) {
				if(!lo || lo > a)
					lo = a;
				if(!hi || hi < a)
					hi = a;
			}
		}
		a = fb->free[0];
		if(!a)
			break;
		if(fmark(a))
			break;
		if(!lo || lo > a)
			lo = a;
		if(!hi || hi < a)
			hi = a;
		if(p)
			putbuf(p);
		p = xtag(a, Tfree, QPNONE);
		if(!p)
			break;
		fb = (Fbuf*)p->iobuf;
	}
	if(p)
		putbuf(p);
	cprint("lo = %ld; hi = %ld\n", lo, hi);
}
Пример #11
0
/**
 * Skriver till fd (skärm eller fil)
 * Returnerar antalet skrivna tecken eller -1 om antalet tecken som ska skrivas
 * är 0 eller om filen inte finns.
 */
int sys_write(int fd, const void* buffer, unsigned length)
{
    if (fd == STDIN_FILENO) // Vi kan inte skriva till tangentbordet
    {
        return -1;
    }

    if (fd == STDOUT_FILENO) // skärmen
    {
        putbuf(buffer, length);
        return length;
    }
    else
    {
        // Skriva till fil
        struct file* write_to = map_find(get_filemap(), fd);
        if(write_to != NULL)
        {
            // Skriver buffer till write_to. Returnerar antalet skrivna tecken
            // Kan returnera ett antal tecken < length om filen är för liten
            return file_write(write_to, buffer, length);
        }
        else
        {
            return -1; // Filen finns inte, eller så ville vi skriva 0 tecken.
        }
    }
    // Hit ska vi inte komma!
}
Пример #12
0
/* Writes up to size bytes from buffer to the file open with descriptor fd,
   and returns the actual number written (may be less than size if EOF is 
   reached), or -1 if no file is open as fd or the write fails for another
   reason.  Writing to 1 will print to standard output */
static int 
sys_write (int fd, const void *buffer, unsigned size) 
{
  int written;
  struct file_fd *ffd;
  
  check_ptr (buffer);
  
  switch (fd) {
  case 0:
    return 0;
  case 1:
    putbuf ((char *) buffer, size);
    return size;
  case 2:
    return 0;
  default:
    ffd = get_file_fd (fd);
    if (ffd == NULL)
      return 0;
    
    lock_acquire (&fs_lock);
    written = file_write (ffd->file, buffer, size);
    lock_release (&fs_lock);
    return written;
  }
}
Пример #13
0
int write (int fd, const void *buffer, unsigned size)
{
  if (fd == STDIN_FILENO)
    return -1;

  if (fd == STDOUT_FILENO)
  {
    putbuf ((const char*)buffer, size);
    return size;
  }

  lock_acquire (&filesys_lock);

  struct file *f = process_get_file (fd);
  if (!f)
  {
    lock_release (&filesys_lock);
    return -1;
  }

  int bytes = file_write (f, buffer, size);

  lock_release (&filesys_lock);

  return bytes;
}
Пример #14
0
int SYS_WRITE_handler(int32_t* esp)
{
  // Default to error...
  int retVal = -1;

  int fd = *(esp + 1);
  char* buffer = (char*)*(esp + 2);
  int len = *(esp + 3);
	
  if(verify_fix_length(esp[2], esp[3]) == false){
	sys_exit(-1);
  }
  if(fd == STDOUT_FILENO){

    putbuf(buffer, len);
    // Since we wrote data, set return value to bytes written.
    retVal = len;
  } else if(fd > 1){

	// A file descriptor has been used.
	struct file* file = flist_get_process_file(fd);
	if(file != NULL){
		retVal = file_write(file, buffer, len);
	}
	
  }

  return retVal;
}
Пример #15
0
static
int
checkindir(long a, Dentry *d, long qpath)
{
	Iobuf *p;
	int i, dmod;

	dmod = touch(a);
	p = xtag(a, Tind1, qpath);
	if(!p)
		return dmod;
	for(i=0; i<INDPERBUF; i++) {
		a = ((long*)p->iobuf)[i];
		if(!a)
			continue;
		if(amark(a)) {
			if(flags & Cbad) {
				((long*)p->iobuf)[i] = 0;
				p->flags |= Bmod;
			}
			continue;
		}
		if(d->mode & DDIR)
			dmod += checkdir(a, qpath);
		else if(flags & Crdall)
			xread(a, qpath);
	}
	putbuf(p);
	return dmod;
}
Пример #16
0
/* Write to a file. */
static int
sys_write (int fd, const void *buffer, unsigned size)
{
  struct user_file *f;
  int ret = -1;

#if PRINT_DEBUG
  printf ("[SYSCALL] SYS_WRITE: fd: %d, buffer: %p, size: %u\n", fd, buffer, size);
#endif

  if (fd == STDIN_FILENO)
    ret = -1;
  else if (fd == STDOUT_FILENO)
    {
      putbuf (buffer, size);
      ret = size;
    }
  else if (!is_user_vaddr (buffer) || !is_user_vaddr (buffer + size))
    sys_exit (-1);
  else
    {
      f = file_by_fid (fd);
      if (f == NULL)
        ret = -1;
      else
        {
          lock_acquire (&file_lock);
          ret = file_write (f->file, buffer, size);
          lock_release (&file_lock);
        }
    }
  return ret;
}
Пример #17
0
/*
 * write to either file or console
 */
void
syscall_write (struct intr_frame *f)
{
  const int argz = 3;
  int args[argz];
  syscall_get_args(f,args,argz);
  syscall_check_arg_buffer_or_exit((const void *)args[1], (unsigned) args[2]);
  args[1] = syscall_user_to_kernel_vaddr((const void*) args[1]);

  if(args[0] == STDOUT_FILENO)
  {
    putbuf ((const void*) args[1], (size_t) args[2]);
    f->eax = (int) args[2];
    return;
  }
  lock_acquire (&flock);
  struct file *file = process_get_file (args[0]);
  if (file == NULL)
  {
    f->eax = -1;
    lock_release (&flock);
    return;
  }
  f->eax = file_write (file, (const void*) args[1], (off_t) args[2] );
  lock_release (&flock);
}
Пример #18
0
int
write(int fd, const void *buffer, unsigned size)
{
    if (fd == STDOUT_FILENO) {
        lock_acquire(&filesys_lock);
        putbuf(buffer, size);
        lock_release(&filesys_lock);
        return size;
    } else {
        struct thread *t = thread_current();
        uint8_t *buf = buffer;  // NEEDED???

        struct file_handle *fh = thread_get_fh(&t->files, fd);

        if (fh == NULL) {
            exit(-1);
        }

        lock_acquire(&filesys_lock);
        off_t wrote = file_write(fh->file, buf, size);
        lock_release(&filesys_lock);

        return wrote;
    }
}
Пример #19
0
static int sys_write(int fd, const void *buffer,unsigned size)
{
  struct thread *curr = thread_current();
  struct opened_file_elem *opened_elem ;
  struct list_elem *e;
  int check_valid=0;
  if(fd<=0)
    return -1;
  else if(fd==1)
  {
    if(size>512)
      return -1;
    else
    {
      putbuf(buffer,size);
      return size;
    }
  }
  else
  {
    for( e = list_begin(&curr->openfile_list) ; e != list_end(&curr->openfile_list) ;
        e = list_next(e) )
    {
      opened_elem=list_entry(e,struct opened_file_elem,elem_f);
      if(opened_elem->fd==fd)
      {
        check_valid=1;
        return file_write(opened_elem->opened_file,buffer,size);
      }
    }
  }
  if(check_valid==0)
    return -1;
}
Пример #20
0
void
fwormream(Device *d)
{
	Iobuf *p;
	Device *fdev;
	Off a, b;

	if(chatty)
		print("fworm ream\n");
	devinit(d);
	fdev = FDEV(d);
	a = fwormsize(d);
	b = devsize(fdev);
	if(chatty){
		print("\tfwsize = %lld\n", (Wideoff)a);
		print("\tbwsize = %lld\n", (Wideoff)b-a);
	}
	for(; a < b; a++) {
		p = getbuf(fdev, a, Bmod|Bres);
		if(!p)
			panic("fworm: init");
		memset(p->iobuf, 0, RBUFSIZE);
		settag(p, Tvirgo, a);
		putbuf(p);
	}
}
Пример #21
0
/*
 * System Call: int write (int fd, const void *buffer, unsigned size)
 * Writes size bytes from buffer to the open file fd. Returns the number of
 * bytes actually written, which may be less than size if some bytes could
 * not be written.
 *
 * Writing past end-of-file would normally extend the file, but file growth
 * is not implemented by the basic file system. The expected behavior is to
 * write as many bytes as possible up to end-of-file and return the actual
 * number written, or 0 if no bytes could be written at all.
 *
 * Fd 1 writes to the console. Your code to write to the console should
 * write all of buffer in one call to putbuf(), at least as long as size
 * is not bigger than a few hundred bytes. (It is reasonable to break up
 * larger buffers.) Otherwise, lines of text output by different processes
 * may end up interleaved on the console, confusing both human readers and
 * our grading scripts.
 */
int write_handler(int fd, const void *buffer, unsigned size) {
	if (buffer_access_ok(buffer, size, false)) {
		/*
		* TODO:
		* buffer needs to be pinned during I/O
		*/
//		frame_pin_buffer(buffer,size);
		if (fd == STDOUT_FILENO) {
			putbuf(buffer, size);
//			frame_unpin_buffer(buffer,size);
			return size;
		}
		lock_acquire (&fic_m);
		struct file* f = findfd(fd);
		if (f != NULL) {
			int ret = -1;
			if(!is_deny_write(f)){
				ret = file_write(f, buffer, size);
			}
			lock_release (&fic_m);
//			frame_unpin_buffer(buffer,size);
			return ret;
		}
		lock_release (&fic_m);
	}
//	frame_unpin_buffer(buffer,size);
	return -1;
}
Пример #22
0
void
addfree(Device dev, long addr, Superb *sb)
{
	int n;
	Iobuf *p;

	if(addr >= sb->fsize){
		print("addfree: bad addr %lux\n", addr);
		return;
	}
	n = sb->fbuf.nfree;
	if(n < 0 || n > FEPERBUF)
		panic("addfree: bad freelist");
	if(n >= FEPERBUF) {
		p = getbuf(dev, addr, Bmod);
		if(p == 0)
			panic("addfree: getbuf");
		memmove(p->iobuf, &sb->fbuf, (FEPERBUF+1)*sizeof(long));
		settag(p, Tfree, QPNONE);
		putbuf(p);
		n = 0;
	}
	sb->fbuf.free[n++] = addr;
	sb->fbuf.nfree = n;
	sb->tfree++;
	if(addr >= sb->fsize)
		sb->fsize = addr+1;
}
Пример #23
0
void
scrinterp::putch(int ch)
{
  cell_t x, y, mx, my;

  // We can handle all of the standard control chrs here
  switch (ch)
  {
  case '\r':                  // CR
    flushbuf();
    vs.wherexy(x, y);
    vs.gotoxy(0, y);
    break;

  case '\t':                  // TAB
    flushbuf();
    vs.wherexy(x, y);
    vs.maxxy(mx, my);
    x = cell_t((((x + 8) / 8) + 1) * 8);
    if (x >= mx)
    {
      x = cell_t(x % mx);
      goto dolf;
    }
    vs.gotoxy(x, y);
    break;

  case '\n':                  // NL
    flushbuf();
    vs.wherexy(x, y);
    vs.maxxy(mx, my);
  dolf:
    if (y == cell_t(my - 1))  // On last line
      vs.scroll(0, 0, mx, my, 1);
    else
      ++y;
    vs.gotoxy(x, y);
    break;

  case '\007':                 // BELL
    // beep() !
    break;

  case '\b':
    vs.wherexy(x, y);
    if (x > 0)
      vs.gotoxy(--x, y);
    break;

  case '\x0c':                // LF
    // Should to a cls here with home, perhaps...
    break;

  default:
    putbuf(ch);
    if (flushevery)
      flushbuf();
    break;
  }
}
Пример #24
0
/* write file */
int
write(int fd, void *buffer, unsigned size)
{
	int write_size = 0;
	struct file *current_file;
	struct inode *inode;

	lock_acquire(&file_lock);
	if(fd == 1)                    /* stdout */
	{ 
		putbuf((const char *)buffer,size);
		write_size = size;
	}
	else
	{
		current_file = process_get_file(fd);
		inode = file_get_inode(current_file);
		/* if file is directory, return -1 */
		if( inode_is_dir(inode) == true){
			lock_release(&file_lock);
			return -1;
		}
		if(current_file != NULL)
			write_size = file_write(current_file,(const void *)buffer,size);
	}
	lock_release(&file_lock);
	return write_size;
}
Пример #25
0
int sys_write(int fd, const void *buffer, unsigned size) {
  // memory validation : [buffer+0, buffer+size) should be all valid
  check_user((const uint8_t*) buffer);
  check_user((const uint8_t*) buffer + size - 1);

  lock_acquire (&filesys_lock);
  int ret;

  if(fd == 1) { // write to stdout
    putbuf(buffer, size);
    ret = size;
  }
  else {
    // write into file
    struct file_desc* file_d = find_file_desc(thread_current(), fd, FD_FILE);

    if(file_d && file_d->file) {
#ifdef VM
      preload_and_pin_pages(buffer, size);
#endif

      ret = file_write(file_d->file, buffer, size);

#ifdef VM
      unpin_preloaded_pages(buffer, size);
#endif
    }
    else // no such file or can't open
      ret = -1;
  }

  lock_release (&filesys_lock);
  return ret;
}
Пример #26
0
void
rahead(void *)
{
	Rabuf *rb[50];
	Iobuf *p;
	int i, n;

	for (;;) {
		rb[0] = fs_recv(raheadq, 0);
		for(n = 1; n < nelem(rb); n++) {
			if(raheadq->count <= 0)
				break;
			rb[n] = fs_recv(raheadq, 0);
		}
		qsort(rb, n, sizeof rb[0], rbcmp);
		for(i = 0; i < n; i++) {
			if(rb[i] == 0)
				continue;
			p = getbuf(rb[i]->dev, rb[i]->addr, Brd);
			if(p)
				putbuf(p);
			lock(&rabuflock);
			rb[i]->link = rabuffree;
			rabuffree = rb[i];
			unlock(&rabuflock);
		}
	}
}
Пример #27
0
/*
 * return the number of the highest-numbered block actually written, plus 1.
 * 0 indicates an error.
 */
static Devsize
writtensize(Device *worm)
{
	Devsize lim = devsize(worm);
	Iobuf *p;

	print("devsize(%Z) = %lld\n", worm, (Wideoff)lim);
	if (!blockok(worm, 0) || !blockok(worm, lim-1))
		return 0;
	delay(5*1000);
	if (userabort("sanity checks"))
		return 0;

	/* find worm's last valid block in case "worm" is an (f)worm */
	while (lim > 0) {
		if (userabort("sizing")) {
			lim = 0;		/* you lose */
			break;
		}
		--lim;
		p = getbuf(worm, lim, Brd);
		if (p != 0) {			/* actually read one okay? */
			putbuf(p);
			break;
		}
	}
	print("limit(%Z) = %lld\n", worm, (Wideoff)lim);
	if (lim <= 0)
		return 0;
	return lim + 1;
}
Пример #28
0
static int32_t
iread(Xfile *f, char *buf, int64_t offset, int32_t count)
{
	int n, o, rcnt = 0;
	int64_t size, addr;
	Isofile *ip = f->ptr;
	Iobuf *p;

	size = fakemax(l32(ip->d.size));
	if(offset >= size)
		return 0;
	if(offset+count > size)
		count = size - offset;
	addr = ((int64_t)l32(ip->d.addr) + ip->d.attrlen)*ip->blksize + offset;
	o = addr % Sectorsize;
	addr /= Sectorsize;
	/*chat("d.addr=%ld, addr=%lld, o=%d...", l32(ip->d.addr), addr, o);*/
	n = Sectorsize - o;

	while(count > 0){
		if(n > count)
			n = count;
		p = getbuf(f->xf->d, addr);
		memmove(&buf[rcnt], &p->iobuf[o], n);
		putbuf(p);
		count -= n;
		rcnt += n;
		++addr;
		o = 0;
		n = Sectorsize;
	}
	return rcnt;
}
Пример #29
0
/* zero bytes past new file length; return an error code */
int
trunczero(Truncstate *ts)
{
	int blkoff = ts->newsize % BUFSIZE;
	Iobuf *pd;

	pd = dnodebuf(ts->p, ts->d, ts->lastblk, Tfile, ts->uid);
	if (pd == nil || checktag(pd, Tfile, QPNONE)) {
		if (pd != nil)
			putbuf(pd);
		ts->err = Ephase;
		return Ephase;
	}
	memset(pd->iobuf+blkoff, 0, BUFSIZE - blkoff);
	putbuf(pd);
	return 0;
}
Пример #30
0
/* Writes size bytes from buffer to the OPEN file fd. Returns the number
   of bytes actually written. Since file growth is not implemented, if we
   get to the end of the file, just stop writing and return the number of
   bytes already written. fd = 1 writes to the console. */
static int
sys_write(int fd, const void *buffer, unsigned size) 
{

  if (fd == STDIN_FILENO)
    sys_exit(ERROR);

  check_mem_ptr(buffer);
  check_fd(fd);
  check_buffer(buffer, size);

  int bytes;
  lock_acquire(&secure_file);

  /* fd = 1 corresponds to writing to stdout. */
  if (fd == STDOUT_FILENO)
  {
    /* If we are writing a fairly large amount of bytes to stdout, write
       MAX_CONSOLE_WRITE bytes per call to putbuf(), then write the rest
       of the bytes, calling sys_write() recursively. */
    if (size < MAX_CONSOLE_WRITE) {
      putbuf(buffer, size);

    } else {
      putbuf(buffer, MAX_CONSOLE_WRITE);
      sys_write(fd, buffer + MAX_CONSOLE_WRITE, size - MAX_CONSOLE_WRITE);
    }
    /* Must have successfully written all bytes we were told to. */
    bytes = size;
  } 
    else 
  {
    struct file *f = get_file(fd);
    if (f == NULL) 
    {
      lock_release(&secure_file);
      return ERROR;
    }
    bytes = file_write(f, buffer, size);
  }

  lock_release(&secure_file);

  return bytes;

}