]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - fs/binfmt_aout.c
coredump: unify dump_seek() implementations for each binfmt_*.c
[net-next-2.6.git] / fs / binfmt_aout.c
index 61dd00a6c7b4f7ed5ff692d0bdfb81b887677871..d2f8872dd767173d59051b7d7b71e1a6bca3e53e 100644 (file)
@@ -69,16 +69,32 @@ static int dump_write(struct file *file, const void *addr, int nr)
        return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
 }
 
+static int dump_seek(struct file *file, loff_t off)
+{
+       if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
+               if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
+                       return 0;
+       } else {
+               char *buf = (char *)get_zeroed_page(GFP_KERNEL);
+               if (!buf)
+                       return 0;
+               while (off > 0) {
+                       unsigned long n = off;
+                       if (n > PAGE_SIZE)
+                               n = PAGE_SIZE;
+                       if (!dump_write(file, buf, n))
+                               return 0;
+                       off -= n;
+               }
+               free_page((unsigned long)buf);
+       }
+       return 1;
+}
+
 #define DUMP_WRITE(addr, nr)   \
        if (!dump_write(file, (void *)(addr), (nr))) \
                goto end_coredump;
 
-#define DUMP_SEEK(offset) \
-if (file->f_op->llseek) { \
-       if (file->f_op->llseek(file,(offset),0) != (offset)) \
-               goto end_coredump; \
-} else file->f_pos = (offset)
-
 /*
  * Routine writes a core dump image in the current directory.
  * Currently only a stub-function.
@@ -132,7 +148,8 @@ static int aout_core_dump(struct coredump_params *cprm)
 /* struct user */
        DUMP_WRITE(&dump,sizeof(dump));
 /* Now dump all of the user data.  Include malloced stuff as well */
-       DUMP_SEEK(PAGE_SIZE);
+       if (!dump_seek(cprm->file, PAGE_SIZE - sizeof(dump)))
+               goto end_coredump;
 /* now we start writing out the user space info */
        set_fs(USER_DS);
 /* Dump the data area */