1

This code for getting a temporary filename is returning an empty string. I'm trying to work out how it ever worked, since all doco I can find on mkstemp says it needs a format of something like /tmp/prefixXXXXXX, and here that's not being used.

function get_Temp_Name
    return String
is

  Temp_File_Name : String (1 .. 25) := (others => ' ');

  C_Buffer      : aliased  Interfaces.C.Char_Array          := Interfaces.C.To_C(Temp_File_Name, Append_Nul => True);
  C_Ptr         : constant Interfaces.C.Strings.Chars_Ptr   := Interfaces.C.Strings.To_Chars_Ptr(C_Buffer'Unchecked_Access);
  Result_Ptr    : Interfaces.C.Strings.Chars_Ptr;

begin
    Result_Ptr := C_Mkstemp(C_Ptr);             
    return Ada.Strings.Fixed.Trim(Interfaces.C.To_Ada(C_Buffer, True), Ada.Strings.Both);

    EXCEPTION
        when Error : others =>
            -- redacted
            raise;

end Get_Temp_Name;

Is this an old form of the call?

Would directory permissions effect the execution of C_Mkstemp() ?

EDIT: definition / import of C_Mkstemp:

  function C_Mkstemp( template : Interfaces.C.Strings.Chars_Ptr )
      return Interfaces.C.Strings.Chars_Ptr;
      pragma Import(C, C_Mkstemp, "mkstemp");
Kingsley
  • 14,398
  • 5
  • 31
  • 53
  • 4
    If you want a temp file in Ada, just use Create with an empty file name. – Zerte Nov 24 '20 at 07:08
  • 4
    Not answering your actual question, but you can create temporary files by leaving the Name parameter blank in Ada.Text_IO.Create (or the other *_IO packages) – egilhh Nov 24 '20 at 07:09
  • Please show the declaration of `C_Mkstemp`. The signature seems off since it is [specified to return an int](https://pubs.opengroup.org/onlinepubs/9699919799/) but yours returns a `Chars_Ptr`. It's possible that there's a typo which accidentally imports `mkdtemp` instead which has a matching signature. In any case, not passing `X`s in the input seems to be undefined behavior, which could explain why it did something sensible in the past but doesn't now. – flyx Nov 24 '20 at 08:53
  • 3
    `mkstemp()` returns a file descriptor opened for read and write. `mktemp()` returns a `char *`, which is what your code assumes. – Simon Wright Nov 24 '20 at 16:48
  • @Zerte - But is that temp filename guaranteed to be unique & thread-safe? I did read about this, but all references lacked any specific detail. – Kingsley Nov 24 '20 at 21:02
  • 1
    @Kingsley: For reference, the standard says, "A null string for Name specifies an external file that is not accessible after the completion of the main program (a temporary file)." Would that meet your requirement? – trashgod Nov 25 '20 at 00:49
  • I ended up re-writing the function to properly use the resources allocated by `mkstemp()`. Thanks for all your help. Obviously the above code is riddled with bugs (including leaking file handles). – Kingsley Nov 25 '20 at 01:49
  • 1
    @Kingsley: if you are using GNAT, the standard temp files use mkstemp on (I just copy-paste the target names): linux, FreeBSD, NetBSD, OpenBSD, GLIBC, ANDROID, DragonFly, QNX. If an Ada compiler provides temp file names that are not unique and thread-safe, it is certainly a bug. – Zerte Nov 25 '20 at 16:47
  • 1
    See `lib/gcc/…/adainclude/adaint.c` for more on implementation GNAT details. – trashgod Nov 25 '20 at 18:56

0 Answers0