CreateProcess - Writing to Pipe
BlitzMax Forums/BlitzMax Programming/CreateProcess - Writing to Pipe
| ||
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? |
| ||
One problem I think is similar to if you type "/bin/bash" into terminal but forget to hit return key. |
| ||
Maybe you needprocess.pipe.Write(pointer1, 1 + str1.length) to include the null terminator for the c string. |
| ||
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. |
| ||
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 |
| ||
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 |
| ||
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 |
| ||
not the best solution concerning English comprehension symlink() returns 0 for success, as is the general case for status from a function. |
| ||
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 |
| ||
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 |
| ||
nice :) |
| ||
where can i read about process? |
| ||
There aren't any official docs, but it's fairly simple to use. Forum search for freeprocess should suffice. -Henri |