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

new topic     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

3. Re: 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?
>[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. smile
________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com

new topic     » goto parent     » topic index » view message » categorize

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
----------------------------------------------------------------

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu