2
0

initc.pp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. {
  2. $Id$
  3. }
  4. unit initc;
  5. interface
  6. {$LINKLIB cygwin}
  7. {$linklib kernel32}
  8. { this unit is just ment to run
  9. startup code to get C code to work correctly PM }
  10. implementation
  11. uses
  12. windows;
  13. {$i textrec.inc}
  14. procedure cygwin_crt0(p : pointer);cdecl;external;
  15. {
  16. procedure do_global_dtors;cdecl;external;
  17. this does not work because
  18. do_global_dtors is a static C function PM
  19. it is inserted into the atexit chain,
  20. but how do we call this from FPC ???
  21. it seems to be done in exit function
  22. but that one ends with _exit that is system dependent !! }
  23. { avoid loading of cygwin _exit code
  24. so that exit returns
  25. apparently this is not enough anymore
  26. use longjmp instead PM }
  27. var
  28. entryjmpbuf,exitjmpbuf : jmp_buf;
  29. const
  30. exitjmpbufset : boolean = false;
  31. procedure _exit(status : longint);cdecl;
  32. begin
  33. if exitjmpbufset then
  34. longjmp(exitjmpbuf,1)
  35. else
  36. RunError(status);
  37. end;
  38. procedure C_exit(status : longint);cdecl;external name '_exit';
  39. const
  40. STD_INPUT_HANDLE = $fffffff6;
  41. STD_OUTPUT_HANDLE = $fffffff5;
  42. STD_ERROR_HANDLE = $fffffff4;
  43. procedure UpdateStdHandle(var t:TextRec;var stdHandle:Thandle;newHandle:Thandle);
  44. { Check if the stdHandle is the same as the one in the TextRec, then
  45. also update the TextRec }
  46. begin
  47. if t.Handle=stdHandle then
  48. t.Handle:=newHandle;
  49. stdHandle:=newHandle;
  50. end;
  51. function entry : longint;
  52. begin
  53. longjmp(entryjmpbuf,1);
  54. entry:=0;
  55. end;
  56. var
  57. ConsoleMode: DWORD;
  58. ConsoleModeValid : boolean;
  59. initialization
  60. ConsoleModeValid:=GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), @ConsoleMode);
  61. if setjmp(entryjmpbuf)=0 then
  62. begin
  63. cygwin_crt0(@entry);
  64. end;
  65. if ConsoleModeValid then
  66. SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ConsoleMode);
  67. { Reinitialize std handles that can be changed }
  68. UpdateStdHandle(TextRec(Input),StdInputHandle,GetStdHandle(STD_INPUT_HANDLE));
  69. UpdateStdHandle(TextRec(Output),StdOutputHandle,GetStdHandle(STD_OUTPUT_HANDLE));
  70. TextRec(StdOut).Handle:=StdOutputHandle;
  71. UpdateStdHandle(TextRec(Stderr),StdErrorHandle,GetStdHandle(STD_ERROR_HANDLE));
  72. finalization
  73. { should we pass exit code ?
  74. its apparently only used by _exit so it doesn't matter PM }
  75. if setjmp(exitjmpbuf)=0 then
  76. begin
  77. exitjmpbufset:=true;
  78. { C_exit(errorcode);
  79. this code does not work correctly anymore
  80. C function _exit is not called at end of exit function
  81. thus the code of exit does not return at all
  82. disabled PM }
  83. end;
  84. end.
  85. {
  86. $Log$
  87. Revision 1.9 2003-11-03 09:42:28 marco
  88. * Peter's Cardinal<->Longint fixes patch
  89. Revision 1.8 2003/09/08 18:25:45 peter
  90. * popstack to cdecl
  91. Revision 1.7 2002/09/07 16:01:28 peter
  92. * old logs removed and tabs fixed
  93. }