Exemple #1
0
Fichier : move.c Projet : jes/zoe
/* return a list of moves that can be played from the given position */
void generate_movelist(Game *game, Move *movelist, int *nmoves) {
    uint64_t pieces = game->board.b[game->turn][OCCUPIED];
    Move m;
    int nmove = 0;

    /* for each of the pieces... */
    while(pieces) {
        /* pick the next piece */
        int piece = bsf(pieces);

        /* remove this piece from the set */
        pieces ^= 1ull << piece;

        /* set the start square of the moves */
        m.begin = piece;

        /* generate the moves for this piece */
        uint64_t moves = generate_moves(game, piece);

        /* for each of this piece's moves */
        while(moves) {
            /* pick the next move */
            int move = bsf(moves);

            /* remove this move from the set */
            moves ^= 1ull << move;

            /* set the end square of this move */
            m.end = move;

            /* promote pawns */
            if(game->board.mailbox[piece] == PAWN
                    && (m.end / 8 == 0 || m.end / 8 == 7)) {
                m.promote = QUEEN;
                movelist[nmove++] = m;
                m.promote = KNIGHT;
                movelist[nmove++] = m;
                m.promote = ROOK;
                movelist[nmove++] = m;
                m.promote = BISHOP;
                movelist[nmove++] = m;
            } else {
                m.promote = 0;
                movelist[nmove++] = m;
            }
        }
    }

    *nmoves = nmove;
}
void bsf_test ( )

/******************************************************************************/
/*
  Purpose:

    BSF_TEST tests BSF.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    18 February 2012

  Author:

    John Burkardt
*/
{
  double c;
  double e;
  double r;
  double s0;
  double sigma;
  double t0;
  double t1;

  printf ( "\n" );
  printf ( "BSF_TEST:\n" );
  printf ( "  A demonstration of the Black-Scholes formula\n" );
  printf ( "  for option valuation.\n" );

  s0 = 2.0;
  t0 = 0.0;
  e = 1.0;
  r = 0.05;
  sigma = 0.25;
  t1 = 3.0;

  printf ( "\n" );
  printf ( "  The asset price at time T0 S0    = %g\n", s0 );
  printf ( "  The time                   T0    = %g\n", t0 );
  printf ( "  The exercise price         E     = %g\n", e );
  printf ( "  The interest rate          R     = %g\n", r );
  printf ( "  The asset volatility       SIGMA = %g\n", sigma );
  printf ( "  The expiry date            T1    = %g\n", t1 );

  c = bsf ( s0, t0, e, r, sigma, t1 );

  printf ( "\n" );
  printf ( "  The option value C = %g\n\n", c );

  return;
}
/*
 * Reposition the device to file, block
 *
 * Returns: false on failure
 *          true  on success
 */
bool generic_tape_device::reposition(DCR *dcr, uint32_t rfile, uint32_t rblock)
{
   Dmsg4(100, "reposition from %u:%u to %u:%u\n", file, block_num, rfile, rblock);
   if (rfile < file) {
      Dmsg0(100, "Rewind\n");
      if (!rewind(NULL)) {
         return false;
      }
   }

   if (rfile > file) {
      Dmsg1(100, "fsf %d\n", rfile-file);
      if (!fsf(rfile-file)) {
         Dmsg1(100, "fsf failed! ERR=%s\n", bstrerror());
         return false;
      }
      Dmsg2(100, "wanted_file=%d at_file=%d\n", rfile, file);
   }

   if (rblock < block_num) {
      Dmsg2(100, "wanted_blk=%d at_blk=%d\n", rblock, block_num);
      Dmsg0(100, "bsf 1\n");
      bsf(1);
      Dmsg0(100, "fsf 1\n");
      fsf(1);
      Dmsg2(100, "wanted_blk=%d at_blk=%d\n", rblock, block_num);
   }

   if (has_cap(CAP_POSITIONBLOCKS) && rblock > block_num) {
      /*
       * Ignore errors as Bareos can read to the correct block.
       */
      Dmsg1(100, "fsr %d\n", rblock-block_num);
      return fsr(rblock-block_num);
   } else {
      while (rblock > block_num) {
         if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
            berrno be;
            dev_errno = errno;
            Dmsg2(30, "Failed to find requested block on %s: ERR=%s", prt_name, be.bstrerror());
            return false;
         }
         Dmsg2(300, "moving forward wanted_blk=%d at_blk=%d\n", rblock, block_num);
      }
   }

   return true;
}
Exemple #4
0
/*
 *	timer signal (SIGALRM) handler
 *	SIGALRM  handler - only set during hibernate
 */
static void user_tim_handler (int sig)
{
	int threads = att_val (&enabled_threads);
	
	if (RTS_TRACING) {
		MESSAGE ("USERPROC: Alarm ringing (SIGALRM).\n");
		FFLUSH (stderr);
	}

	while (threads) {
		int n 		= bsf (threads);
		sched_t *s 	= schedulers[n];

		threads &= ~(s->id);

		ccsp_wake_thread (s, SYNC_TIME_BIT);
	}
	
	#if defined(SIGNAL_TYPE_SYSV)
		signal (SIGALRM, user_tim_handler);
	#endif /* SIGNAL_TYPE */
}
Exemple #5
0
int doAnalysis(Board board) {
	int ret = -1;
	DEBUG("IN");

	if (board == NULL) {
		ERROR("The board for analyzing or the memory to store result boards is NULL.");
		return ret;
	}

	if (que == NULL || ht == NULL) {
		WARN("queue or hashtable is/are NULL.");
		if(initMemo()) {
			ERROR("initializing memory failed.");
			return ret;
		}
	} else {
		clearMemo();
	}

	ret = bsf(board);

	DEBUG("OUT");
	return ret;
}
Exemple #6
0
static int elf_mod_parse(uintptr_t elf, const char *name, int export_symbol, 
        uintptr_t * common_data, uint32_t * common_size,
        uintptr_t * mod_load_ptr, uintptr_t * mod_unload_ptr) {
    uint32_t i, x;
    uintptr_t reloc_addr;
    void * mem_addr;

    struct elfhdr *eh;
    struct secthdr *sh;
    struct reloc_a_s *reloc;
    struct symtab_s *symtab;

    uintptr_t cur_common_alloc = 0;
    uintptr_t cur_common_align = 1;

    eh = (struct elfhdr *)elf;

    kprintf("[ II ] shnum = %d, shsize = %d\n", eh->e_shnum, eh->e_shentsize);

    for (i = 0; i < eh->e_shnum; i++) {
        sh = (struct secthdr*)(elf + eh->e_shoff + (i * eh->e_shentsize));
        kprintf("[ II ] sh type = %d\n", sh->sh_type);
        if (sh->sh_type == SH_TYPE_SYMTAB) {
            for (x = 0; x < sh->sh_size; x += sh->sh_entsize) {
                symtab = (struct symtab_s *)(elf + sh->sh_offset + x);
                kprintf("[ II ] found sym: [%s] info[%02x] size[%d] addr[%08x]\n",
                        get_symbol_string(elf, symtab->sym_name),
                        symtab->sym_info,
                        symtab->sym_size,
                        symtab->sym_address);
                if (symtab->sym_shndx != SHN_UNDEF && symtab->sym_shndx < 0xff00) {
                    kprintf("[ II ]     value offset [%08x]\n", get_section_offset(elf, symtab->sym_shndx) + symtab->sym_address);
                    const char * sym_name = get_symbol_string(elf, symtab->sym_name);
                    switch (GET_SYMTAB_BIND(symtab->sym_info)) {
                        case STB_GLOBAL:
                            kprintf("[ II ]     global symbol\n");
                        case STB_LOCAL:
                            if (strcmp(sym_name, MOD_INIT_MODULE) == 0) {
                                *mod_load_ptr = get_section_offset(elf, symtab->sym_shndx) + symtab->sym_address + elf;
                            } else if (strcmp(sym_name, MOD_CLEANUP_MODULE) == 0) {
                                *mod_unload_ptr = get_section_offset(elf, symtab->sym_shndx) + symtab->sym_address + elf;
                            }

                            // global
                            if (GET_SYMTAB_BIND(symtab->sym_info) == 1 && export_symbol) {
                                mod_touch_symbol(sym_name, (void *)(get_section_offset(elf, symtab->sym_shndx) + symtab->sym_address + elf), 0);
                            }
                            break;

                        case STB_WEAK:
                            kprintf("[ II ]     weak symbol\n");
                            if (export_symbol) {
                                elf_mod_create_symbol(sym_name, (void *)(symtab->sym_address + elf), 0);
                            }
                            break;
                    }
                } else if (symtab->sym_shndx == SHN_COMMON) {
                    // TODO: implement SHN_COMMON
                    kprintf("[ EE ] not implemented\n");
                } else {
                    kprintf("[ II ] shndx[%04x]\n", symtab->sym_shndx);
                }
            }
        } else if (sh->sh_type == SH_TYPE_NOBITS) {
            kprintf("[ II ] bss section, alloc %d byte align 0x%x\n", sh->sh_size, sh->sh_addralign);
            if (bsf(sh->sh_addralign != bsr(sh->sh_addralign))) {
                error(" bad align\n");
                return -1;
            }
            if (sh->sh_addralign > cur_common_align) {
                cur_common_align = sh->sh_addralign;
            }
            cur_common_alloc = ((cur_common_alloc - 1) | (sh->sh_addralign - 1)) + 1;
            sh->sh_addr = cur_common_alloc;
            cur_common_alloc += sh->sh_size;
        }
    }

    uintptr_t common_space;
    if (cur_common_align > PGSIZE) {
        error("align failed\n");
        return -1;
    } else if (cur_common_alloc > 0) {
        // TODO: kmalloc would return non-kernel-area memory pointer, which would cause PG FAULT
        common_space = (uintptr_t)kmalloc(cur_common_alloc);
        memset((void*)common_space, 0, cur_common_alloc);

        *common_data = common_space;
        *common_size = cur_common_alloc;
    } else {
        *common_data = 0;
        *common_size = 0;
    }

    // fill the relocation entries
    for (i = 0; i < eh->e_shnum; i++) {
        sh = (struct secthdr *)(elf + eh->e_shoff + (i * eh->e_shentsize));

        if (sh->sh_type == SH_TYPE_RELA) {
            for (x = 0; x < sh->sh_size; x += sh->sh_entsize) {
                reloc = (struct reloc_a_s *)(elf + sh->sh_offset + x);
                symtab = fill_symbol_struct(elf, GET_RELOC_SYM(reloc->rl_info));

                kprintf("[ II ] reloc[%02x] offset[%08x] for [%s], sym offset[%08x]\n",
                        GET_RELOC_TYPE(reloc->rl_info),
                        reloc->rl_offset,
                        get_symbol_string(elf, symtab->sym_name),
                        symtab->sym_address);

                mem_addr = (void *)(elf + reloc->rl_offset + get_section_offset(elf, sh->sh_info));

                /* external reference (kernel symbol most likely) */
                if (symtab->sym_shndx == SHN_UNDEF) {
                    const char *sym_name = get_symbol_string(elf, symtab->sym_name);
                    int idx = find_export_sym(sym_name, 0);
                    if (idx == -1) {
                        if (strcmp(sym_name, name) == 0) {
                            reloc_addr = elf;
                        } else {
                            error("unresolved symbol \"%s\", set with 0\n", sym_name);
                            reloc_addr = 0;
                        }
                    } else {
                        kprintf("external symbol %s addr = %p\n", sym_name, ex_sym_ptr[idx]);
                        reloc_addr = ex_sym_ptr[idx];
                    }
                } else if (symtab->sym_shndx < 0xff00) {
                    kprintf("section offset %16x, addr %16x\n", get_section_offset(elf, symtab->sym_shndx), symtab->sym_address);
                    if (((struct secthdr *)(elf + eh->e_shoff + (symtab->sym_shndx * eh->e_shentsize)))->sh_type == SH_TYPE_NOBITS) {
                        reloc_addr = common_space;
                    } else {
                        reloc_addr = elf;
                    }
                    reloc_addr += get_section_offset(elf, symtab->sym_shndx);
                    reloc_addr += symtab->sym_address;
                } else if (symtab->sym_shndx == SHN_COMMON) {
                    reloc_addr = common_space + symtab->sym_address;
                } else {
                    error("unhandled syn_shndx\n");
                }
                
                switch (GET_RELOC_TYPE(reloc->rl_info)) {
                    case 0x02:      // S + A - P
                        reloc_addr = reloc_addr - (uintptr_t)mem_addr;
                        //*(uintptr_t *)mem_addr = reloc_addr + *(uintptr_t *)mem_addr;
                        *(uint32_t *)mem_addr = reloc_addr + reloc->rl_addend;
                        kprintf("fill rel address %08x to %08x\n", *(uint32_t *)mem_addr, mem_addr);
                        break;

                    case 0x0b:      // S + A
                        *(uint32_t *)mem_addr = reloc_addr + reloc->rl_addend;
                        kprintf("fill rel address %08x to %08x\n", *(uint32_t *)mem_addr, mem_addr);
                        break;

                    default:
                        error("unsupported relocation type (%x)\n", GET_RELOC_TYPE(reloc->rl_info));
                        break;

                }
            }
        } else if (sh->sh_type == SH_TYPE_REL) {
            kprintf("[ EE ] relocation SH_TYPE_REL not implemented\n");
        }
    }

    return 0;
}
Exemple #7
0
int vtape::tape_op(struct mtop *mt_com)
{
   int result=0;
   int count = mt_com->mt_count;

   if (!online) {
      errno = ENOMEDIUM;
      return -1;
   }

   switch (mt_com->mt_op)
   {
   case MTRESET:
   case MTNOP:
   case MTSETDRVBUFFER:
      break;

   default:
   case MTRAS1:
   case MTRAS2:
   case MTRAS3:
   case MTSETDENSITY:
      errno = ENOTTY;
      result = -1;
      break;

   case MTFSF:                  /* Forward space over mt_count filemarks. */
      do {
         result = fsf();
      } while (--count > 0 && result == 0);
      break;

   case MTBSF:                  /* Backward space over mt_count filemarks. */
      do {
         result = bsf();
      } while (--count > 0 && result == 0);
      break;

   case MTFSR:      /* Forward space over mt_count records (tape blocks). */
/*
    file number = 1
    block number = 0

    file number = 1
    block number = 1

    mt: /dev/lto2: Erreur d'entree/sortie

    file number = 2
    block number = 0
*/
      /* tester si on se trouve a la fin du fichier */
      result = fsr(mt_com->mt_count);
      break;

   case MTBSR:      /* Backward space over mt_count records (tape blocks). */
      result = bsr(mt_com->mt_count);
      break;

   case MTWEOF:                 /* Write mt_count filemarks. */
      do {
         result = weof();
      } while (result == 0 && --count > 0);
      break;

   case MTREW:                  /* Rewind. */
      Dmsg0(dbglevel, "rewind vtape\n");
      check_eof();
      atEOF = atEOD = false;
      atBOT = true;
      current_file = 0;
      current_block = 0;
      lseek(fd, 0, SEEK_SET);
      result = !read_fm(VT_READ_EOF);
      break;

   case MTOFFL:                 /* put tape offline */
      result = offline();
      break;

   case MTRETEN:                /* Re-tension tape. */
      result = 0;
      break;

   case MTBSFM:                 /* not used by bareos */
      errno = EIO;
      result = -1;
      break;

   case MTFSFM:                 /* not used by bareos */
      errno = EIO;
      result = -1;
      break;

   case MTEOM:/* Go to the end of the recorded media (for appending files). */
      while (next_FM) {
         lseek(fd, next_FM, SEEK_SET);
         if (read_fm(VT_READ_EOF)) {
            current_file++;
         }
      }
      boffset_t l;
      while (::read(fd, &l, sizeof(l)) > 0) {
         if (l) {
            lseek(fd, l, SEEK_CUR);
         } else {
            ASSERT(0);
         }
         Dmsg0(dbglevel, "skip 1 block\n");
      }
      current_block = -1;
      atEOF = false;
      atEOD = true;

/*
   file number = 3
   block number = -1
*/
      /* Can be at EOM */
      break;

   case MTERASE:                /* not used by bareos */
      atEOD = true;
      atEOF = false;
      atEOT = false;

      current_file = 0;
      current_block = -1;
      lseek(fd, 0, SEEK_SET);
      read_fm(VT_READ_EOF);
      truncate_file();
      break;

   case MTSETBLK:
      break;

   case MTSEEK:
      break;

   case MTTELL:
      break;

   case MTFSS:
      break;

   case MTBSS:
      break;

   case MTWSM:
      break;

   case MTLOCK:
      break;

   case MTUNLOCK:
      break;

   case MTLOAD:
      break;

   case MTUNLOAD:
      break;

   case MTCOMPRESSION:
      break;

   case MTSETPART:
      break;

   case MTMKPART:
      break;
   }

   return result == 0 ? 0 : -1;
}
Exemple #8
0
void		_main(void)
{
  uint32_t i;

  /**
   *
   *	Basic setup
   */

  /* enable the A20 line */
 
  /* disable the PIC (8259A chip) */
  pic_enable(false);

  /* disable the local APIC */
  //apic_enable(false);
  //apic_local_enable(false)

  /**
   *
   *	Protection
   */

  /* init and enable segmentation */
  //gdt_init();

  seg_init();
  //  INFINITE_LOOP();

  /* init and enable paging */
  //mmu_init();
  console_clear();
  mmu_init();

  /* init the system-call facilities */
  sc_init();

  /**
   *
   *	Interrupts
   */
  // INFINITE_LOOP();
  /* init and enable interrupts */
  idt_init();

  //INFINITE_LOOP();

  /* bind stage2 isrs */
  //isr_init();
  int_init();
  ex_init();

  //INFINITE_LOOP();

  /* configure the Local-APIC timer */
  //apic_local_timer_init(0x2ffffff);
  //apic_local_timer_init(0xffffff);

  /* configure the PIT timer */
  pit_init();

  printf("Local-APIC init...\n");
  /* Init the Local-APIC. */
  apic_local_init();
  apic_local_set_task_priority(0);
  printf("Local-APIC timer config...\n");
  apic_local_timer_config(0x2ffffff);
  printf("IO-APIC init...\n");
  apic_io_init();
  /* enable the local APIC */
  //apic_enable(true);
  apic_local_enable(true);

  printf("OK\n");

  /* configure the I/O APIC in charge of the PIT, keyboard, ... */
  //apic_io_init();
  /* STI(); */
/*   INFINITE_LOOP(); */

  /* clear the screen */
  console_clear();
  console_init();

  /* init the basic I/O services */
  stdio_init();
  //tty_init();
  //tty_activate(0);

 /*  sysenter(); */
  /*   vmx_supported(1); */
  test_malloc();

  /* init the serial number facility */
  serial_init();
  /*   printf("UID %d\n", serial_generate()); */
  /*   printf("UID %d\n", serial_generate()); */
  /*   printf("UID %d\n", serial_generate()); */

  /* init the task manager */
  thread_init();

  /* init the scheduler manager */
  sched_init();

  /* dump the memory */
  mem_dump();

  /* test the mmu. */
  //mmu_test();
  /* while (1) */
/*     ; */

  //video_init();

/*   msr = rdmsr(MSR_IA32_APIC_BASE); */
/*   printf("msr hi: %x\n", (uint32_t)(msr >> 32)); */
/*   printf("msr lo: %x\n", (uint32_t) msr); */
/*   msr = rdmsr(MSR_IA32_CR_PAT); */
/*   printf("msr hi: %x\n", (uint32_t)(msr >> 32)); */
/*   printf("msr lo: %x\n", (uint32_t) msr); */
/*   msr = rdmsr(MSR_IA32_PERF_GLOBAL_STATUS); */
/*   printf("msr hi: %x\n", (uint32_t)(msr >> 32)); */
/*   printf("msr lo: %x\n", (uint32_t) msr); */
/*   msr = rdmsr(MSR_IA32_PLATFORM_ID); */
/*   printf("msr hi: %x\n", (uint32_t)(msr >> 32)); */
/*   printf("msr lo: %x\n", (uint32_t) msr); */
/*   printf("Macrotest\n"); */
/*   MACROTEST(&msr); */
/*   printf("msr hi: %x\n", (uint32_t)(msr >> 32)); */
 /*  printf("apic-io ver: %x\n", apic_io_get_version()); */
/*   printf("apic-io id: %x\n", apic_io_get_id()); */

/*   printf("New GDT:\n"); */
/*   seg_init(); */
/*   printf("Old GDT:\n"); */
/*   for (i = 0; i < SEG_DESC_N; i++) */
/*     { */
/*       printf("%x - %x\n", gdt[i].high, gdt[i].low); */
/*     } */
  //INFINITE_LOOP();

  i = 1 << 5 | 1 << 9;
  printf("bsf(i) = %d\n", bsf(i));
  printf("bsr(i) = %d\n", bsr(i));
  i = 0;
  printf("bsr(i) = %d\n", bsr(i));

  printf("MSR_IA32_SYSENTER_CS high = %x\n", (uint32_t)(rdmsr(MSR_IA32_SYSENTER_CS) >> 32));
  printf("MSR_IA32_SYSENTER_CS low = %x\n", (uint32_t) rdmsr(MSR_IA32_SYSENTER_CS));

  printf("IA32_CR_PAT high = %x\n", (uint32_t)(rdmsr(MSR_IA32_CR_PAT) >> 32));
  printf("IA32_CR_PAT low = %x\n", (uint32_t) rdmsr(MSR_IA32_CR_PAT));

  /* jump to background task - code after this function is never reached */
  sched_launch();


  /*   test_multiline(); */
  /*   test_println(); */
  /*   test_interrupts(); */
  /*   test_itoa(); */
  /*   test_msr(); */
  //test_apic();
  //test_ide_dma();

  //printf("+ Bus 0\n", BG_BLACK | FG_RED | FG_INTENSITY);
  //pci_list(0, 2, 64);
  /*   printf("Bus 1\n", BG_BLACK | FG_RED | FG_INTENSITY); */
  /*   pci_list(1); */
  //test_ide_dma();
  //test_apic();

  //fprintf(0, "Protos v%d.%d - id:%x\n", 0, 12, 0xbe01);
  //fprintf(0, "\tid reg:\t%r\n", 0xbe01);
  //fprintf(0, "Ok!\n");
  // printf("Helo %% %d-%x-%r\n", 45, 0xabc78, 0xabc78);
  //printf("Helo %r\n", 0xbe01);

  //r = fprintf(stdout, "Almost %x years :)\n", 26);
  //fprintf(stdout, "size:%d\n", strlen("hello!"));

  //printf("fprintf result = %d\n", r);
  //printf(&((&stdio_filedes[0])->buffer[0]));

  //__asm__ ("rdtsc");


  // Halt the system
  while (1)
    HLT();
}
Exemple #9
0
static inline int find_mask_bsf(const uint64_t *mask, int size) {
  for (int i = 0; i < size; i++)
    if (mask[i])
      return i * 64 + bsf(mask[i]);
  return -1;
}
/*
 * Position device to end of medium (end of data)
 *
 * Returns: true  on succes
 *          false on error
 */
bool generic_tape_device::eod(DCR *dcr)
{
   struct mtop mt_com;
   bool ok = true;
   int32_t os_file;

   if (m_fd < 0) {
      dev_errno = EBADF;
      Mmsg1(errmsg, _("Bad call to eod. Device %s not open\n"), prt_name);
      return false;
   }

#if defined (__digital__) && defined (__unix__)
   return fsf(VolCatInfo.VolCatFiles);
#endif

   Dmsg0(100, "Enter eod\n");
   if (at_eot()) {
      return true;
   }

   clear_eof();         /* remove EOF flag */
   block_num = file = 0;
   file_size = 0;
   file_addr = 0;

#ifdef MTEOM
   if (has_cap(CAP_FASTFSF) && !has_cap(CAP_EOM)) {
      Dmsg0(100,"Using FAST FSF for EOM\n");
      /*
       * If unknown position, rewind
       */
      if (get_os_tape_file() < 0) {
        if (!rewind(NULL)) {
          Dmsg0(100, "Rewind error\n");
          return false;
        }
      }
      mt_com.mt_op = MTFSF;
      /*
       * ***FIXME*** fix code to handle case that INT16_MAX is not large enough.
       */
      mt_com.mt_count = INT16_MAX;    /* use big positive number */
      if (mt_com.mt_count < 0) {
         mt_com.mt_count = INT16_MAX; /* brain damaged system */
      }
   }

   if (has_cap(CAP_MTIOCGET) && (has_cap(CAP_FASTFSF) || has_cap(CAP_EOM))) {
      if (has_cap(CAP_EOM)) {
         Dmsg0(100,"Using EOM for EOM\n");
         mt_com.mt_op = MTEOM;
         mt_com.mt_count = 1;
      }

      if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
         berrno be;
         clrerror(mt_com.mt_op);
         Dmsg1(50, "ioctl error: %s\n", be.bstrerror());
         update_pos(dcr);
         Mmsg2(errmsg, _("ioctl MTEOM error on %s. ERR=%s.\n"), prt_name, be.bstrerror());
         Dmsg0(100, errmsg);
         return false;
      }

      os_file = get_os_tape_file();
      if (os_file < 0) {
         berrno be;
         clrerror(-1);
         Mmsg2(errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"), prt_name, be.bstrerror());
         Dmsg0(100, errmsg);
         return false;
      }
      Dmsg1(100, "EOD file=%d\n", os_file);
      set_ateof();
      file = os_file;
   } else {
#endif
      /*
       * Rewind then use FSF until EOT reached
       */
      if (!rewind(NULL)) {
         Dmsg0(100, "Rewind error.\n");
         return false;
      }

      /*
       * Move file by file to the end of the tape
       */
      int file_num;
      for (file_num=file; !at_eot(); file_num++) {
         Dmsg0(200, "eod: doing fsf 1\n");
         if (!fsf(1)) {
            Dmsg0(100, "fsf error.\n");
            return false;
         }
         /*
          * Avoid infinite loop by ensuring we advance.
          */
         if (!at_eot() && file_num == (int)file) {
            Dmsg1(100, "fsf did not advance from file %d\n", file_num);
            set_ateof();
            os_file = get_os_tape_file();
            if (os_file >= 0) {
               Dmsg2(100, "Adjust file from %d to %d\n", file_num, os_file);
               file = os_file;
            }
            break;
         }
      }
#ifdef MTEOM
   }
#endif

   /*
    * Some drivers leave us after second EOF when doing MTEOM, so we must backup
    * so that appending overwrites the second EOF.
    */
   if (has_cap(CAP_BSFATEOM)) {
      /*
       * Backup over EOF
       */
      ok = bsf(1);

      /*
       * If BSF worked and fileno is known (not -1), set file
       */
      os_file = get_os_tape_file();
      if (os_file >= 0) {
         Dmsg2(100, "BSFATEOF adjust file from %d to %d\n", file , os_file);
         file = os_file;
      } else {
         file++;                       /* wing it -- not correct on all OSes */
      }
   } else {
      update_pos(dcr);                 /* update position */
   }
   Dmsg1(200, "EOD dev->file=%d\n", file);

   return ok;
}