ports/pharo/src/LibGDBs-Internal-Portlib-Pharo/GDBPortlibPharo.class.st
changeset 297 590dadb8382f
child 302 fdfe1a981363
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/pharo/src/LibGDBs-Internal-Portlib-Pharo/GDBPortlibPharo.class.st	Mon Aug 14 16:35:57 2023 +0100
@@ -0,0 +1,124 @@
+Class {
+	#name : #GDBPortlibPharo,
+	#superclass : #GDBPortlib,
+	#category : #'LibGDBs-Internal-Portlib-Pharo'
+}
+
+{ #category : #initialization }
+GDBPortlibPharo class >> initialize [
+	Current := self basicNew initialize.
+	
+	"
+	GDBPortlib current
+	"
+]
+
+{ #category : #'user interface' }
+GDBPortlibPharo >> newCLI: aGDBDebugger [
+	"Open GDB CLI for interactive debugging for given debugger.
+	 See `GDBDebugger >> #cli`."
+
+	| win |
+
+	(Smalltalk includesKey: #TerminalEmulator) ifFalse: [ 
+		self error: 'PTerm not available - you may want to load PTerm from https://github.com/janvrany/PTerm'
+		
+	].
+
+	win := aGDBDebugger propertyAt: #cli.
+	win isNil ifTrue: [
+		aGDBDebugger consoleOutput isNil ifTrue:[
+			self error: 'This GDBDebugger does not have CLI channel open - you may want to use GDBUnixProcess.'
+		].
+		win := TerminalEmulator openPTY: aGDBDebugger consoleOutput fileDescriptor.
+		win setLabel: 'GDB CLI'.
+		
+		"When window is closed, forget it (so subsequent call to 
+		`GDBDebugger >> #cli` opens a new CLI window):"
+		win announcer when: WindowClosed do: [ :windowClosed | 
+			windowClosed window == win ifTrue:[ 
+				aGDBDebugger propertyAt: #cli put: win.		
+			]
+		].
+		
+		"When GDB terminates, close the CLI."
+		aGDBDebugger announcer when: GDBExitEvent do:[ :exit |
+			| winFromDebugger |
+			
+			winFromDebugger := aGDBDebugger propertyAt: #cli.
+			winFromDebugger notNil ifTrue:[
+				winFromDebugger close.
+			].
+		].
+	
+		"Finally, store the reference to CLI window into debugger
+		 so we can fetch it later..."		
+		aGDBDebugger propertyAt: #cli put: win.		
+	] ifFalse: [ 
+		win activate.
+	].
+
+	"Created: / 05-08-2023 / 07:38:23 / Jan Vrany <jan.vrany@labware.com>"
+
+]
+
+{ #category : #streams }
+GDBPortlibPharo >> newPTY [
+	"Allocate a PTY and return it as an instance of GDBPTY"
+	
+	| fdM fdS name streamM streamS |
+	
+	fdM := LibC posix_openpt: (2"O_RDWR" | 0400"O_NOCTTY" | 04000"O_NONBLOCK").
+	fdM < 0 ifTrue:[ 
+		self error: 'posix_openpt() failed'.
+		^ nil		
+	].
+	LibC grantpt: fdM.
+	LibC unlockpt: fdM.
+	name := LibC ptsname: fdM.
+	name isNil ifTrue:[
+		LibC close: fdM.
+		self error: 'ptsname() failed'.
+		^ nil
+	].
+	fdS := LibC open: name _: 2"O_RDWR".
+	fdS < 0 ifTrue:[
+		LibC close: fdM.
+		self error: 'Failed to open ', name.
+		^ nil.
+	].
+
+	streamM := BinaryPipeStream basicNew descriptor: fdM writable: true.
+	streamS := BinaryPipeStream basicNew descriptor: fdS writable: true.
+	
+	^ GDBPTY name: name 
+			masterReadStream: (ZnCharacterReadStream  on: streamM encoding: 'ascii')
+			masterWriteStream: (ZnCharacterWriteStream  on: streamM encoding: 'ascii')
+			slaveReadStream: (ZnCharacterReadStream  on: streamS encoding: 'ascii')
+			slaveWriteStream: (ZnCharacterWriteStream  on: streamS encoding: 'ascii')
+
+]
+
+{ #category : #streams }
+GDBPortlibPharo >> newPipe [
+	"Create a pipe and return an array with pipe's read end and write end
+	 (in this order) as smalltalk streams."
+	
+	| pipe |
+	
+	pipe := BinaryPipeStream create.
+	^ { ZnCharacterReadStream  on: pipe first  encoding: 'ascii' .
+	    ZnCharacterWriteStream on: pipe second encoding: 'ascii' }
+
+
+]
+
+{ #category : #processes }
+GDBPortlibPharo >> spawn: argv stdin: stdin stdout: stdout stderr: stderr exit: action [ 
+	^ Smalltalk os spawn: argv stdin: stdin stdout: stdout stderr: stderr exit: action 
+
+	
+	
+	
+
+]