* errno.cc (errmap): Handle ERROR_BUS_RESET.
* fhandler.h (fhandler_dev_raw::write_file): New method, created from former static function. (fhandler_dev_raw::read_file): Ditto. (reset_devbuf): New inline method. (class fhandler_dev_tape): Add TAPE_GET_DRIVE_PARAMETERS member `dp'. (fhandler_dev_tape::write_file): New method. (fhandler_dev_tape::read_file): Ditto. (fhandler_dev_tape::tape_get_feature): Convert to inline method. (fhandler_dev_tape::tape_error): New method, created from former static function. (fhandler_dev_tape::tape_get_blocksize): Remove declaration. * fhandler_raw.cc (fhandler_dev_raw::write_file): New method, created from former static function. (fhandler_dev_raw::read_file): Ditto. (fhandler_dev_raw::writebuf): Accomodate the fact that no devbuf exists under variable block size condition. (fhandler_dev_raw::raw_read): Ditto. Add local p pointer to simplify pointer arithmetic. (fhandler_dev_raw::raw_write): Always set devbufend to 0 when starting with writing. Accomodate the fact that no devbuf exists under variable block size condition. * fhandler_tape.cc: Various formatting changes. (TAPE_FUNC): New macro. Use throughout as tape function loop. (get_ll): Convert into macro. (IS_EOM): New macro. (IS_EOF): New macro. (fhandler_dev_tape::is_eom): Use IS_EOM macro. (fhandler_dev_tape::is_eof): Use IS_EOF macro. (fhandler_dev_tape::write_file): New method. (fhandler_dev_tape::read_file): New method. (fhandler_dev_tape::open): Get drive information block here once. (fhandler_dev_tape::lseek): Remove unneeded duplicate code. (fhandler_dev_tape::dup): Duplicate drive information block. (fhandler_dev_tape::ioctl): Remove drvbuf in variable block size mode. Return ERROR_INVALID_BLOCK_LENGTH instead of ERROR_MORE_DATA if buffer contains data which would get lost on buffer size changing. Use absolute tape positioning also if drive only supports logical block positioning. (fhandler_dev_tape::tape_error): New method, created from former static function. (fhandler_dev_tape::tape_get_pos): Allow logical block reporting. Workaround tape driver bug. (fhandler_dev_tape::_tape_set_pos): Reset device buffer and flags after successful repositioning. (fhandler_dev_tape::tape_set_pos): Allow logical block positioning. Workaround tape driver bug. (fhandler_dev_tape::tape_erase): Use dp instead of calling GetTapeParameters. (fhandler_dev_tape::tape_prepare): Ditto. (fhandler_dev_tape::tape_get_blocksize): Remove. (fhandler_dev_tape::tape_set_blocksize): Don't call tape_get_blocksize. Error handling already done in fhandler_dev_tape::ioctl. (fhandler_dev_tape::tape_status): Remove local `dp' variable. Accomodate logical tape reporting. Call tape_get_feature instead of accessing feature words directly. (fhandler_dev_tape::tape_compression): Use dp instead of calling GetTapeParameters. Fix resetting datcompression.
This commit is contained in:
		| @@ -24,52 +24,6 @@ | ||||
| #include "cygheap.h" | ||||
| #include "ntdll.h" | ||||
|  | ||||
| /* static wrapper functions to hide the effect of media changes and | ||||
|    bus resets which occurs after a new media is inserted. This is | ||||
|    also related to the used tape device.  */ | ||||
|  | ||||
| static BOOL write_file (HANDLE fh, const void *buf, DWORD to_write, | ||||
| 			DWORD *written, int *err) | ||||
| { | ||||
|   BOOL ret; | ||||
|  | ||||
|   *err = 0; | ||||
|   if (!(ret = WriteFile (fh, buf, to_write, written, 0))) | ||||
|     { | ||||
|       if ((*err = GetLastError ()) == ERROR_MEDIA_CHANGED | ||||
| 	  || *err == ERROR_BUS_RESET) | ||||
| 	{ | ||||
| 	  *err = 0; | ||||
| 	  if (!(ret = WriteFile (fh, buf, to_write, written, 0))) | ||||
| 	    *err = GetLastError (); | ||||
| 	} | ||||
|     } | ||||
|   syscall_printf ("%d (err %d) = WriteFile (%d, %d, write %d, written %d, 0)", | ||||
| 		  ret, *err, fh, buf, to_write, *written); | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| static BOOL read_file (HANDLE fh, void *buf, DWORD to_read, | ||||
| 		       DWORD *read, int *err) | ||||
| { | ||||
|   BOOL ret; | ||||
|  | ||||
|   *err = 0; | ||||
|   if (!(ret = ReadFile (fh, buf, to_read, read, 0))) | ||||
|     { | ||||
|       if ((*err = GetLastError ()) == ERROR_MEDIA_CHANGED | ||||
| 	  || *err == ERROR_BUS_RESET) | ||||
| 	{ | ||||
| 	  *err = 0; | ||||
| 	  if (!(ret = ReadFile (fh, buf, to_read, read, 0))) | ||||
| 	    *err = GetLastError (); | ||||
| 	} | ||||
|     } | ||||
|   syscall_printf ("%d (err %d) = ReadFile (%d, %d, to_read %d, read %d, 0)", | ||||
| 		  ret, *err, fh, buf, to_read, *read); | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| /**********************************************************************/ | ||||
| /* fhandler_dev_raw */ | ||||
|  | ||||
| @@ -86,13 +40,43 @@ fhandler_dev_raw::clear (void) | ||||
|   varblkop = 0; | ||||
| } | ||||
|  | ||||
| /* Wrapper functions to allow fhandler_dev_tape to detect and care for | ||||
|    media changes and bus resets. */ | ||||
|  | ||||
| BOOL | ||||
| fhandler_dev_raw::write_file (const void *buf, DWORD to_write, | ||||
| 			      DWORD *written, int *err) | ||||
| { | ||||
|   BOOL ret; | ||||
|  | ||||
|   *err = 0; | ||||
|   if (!(ret = WriteFile (get_handle (), buf, to_write, written, 0))) | ||||
|     *err = GetLastError (); | ||||
|   syscall_printf ("%d (err %d) = WriteFile (%d, %d, write %d, written %d, 0)", | ||||
| 		  ret, *err, get_handle (), buf, to_write, *written); | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| BOOL | ||||
| fhandler_dev_raw::read_file (void *buf, DWORD to_read, DWORD *read, int *err) | ||||
| { | ||||
|   BOOL ret; | ||||
|  | ||||
|   *err = 0; | ||||
|   if (!(ret = ReadFile (get_handle (), buf, to_read, read, 0))) | ||||
|     *err = GetLastError (); | ||||
|   syscall_printf ("%d (err %d) = ReadFile (%d, %d, to_read %d, read %d, 0)", | ||||
| 		  ret, *err, get_handle (), buf, to_read, *read); | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int | ||||
| fhandler_dev_raw::writebuf (void) | ||||
| { | ||||
|   DWORD written; | ||||
|   int ret = 0; | ||||
|  | ||||
|   if (is_writing && devbuf && devbufend) | ||||
|   if (!varblkop && is_writing && devbuf && devbufend) | ||||
|     { | ||||
|       DWORD to_write; | ||||
|       int ret = 0; | ||||
| @@ -100,11 +84,9 @@ fhandler_dev_raw::writebuf (void) | ||||
|       memset (devbuf + devbufend, 0, devbufsiz - devbufend); | ||||
|       if (get_major () != DEV_TAPE_MAJOR) | ||||
| 	to_write = ((devbufend - 1) / 512 + 1) * 512; | ||||
|       else if (varblkop) | ||||
| 	to_write = devbufend; | ||||
|       else | ||||
| 	to_write = devbufsiz; | ||||
|       if (!write_file (get_handle (), devbuf, to_write, &written, &ret) | ||||
|       if (!write_file (devbuf, to_write, &written, &ret) | ||||
| 	  && is_eom (ret)) | ||||
| 	eom_detected = 1; | ||||
|       if (written) | ||||
| @@ -216,6 +198,7 @@ fhandler_dev_raw::raw_read (void *ptr, size_t& ulen) | ||||
|   int ret; | ||||
|   size_t len = ulen; | ||||
|   char *tgt; | ||||
|   char *p = (char *) ptr; | ||||
|  | ||||
|   /* In mode O_RDWR the buffer has to be written to device first */ | ||||
|   ret = writebuf (); | ||||
| @@ -251,10 +234,10 @@ fhandler_dev_raw::raw_read (void *ptr, size_t& ulen) | ||||
| 	    { | ||||
| 	      bytes_to_read = min (len, devbufend - devbufstart); | ||||
| 	      debug_printf ("read %d bytes from buffer (rest %d)", | ||||
| 			    bytes_to_read, devbufstart - devbufend); | ||||
| 	      memcpy (ptr, devbuf + devbufstart, bytes_to_read); | ||||
| 			    bytes_to_read, devbufend - devbufend); | ||||
| 	      memcpy (p, devbuf + devbufstart, bytes_to_read); | ||||
| 	      len -= bytes_to_read; | ||||
| 	      ptr = (void *) ((char *) ptr + bytes_to_read); | ||||
| 	      p += bytes_to_read; | ||||
| 	      bytes_read += bytes_to_read; | ||||
| 	      devbufstart += bytes_to_read; | ||||
|  | ||||
| @@ -266,21 +249,15 @@ fhandler_dev_raw::raw_read (void *ptr, size_t& ulen) | ||||
| 	    } | ||||
| 	  if (len > 0) | ||||
| 	    { | ||||
| 	      if (!varblkop && len >= devbufsiz) | ||||
| 	      if (len >= devbufsiz) | ||||
| 		{ | ||||
| 		  if (get_major () == DEV_TAPE_MAJOR) | ||||
| 		    bytes_to_read = (len / devbufsiz) * devbufsiz; | ||||
| 		  else | ||||
| 		    bytes_to_read = (len / 512) * 512; | ||||
| 		  tgt = (char *) ptr; | ||||
| 		  tgt = p; | ||||
| 		  debug_printf ("read %d bytes direct from file",bytes_to_read); | ||||
| 		} | ||||
| 	      else if (varblkop) | ||||
| 		{ | ||||
| 		  tgt = (char *) ptr; | ||||
| 		  bytes_to_read = len; | ||||
| 		  debug_printf ("read variable bytes direct from file"); | ||||
| 		} | ||||
| 	      else | ||||
| 		{ | ||||
| 		  tgt = devbuf; | ||||
| @@ -288,16 +265,11 @@ fhandler_dev_raw::raw_read (void *ptr, size_t& ulen) | ||||
| 		  debug_printf ("read %d bytes from file into buffer", | ||||
| 				bytes_to_read); | ||||
| 		} | ||||
| 	      if (!read_file (get_handle (), tgt, bytes_to_read, &read2, &ret)) | ||||
| 	      if (!read_file (tgt, bytes_to_read, &read2, &ret)) | ||||
| 		{ | ||||
| 		  if (!is_eof (ret) && !is_eom (ret)) | ||||
| 		    { | ||||
| 		      if (varblkop && ret == ERROR_MORE_DATA) | ||||
| 		        /* *ulen < blocksize.  Linux returns ENOMEM here | ||||
| 			   when reading with variable blocksize . */ | ||||
| 		        set_errno (ENOMEM); | ||||
| 		      else | ||||
| 			__seterrno (); | ||||
| 		      __seterrno (); | ||||
| 		      goto err; | ||||
| 		    } | ||||
|  | ||||
| @@ -325,26 +297,24 @@ fhandler_dev_raw::raw_read (void *ptr, size_t& ulen) | ||||
| 		  devbufstart = 0; | ||||
| 		  devbufend = read2; | ||||
| 		} | ||||
| 	      else if (varblkop) | ||||
| 		{ | ||||
| 		  /* When reading tapes with variable block size, we | ||||
| 		     leave right after reading one block. */ | ||||
| 		  bytes_read = read2; | ||||
| 		  break; | ||||
| 		} | ||||
| 	      else | ||||
| 		{ | ||||
| 		  len -= read2; | ||||
| 		  ptr = (void *) ((char *) ptr + read2); | ||||
| 		  p += read2; | ||||
| 		  bytes_read += read2; | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|   else if (!read_file (get_handle (), ptr, len, &bytes_read, &ret)) | ||||
|   else if (!read_file (p, len, &bytes_read, &ret)) | ||||
|     { | ||||
|       if (!is_eof (ret) && !is_eom (ret)) | ||||
| 	{ | ||||
| 	  if (varblkop && ret == ERROR_MORE_DATA) | ||||
| 	    /* *ulen < blocksize.  Linux returns ENOMEM here | ||||
| 	       when reading with variable blocksize . */ | ||||
| 	    set_errno (ENOMEM); | ||||
| 	  else | ||||
| 	  __seterrno (); | ||||
| 	  goto err; | ||||
| 	} | ||||
| @@ -389,18 +359,14 @@ fhandler_dev_raw::raw_write (const void *ptr, size_t len) | ||||
|     } | ||||
|  | ||||
|   if (!is_writing) | ||||
|     { | ||||
|       devbufend = devbufstart; | ||||
|       devbufstart = 0; | ||||
|     } | ||||
|     devbufstart = devbufend = 0; | ||||
|   is_writing = 1; | ||||
|  | ||||
|   if (devbuf) | ||||
|     { | ||||
|       while (len > 0) | ||||
| 	{ | ||||
| 	  if (!varblkop && | ||||
| 	      (len < devbufsiz || devbufend > 0) && devbufend < devbufsiz) | ||||
| 	  if ((len < devbufsiz || devbufend > 0) && devbufend < devbufsiz) | ||||
| 	    { | ||||
| 	      bytes_to_write = min (len, devbufsiz - devbufend); | ||||
| 	      memcpy (devbuf + devbufend, p, bytes_to_write); | ||||
| @@ -411,12 +377,7 @@ fhandler_dev_raw::raw_write (const void *ptr, size_t len) | ||||
| 	    } | ||||
| 	  else | ||||
| 	    { | ||||
| 	      if (varblkop) | ||||
| 		{ | ||||
| 		  bytes_to_write = len; | ||||
| 		  tgt = p; | ||||
| 		} | ||||
| 	      else if (devbufend == devbufsiz) | ||||
| 	      if (devbufend == devbufsiz) | ||||
| 		{ | ||||
| 		  bytes_to_write = devbufsiz; | ||||
| 		  tgt = devbuf; | ||||
| @@ -428,7 +389,7 @@ fhandler_dev_raw::raw_write (const void *ptr, size_t len) | ||||
| 		} | ||||
|  | ||||
| 	      ret = 0; | ||||
| 	      write_file (get_handle (), tgt, bytes_to_write, &written, &ret); | ||||
| 	      write_file (tgt, bytes_to_write, &written, &ret); | ||||
| 	      if (written) | ||||
| 		has_written = 1; | ||||
|  | ||||
| @@ -471,7 +432,7 @@ fhandler_dev_raw::raw_write (const void *ptr, size_t len) | ||||
|     } | ||||
|   else if (len > 0) | ||||
|     { | ||||
|       if (!write_file (get_handle (), ptr, len, &bytes_written, &ret)) | ||||
|       if (!write_file (p, len, &bytes_written, &ret)) | ||||
| 	{ | ||||
| 	  if (bytes_written) | ||||
| 	    has_written = 1; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user