static void shutDown(int a) { printf("Client is shutting down\n"); logout(); semctl(semid, 0,IPC_RMID, NULL); disconnectFromChannel(channel); free(channel); close(syncPipe[0]); close(signalPipe[0]); kill(receiverPid, SIGHUP); exit(0); }
/*Jamas termina, si termina , cierra el programa*/ void beginShell(){ int op; char buff[100]; while(1){ printf("Elija una opcion\n"); printf("\t(1) Registrarse\n"); printf("\t(2) Login\n"); printf("\t(3) Salir\n"); scanf("%d", &op); BORRA_BUFFER // printf("Opcode leido: %d\n", op); switch (op) { case 1: if ( reg() == 0 ) { read(syncPipe[0],buff,20); if(!strcmp(buff,"GOTO_SHELL")){ // printf("Yendo al shell\n"); shell(); } } break; case 2: logg(); read(syncPipe[0],buff,20); // printf("Leido del pipe: %s\n", buff); if(!strcmp(buff,"GOTO_SHELL")) shell(); break; case 3: disconnectFromChannel(channel); kill(receiverPid, SIGHUP); exit(0); default: printf("Opcion invalida"); break; } } return; }
int main(void) { char buff[100]; channel = (void *)malloc(200); /*---Establezco los canales de comunicacion---*/ getDefaultChannel(channel); if ( connectToChannel(channel,CLIENT) < 0 ) { printf("Server not available\n"); return 0; } itoa(buff,GET_CHANNEL); sendPacket(buff,strlen(buff)+1, channel, CLIENT); receivePacket(buff,MAX_SIZE, channel, CLIENT); disconnectFromChannel(channel); stringToChannel(buff, channel); connectToChannel(channel,CLIENT); /*---Abro el pipe de sincronismo entre padre e hijo---*/ if( pipe(syncPipe) == -1 ){ printf("Error al crear el pipe de sincronismo en el client.\n"); return 0; } /*---Abro el pipe de pasaje de argumentos para seniales---*/ if( pipe(signalPipe) == -1 ){ printf("Error al crear el pipe de args para seniales.\n"); return 0; } /*---Seteo el semaforo---*/ int semkey = getpid(); semun x; x.val = 1; int flags = IPC_CREAT | IPC_EXCL; if ( ( semid = semget(semkey, 1, 0666 | flags )) == -1 ) { printf("Error al crear semaforo: %d\n", semkey); return -1; } if ( semctl(semid, 0, SETVAL, x) == -1 ) { printf("Error al configurar semaforo\n"); return -1; } /*---Configuracion de manejo de seniales---*/ /* SIGUSR1 -> SHELL_SIGNAL */ /* SIGUSR2 -> DRAFT_SIGNAL */ struct sigaction draftSigAct; draftSigAct.sa_handler = draftSignalHandler; sigemptyset(&(draftSigAct.sa_mask)); draftSigAct.sa_flags = SA_NODEFER; struct sigaction shellSigAct; shellSigAct.sa_handler = shellSignalHandler; sigemptyset(&(shellSigAct.sa_mask)); shellSigAct.sa_flags = SA_NODEFER; sigaction( SIGUSR1, &shellSigAct, NULL); sigaction( SIGUSR2, &draftSigAct, NULL); static struct sigaction act3; act3.sa_handler = catchSigPipe; sigfillset(&(act3.sa_mask)); sigaction(SIGPIPE, &act3, NULL); static struct sigaction act1; static struct sigaction act2; /*Convenimos a este proceso como programa de envio de datos*/ senderPid = getpid(); pid_t auxPid; switch( auxPid = fork() ) { case -1: printf("Error al configurar el cliente.\n"); break; case 0: receiverPid = getpid(); close(syncPipe[0]); close(signalPipe[0]); receive(); break; default: act1.sa_handler = shutDown; sigfillset(&(act1.sa_mask)); sigaction(SIGINT, &act1, NULL); act2.sa_handler = shutDown; sigfillset(&(act2.sa_mask)); sigaction(SIGTSTP, &act2, NULL); receiverPid = auxPid; close(signalPipe[1]); close(syncPipe[1]); raise(SIGUSR1);break; } return 0; }
QDSActionPrivate::~QDSActionPrivate() { disconnectFromChannel(); }