Spooler di stampa – C (linux)

spoolerSpooler di stampa

Spooler di stampa in C usando una NAMED PIPE(o FIFO) che non è altro che un canale unidirezionale dove faremo passare il nome del file temporaneo.

Per far funzionare questo spooler bisogna creare due programmi uno copierà il file originale in uno univoco e temporale e il secondo programma sarà il servizio dello spooler che prenderà il file temporaneo e lo copierà in un file che simula la stampante.

stampa.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

int creaFileUnivoco(char nomeTmp[]);
int main (int argc, char** argv) {
    int fd, fdtmp, fdcanale;
    int num, i;
    char* nome;
    char nometmp[8], c;
    
    // Controllo parametri
    if(argc < 2){
		printf("Errore parametri\n");
		printf("Inserire il nome del file da stampare\n");
		fflush(stdout);
		exit(-1);
    }
    // Numero di file da stampare
    num = argc - 1;
    i = 1;
    while(i <= num){
		// Controllo l'esistenza del file
    	if((fd = open(argv[i],O_RDONLY)) >= 0){
			// Creo un file univoco
			fdtmp = creaFileUnivoco(nometmp);
			printf("File temporaneo : %s\n", nometmp);
			fflush(stdout);
			// Copio il file sorgente nel file temporaneo
			while(read(fd, &c, sizeof(char)) > 0){
				write(fdtmp, &c, sizeof(char));
			}
			// Apro il canale della FIFO
    	    fdcanale = open("canale", O_RDWR);
			// Scrivo nel canale il nome del file temporaneo da stampare
			write(fdcanale, nometmp, sizeof(nometmp));    	
    	}else{
			// File non trovato
			printf("file non trovato: %s\n", argv[1]);
			fflush(stdout);
		}
		i++;
    }
}

// Crea un file univoco  
int creaFileUnivoco(char nomeTmp[]){
    int i, fd;
    i = 0;
    // inizializzo il nome del file : tmp0000
    sprintf(nomeTmp, "tmp%04d", i);
    // controllo se esiste già un file con lo stesso nome
    while((fd = open(nomeTmp,O_CREAT | O_EXCL | O_WRONLY, 0666))<0){
		i++;
        sprintf(nomeTmp, "tmp%04d", i);
    }
    return fd;
}

spooler.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>

int isEsecuzione();
void chiudi(int);

int main(){
	int fd, fdcanale, fdstampa;
	char nometmp[8], c;
	// Assegno al segnale SIGINT(^C) la funzione chiudi
	signal(SIGINT, chiudi);
	signal(SIGKILL, chiudi);
	// Controllo che il processo non sia già stato avviato
	if(isEsecuzione()){
		printf("processo in esecuzione\n");
		fflush(stdout);
		exit(-1);
	}
	printf("Spooler in esecuzione\n");
	fflush(stdout);
	// Apro la FIFO
	fdcanale = open("canale", O_RDWR);
	// Leggo il nome del file temporaneo 
	while(read(fdcanale, nometmp, sizeof(nometmp))){
		// Apro il file che simulerà la stampante
		fdstampa = open("bufferStampa",O_CREAT | O_WRONLY | O_APPEND, 0666);
		// Apro il file temporaneo in lettura
		fd = open(nometmp, O_RDONLY);
		printf("Aggiunta stampa in coda\n");
		fflush(stdout);
		// Copio il file temporaneo nel buffer della stampante
		while(read(fd, &c, sizeof(char))){
			write(fdstampa, &c, sizeof(char));
		}
		// Chiusura del file che simula la stampante
		close(fdstampa);
		// Rimozione del file temporaneo
		close(fd);
		unlink(nometmp);
	}
}

int isEsecuzione(){
	int fd;
	// Uso un file per controllare se il processo è in esecuzione
	if(fd = open("crt",O_CREAT | O_EXCL) < 0){
		close(fd);
		return 1;
	}
	return 0;
}
void chiudi(int a){
	// Cancello il file di controllo ed chiudo il processo
	unlink("crt");
	exit(-1);
}

Creare una comunicazione usando i socket – JAVA(client) e PHP(server)

Precedente Creare una comunicazione usando i socket - JAVA(client) e PHP(server) Successivo GPass - Gestione password - C#