1. open() long file names
Has there been any progress on the bug in open(), where you can't create
long filenames if the file didn't previously exist? Any good workarounds? I
guess this falls into the category of 'unified file tools' that people have
been talking about.
I guess I could shell out and rename the file, if worse came to worse...
Thanks!
-- David Cuny
2. Re: open() long file names
On Wed, 26 Apr 2000 13:01:01 -0700, Cuny, David@DSS wrote:
>Has there been any progress on the bug in open(), where you can't create
>long filenames if the file didn't previously exist? Any good workarounds? I
>guess this falls into the category of 'unified file tools' that people have
>been talking about.
>
>I guess I could shell out and rename the file, if worse came to worse...
Are you referring to long file names for DOS (ex.exe)? Since you can't
really count on long file name support for all versions of DOS, wouldn't
your program be considered a Windows program (exw.exe)? There are no
problems creating long file names using open() with exw.exe...
-- Brian
3. Re: open() long file names
- Posted by Gabriel Boehme <gabrielboehme at HOTMAIL.COM>
Apr 26, 2000
-
Last edited Apr 27, 2000
>Has there been any progress on the bug in open(), where you can't create
>long filenames if the file didn't previously exist? Any good workarounds?
>[snip]
Mike Nelson and I came up with one earlier this month. You can find it on
the recent contributions page.
HTH,
Gabriel
______________________________________________________
PLEASE IGNORE ANY ADS YOU MAY SEE BELOW THIS LINE.
________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com
4. Re: open() long file names
> From: "Cuny, David at DSS" <David.Cuny at DSS.CA.GOV>
> Subject: open() long file names
>
> Has there been any progress on the bug in open(), where you can't create
> long filenames if the file didn't previously exist? Any good workarounds? I
> guess this falls into the category of 'unified file tools' that people have
> been talking about.
>
> I guess I could shell out and rename the file, if worse came to worse...
>
> Thanks!
Here's my solution from January of last year:
----------------------------------------------------------------
--LFNopen.e
--
--By: FaIkon1313 at aol.com
--Date: January 31, 1999 (finished at 03:00 a.m., of course :)
--Platform: DOS32
--
----------------------------------------------------------------
--
-- While poking about with some generic test code, I was
--getting errors when trying to save my output file...Every
--time. Upon closer inspection, the cause became obvious.
--One of the directories in my output path was a 'long
--filename'. I figured somebody'd surely solved that problem
--by now, but a search of the mailing list, archive, and
--recent-user-contributions came out with nothing.
-- So here it is. This code redefines open() so that it
--will work with long filenames on versions of DOS >= 7.0.
--When run on earlier versions of DOS, the original version
--of open() will be called, which truncates any long
--filenames when creating new files. (Which causes an
--"unable to create file" error if one of the parent directories
--of the file is an LFN. But that shouldn't be a problem
--on versions of DOS prior to 7.0.)
--
----------------------------------------------------------------
without warning
include machine.e
global constant READ = 0, WRITE = 1, READ_WRITE=2
global constant LFN_OPEN = 1, LFN_TRUNC = 2, LFN_CREATE = 16
global function DosVer()
sequence reg_list
reg_list = repeat(0,10)
reg_list[REG_AX] = #3000
reg_list = dos_interrupt( #21, reg_list )
return( remainder( reg_list[REG_AX], 256 ) + floor( reg_list[REG_AX]/256 )
/ 100 )
end function
global function DosClose( integer Handle )
-- close a file open with DosOpen()
-- return 1 if success else return 0
sequence regs
regs = repeat( 0,10 )
regs[REG_AX] = #3E00
regs[REG_BX] = Handle
regs = dos_interrupt( #21,regs )
if and_bits( regs[REG_FLAGS], 1 ) then
return( 0 )
end if
return( 1 )
end function -- DosClose()
global function DosOpenLong( sequence FileName, integer Mode,
integer Attributes, integer Action, integer DN )
-- use DOS function #716C to open/create a file
-- return file handle or -1 if error
-- mode is 0 = read only
-- 1 = write only
-- 2 = read/write
--Bitfields for Windows95 long-name open action:
--Bit(s) Description (Table 01781)
--0 open file (fail if file does not exist)
--1 truncate file if it already exists (fail if file does not exist)
--4 create new file if file does not already exist (fail if exists)
--Note: The only valid combinations of multiple flags are bits 4&0 and 4&1
atom NameBuffer
sequence regs
regs = repeat( 0,10 )
if DosVer() < 7 then
return( -1 )
end if
NameBuffer = allocate_low( length( FileName ) +1 )
if not NameBuffer then
return( -1 )
end if
poke( NameBuffer, FileName & 0 )
regs[REG_AX] = #716C
regs[REG_BX] = Mode
regs[REG_CX] = Attributes
regs[REG_DX] = Action
regs[REG_DS] = floor( NameBuffer / 16 ) --address segment
regs[REG_SI] = remainder( NameBuffer, 16 ) -- offset
regs[REG_DI] = DN --disambiguation number
regs = dos_interrupt( #21, regs )
free_low( NameBuffer )
if and_bits( regs[REG_FLAGS], 1 ) then
return( -1 ) -- fail to open
end if
return regs[REG_AX] -- return file handle
end function
global function LFNopen( sequence filename, sequence mode )
integer tfn
-- puts( 1, "\nLFNO called." )
if ( not find( mode, {"r","rb","w","wb","u","ub","a","ab"} ) ) or
( DosVer() < 7 )then
return( -1 )
end if
if ( mode[1] = 'w' ) or ( mode[1] = 'a' ) then
--use LFN_OPEN as well as LFN_CREATE so that we
--won't get an error if it already exists
tfn = DosOpenLong( filename, WRITE, 0, or_bits( LFN_OPEN, LFN_CREATE ),
1 )
if ( tfn < 0 ) then
--unable to create file
return( -1 )
end if
tfn = DosClose( tfn )
end if
--now it exists, we can try to open it
return( open( filename, mode ) )
end function
function original_open( sequence filename, sequence mode )
-- puts( 1, "\nOO called." )
return( open( filename, mode ) )
end function
constant ORIGINAL_OPEN = routine_id( "original_open" )
global function open( sequence filename, sequence mode )
if DosVer() < 7 then
--no long filename support, use original
return call_func( ORIGINAL_OPEN, { filename, mode } )
else
return( LFNopen( filename, mode ) )
end if
end function
----------------------------------------------------------------
--end LFNopen.e
----------------------------------------------------------------
5. Re: open() long file names
Falkon 1313 wrote:
> Here's my solution from January of last year:
Thanks; I now have long file name support in a version of my editor (used
for Java coding). Another routine missing lfn support was current_dir; I
wrote it with the help of Francis Bussiere's Dir95 routine. It would be nice
if these could be added to Euphoria.
Thanks!
-- David Cuny
global function split_nodes( sequence s )
-- splits a sequence delimited by "\" into a sequence of nodes
sequence path, node
path = {}
node = ""
-- split path on "\"
for i = 1 to length( s ) do
if s[i] = '\\' then
path = append( path, node )
node = ""
else
node = node & s[i]
end if
end for
-- remainder?
if length( node ) > 0 then
path = append( path, node )
end if
return path
end function
global function CurrentDir95()
sequence nodes, path, list
-- get a list of nodes making up the current path
nodes = split_nodes(current_dir())
-- start with the first node
path = nodes[1]
-- replace each subnode with the long file name
for i = 1 to length( nodes )-1 do
-- get a list of all files under the directory
list = Dir95(path)
-- look through the list
for j = 1 to length( list ) do
-- directory?
if find( 'd', list[j][D_ATTRIBUTES] ) then
-- same name as next node?
if equal(list[j][D_NAME], nodes[i+1]) then
-- replace with long name
nodes[i+1] = list[j][D_LONGNAME]
-- leave loop
exit
end if
end if
end for
-- move down one directory
path = path & "\\" & nodes[i+1]
end for
return path
end function