Author Topic: problems programming a new text window for cmd.exe/4os2.exe  (Read 38719 times)

Martin Vieregg

  • Sr. Member
  • ****
  • Posts: 278
  • Karma: +2/-0
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #75 on: February 04, 2020, 03:06:01 pm »
Laurence,

(5) works now. I have indeed to pass the argument "cmd.exe /K\0" instead of "/K". The error message has vanished now. Does that mean that two instances of cmd.exe are executed?

(4) "help KEYS" fits my purpose, thank you.

(1) Of course I can read stdout, and this works fine already. My query relates to the other stuff which is sent to the PM window like changing the size with "mode" or deleting the screen buffer with "cls" and so on.
« Last Edit: February 05, 2020, 06:07:07 pm by Martin Vieregg »

Laurence Pithie

  • Jr. Member
  • **
  • Posts: 62
  • Karma: +1/-0
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #76 on: February 04, 2020, 03:39:11 pm »
Quote
(5) works now. I have indeed to pass the argument "cmd\0 /K" instead of "/K". The error message has vanished now. Does that mean that two instances of cmd.exe are executed?
No there's only one instance of the command shell,  It's a convention in C that the first entry in the array of command parmaters passed to a program is the name of the command. argv[0]. The called program skips the first parameter if it's the name of the called and reads the rest of the paramters. If the first parameter isn't the name of the shell then it treats it as an external command. If there are no parameters to pass then you can pass a null string and you won't get an error.

Quote
Of course I can read stdout, and this works fine already. My query relates to the other stuff which is sent to the PM window like changing the size with "mode" or deleting the screen buffer with "cls" and so on.
Write the commands you are sending to stdin to a log file in addition to sending them to stdin. Or are you asking how to capture the return code from the command you are sending to stdin? In which case check the %ERRORLEVEL% value immediately after issuing the command.

Martin Vieregg

  • Sr. Member
  • ****
  • Posts: 278
  • Karma: +2/-0
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #77 on: February 05, 2020, 10:22:51 am »
I want to capture the VIO calls cmd.exe sends to the PM window or to the screen (fullscreen) when e.g. a user types "mode" or "cls".
The problem I have is that I see the user input in the editor of course and the editor can interpretate these command by itself, but when cmd.exe executes a cmd file which holds "mode" or "cls", it won't get interpretated by the editor.

Laurence Pithie

  • Jr. Member
  • **
  • Posts: 62
  • Karma: +1/-0
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #78 on: February 05, 2020, 12:21:16 pm »
Quote
I  want to capture the VIO calls cmd.exe sends to the PM window or to the screen (fullscreen) when e.g. a user types "mode" or "cls".
To capture the indivdual calls you'd need to enable debugging in the call to DosExecPgm by setting the execFlag to EXEC_TRACE and using DosDebug to trace the execution of the process. I'm pretty sure this is not what you want to do, It dependson the debugging symbols being available for the executable and/or the ability to identify the assembly langage calls to the vio functions.

Quote
The problem I have is that I see the user input in the editor of course and the editor can interpretate these command by itself, but when cmd.exe executes a cmd file which holds "mode" or "cls", it won't get interpretated by the editor.
This is simpler, check for a .cmd extension then load the cmd file into a buffer and interpret it line by line and once you've done that send the cmd file to the cmd process. Implementing a full cmd file interpreter is non trivial,  but if you are only interested in specifc commands then it can be simplified to a straight word search.

Martin Vieregg

  • Sr. Member
  • ****
  • Posts: 278
  • Karma: +2/-0
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #79 on: February 05, 2020, 05:56:39 pm »
Quote
This is simpler, check for a .cmd extension then load the cmd file into a buffer and interpret it line by line

Yes. Then I have only to interpretate my commands like mode and cls and I have to interpretate call to open cmd files recursive. That's not difficult to program. But I will introduce the rule that .cmd has to be added, otherwise cmd.exe executes the cmd file directly. (The user has the choice. It would be possible, but difficult to check whether a command is a cmd file or not.)

But this concept will fail with REXX scripts. I tried to copy a REXX script into the clipboard, then I copied it to the cmd.exe window, and it fails. So REXX scripts have to be executed directly by cmd.exe. If the user tries to type myrexxscript.cmd, then cmd.exe has to exeute the file directly nevertheless. REXX programs awas begin with /*, so they are easy to identify.

Dave Yeo

  • Hero Member
  • *****
  • Posts: 4787
  • Karma: +99/-1
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #80 on: February 05, 2020, 06:30:41 pm »
Doesn't cmd.exe just pass execution to the REXX interpreter? You could pass REXX to pmrexx.exe and execute it that way perhaps.
There's also the EXTPROC keyword which can pass execution to another interpreter, I've used it to call sh scripts and it's used for Perl scripts, eg
Code: [Select]
extproc perl -S
#!L:/Perl/bin/perl
    eval 'exec L:/Perl/bin/perl -S $0 ${1+"$@"}'
        if $running_under_some_shell;

Laurence Pithie

  • Jr. Member
  • **
  • Posts: 62
  • Karma: +1/-0
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #81 on: February 05, 2020, 07:18:30 pm »
For a rexx script check for the two charactee /* as the first two characters in the cmd file. You can extend this to other intepreted scripts by checking whether extrpoc or #!(4OS2 extension if the UnixPaths option is enabled) are the first characters in athe command fiile. and that is followed by the name of the external processor, perl, python, etc.

Martin Vieregg

  • Sr. Member
  • ****
  • Posts: 278
  • Karma: +2/-0
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #82 on: February 15, 2020, 12:47:06 pm »
- Problem with named pipes error 231 "pipe busy" when DosOpen
- Problem with cmd.exe idle state (program running or waiting for user input with prompt)

I thought that all OS-specific programming works fine now, but I still have got a problem with named pipes. When the helper program opens the named pipe, I sometimes get an error 231 (pipe busy). I cannot reproduce the problem regulary. It even occurs if I run only one instance of my program. I checked all named pipe API call returns. All works fine up to the DosOpen call. DosDisConnectNPipe returns 0 when exiting the last program session and DosCreateNPipe in the current session also returns 0. DosClose in the helper program of the previous session also returns 0. The problem does not occur when running the first session of the program after booting the computer. So it seems that the previous cmdme session did not clean up all properly. Any ideas?

Then I have got another problem. I have realized that the editor has to know whether cmd.exe is in idle state (waiting for user input) or not. Because if cmd.exe is exeuting a program and e.g. the user has to enter "Y" or "N", for example, a user input has to be sent immideately to cmd.exe. If there's a prompt and the user wants to enter a new command, the finished complete line of the new command with an ending Return character is sent and before, the user can change the input, has tab completion support and so on. I can read the prompt, but the prompt can change with the PROMPT command. A program which is executed by cmd.exe could generate a similar input. Any ideas how to query this state is appreciated. (I have got the session ID of the helper which executes cmd.exe. Perhaps I can query this state by querying the current session? Or I need a very intelligent interpretation of the proposed prompt string?)
« Last Edit: February 15, 2020, 12:50:11 pm by Martin Vieregg »

Laurence Pithie

  • Jr. Member
  • **
  • Posts: 62
  • Karma: +1/-0
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #83 on: February 15, 2020, 02:06:09 pm »
Quote
- Problem with named pipes error 231 "pipe busy" when DosOpen
Generally you should check for this error and issue a DosWaitNPipe on reciept of this error followed by another call to DosOpen.
Quote
DosClose in the helper program of the previous session also returns 0
Are you issuing a DosClose call on the pipe from the server application?
Quote
Named-Pipe Considerations

DosClose closes a named pipe by handle. When all handles that refer to one end of a pipe are closed, the pipe is considered broken.

If the client end closes, no other process can reopen the pipe until the serving end issues DosDisConnectNPipe, followed by DosConnectNPipe.

If the server end closes when the pipe is already broken, the pipe is immediately deallocated; otherwise, it is not deallocated until the last client handle is closed.

The pipe isn't deallocated until both server and client handles are closed.

Quote
Or I need a very intelligent interpretation of the proposed prompt string?)
Isn't the user seeing the contents of stdout?

Martin Vieregg

  • Sr. Member
  • ****
  • Posts: 278
  • Karma: +2/-0
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #84 on: February 15, 2020, 02:57:27 pm »
Quote
Are you issuing a DosClose call on the pipe from the server application?
The server app (the PM editor) calls:
DosCreateNPipe
DosConnectNPipe (waits for DosOpen on client)

Meanwhile, the client (the helper which executes cmd.exe) calls DosOpen

Then the server continues. I do not use DosOpen in the server.

When the program gets finished, the client runs DosClose first. Then the server calls DosDisconnectNPipe.

I assumed that in the server I only have to use DosCreateNPipe, then Connect and Disconnect which is a substutute for DosOpen and DosClose. So do I have to use both DosOpen and DosClose in the server app or only DosClose?

------------
Quote
Isn't the user seeing the contents of stdout?
Yes, the user sees stdout in the PM editor immediately. But the PM editor has to know whether to send each keyboard user input character to cmd.exe immediately (within a sub program) or (prompting/idle) to wait until the user presses Enter.

Andreas Schnellbacher

  • Hero Member
  • *****
  • Posts: 827
  • Karma: +14/-0
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #85 on: February 15, 2020, 04:18:36 pm »
I have realized that the editor has to know whether cmd.exe is in idle state (waiting for user input) or not.
You can parse the last line for a usual prompt. That's not perfect, but it works suitably.

Laurence Pithie

  • Jr. Member
  • **
  • Posts: 62
  • Karma: +1/-0
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #86 on: February 15, 2020, 04:30:26 pm »
You only have to use DosClose in the server because threads in the process that creates the pipe have access to it and don't need to call DosOpen. DosDisconnectNPipe doesn't deallocate the pipe, which is why it can be reopened with another call to DosConnectNPipe without haveing to call DosCreateNPipe to recreate it. .
Quote
DosDisConnectNPipe is issued by a server process to acknowledge that a client process has closed a named pipe. (If a client process tries to issue DosDisConnectNPipe, ERROR_BAD_PIPE is returned.) The pipe cannot be opened by another client process until the server process issues this function, followed by DosConnectNPipe.

Quote
But the PM editor has to know whether to send each keyboard user input character to cmd.exe immediately (within a sub program) or (prompting/idle) to wait until the user presses Enter.
If it's using standard i/o then it doesn't matter whether the editor waits for the enter key to be pressed before sending the character, If it's doing single character i/o and you send it a line of characters then they'll be buffered for subsequent reads, if it's only expecting a single character input then it should ignore the enter key, and if it's not flushing the input buffer before each read then that's a bug. If it's using Vio calls to read character strings then you can't use it from a pipe.

So, if you've got a prompt Y/N and you send "Y\n" the newline "\n"  should be discarded by the calling program.

Laurence Pithie

  • Jr. Member
  • **
  • Posts: 62
  • Karma: +1/-0
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #87 on: February 15, 2020, 04:36:52 pm »
In regard to parsing the prompt the simplest solution is to set the prompt to a known state at the start of the session and prevent the user from changing it during the session.
« Last Edit: February 15, 2020, 04:39:19 pm by Laurence Pithie »

Martin Vieregg

  • Sr. Member
  • ****
  • Posts: 278
  • Karma: +2/-0
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #88 on: February 15, 2020, 09:18:54 pm »
If I understand it right, DosConnectPipe and DosDisConnectPipe using in the server only waits for client action opening and closing the pipe on the client end. I have to DosClose the named pipe both on the server and on the client end.

When ending the program, I inserted DosClose after DosDisConnectNPipe in my server program. And, alternatively, I use DosClose in the server program instead of DosDisconncectNPipe which should be not necessary (because I do not want to open the pipe again).

But the casually pipe busy error after restarting the program and its client still remains. ???

Laurence Pithie

  • Jr. Member
  • **
  • Posts: 62
  • Karma: +1/-0
    • View Profile
Re: problems programming a new text window for cmd.exe/4os2.exe
« Reply #89 on: February 16, 2020, 01:29:21 am »
My apologies, I didn't read your orignal post properly. The problem occurs when the client program calls DosOpen. It sounds like a race condition, The server creates the pipe and then calls DosConnectNPipe to put it into a listening state. If the client program calls DosOpen before the DosConnectNPipe call completes the client will get an ERROR_PIPE_BUSY returned from the call to DosOpen. You can either check for the error and issue a DosWaitNPipe call or synchronose the pipe setup in the server with the opening of the pipe in the client using a semaphore.