CreateProcess - Writing to Pipe

BlitzMax Forums/BlitzMax Programming/CreateProcess - Writing to Pipe

Addi(Posted 2013) [#1]
Hi there,

I'm triing to create a shortcut to a program on my Linux-Desktop using Bash-Commands. In order to do that I'm creating a process to the Bashterminal and then I write the commands into the pipe:
Function CreateLinuxShortcut(title:String , path:String)
	path = Replace(path , "\" , "/")
	
	Local str1:String = "cd $HOME/Desktop && ln -s ~q" + path + "~q " + title + " && exit"	
	Local process:TProcess = CreateProcess("/bin/bash"), output:String
	
	Local pointer1:Byte Ptr = str1.ToCString()
	process.pipe.Write(pointer1, str1.length)
	
	While process.Status()
		Delay(20)
		If process.pipe.ReadAvail() > 0 Then Print(process.pipe.ReadString(process.pipe.ReadAvail()))
	Wend
	
	MemFree(pointer1)
	Print "Done"
End Function

Executing this Function will create the shortcut but the problem is
that the process will never terminate it's work. After triing arround some time I found out that it has to do with that line:
Local pointer1:Byte Ptr = str1.ToCString()

But I don't know how to slove that problem.
Does anyone of you know how to fix that?


skidracer(Posted 2013) [#2]
One problem I think is similar to if you type "/bin/bash" into terminal but forget to hit return key.


Floyd(Posted 2013) [#3]
Maybe you need

	process.pipe.Write(pointer1, 1 + str1.length)

to include the null terminator for the c string.


Brucey(Posted 2013) [#4]
Although it's good to learn new things like pipes in BlitzMax, in this case I would use the symlink() system API instead - since it doesn't require you to be messing around with external commands and things.

Simply pass it two UTF8-encoded strings, and it should work as expected.


Brucey(Posted 2013) [#5]
Here's a working example :
SuperStrict

Framework BRL.StandardIO


If Symlink("/home/brucey/export.sql", "/home/brucey/link") Then
	Print "symlink failed"
End If




Extern
	Function _symlink:Int(path1:Byte Ptr, path2:Byte Ptr)="symlink"
End Extern

Rem
bbdoc: Creates a symbolic link called path2 that contains the string pointed to by path1.
about: path2 is the name of the symbolic link created, path1 is the string contained in the symbolic link.
End Rem
Function Symlink:Int(path1:String, path2:String)

	Local p1:Byte Ptr = path1.ToUTF8String()
	Local p2:Byte Ptr = path2.ToUTF8String()
	
	Local res:Int = _symlink(p1, p2)
	
	MemFree(p2)
	MemFree(p1)
	
	Return res

End Function

And the result of ls -l :
-rw-rw-r--  1 brucey brucey       0 Aug  8 10:57 export.sql
lrwxrwxrwx  1 brucey brucey      23 Dec 31 08:52 link -> /home/brucey/export.sql



Addi(Posted 2013) [#6]
Thanks for the Ideas ;)
I will try them but I don't think that they will fix the problem. It doesn't even matter if you are writing to the pipe or not the process never terminates.
Remove the process.pipe.Write(), try it again and you will see what I mean.

@Bruce
Good Idea I think I gonna change it


Derron(Posted 2013) [#7]

If Symlink("/home/brucey/export.sql", "/home/brucey/link") Then
	Print "symlink failed"
End If




not the best solution concerning English comprehension... "if copyFile then print failedCopyFile".


@Process pipes
I remember to have had similar problems when writing a small ide-test for blitzmax - sometimes the stream wasn't filled with what it has to be (so I missed compiler output). Had to have artificial delays to circumvent it. Maybe that is somehow connected.


bye
Ron


Brucey(Posted 2013) [#8]
not the best solution concerning English comprehension

symlink() returns 0 for success, as is the general case for status from a function.


Derron(Posted 2013) [#9]
that is why I said "English comprehension".

Also I (personally) find it way more intuitive to write

"If Symlink("...","...") = 0" if I know that it does not return a "bool" but a "status-integer".
Else my (German-language trained) brain thinks it is a "if blaIsTrue then".



bye
Ron


Addi(Posted 2013) [#10]
I fixed it :D
The problem was the Line that I mentioned in the first Post.
I just switched the Order of this Line and the Line where I create the process. Now its working ;):

Function CreateLinuxShortcut(title:String , path:String)
	path = Replace(path , "\" , "/")
	
	Local str1:String = "cd $HOME/Desktop && ln -s ~q" + path + "~q " + title + " && exit"
	Local pointer1:Byte Ptr = str1.ToCString()
		
	Local process:TProcess = CreateProcess("/bin/bash"), output:String
	process.pipe.Write(pointer1, str1.length)
	
	While process.Status()
		Delay(20)
		If process.pipe.ReadAvail() > 0 Then Print(process.pipe.ReadString(process.pipe.ReadAvail()))
	Wend
	
	MemFree(pointer1)
	Print "Done"
End Function



Sub_Zero(Posted 2013) [#11]
nice :)


Hardcoal(Posted 2014) [#12]
where can i read about process?


Henri(Posted 2014) [#13]
There aren't any official docs, but it's fairly simple to use. Forum search for freeprocess should suffice.

-Henri