ports/pharo/src/LibGDBs-Internal-Portlib-Pharo/GDBPortlibPharo.class.st
changeset 297 590dadb8382f
child 302 fdfe1a981363
equal deleted inserted replaced
296:5a4842a477a6 297:590dadb8382f
       
     1 Class {
       
     2 	#name : #GDBPortlibPharo,
       
     3 	#superclass : #GDBPortlib,
       
     4 	#category : #'LibGDBs-Internal-Portlib-Pharo'
       
     5 }
       
     6 
       
     7 { #category : #initialization }
       
     8 GDBPortlibPharo class >> initialize [
       
     9 	Current := self basicNew initialize.
       
    10 	
       
    11 	"
       
    12 	GDBPortlib current
       
    13 	"
       
    14 ]
       
    15 
       
    16 { #category : #'user interface' }
       
    17 GDBPortlibPharo >> newCLI: aGDBDebugger [
       
    18 	"Open GDB CLI for interactive debugging for given debugger.
       
    19 	 See `GDBDebugger >> #cli`."
       
    20 
       
    21 	| win |
       
    22 
       
    23 	(Smalltalk includesKey: #TerminalEmulator) ifFalse: [ 
       
    24 		self error: 'PTerm not available - you may want to load PTerm from https://github.com/janvrany/PTerm'
       
    25 		
       
    26 	].
       
    27 
       
    28 	win := aGDBDebugger propertyAt: #cli.
       
    29 	win isNil ifTrue: [
       
    30 		aGDBDebugger consoleOutput isNil ifTrue:[
       
    31 			self error: 'This GDBDebugger does not have CLI channel open - you may want to use GDBUnixProcess.'
       
    32 		].
       
    33 		win := TerminalEmulator openPTY: aGDBDebugger consoleOutput fileDescriptor.
       
    34 		win setLabel: 'GDB CLI'.
       
    35 		
       
    36 		"When window is closed, forget it (so subsequent call to 
       
    37 		`GDBDebugger >> #cli` opens a new CLI window):"
       
    38 		win announcer when: WindowClosed do: [ :windowClosed | 
       
    39 			windowClosed window == win ifTrue:[ 
       
    40 				aGDBDebugger propertyAt: #cli put: win.		
       
    41 			]
       
    42 		].
       
    43 		
       
    44 		"When GDB terminates, close the CLI."
       
    45 		aGDBDebugger announcer when: GDBExitEvent do:[ :exit |
       
    46 			| winFromDebugger |
       
    47 			
       
    48 			winFromDebugger := aGDBDebugger propertyAt: #cli.
       
    49 			winFromDebugger notNil ifTrue:[
       
    50 				winFromDebugger close.
       
    51 			].
       
    52 		].
       
    53 	
       
    54 		"Finally, store the reference to CLI window into debugger
       
    55 		 so we can fetch it later..."		
       
    56 		aGDBDebugger propertyAt: #cli put: win.		
       
    57 	] ifFalse: [ 
       
    58 		win activate.
       
    59 	].
       
    60 
       
    61 	"Created: / 05-08-2023 / 07:38:23 / Jan Vrany <jan.vrany@labware.com>"
       
    62 
       
    63 ]
       
    64 
       
    65 { #category : #streams }
       
    66 GDBPortlibPharo >> newPTY [
       
    67 	"Allocate a PTY and return it as an instance of GDBPTY"
       
    68 	
       
    69 	| fdM fdS name streamM streamS |
       
    70 	
       
    71 	fdM := LibC posix_openpt: (2"O_RDWR" | 0400"O_NOCTTY" | 04000"O_NONBLOCK").
       
    72 	fdM < 0 ifTrue:[ 
       
    73 		self error: 'posix_openpt() failed'.
       
    74 		^ nil		
       
    75 	].
       
    76 	LibC grantpt: fdM.
       
    77 	LibC unlockpt: fdM.
       
    78 	name := LibC ptsname: fdM.
       
    79 	name isNil ifTrue:[
       
    80 		LibC close: fdM.
       
    81 		self error: 'ptsname() failed'.
       
    82 		^ nil
       
    83 	].
       
    84 	fdS := LibC open: name _: 2"O_RDWR".
       
    85 	fdS < 0 ifTrue:[
       
    86 		LibC close: fdM.
       
    87 		self error: 'Failed to open ', name.
       
    88 		^ nil.
       
    89 	].
       
    90 
       
    91 	streamM := BinaryPipeStream basicNew descriptor: fdM writable: true.
       
    92 	streamS := BinaryPipeStream basicNew descriptor: fdS writable: true.
       
    93 	
       
    94 	^ GDBPTY name: name 
       
    95 			masterReadStream: (ZnCharacterReadStream  on: streamM encoding: 'ascii')
       
    96 			masterWriteStream: (ZnCharacterWriteStream  on: streamM encoding: 'ascii')
       
    97 			slaveReadStream: (ZnCharacterReadStream  on: streamS encoding: 'ascii')
       
    98 			slaveWriteStream: (ZnCharacterWriteStream  on: streamS encoding: 'ascii')
       
    99 
       
   100 ]
       
   101 
       
   102 { #category : #streams }
       
   103 GDBPortlibPharo >> newPipe [
       
   104 	"Create a pipe and return an array with pipe's read end and write end
       
   105 	 (in this order) as smalltalk streams."
       
   106 	
       
   107 	| pipe |
       
   108 	
       
   109 	pipe := BinaryPipeStream create.
       
   110 	^ { ZnCharacterReadStream  on: pipe first  encoding: 'ascii' .
       
   111 	    ZnCharacterWriteStream on: pipe second encoding: 'ascii' }
       
   112 
       
   113 
       
   114 ]
       
   115 
       
   116 { #category : #processes }
       
   117 GDBPortlibPharo >> spawn: argv stdin: stdin stdout: stdout stderr: stderr exit: action [ 
       
   118 	^ Smalltalk os spawn: argv stdin: stdin stdout: stdout stderr: stderr exit: action 
       
   119 
       
   120 	
       
   121 	
       
   122 	
       
   123 
       
   124 ]