Jump to content

Implementing pause in a shell program

- - - - -

  • Please log in to reply
9 replies to this topic

#1
fread

fread

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 787 posts
Im trying to implement the pause and continue method in a shell program. I am supposed to use pause key (on my laptop thats: fnkey + pausekey) and enter key. On a regular keyboard think its called a virtual key. Also on a regular keyboard pause and break shares the same key.

I wondering if it would be wiser to implement the pause and continue action using only signals(if there exist a signal for pause and enter keys) or by using pause()?
If i am using pause() then i need to be able to capture the pausekey character(not quite sure how to capture that key as yet). If it pauses then i would have to depend on signal to continue. Hopefully the a signal associated with the enter key.
Perfection of means and confusion of ends seem to characterize our age. Albert Einstein :confused:

#2
AdvMutant

AdvMutant

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 438 posts
You kinda confused me. So you want to pause your program every time you press a certain key, until you press enter to release it?

Posted Image
There is no problem that cannot be solved by the use of high explosives.


#3
Alexander

Alexander

    It's Science!

  • Moderators
  • 4,118 posts
  • Location:Vancouver, Eh! Cleverness: 200
I would put program into thread A and handle signal keys in thread B. FN+PAUSE can be captured to call pause()/sigprocmask/sigsuspend/etc on a thread (or pthread_sigmask and sigwait / pthread_kill POSIX signal calls if that is what you are doing) and resume it as so if ENTER is pressed.

I would assume you would capture FN+PAUSE from the keyboard event in /dev/input/...
Be sure to read the updated FAQ! || Health is achieved through the same 10,000 steps.
If a suggested code/method fails, informing us is less important than telling us why or what errors occurred.

#4
fread

fread

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 787 posts
Hmm duly noted. one thing

Quote

I would assume you would capture FN+PAUSE from the keyboard event in /dev/input/...
having problems capturing the pause key.
I am using iscntrl() from ctype.h.
Perfection of means and confusion of ends seem to characterize our age. Albert Einstein :confused:

#5
AdvMutant

AdvMutant

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 438 posts
What kind of trouble?

Posted Image
There is no problem that cannot be solved by the use of high explosives.


#6
Alexander

Alexander

    It's Science!

  • Moderators
  • 4,118 posts
  • Location:Vancouver, Eh! Cleverness: 200
You will not be able to access those key sequences from getchar without setting terminal output to a raw state, my scan codes should match to your system but note I cannot test this as my laptop does not have FN keys set up, the pause button should be the same regardless of key modifier else you will need to use my code to find what FN+pause scan code is yourself.

You may need to install your linux kernel headers to get sys/ioctl.h. After the loop breaks I had used tcsetattr() to commit old terminal configuration back, so be sure it is run or you may require a reboot of tty or your system.
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/kd.h>

int main () {
    /* contain terminal config and backup */
    struct termios termnew, termbk;
    unsigned char scancode = 0;
    /* set keyboard control into raw scancode */
    ioctl(0, KDSKBMODE, K_RAW);
    
    /* commit termios struct to be-rid of echo, canonical mode, stop signal gen keys, stop cr passing */
    tcgetattr( 0, &termnew );
    termbk = termnew;
    termnew.c_lflag &= ~ECHO & ~ECHONL & ~ICANON & ~ISIG;
    termnew.c_lflag = termnew.c_lflag & ~( ICANON | ECHO | ISIG );
    termnew.c_cc[ VMIN ] = 0;
    termnew.c_cc[ VTIME ] = 0;
    tcsetattr( 0, TCSANOW, &termnew );


    while(scancode != '\n') {
        /* read from STDIN_FILENO handle 0 to keycode address */    
        if (read( 0, &scancode, 1 ) && scancode == 0x45
            && read( 0, &scancode, 1 ) && scancode == 0xE1
            && read( 0, &scancode, 1 ) && scancode == 0x1D
        )  
        {
            printf("Scan code %i (i.e. pause) was pressed\n", scancode);
        }
    }
    
    /* reset terminal to sane values, should work */
    tcsetattr( 0, TCSANOW, &termbk );
    
    return 0;
}
tty also has the command 'reset' you can type in to your terminal afterwards, some systems it does not matter though.
Be sure to read the updated FAQ! || Health is achieved through the same 10,000 steps.
If a suggested code/method fails, informing us is less important than telling us why or what errors occurred.

#7
AdvMutant

AdvMutant

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 438 posts
Wait a second, Fn+Pause is like just Pause ona a regular computer. Isn't it?

Posted Image
There is no problem that cannot be solved by the use of high explosives.


#8
fread

fread

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 787 posts
Don't forget this is an assignment so my code has to be very portable. I cant install anything on the computers in the lab. Compiled and ran the program but nothing happened. It hanged in the while loop.
Perfection of means and confusion of ends seem to characterize our age. Albert Einstein :confused:

#9
Alexander

Alexander

    It's Science!

  • Moderators
  • 4,118 posts
  • Location:Vancouver, Eh! Cleverness: 200
It did what it was supposed to, do nothing but wait for PAUSE to be pressed. If you want it to be portable that should had worked, you can run the following program and press FN+PAUSE to see what your keyboard emits for pause and map them to my IF statements in my prior post.
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/kd.h>

int main () {
    struct termios termnew, termbk;
    unsigned char scancode = 0;
    ioctl(0, KDSKBMODE, K_RAW);
    tcgetattr( 0, &termnew );
    termbk = termnew;
    termnew.c_lflag &= (~ECHO & ~ECHONL & ~ICANON & ~ISIG);
    termnew.c_cc[ VMIN ] = 0;
    termnew.c_cc[ VTIME ] = 0;
    tcsetattr( 0, TCSANOW, &termnew );

    while(scancode != '\n') {
        if (read( 0, &scancode, 1 ))  
        {
            printf("Scan code 0x%x was pressed\n", scancode);
        }
    }
    
    tcsetattr( 0, TCSANOW, &termbk );
    
    return 0;
}
Xorg may handle your keyboard device differently, this capture is always dependent of systems, it is always possible YOUR device does not handle it and pause is impossible to be captured.
Be sure to read the updated FAQ! || Health is achieved through the same 10,000 steps.
If a suggested code/method fails, informing us is less important than telling us why or what errors occurred.

#10
fread

fread

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 787 posts
I did not get the pause to work. I will have to do apart from the assignment just for the understanding. thanks for your help. i copied your code post and will build from there...much thanks
Perfection of means and confusion of ends seem to characterize our age. Albert Einstein :confused:




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users