1

I need to create a interface in terminal using the termios.h in C. To keep it short I have to create a executable like ./exec and after I run, it has to stop displaying the PS1 variable. If I have a program which displays the following text Hello World that uses printf it will look like:

$:> ./exec
Hello World!

But instead of printing that, I need only the Hello World! to be in the terminal, like when you clear the screen while the program is displaying.

Hello World!

To say it in other way, the purpose is to clean the terminal, and when the ./exec is runned, it should clear this line as well, $:> ./exec.

So far I managed to make this function

void    clear_screen()
{
    char buf[1024];
    char *str;

    tgetent(buf, getenv("TERM"));
    str = tgetstr("cl", NULL);
    fputs(str, stdout);
}

Which clears the screen but it keeps the line with the command itself $:> ./exec. I am not allowed to use ncurses.h library.

Here is a main:

int main(void)
{
    clear_screen();
    printf("Hello World!\n");
    return (0);
}
JohnnyOnPc
  • 386
  • 1
  • 5
  • 18
  • 1
    How about using [VT100 control codes](http://www.termsys.demon.co.uk/vtansi.htm)? – Some programmer dude Aug 29 '17 at 14:12
  • That could be an idea, but iI heard there are more simpler solutions since i dont really how many characters i need to delete. – JohnnyOnPc Aug 29 '17 at 14:25
  • You don't need to know that. Just print the `Erase screen` sequence and the whole "screen" should be cleared. – Some programmer dude Aug 29 '17 at 14:28
  • Okay , I'll give it a go and post an update after that. – JohnnyOnPc Aug 29 '17 at 14:30
  • 2
    Don't create programs called `test` or `exec` — those are both names of commands built into the shell, and sooner or later, you'll run into problems. Similarly with other commands built into the shell. – Jonathan Leffler Aug 29 '17 at 14:45
  • Okay thanks for the tip, I will find other names. – JohnnyOnPc Aug 29 '17 at 14:46
  • Are you sure your shell isn't screwing you up? You should get a PS1 prompt after the "Hello World", but everything else on the screen should be cleared if the clear command works — unless your shell has different ideas. You don't actually show an MCVE ([MCVE]), so we can't be sure what your program does. The MCVE needn't be much longer than the code you show: `int main(void) { clear_screen(); puts("Hello World"); return 0; }` might be all (apart from a couple of headers — identifying those helps too). – Jonathan Leffler Aug 29 '17 at 14:48
  • While you clear the screen the PS1 remains and the executable remains and then the output of the program follows, I need only the output of the program to be displayed without the PS1 . – JohnnyOnPc Aug 29 '17 at 14:53
  • @Someprogrammerdude Using the VT100 doesn't help since I haven't printed anything on the screen and the "thing" I need to stop displaying is the PS1. – JohnnyOnPc Aug 29 '17 at 20:38

2 Answers2

1

Something was omitted from the question (and it confuses termcap with termios). Since the sample code uses termcap, answers should address that. To recap, here's a complete example:

#include <stdio.h>
#include <stdlib.h>
#include <termcap.h>    /* this comes from ncurses, anyway... */

static void clear_screen(void)
{
    char buf[1024];
    char *str;

    tgetent(buf, getenv("TERM"));
    str = tgetstr("cl", NULL);
    fputs(str, stdout);
}

int main(void)
{
    clear_screen();
    printf("Hello World!\n");
    return (0);
}

The "cl" capability is what matters. It is defined as the corresponding feature to terminfo clear:

   clear_screen                  clear      cl        clear screen and
                                                      home cursor (P*)

If you run that example from the command-line with a correctly written terminal description, the output does this:

  • clear the entire display,
  • move the cursor to the home-position
  • print a message (which would be on the first line of the screen)
  • exit

After that, the shell prints its prompt again.

There's a couple of problems with the example:

  • it is using fputs for output. terminfo/termcap data could include padding, which won't work with that. You won't notice that with common terminal emulators' terminal description, but it matters for hardware terminals. The vt100 termcap would have this, for instance (the "50" is padding):
    :cl=50\E[H\E[J:

The proper function to use would be tputs. It happens to be in an overlapping set of functions between termcap and terminfo. In ncurses, the complete description is in the terminfo manual page.

  • some terminals (Microsoft telnet used to be a good example, though no one's tested recently...) didn't treat the control sequence properly. IN the previous example, one might have used
    :cl=\E[J\E[H

to demonstrate this: the terminal didn't clear the whole screen, but only the remainder. To work around this, the terminal descriptions were modified to move the cursor first.

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
0
printf("\033[2J"); // clear screen
printf("\033[H"); // cursor home

If you want to do anything with the screen, this is one way. You can look up other codes from 'some programmer dude's comment. You can also google vt100 codes.

There are libraries that abstract this like Ncurses but since you can't use that (why?) that's out - I'll let others elaborate on that though, maybe there are others that are allowed..

edit

try this:

printf("\033[1A\r\033[2K");

See my comment.

the VT100 codes don't help either

If you want to do anything with the screen vt100 codes are like a hacker's dream come true. Run, if you see the DEA coming, they are that good.

Community
  • 1
  • 1
FastAl
  • 6,194
  • 2
  • 36
  • 60
  • Well, this doesn't help since it is clearing the screen, but the PS1 in the terminal remains, and the VT100 codes don't help either. – JohnnyOnPc Aug 30 '17 at 08:59
  • @JohnnyOnPc, So what it sounds like, you just want (1) whatever is on the screen to remain there but (2) the command where you ran, including the $:> and the app name (./exec for this example) _both erased_ ? ... I can give you code that does that ... just want to be clear what you are trying. Hint: combine vt100 codes for (1) go up 1 line (2) cursor home in line (\r) (3) clear to EOL – FastAl Aug 30 '17 at 20:01
  • @FastAI Well, I need both of them erased, but the problem is that the $:> is printed anyway by the terminal and I need to stop that. When I run the ./exec i want a blank terminal, without anything printed, as if you've scrolled down. – JohnnyOnPc Aug 30 '17 at 22:32
  • I think I get it now ... the program RUNs, clears the screen, which is what you want, but then it ends ... and then you have the $:> there waiting for the next command from you? I am I understanding that right? – FastAl Sep 05 '17 at 16:29
  • @FastAI yes you got me right until the " you have the $:> " I dont want the $:> to be displayed. – JohnnyOnPc Sep 07 '17 at 15:00
  • @JohnnyOnPc Since this is generated by the shell, you will have to turn this off in the shell. And there is a design feature in unix that will frustrate your desire here even more: __child processes inherit a COPY of the shell environment__, which sounds irrelevant, but is not, because if you turn off the prompt from your app, it will only effect the environment your app has, **not** that of the shell.. __EDIT: sorry__ I just re-read this and saw you are using EXEC. Maybe just clear the PS1 environment variable in the app? – FastAl Sep 14 '17 at 18:41
  • @FastAI Thanks for response, but the problem is that for having a child processes I have to use the fork() function which I am not allowed to. I have thought of cleaning the PS1 variable which is easy. but the problem then is how do I export the envp (enviroment variable) in order to use it? – JohnnyOnPc Sep 15 '17 at 06:47
  • @JohnnyOnPc - I don't know ;-) you've reached the end of my Unix exertise. I would recommend posting a question on exactly how to do that. Please be careful with stack overflow questions - read the guideline on posting, they are extremely picky and will delete your question. Things to include - exactly what you told me plus code samples. Question title: "How do I export PS1 when I can't fork?" I found this question very hard to figure out what you are trying to accomplish. I don't know why, and I can't figure out a better way, so really I'm in no place to criticize, just feedback. Good luck!!! – FastAl Sep 18 '17 at 15:35