Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2007-12

getlastoserror giving wrong value?

5 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Marc Santhoff

Hi,

when I try to use getlastoserror something "funny" happens.

We're dealing with:

$ ll /home/marc/program/Test_C/unreadable/
ls: : Permission denied

The source:

  tmp := aFile^ + '/' + dirrec.Name;
  writeln('file: '+ tmp );
  n := fpaccess(tmp , R_OK);
  writeln(n);
  n := getlastoserror;
  writeln(n);

The output:

file: /home/marc/program/Test_C/unreadable/
-1
-65523

If I do this:

program stat;
uses baseunix,errors,sysutils;
var
  st: baseunix.stat;
  res: integer;
begin
  //res := fpstat('/home/marc/program/Test_C/unreadable/', st);
  res := fpaccess('/home/marc/program/Test_C/unreadable/', R_OK);
  writeln(res);
  res := getlastoserror;
  writeln(res);
end.

The result is correct:

$ ./stat
-1
13

and shows ESysEACCES as error number.

How can that happen?

Marc

Reply by email

Jonas Maebe
to Marc Santhoff
Marc Santhoff wrote 21 lines
when I try to use getlastoserror something "funny" happens. We're dealing with: $ ll /home/marc/program/Test_C/unreadable/ ls: : Permission denied The source: tmp := aFile^ + '/' + dirrec.Name; writeln('file: '+ tmp ); n := fpaccess(tmp , R_OK); writeln(n); n := getlastoserror; writeln(n); The output: file: /home/marc/program/Test_C/unreadable/ -1 -65523

Regardless of what the real problem is, the above code is wrong: writeln (obviously) also makes use of OS functions to write things out to the screen, and if one of those (temporarily) fails for some reason (e.g., ESysEINTR) then your call to getlastoserror will return the result of that failure. Just like with ioresult, you always have to store the result of getlastoserror immediately in a local variable after the operation you want to check.

Jonas

Reply by email

Marc Santhoff
to Jonas Maebe
Jonas Maebe wrote 31 lines
On 21 Dec 2007, at 06:37, Marc Santhoff wrote: > when I try to use getlastoserror something "funny" happens. > > We're dealing with: > > $ ll /home/marc/program/Test_C/unreadable/ > ls: : Permission denied > > The source: > > tmp := aFile^ + '/' + dirrec.Name; > writeln('file: '+ tmp ); > n := fpaccess(tmp , R_OK); > writeln(n); > n := getlastoserror; > writeln(n); > > The output: > > file: /home/marc/program/Test_C/unreadable/ > -1 > -65523 Regardless of what the real problem is, the above code is wrong: writeln (obviously) also makes use of OS functions to write things out to the screen, and if one of those (temporarily) fails for some reason (e.g., ESysEINTR) then your call to getlastoserror will return the result of that failure. Just like with ioresult, you always have to store the result of getlastoserror immediately in a local variable after the operation you want to check.

I know and the writeln was inserted later to be sure the system call fails (=-1). If the line is commented out the results are the same in both cases.

Marc

Reply by email

Marc Santhoff
to Marc Santhoff: when I try to use getlastoserror something "funny" happens. We're dealing with: $ ll…

Hi,

I'm really stuck here, meanwhile I made the testing program look exactly the same in structure like the code sequence in question, forced both to use AnsiStrings and stared at the assembler code - to no avail, because I do not understand enough x86 asm. ;)

The string variable is holding the same directory name and path in both cases, of course. For the code look into my previous mail, please.

Can someone comment on these snippets:

<original>
# [457] fpaccess((*ExpandFileName*) tmp , R_OK);
movl $4,%ebx
movl -192(%ebp),%eax
call FPC_ANSISTR_INCR_REF
leal -520(%ebp),%eax
call FPC_ANSISTR_DECR_REF
movl -192(%ebp),%eax
movl %eax,-520(%ebp)
movl %ebx,%edx
movl -520(%ebp),%eax
testl %eax,%eax
jne .L583
movl $FPC_EMPTYCHAR,%eax
.L583:
call FPC_SYSC_ACCESS
# [458] n := getlastoserror;
call SYSUTILS_GETLASTOSERROR$$LONGINT
movl %eax,-120(%ebp)
# [459] writeln(n);
call fpc_get_output
</original>

<test>
# [11] res := fpaccess(tmp, R_OK);
movl $4,%ebx
movl U_P$STAT_TMP,%eax
call FPC_ANSISTR_INCR_REF
leal -44(%ebp),%eax
call FPC_ANSISTR_DECR_REF
movl U_P$STAT_TMP,%eax
movl %eax,-44(%ebp)
movl %ebx,%edx
movl -44(%ebp),%eax
testl %eax,%eax
jne .L24
movl $FPC_EMPTYCHAR,%eax
.L24:
call FPC_SYSC_ACCESS
movw %ax,U_P$STAT_RES
# [13] res := getlastoserror;
call SYSUTILS_GETLASTOSERROR$$LONGINT
movw %ax,U_P$STAT_RES
# [14] writeln(res);
</test>

For me the look structurally identical, but some differences like the $XXX-variables(?) don't.

Marc

Reply by email

Marc Santhoff
to Marc Santhoff: when I try to use getlastoserror something "funny" happens. We're dealing with: $ ll…
Marc Santhoff wrote
How can that happen?

Pretty simple, all occurences of getlastoserror() and the error variable seem to declare the number as longint. In my program I did the same. The value given back is only a word - or looks as if it is.

When looking at the hex form of the error number in question things are getting clear:

longint -65523 = hex FFFF000D

So somewhere the upper word is lost or set to FFFF, when omitting this part by using word as variable type anything is okay.

I'll try to find out if this is something special coming from the OS or if it's a compiler issue.

[FreeBSD 4.11, fpc 2.0.4]

Marc

Reply by email