initc.pp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. {$i textrec.inc}
  12. procedure cygwin_crt0(p : pointer);cdecl;external;
  13. {
  14. procedure do_global_dtors;cdecl;external;
  15. this does not work because
  16. do_global_dtors is a static C function PM
  17. it is inserted into the atexit chain,
  18. but how do we call this from FPC ???
  19. it seems to be done in exit function
  20. but that one ends with _exit that is system dependent !! }
  21. { avoid loading of cygwin _exit code
  22. so that exit returns
  23. apparently this is not enough anymore
  24. use longjmp instead PM }
  25. var
  26. entryjmpbuf,exitjmpbuf : jmp_buf;
  27. const
  28. exitjmpbufset : boolean = false;
  29. procedure _exit(status : longint);cdecl;
  30. begin
  31. if exitjmpbufset then
  32. longjmp(exitjmpbuf,1)
  33. else
  34. RunError(status);
  35. end;
  36. procedure C_exit(status : longint);popstack;external name '_exit';
  37. const
  38. STD_INPUT_HANDLE = $fffffff6;
  39. STD_OUTPUT_HANDLE = $fffffff5;
  40. STD_ERROR_HANDLE = $fffffff4;
  41. function GetStdHandle(nStdHandle:DWORD):longint;external 'kernel32' name 'GetStdHandle';
  42. procedure UpdateStdHandle(var t:TextRec;var stdHandle:longint;newHandle:longint);
  43. { Check if the stdHandle is the same as the one in the TextRec, then
  44. also update the TextRec }
  45. begin
  46. if t.Handle=stdHandle then
  47. t.Handle:=newHandle;
  48. stdHandle:=newHandle;
  49. end;
  50. function entry : longint;
  51. begin
  52. longjmp(entryjmpbuf,1);
  53. entry:=0;
  54. end;
  55. initialization
  56. if setjmp(entryjmpbuf)=0 then
  57. begin
  58. cygwin_crt0(@entry);
  59. end;
  60. { Reinitialize std handles that can be changed }
  61. UpdateStdHandle(TextRec(Input),StdInputHandle,GetStdHandle(STD_INPUT_HANDLE));
  62. UpdateStdHandle(TextRec(Output),StdOutputHandle,GetStdHandle(STD_OUTPUT_HANDLE));
  63. TextRec(StdOut).Handle:=StdOutputHandle;
  64. UpdateStdHandle(TextRec(Stderr),StdErrorHandle,GetStdHandle(STD_ERROR_HANDLE));
  65. finalization
  66. { should we pass exit code ?
  67. its apparently only used by _exit so it doesn't matter PM }
  68. if setjmp(exitjmpbuf)=0 then
  69. begin
  70. exitjmpbufset:=true;
  71. { C_exit(errorcode);
  72. this code does not work correctly anymore
  73. C function _exit is not called at end of exit function
  74. thus the code of exit does not return at all
  75. disabled PM }
  76. end;
  77. end.
  78. {
  79. $Log$
  80. Revision 1.5 2001-09-22 11:15:31 peter
  81. * merged v10 version for exit fixes
  82. Revision 1.1.2.4 2001/09/19 15:23:39 pierre
  83. * work for newer cygwin version
  84. Revision 1.1.2.3 2001/04/23 01:15:44 carl
  85. - removed unused and useless ifdef
  86. Revision 1.1.2.2 2001/04/02 13:30:14 pierre
  87. * Remove call to C exit procedure as it does not return anymore
  88. Revision 1.1.2.1 2000/12/30 17:49:48 peter
  89. * update std handles after initializing c
  90. }