mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 18:07:37 +00:00 
			
		
		
		
	 eb477f05cf
			
		
	
	
		eb477f05cf
		
	
	
	
	
		
			
			implement its locking scheme, this module implements a crude link() by way of copying the source to the destination provided the destination doesn't already exist.
		
			
				
	
	
		
			79 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			79 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # _emx_link.py
 | |
| 
 | |
| # Written by Andrew I MacIntyre, December 2002.
 | |
| 
 | |
| """_emx_link.py is a simplistic emulation of the Unix link(2) library routine 
 | |
| for creating so-called hard links.  It is intended to be imported into
 | |
| the os module in place of the unimplemented (on OS/2) Posix link()
 | |
| function (os.link()).
 | |
| 
 | |
| We do this on OS/2 by implementing a file copy, with link(2) semantics:-
 | |
|   - the target cannot already exist;
 | |
|   - we hope that the actual file open (if successful) is actually
 | |
|     atomic...
 | |
| 
 | |
| Limitations of this approach/implementation include:-
 | |
|   - no support for correct link counts (EMX stat(target).st_nlink
 | |
|     is always 1);
 | |
|   - thread safety undefined;
 | |
|   - default file permissions (r+w) used, can't be over-ridden;
 | |
|   - implemented in Python so comparatively slow, especially for large
 | |
|     source files;
 | |
|   - need sufficient free disk space to store the copy.
 | |
| 
 | |
| Behaviour:-
 | |
|   - any exception should propagate to the caller;
 | |
|   - want target to be an exact copy of the source, so use binary mode;
 | |
|   - returns None, same as os.link() which is implemented in posixmodule.c;
 | |
|   - target removed in the event of a failure where possible;
 | |
|   - given the motivation to write this emulation came from trying to
 | |
|     support a Unix resource lock implementation, where minimal overhead
 | |
|     during creation of the target is desirable and the files are small,
 | |
|     we read a source block before attempting to create the target so that
 | |
|     we're ready to immediately write some data into it.
 | |
| """
 | |
| 
 | |
| import os
 | |
| import errno
 | |
| 
 | |
| __all__ = ['link']
 | |
| 
 | |
| def link(source, target):
 | |
|     """link(source, target) -> None
 | |
| 
 | |
|     Attempt to hard link the source file to the target file name.
 | |
|     On OS/2, this creates a complete copy of the source file.
 | |
|     """
 | |
| 
 | |
|     s = os.open(source, os.O_RDONLY | os.O_BINARY)
 | |
|     if os.isatty(s):
 | |
|         raise OSError, (errno.EXDEV, 'Cross-device link')
 | |
|     data = os.read(s, 1024)
 | |
| 
 | |
|     try:
 | |
|         t = os.open(target, os.O_WRONLY | os.O_BINARY | os.O_CREAT | os.O_EXCL)
 | |
|     except OSError:
 | |
|         os.close(s)
 | |
|         raise
 | |
| 
 | |
|     try:
 | |
|         while data:
 | |
|             os.write(t, data)
 | |
|             data = os.read(s, 1024)
 | |
|     except OSError:
 | |
|         os.close(s)
 | |
|         os.close(t)
 | |
|         os.unlink(target)
 | |
|         raise
 | |
| 
 | |
|     os.close(s)
 | |
|     os.close(t)
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     import sys
 | |
|     try:
 | |
|         link(sys.argv[1], sys.argv[2])
 | |
|     except IndexError:
 | |
|         print 'Usage: emx_link <source> <target>'
 | |
|     except OSError:
 | |
|         print 'emx_link: %s' % str(sys.exc_info()[1])
 |