[ LUGOS ] prikaz na konzoli

Andrej Komelj andrej.komelj na guest.arnes.si
Čet Jun 3 01:38:20 CEST 1999


> zanima me, ce obstaja kaksen progy, ki bi na kozoli prikazal tocen cas.

Izvoli, majhen programcek (brez komentarjev) posebej zate. :-)

Deluje samo na linuxih (oz. sistemih, ki imajo /dev/vcs datoteke) in se to
samo v vritualnih konzolah. V xtermu tudi teoreticno ne more delovati --
bi se pa dalo narediti tudi to, vendar na malce drugacen nacin: z escape
sekvencami.

No, /dev/vcs? datoteka je "reprezentacija" fizicnega ekrana virtualne
konzole (vcs1 -> tty2, itd).  Po datoteki se lahko premikas z fseek, pises
vanjo in beres iz nje. Tocka (x, y) ustreza odmiku
d = (y - 1) * stevilo_stolpcev + (x - 1).

Programcek deluje tako, da ugotovi, na kateri konzoli je pognan, se nato
postavi v ozadje in periodicno pise trenutni cas na ekran v zgornji desni
kot. Stevilo stoplcev na ekranu ugotovi s pomocjo COLUMNS "okoljske"
spremenljivk (ok: environment variable). Ce le-ta ni nastavljena, privzame
vrednost 80.

Kdor hoce naj si ga prevede sam, popravi naj si le cas za osvezevanje
(#define DELAY vrstica). Trenutno je nastavljen na dve desetinki sekunde.

Uzivajte. Ce vam unici kar koli, ne krivite mene, bla bla bla, skratka,
mene ni.

Mimogrede, program potrebuje pisalni dostop do datotek /dev/vcs*. Ne
dovolite pisanja po in branja iz teh datotek vsakomur -- to je kar velika
varnostna luknja. Programcku morate zato dati suid zastavico (chmod u+s
proggy) ali pa, se bolje, datoteke "podelite" neki posebni skupini in
programcku dodajte sgid zastavico.

Kako?

chgrp tty /dev/vcs*
chmod g+w /dev/vcs*
chgrp tty proggy
chmod g+s proggy

In pa preverite se stanje /dev/vcs0 datoteke, ki naj bi imela permissione:
-rw-r--r-- (022)

-----------------------------------------------------------------------
#include <errno.h>
#include <error.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#define DELAY 200000	/* cas med osvezitvijo ure v mikro sekundah */

int main(void)
{
	int cols;
	FILE *vcs;
	time_t curtime;
	struct tm *loctime;
	char date[9], tty[11];

	strcpy(tty, ttyname(0));
	sprintf(tty, "/dev/vcs%s", strrchr(tty, 'y') + 1);
	if ((vcs = fopen(tty, "r+")) == NULL) error(1, errno, "%s", tty);
	if (getenv("COLUMNS") == NULL) cols = 80;
	else cols = (int)strtol(getenv("COLUMNS"), NULL, 10);
	
	switch (fork()) {
		case 0:	/* child */
			break;
		case -1:	/* napaka */
			error(1, errno, "fork()");
			break;
		default:	/* parent */
			fclose(vcs);
			return 0;
	}

	while (1) {
		curtime = time(NULL);
		loctime = localtime(&curtime);
		strftime(date, 15, "%H:%M:%S", loctime);
		fseek(vcs, cols - 8, SEEK_SET); 
		fwrite(&date, 1, 8, vcs);
		fflush(vcs);
		usleep(DELAY);
	}

	return 0;
}
-----------------------------------------------------------------------

-- 
Andrej.




Dodatne informacije o seznamu Starilist