Deleted Added
full compact
linux_file.c (9313) linux_file.c (10355)
1/*-
2 * Copyright (c) 1994-1995 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
1/*-
2 * Copyright (c) 1994-1995 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $Id: linux_file.c,v 1.2 1995/06/07 21:27:57 sos Exp $
28 * $Id: linux_file.c,v 1.1 1995/06/25 17:32:34 sos Exp $
29 */
30
31#include <i386/linux/linux.h>
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/fcntl.h>
35#include <sys/file.h>
36#include <sys/filedesc.h>

--- 297 unchanged lines hidden (view full) ---

334 caddr_t outp; /* Linux-format */
335 int resid, linuxreclen=0; /* Linux-format */
336 struct file *fp;
337 struct uio auio;
338 struct iovec aiov;
339 struct vattr va;
340 off_t off;
341 struct linux_dirent linux_dirent;
29 */
30
31#include <i386/linux/linux.h>
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/fcntl.h>
35#include <sys/file.h>
36#include <sys/filedesc.h>

--- 297 unchanged lines hidden (view full) ---

334 caddr_t outp; /* Linux-format */
335 int resid, linuxreclen=0; /* Linux-format */
336 struct file *fp;
337 struct uio auio;
338 struct iovec aiov;
339 struct vattr va;
340 off_t off;
341 struct linux_dirent linux_dirent;
342 int buflen, error, eofflag, nbytes, justone;
342 int buflen, error, eofflag, nbytes, justone, blockoff;
343
344#ifdef DEBUG
345 printf("Linux-emul(%d): readdir(%d, *, %d)\n",
346 p->p_pid, args->fd, args->count);
347#endif
343
344#ifdef DEBUG
345 printf("Linux-emul(%d): readdir(%d, *, %d)\n",
346 p->p_pid, args->fd, args->count);
347#endif
348 if ((error = getvnode(p->p_fd, args->fd, &fp)) != 0)
348 if ((error = getvnode(p->p_fd, args->fd, &fp)) != 0) {
349 return (error);
349 return (error);
350}
350
351 if ((fp->f_flag & FREAD) == 0)
352 return (EBADF);
353
354 vp = (struct vnode *) fp->f_data;
355
356 if (vp->v_type != VDIR)
357 return (EINVAL);
358
351
352 if ((fp->f_flag & FREAD) == 0)
353 return (EBADF);
354
355 vp = (struct vnode *) fp->f_data;
356
357 if (vp->v_type != VDIR)
358 return (EINVAL);
359
359 if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)))
360 if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p))) {
360 return error;
361 return error;
362 }
361
362 nbytes = args->count;
363 if (nbytes == 1) {
364 nbytes = sizeof (struct linux_dirent);
365 justone = 1;
366 }
367 else
368 justone = 0;
369
363
364 nbytes = args->count;
365 if (nbytes == 1) {
366 nbytes = sizeof (struct linux_dirent);
367 justone = 1;
368 }
369 else
370 justone = 0;
371
370 buflen = max(va.va_blocksize, nbytes);
372 off = fp->f_offset;
373 blockoff = off % va.va_blocksize;
374 buflen = max(va.va_blocksize, (nbytes + blockoff));
371 buf = malloc(buflen, M_TEMP, M_WAITOK);
372 VOP_LOCK(vp);
375 buf = malloc(buflen, M_TEMP, M_WAITOK);
376 VOP_LOCK(vp);
373 off = fp->f_offset;
374again:
375 aiov.iov_base = buf;
376 aiov.iov_len = buflen;
377 auio.uio_iov = &aiov;
378 auio.uio_iovcnt = 1;
379 auio.uio_rw = UIO_READ;
380 auio.uio_segflg = UIO_SYSSPACE;
381 auio.uio_procp = p;
382 auio.uio_resid = buflen;
377again:
378 aiov.iov_base = buf;
379 aiov.iov_len = buflen;
380 auio.uio_iov = &aiov;
381 auio.uio_iovcnt = 1;
382 auio.uio_rw = UIO_READ;
383 auio.uio_segflg = UIO_SYSSPACE;
384 auio.uio_procp = p;
385 auio.uio_resid = buflen;
383 auio.uio_offset = off;
386 auio.uio_offset = off - (off_t)blockoff;
384
385 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, (u_long *) 0, 0);
387
388 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, (u_long *) 0, 0);
386 if (error)
389 if (error) {
387 goto out;
390 goto out;
391}
388
389 inp = buf;
392
393 inp = buf;
394 inp += blockoff;
390 outp = (caddr_t) args->dent;
391 resid = nbytes;
395 outp = (caddr_t) args->dent;
396 resid = nbytes;
392 if ((len = buflen - auio.uio_resid) == 0)
397 if ((len = buflen - auio.uio_resid - blockoff) == 0) {
393 goto eof;
398 goto eof;
399 }
394
395 while (len > 0) {
400
401 while (len > 0) {
396 reclen = ((struct dirent *) inp)->d_reclen;
397 if (reclen & 3)
398 panic("linux_readdir");
399 off += reclen;
400 bdp = (struct dirent *) inp;
402 bdp = (struct dirent *) inp;
403 reclen = bdp->d_reclen;
404 if (reclen & 3) {
405 printf("linux_readdir: reclen=%d\n", reclen);
406 error = EFAULT;
407 goto out;
408 }
409
410 off += reclen;
401 if (bdp->d_fileno == 0) {
402 inp += reclen;
411 if (bdp->d_fileno == 0) {
412 inp += reclen;
413 len -= reclen;
403 continue;
404 }
405 linuxreclen = LINUX_RECLEN(&linux_dirent, bdp->d_namlen);
406 if (reclen > len || resid < linuxreclen) {
407 outp++;
408 break;
409 }
410 linux_dirent.dino = (long) bdp->d_fileno;
411 linux_dirent.doff = (linux_off_t) linuxreclen;
412 linux_dirent.dreclen = (u_short) bdp->d_namlen;
413 strcpy(linux_dirent.dname, bdp->d_name);
414 continue;
415 }
416 linuxreclen = LINUX_RECLEN(&linux_dirent, bdp->d_namlen);
417 if (reclen > len || resid < linuxreclen) {
418 outp++;
419 break;
420 }
421 linux_dirent.dino = (long) bdp->d_fileno;
422 linux_dirent.doff = (linux_off_t) linuxreclen;
423 linux_dirent.dreclen = (u_short) bdp->d_namlen;
424 strcpy(linux_dirent.dname, bdp->d_name);
414 if ((error = copyout((caddr_t)&linux_dirent, outp, linuxreclen)))
425 if ((error = copyout((caddr_t)&linux_dirent, outp, linuxreclen))) {
415 goto out;
426 goto out;
427 }
416 inp += reclen;
417 outp += linuxreclen;
418 resid -= linuxreclen;
419 len -= reclen;
420 if (justone)
421 break;
422 }
423
424 if (outp == (caddr_t) args->dent)
425 goto again;
426 fp->f_offset = off;
427
428 if (justone)
429 nbytes = resid + linuxreclen;
428 inp += reclen;
429 outp += linuxreclen;
430 resid -= linuxreclen;
431 len -= reclen;
432 if (justone)
433 break;
434 }
435
436 if (outp == (caddr_t) args->dent)
437 goto again;
438 fp->f_offset = off;
439
440 if (justone)
441 nbytes = resid + linuxreclen;
442
430eof:
431 *retval = nbytes - resid;
432out:
433 VOP_UNLOCK(vp);
434 free(buf, M_TEMP);
435 return error;
436}
443eof:
444 *retval = nbytes - resid;
445out:
446 VOP_UNLOCK(vp);
447 free(buf, M_TEMP);
448 return error;
449}