Enhance the fp_*() API. Reorganize the ELF dump code using the fp_*()
authorMatthew Dillon <dillon@dragonflybsd.org>
Sun, 19 Oct 2003 19:24:20 +0000 (19:24 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Sun, 19 Oct 2003 19:24:20 +0000 (19:24 +0000)
API and adding hooks to make checkpointing easier.

Submitted-by: Kip Macy <kmacy@fsmware.com>
sys/kern/imgact_elf.c
sys/kern/kern_fp.c
sys/sys/ckpt.h [new file with mode: 0644]
sys/sys/file.h
sys/sys/imgact_elf.h

index 66e795e..ca26137 100644 (file)
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/kern/imgact_elf.c,v 1.73.2.13 2002/12/28 19:49:41 dillon Exp $
- * $DragonFly: src/sys/kern/imgact_elf.c,v 1.9 2003/09/23 05:03:51 dillon Exp $
+ * $DragonFly: src/sys/kern/imgact_elf.c,v 1.10 2003/10/19 19:24:18 dillon Exp $
  */
 
 #include <sys/param.h>
 #include <sys/exec.h>
 #include <sys/fcntl.h>
+#include <sys/file.h>
 #include <sys/imgact.h>
 #include <sys/imgact_elf.h>
 #include <sys/kernel.h>
@@ -62,7 +63,8 @@
 
 #include <machine/elf.h>
 #include <machine/md_var.h>
-
+#include <sys/mount.h>
+#include <sys/ckpt.h>
 #define OLD_EI_BRAND   8
 
 __ElfType(Brandinfo);
@@ -185,7 +187,9 @@ elf_check_header(const Elf_Ehdr *hdr)
 }
 
 static int
-elf_load_section(struct proc *p, struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot)
+elf_load_section(struct proc *p, struct vmspace *vmspace, struct vnode *vp, 
+                vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, 
+                vm_prot_t prot)
 {
        size_t map_len;
        vm_offset_t map_addr;
@@ -763,44 +767,88 @@ struct sseg_closure {
        size_t size;            /* Total size of all writable segments. */
 };
 
+struct fp_closure {
+       struct vn_hdr *vnh;
+       int count;
+       struct stat *sb;
+};
+
+       
+
 static void cb_put_phdr (vm_map_entry_t, void *);
 static void cb_size_segment (vm_map_entry_t, void *);
-static void each_writable_segment (struct proc *, segment_callback,
-    void *);
-static int elf_corehdr (struct proc *, struct vnode *, struct ucred *,
+static void cb_fpcount_segment(vm_map_entry_t, void *);
+static void cb_put_fp(vm_map_entry_t, void *);
+
+
+static void each_segment (struct proc *, segment_callback,
+    void *, int);
+static int elf_corehdr (struct proc *, struct file *, struct ucred *,
     int, void *, size_t);
 static void elf_puthdr (struct proc *, void *, size_t *,
     const prstatus_t *, const prfpregset_t *, const prpsinfo_t *, int);
 static void elf_putnote (void *, size_t *, const char *, int,
     const void *, size_t);
 
+static void elf_putsigs(struct proc *, void *, int *);
+
+static void elf_puttextvp(struct proc *, void *, int *);
+static void elf_putfiles(struct proc *, void *, int *); 
+
+
 extern int osreldate;
 
 int
-elf_coredump(p, vp, limit)
-       struct proc *p;
-       struct vnode *vp;
-       off_t limit;
+elf_coredump(struct proc *p, struct vnode *vp, off_t limit)
 {
+       struct file *fp; 
+       int error;
+
+       if ((error = falloc(NULL, &fp, NULL)) != 0)
+               return (error);
+       fsetcred(fp, p->p_ucred);
+
+       fp->f_data = (caddr_t)vp;
+       fp->f_flag = O_CREAT|O_WRONLY|O_NOFOLLOW;
+       fp->f_ops = &vnops;
+       fp->f_type = DTYPE_VNODE;
+       VOP_UNLOCK(vp, 0, p->p_thread);
+       
+       error = generic_elf_coredump(p, fp, limit);
+
+       fp->f_data = NULL;
+       fp->f_flag = 0;
+       fp->f_ops = &badfileops;
+       fp->f_type = 0;
+       fdrop(fp, p->p_thread);
+       return (error);
+}
+
+int
+generic_elf_coredump(struct proc *p, struct file *fp, off_t limit)
+{
+
        struct ucred *cred = p->p_ucred;
-       struct thread *td = p->p_thread;
        int error = 0;
        struct sseg_closure seginfo;
        void *hdr;
        size_t hdrsize;
 
+       if (!fp)
+               printf("can't dump core - null fp\n");
        /* Size the program segments. */
        seginfo.count = 0;
        seginfo.size = 0;
-       each_writable_segment(p, cb_size_segment, &seginfo);
+       each_segment(p, cb_size_segment, &seginfo, 1);
 
        /*
         * Calculate the size of the core file header area by making
         * a dry run of generating it.  Nothing is written, but the
         * size is calculated.
         */
+
        hdrsize = 0;
-       elf_puthdr((struct proc *)NULL, (void *)NULL, &hdrsize,
+       elf_puthdr(p, (void *)NULL, &hdrsize,
            (const prstatus_t *)NULL, (const prfpregset_t *)NULL,
            (const prpsinfo_t *)NULL, seginfo.count);
 
@@ -815,7 +863,7 @@ elf_coredump(p, vp, limit)
        if (hdr == NULL) {
                return EINVAL;
        }
-       error = elf_corehdr(p, vp, cred, seginfo.count, hdr, hdrsize);
+       error = elf_corehdr(p, fp, cred, seginfo.count, hdr, hdrsize);
 
        /* Write the contents of all of the writable segments. */
        if (error == 0) {
@@ -826,11 +874,9 @@ elf_coredump(p, vp, limit)
                php = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr)) + 1;
                offset = hdrsize;
                for (i = 0;  i < seginfo.count;  i++) {
-                       error = vn_rdwr_inchunks(UIO_WRITE, vp, 
-                           (caddr_t)php->p_vaddr,
-                           php->p_filesz, offset, UIO_USERSPACE,
-                           IO_UNIT | IO_DIRECT | IO_CORE, cred, 
-                           (int *)NULL, td);
+                       int nbytes;
+                       error = fp_pwrite(fp, (caddr_t)php->p_vaddr, php->p_filesz, 
+                                        offset, &nbytes);
                        if (error != 0)
                                break;
                        offset += php->p_filesz;
@@ -843,13 +889,11 @@ elf_coredump(p, vp, limit)
 }
 
 /*
- * A callback for each_writable_segment() to write out the segment's
+ * A callback for each_segment() to write out the segment's
  * program header entry.
  */
 static void
-cb_put_phdr(entry, closure)
-       vm_map_entry_t entry;
-       void *closure;
+cb_put_phdr(vm_map_entry_t entry, void *closure)
 {
        struct phdr_closure *phc = (struct phdr_closure *)closure;
        Elf_Phdr *phdr = phc->phdr;
@@ -879,9 +923,7 @@ cb_put_phdr(entry, closure)
  * the number of segments and their total size.
  */
 static void
-cb_size_segment(entry, closure)
-       vm_map_entry_t entry;
-       void *closure;
+cb_size_segment(vm_map_entry_t entry, void *closure)
 {
        struct sseg_closure *ssc = (struct sseg_closure *)closure;
 
@@ -889,16 +931,64 @@ cb_size_segment(entry, closure)
        ssc->size += entry->end - entry->start;
 }
 
+/*
+ * A callback for each_segment() to gather information about
+ * the number of text segments.
+ */
+static void
+cb_fpcount_segment(vm_map_entry_t entry, void *closure)
+{
+       int *count = (int *)closure;
+       if (entry->object.vm_object->type == OBJT_VNODE)
+               ++*count;
+}
+
+static void
+cb_put_fp(vm_map_entry_t entry, void *closure) 
+{
+       struct fp_closure *fpc = (struct fp_closure *)closure;
+       struct vn_hdr *vnh = fpc->vnh;
+       Elf_Phdr *phdr = &vnh->vnh_phdr;
+       struct vnode *vp;
+       int error;
+
+       if (entry->object.vm_object->type == OBJT_VNODE) {
+               vp = (struct vnode *)entry->object.vm_object->handle;
+               
+               vnh->vnh_fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
+               error = VFS_VPTOFH(vp, &vnh->vnh_fh.fh_fid);
+               if (error) 
+                       return;
+               
+               
+               phdr->p_type = PT_LOAD;
+               phdr->p_offset = 0;        /* not written to core */
+               phdr->p_vaddr = entry->start;
+               phdr->p_paddr = 0;
+               phdr->p_filesz = phdr->p_memsz = entry->end - entry->start;
+               phdr->p_align = PAGE_SIZE;
+               phdr->p_flags = 0;
+               if (entry->protection & VM_PROT_READ)
+                       phdr->p_flags |= PF_R;
+               if (entry->protection & VM_PROT_WRITE)
+                       phdr->p_flags |= PF_W;
+               if (entry->protection & VM_PROT_EXECUTE)
+                       phdr->p_flags |= PF_X;
+               ++fpc->vnh;
+               ++fpc->count;
+       }
+}
+
+
+
+
 /*
  * For each writable segment in the process's memory map, call the given
  * function with a pointer to the map entry and some arbitrary
  * caller-supplied data.
  */
 static void
-each_writable_segment(p, func, closure)
-       struct proc *p;
-       segment_callback func;
-       void *closure;
+each_segment(struct proc *p, segment_callback func, void *closure, int writable)
 {
        vm_map_t map = &p->p_vmspace->vm_map;
        vm_map_entry_t entry;
@@ -916,10 +1006,10 @@ each_writable_segment(p, func, closure)
                 * need to arbitrarily ignore such segments.
                 */
                if (elf_legacy_coredump) {
-                       if ((entry->protection & VM_PROT_RW) != VM_PROT_RW)
+                       if (writable && (entry->protection & VM_PROT_RW) != VM_PROT_RW)
                                continue;
                } else {
-                       if ((entry->protection & VM_PROT_ALL) == 0)
+                       if (writable && (entry->protection & VM_PROT_ALL) == 0)
                                continue;
                }
 
@@ -929,7 +1019,7 @@ each_writable_segment(p, func, closure)
                 * madvise(2).  Do not dump submaps (i.e. parts of the
                 * kernel map).
                 */
-               if (entry->eflags & (MAP_ENTRY_NOCOREDUMP|MAP_ENTRY_IS_SUB_MAP))
+               if (writable && entry->eflags & (MAP_ENTRY_NOCOREDUMP|MAP_ENTRY_IS_SUB_MAP))
                        continue;
 
                if ((obj = entry->object.vm_object) == NULL)
@@ -954,13 +1044,8 @@ each_writable_segment(p, func, closure)
  * the page boundary.
  */
 static int
-elf_corehdr(p, vp, cred, numsegs, hdr, hdrsize)
-       struct proc *p;
-       struct vnode *vp;
-       struct ucred *cred;
-       int numsegs;
-       size_t hdrsize;
-       void *hdr;
+elf_corehdr(struct proc *p, struct file *fp, struct ucred *cred, int numsegs, 
+           void *hdr, size_t hdrsize)
 {
        struct {
                prstatus_t status;
@@ -971,8 +1056,7 @@ elf_corehdr(p, vp, cred, numsegs, hdr, hdrsize)
        prstatus_t *status;
        prfpregset_t *fpregset;
        prpsinfo_t *psinfo;
-       struct thread *td = p->p_thread;
-
+       int nbytes;
        tempdata = malloc(sizeof(*tempdata), M_TEMP, M_ZERO | M_WAITOK);
        status = &tempdata->status;
        fpregset = &tempdata->fpregset;
@@ -1005,8 +1089,7 @@ elf_corehdr(p, vp, cred, numsegs, hdr, hdrsize)
        free(tempdata, M_TEMP);
 
        /* Write it to the core file. */
-       return vn_rdwr_inchunks(UIO_WRITE, vp, hdr, hdrsize, (off_t)0,
-           UIO_SYSSPACE, IO_UNIT | IO_DIRECT | IO_CORE, cred, NULL, td);
+       return fp_pwrite(fp, hdr, hdrsize, (off_t)0, &nbytes);
 }
 
 static void
@@ -1033,6 +1116,16 @@ elf_puthdr(struct proc *p, void *dst, size_t *off, const prstatus_t *status,
            sizeof *psinfo);
        notesz = *off - noteoff;
 
+       /* put extra cruft for dumping process state here 
+       *  - we really want it be before all the program 
+       *    mappings
+       *  - we just need to update the offset accordingly
+       *    and GDB will be none the wiser.
+       */
+       elf_puttextvp(p, dst, off);
+       elf_putsigs(p, dst, off);
+       elf_putfiles(p, dst, off);
+
        /* Align up to a page boundary for the program segments. */
        *off = round_page(*off);
 
@@ -1087,7 +1180,7 @@ elf_puthdr(struct proc *p, void *dst, size_t *off, const prstatus_t *status,
                /* All the writable segments from the program. */
                phc.phdr = phdr;
                phc.offset = *off;
-               each_writable_segment(p, cb_put_phdr, &phc);
+               each_segment(p, cb_put_phdr, &phc, 1);
        }
 }
 
@@ -1111,6 +1204,89 @@ elf_putnote(void *dst, size_t *off, const char *name, int type,
        *off += roundup2(note.n_descsz, sizeof(Elf_Size));
 }
 
+
+static void
+elf_putsigs(struct proc *p, void *dst, int *off) 
+{
+       struct ckpt_siginfo *csi;
+       if (dst == NULL) { 
+               *off += sizeof(struct ckpt_siginfo);
+               return;
+       }
+       csi = (struct ckpt_siginfo *)((char *)dst + *off);      
+
+       csi->csi_ckptpisz = sizeof(struct ckpt_siginfo);
+       bcopy(p->p_procsig, &csi->csi_procsig, sizeof(struct procsig));
+       bcopy(p->p_procsig->ps_sigacts, &csi->csi_sigacts, sizeof(struct sigacts));
+       bcopy(&p->p_realtimer, &csi->csi_itimerval, sizeof(struct itimerval));
+       csi->csi_sigparent = p->p_sigparent;
+       *off += sizeof(struct ckpt_siginfo);
+}
+
+static void
+elf_putfiles(struct proc *p, void *dst, int *off)
+{
+       int i, error;
+       struct ckpt_filehdr *cfh;
+       struct ckpt_fileinfo *cfi;
+       struct file *fp;        
+       struct vnode *vp;
+       /*
+        * the duplicated loop is gross, but it was the only way
+        * to eliminate uninitialized variable warnings 
+        */
+       if (dst) {
+               cfh = (struct ckpt_filehdr *)((char *)dst + *off);
+               *off += sizeof(struct ckpt_filehdr); 
+               cfh->cfh_nfiles = 0;            
+               /*
+                * ignore STDIN/STDERR/STDOUT
+                */
+               for (i = 3; i < p->p_fd->fd_nfiles; i++) {
+                       if ((fp = p->p_fd->fd_ofiles[i]) != NULL && fp->f_type == DTYPE_VNODE) {        
+                               cfh->cfh_nfiles++;
+                               printf("saving fd: %d\n", i);
+                               cfi = (struct ckpt_fileinfo *)((char *)dst + *off);
+                               cfi->cfi_index = i;
+                               cfi->cfi_flags = fp->f_flag;
+                               cfi->cfi_offset = fp->f_offset;
+                               vp = (struct vnode *)fp->f_data;
+                               cfi->cfi_fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
+                               error = VFS_VPTOFH(vp, &cfi->cfi_fh.fh_fid);
+
+                               *off += sizeof(struct ckpt_fileinfo);
+                       }
+               }
+       } else {
+               *off += sizeof(struct ckpt_filehdr); 
+               for (i = 0; i < p->p_fd->fd_nfiles; i++) 
+                       if ((fp = p->p_fd->fd_ofiles[i]) != NULL  && fp->f_type == DTYPE_VNODE)         
+                               *off += sizeof(struct ckpt_fileinfo);
+       }
+       
+}
+
+static void
+elf_puttextvp(struct proc *p, void *dst, int *off) 
+{
+       int count = 0;
+       struct fp_closure fpc;
+       int *vn_count;
+       if (!dst) {
+               each_segment(p, cb_fpcount_segment, &count, 0);
+               *off += sizeof(struct vn_hdr)*count + sizeof(int);
+               return;
+       }
+       vn_count = (int *)((char *)dst + *off);
+       *off += sizeof(int);
+       fpc.vnh = (struct vn_hdr *)((char *)dst + *off);
+       fpc.count = 0;
+       each_segment(p, cb_put_fp, &fpc, 0);
+       *vn_count = fpc.count;
+       *off += fpc.count*sizeof(struct vn_hdr);
+}
+
+
 /*
  * Tell kern_execve.c about it, with a little help from the linker.
  */
index 7a24daf..feeca14 100644 (file)
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/kern/kern_fp.c,v 1.2 2003/10/13 21:15:43 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_fp.c,v 1.3 2003/10/19 19:24:18 dillon Exp $
  */
 
 /*
@@ -114,8 +114,13 @@ fp_open(const char *path, int flags, int mode, file_t *fpp)
     return(error);
 }
 
+/*
+ * fp_*read() is meant to operate like the normal descriptor based syscalls
+ * would.  Note that if 'buf' points to user memory a UIO_USERSPACE
+ * transfer will be used.
+ */
 int
-fp_read(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res)
+fp_pread(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res)
 {
     struct uio auio;
     struct iovec aiov;
@@ -134,7 +139,10 @@ fp_read(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res)
     auio.uio_offset = offset;
     auio.uio_resid = nbytes;
     auio.uio_rw = UIO_READ;
-    auio.uio_segflg = UIO_SYSSPACE;
+    if ((vm_offset_t)buf < VM_MAXUSER_ADDRESS)
+       auio.uio_segflg = UIO_USERSPACE;
+    else
+       auio.uio_segflg = UIO_SYSSPACE;
     auio.uio_td = curthread;
 
     count = nbytes;
@@ -153,7 +161,48 @@ fp_read(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res)
 }
 
 int
-fp_write(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res)
+fp_read(file_t fp, void *buf, size_t nbytes, ssize_t *res)
+{
+    struct uio auio;
+    struct iovec aiov;
+    size_t count;
+    int error;
+
+    if (res)
+       *res = 0;
+    if (nbytes > INT_MAX)
+       return (EINVAL);
+    bzero(&auio, sizeof(auio));
+    aiov.iov_base = (caddr_t)buf;
+    aiov.iov_len = nbytes;
+    auio.uio_iov = &aiov;
+    auio.uio_iovcnt = 1;
+    auio.uio_offset = 0;
+    auio.uio_resid = nbytes;
+    auio.uio_rw = UIO_READ;
+    if ((vm_offset_t)buf < VM_MAXUSER_ADDRESS)
+       auio.uio_segflg = UIO_USERSPACE;
+    else
+       auio.uio_segflg = UIO_SYSSPACE;
+    auio.uio_td = curthread;
+
+    count = nbytes;
+    error = fo_read(fp, &auio, fp->f_cred, 0, auio.uio_td);
+    if (error) {
+       if (auio.uio_resid != nbytes && (error == ERESTART || error == EINTR ||
+           error == EWOULDBLOCK)
+       ) {
+           error = 0;
+       }
+    }
+    count -= auio.uio_resid;
+    if (res)
+       *res = count;
+    return(error);
+}
+
+int
+fp_pwrite(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res)
 {
     struct uio auio;
     struct iovec aiov;
@@ -172,7 +221,10 @@ fp_write(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res)
     auio.uio_offset = offset;
     auio.uio_resid = nbytes;
     auio.uio_rw = UIO_WRITE;
-    auio.uio_segflg = UIO_SYSSPACE;
+    if ((vm_offset_t)buf < VM_MAXUSER_ADDRESS)
+       auio.uio_segflg = UIO_USERSPACE;
+    else
+       auio.uio_segflg = UIO_SYSSPACE;
     auio.uio_td = curthread;
 
     count = nbytes;
@@ -190,6 +242,48 @@ fp_write(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res)
     return(error);
 }
 
+
+int
+fp_write(file_t fp, void *buf, size_t nbytes, ssize_t *res)
+{
+    struct uio auio;
+    struct iovec aiov;
+    size_t count;
+    int error;
+
+    if (res)
+       *res = 0;
+    if (nbytes > INT_MAX)
+       return (EINVAL);
+    bzero(&auio, sizeof(auio));
+    aiov.iov_base = (caddr_t)buf;
+    aiov.iov_len = nbytes;
+    auio.uio_iov = &aiov;
+    auio.uio_iovcnt = 1;
+    auio.uio_offset = 0;
+    auio.uio_resid = nbytes;
+    auio.uio_rw = UIO_WRITE;
+    if ((vm_offset_t)buf < VM_MAXUSER_ADDRESS)
+       auio.uio_segflg = UIO_USERSPACE;
+    else
+       auio.uio_segflg = UIO_SYSSPACE;
+    auio.uio_td = curthread;
+
+    count = nbytes;
+    error = fo_write(fp, &auio, fp->f_cred, 0, auio.uio_td);
+    if (error) {
+       if (auio.uio_resid != nbytes && (error == ERESTART || error == EINTR ||
+           error == EWOULDBLOCK)
+       ) {
+           error = 0;
+       }
+    }
+    count -= auio.uio_resid;
+    if (res)
+       *res = count;
+    return(error);
+}
+
 int
 fp_stat(file_t fp, struct stat *ub)
 {
diff --git a/sys/sys/ckpt.h b/sys/sys/ckpt.h
new file mode 100644 (file)
index 0000000..5470354
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * $DragonFly: src/sys/sys/ckpt.h,v 1.1 2003/10/19 19:24:20 dillon Exp $
+ */
+#ifndef _SYS_CKPT_H_
+#define _SYS_CKPT_H_
+
+struct ckpt_filehdr {
+       int cfh_nfiles;
+};
+
+
+struct ckpt_fileinfo {
+       int   cfi_index;
+       u_int cfi_flags;        /* saved f_flag */
+       off_t cfi_offset;       /* saved f_offset */
+       fhandle_t cfi_fh;
+};
+
+struct ckpt_siginfo {
+  int               csi_ckptpisz;
+  struct procsig    csi_procsig;
+  struct sigacts    csi_sigacts;
+  struct itimerval  csi_itimerval;
+  int               csi_sigparent;
+};
+
+struct vn_hdr {
+       fhandle_t vnh_fh;
+       Elf_Phdr vnh_phdr;
+};
+
+#ifdef _KERNEL
+#ifdef DEBUG
+#define TRACE_ENTER \
+printf("entering %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__)
+#define TRACE_EXIT \
+printf("exiting %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__)
+#define TRACE_ERR \
+printf("failure encountered in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__)
+#define PRINTF printf
+#else
+#define TRACE_ENTER
+#define TRACE_EXIT
+#define TRACE_ERR
+#define PRINTF()
+#endif
+#endif
+
+#endif
index a1749e2..a666a2c 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)file.h      8.3 (Berkeley) 1/9/95
  * $FreeBSD: src/sys/sys/file.h,v 1.22.2.7 2002/11/21 23:39:24 sam Exp $
- * $DragonFly: src/sys/sys/file.h,v 1.6 2003/10/13 18:01:28 dillon Exp $
+ * $DragonFly: src/sys/sys/file.h,v 1.7 2003/10/19 19:24:20 dillon Exp $
  */
 
 #ifndef _SYS_FILE_H_
@@ -122,8 +122,10 @@ MALLOC_DECLARE(M_FILE);
 extern int fdrop (struct file *fp, struct thread *td);
 
 extern int fp_open(const char *path, int flags, int mode, struct file **fpp);
-extern int fp_read(struct file *fp, void *buf, size_t nbytes, off_t offset, ssize_t *res);
-extern int fp_write(struct file *fp, void *buf, size_t nbytes, off_t offset, ssize_t *res);
+extern int fp_pread(struct file *fp, void *buf, size_t nbytes, off_t offset, ssize_t *res);
+extern int fp_pwrite(struct file *fp, void *buf, size_t nbytes, off_t offset, ssize_t *res);
+extern int fp_read(struct file *fp, void *buf, size_t nbytes, ssize_t *res);
+extern int fp_write(struct file *fp, void *buf, size_t nbytes, ssize_t *res);
 extern int fp_stat(struct file *fp, struct stat *ub);
 extern int fp_mmap(void *addr, size_t size, int prot, int flags, struct file *fp, off_t pos, void **resp);
 
index 5596ffa..1a00d39 100644 (file)
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/sys/imgact_elf.h,v 1.17.2.1 2000/07/06 22:26:40 obrien Exp $
- * $DragonFly: src/sys/sys/imgact_elf.h,v 1.3 2003/08/20 07:31:21 rob Exp $
+ * $DragonFly: src/sys/sys/imgact_elf.h,v 1.4 2003/10/19 19:24:20 dillon Exp $
  */
 
 #ifndef _SYS_IMGACT_ELF_H_
@@ -105,9 +105,9 @@ int elf_remove_brand_entry (Elf64_Brandinfo *entry);
 #endif /* ELF_TARG_CLASS == ELFCLASS32 */
 
 struct proc;
-
+struct file;
 int    elf_coredump (struct proc *, struct vnode *, off_t);
-
+int     generic_elf_coredump(struct proc *p, struct file *fp, off_t limit);
 #endif /* _KERNEL */
 
 #endif /* !_SYS_IMGACT_ELF_H_ */