Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* SISTC T3 - Criação dinâmica de processos
- Utilização das funções fork() e wait() para lidar com a criação e terminação de processos a partir de um programa */
- // Apple Xcode
- // func.c
- // servidor / cliente
- #include "func.h"
- #include <stdio.h>
- #include <string.h>
- #include <signal.h>
- #include <sys/wait.h>
- #include <errno.h>
- void ler_registo(veiculo_t *v)
- {
- char the_aux[8];
- printf("\nmatricula: ");
- // get a line from a stream
- fgets(the_aux, 8, stdin);
- // copy memory area
- memcpy(v->matricula, the_aux, 6);
- printf("\nproprietario: ");
- // get a line from a stream
- fgets(v->proprietario, NAME_BUFFER_SIZE, stdin);
- v->apagado = '0';
- }
- void imprimir_registo(veiculo_t *v)
- {
- if (v->apagado == '0')
- {
- printf("\nproprietario\n %s ", v->proprietario);
- printf("\n matricula\n");
- fwrite(v->matricula, 6, 1, stdout);
- }
- }
- void apagar_registo(char matricula[], FILE *the_record)
- {
- veiculo_t v1;
- // binary stream input/output
- while (fread(&v1, sizeof(v1), 1, the_record) != 0)
- {
- // compare strings
- if (strncmp(matricula, v1.matricula, 6) == 0)
- {
- v1.apagado = '1';
- // reposition a stream
- fseek(the_record, -sizeof(v1), SEEK_CUR);
- fwrite(&v1, sizeof(v1), 1, the_record);
- }
- }
- }
- //
- // func.h
- // servidor / cliente
- #include <stdio.h>
- #define NAME_BUFFER_SIZE 80
- typedef struct
- {
- char matricula[6];
- char proprietario[NAME_BUFFER_SIZE];
- char apagado;
- } veiculo_t;
- void ler_registo(veiculo_t *);
- void imprimir_registo(veiculo_t *);
- void apagar_registo(char *, FILE *);
- void sigchld_handler(int );
- //
- // main.c
- // servidor
- #include "func.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <netinet/in.h>
- #include <unistd.h>
- #include <string.h>
- #include <signal.h>
- #include <sys/wait.h>
- #include <errno.h>
- #include <arpa/inet.h>
- #define PROP "proprietario"
- void atende_pedido(int);
- int prepara_socket_servidor(int the_port);
- int the_ncontrol = 0;
- void sigchld_handler(int signum)
- {
- int the_pid; // the process identification
- // wait for process termination
- while((the_pid = waitpid(-1, NULL, WNOHANG)) > 0)
- {
- printf("processo filho %d terminado\n", the_pid);
- the_ncontrol--;
- }
- }
- // server socket PF_INET
- // communication type SOCK_STREAM
- int main (int argc, const char * argv[])
- {
- int the_ns;
- struct sockaddr_in the_client_address;
- unsigned int the_client_length;
- struct sigaction the_signal;
- the_signal.sa_handler = sigchld_handler;
- the_signal.sa_flags = SA_NOCLDSTOP;
- sigemptyset(&(the_signal.sa_mask));
- sigaction(SIGCHLD, &the_signal, NULL);
- if (argc != 2)
- {
- printf("utilizacao: %s numero_porta\n", argv[0]);
- exit(1);
- }
- // atoi: convert ASCII string to integer
- int the_socket = prepara_socket_servidor(atoi(argv[1]));
- the_client_length = sizeof(the_client_address);
- while(1)
- {
- printf("aguardar ligacao\n");
- // accept/reject jobs sent to a destination
- the_ns = accept(the_socket, (struct sockaddr *) &the_client_address, &the_client_length);
- // accept interrupt control
- if ((the_ns < 0) && (errno == EINTR))
- {
- continue;
- }
- printf("ligacao de %s\n", inet_ntoa(*((struct in_addr *) &(the_client_address.sin_addr))));
- atende_pedido(the_ns);
- }
- return 0;
- }
- int prepara_socket_servidor(int the_port)
- {
- struct sockaddr_in the_server_address;
- // create an endpoint for communication
- int the_socket = socket(PF_INET, SOCK_STREAM, 0);
- if (the_socket < 0)
- {
- perror("erro no socket");
- exit(1);
- }
- // fill a byte string with a byte value
- memset(&the_server_address, 0, sizeof(the_server_address));
- the_server_address.sin_family = AF_INET;
- the_server_address.sin_addr.s_addr = INADDR_ANY;
- the_server_address.sin_port = htons(the_port);
- if (bind(the_socket, (struct sockaddr *)&the_server_address, sizeof(the_server_address)) < 0)
- {
- perror("erro na ligacao");
- exit(1);
- }
- // listen for connections on a socket
- listen(the_socket, 5);
- return the_socket;
- }
- void atende_pedido(int ns)
- {
- veiculo_t v1;
- char matricula[8];
- int the_pid; // the process identification
- struct sigaction the_signal;
- the_signal.sa_handler = sigchld_handler;
- the_signal.sa_flags = SA_NOCLDSTOP;
- sigemptyset(&(the_signal.sa_mask));
- FILE *the_record;
- // stream open function
- FILE *the_fp = fdopen(ns, "r+");
- if (the_fp == NULL)
- {
- perror("fdopen");
- close(ns);
- return;
- }
- // get next character or word from input stream
- char the_option = fgetc(the_fp);
- switch(the_option)
- {
- case '1':
- the_record = fopen(PROP, "a+");
- fread(&v1, sizeof(v1), 1, the_fp);
- // simplified software signal facilities
- signal(SIGCHLD, SIG_DFL);
- while(the_ncontrol > 0)
- {
- wait(NULL);
- the_ncontrol--;
- }
- fwrite(&v1, sizeof(v1), 1, the_record);
- fclose(the_record);
- // software signal facilities
- sigaction(SIGCHLD, &the_signal, NULL);
- break;
- case'2':
- the_ncontrol++;
- // create a new process
- the_pid = fork();
- if (the_pid == 0)
- {
- the_record = fopen(PROP, "a+");
- // binary stream input/output
- while(fread(&v1, sizeof(v1), 1, the_record) != 0)
- {
- if (v1.apagado == '0')
- {
- fwrite(&v1, sizeof(v1), 1, the_fp);
- // flush a stream
- fflush(the_fp);
- // suspend execution for an interval of time
- sleep(5);
- }
- }
- fclose(the_record);
- fclose(the_fp);
- exit(0);
- }
- break;
- case'3':
- // binary stream input/output
- fread(matricula, 8, 1, the_fp);
- the_record = fopen(PROP, "r+");
- apagar_registo(matricula, the_record);
- fclose(the_record);
- break;
- }
- fclose(the_fp);
- }
- //
- // main.c
- // cliente
- #include "func.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <unistd.h>
- #include <string.h>
- FILE *ligar_ao_servidor(struct hostent* the_host_info, int the_port)
- {
- // create an endpoint for communication
- int the_socket = socket(PF_INET, SOCK_STREAM, 0);
- if (the_socket < 0)
- {
- perror("erro no socket");
- return NULL;
- }
- struct sockaddr_in the_address;
- // fill a byte string with a byte value
- memset(&the_address, 0, sizeof(the_address));
- the_address.sin_family = AF_INET;
- the_address.sin_addr = *((struct in_addr *)the_host_info->h_addr);
- the_address.sin_port = htons(the_port);
- // initiate a connection on a socket
- if (connect(the_socket, (struct sockaddr *) &the_address, sizeof(struct sockaddr_in)) < 0)
- {
- perror("erro na ligacao");
- return NULL;
- }
- // stream open function
- FILE *the_fp = fdopen(the_socket, "r+");
- if (the_fp == NULL)
- {
- close(the_socket);
- }
- return the_fp;
- }
- int main (int argc, const char * argv[])
- {
- veiculo_t v1;
- char the_matricula[8];
- FILE *the_fp;
- if (argc != 3)
- {
- printf("utilizacao: %s ip_servidor numero_porta\n",argv[0]);
- exit(1);
- }
- // do it once
- struct hostent *the_host_info = gethostbyname(argv[1]);
- int the_port = atoi(argv[2]);
- int the_option;
- do
- {
- printf("\n1: inserir registo");
- printf("\n2: visualizar registos");
- printf("\n3: apagar registo");
- printf("\n\n4: sair do programa\n");
- scanf("%d", &the_option);
- getchar();
- switch(the_option)
- {
- case 1:
- ler_registo(&v1);
- the_fp = ligar_ao_servidor(the_host_info, the_port);
- fputc('1', the_fp);
- fwrite(&v1, sizeof(v1), 1, the_fp);
- fclose(the_fp);
- break;
- case 2:
- the_fp = ligar_ao_servidor(the_host_info, the_port);
- fputc('2', the_fp);
- while(fread(&v1, sizeof(v1), 1, the_fp) !=0)
- {
- imprimir_registo(&v1);
- }
- fclose(the_fp);
- break;
- case 3:
- printf("\nmatricula: ");
- fgets(the_matricula, 8, stdin);
- the_fp = ligar_ao_servidor(the_host_info, the_port);
- fputc('3', the_fp);
- fwrite(the_matricula, 8, 1, the_fp);
- fclose(the_fp);
- break;
- case 4:
- break;
- default:
- printf("opcao invalida");
- break;
- }
- } while (the_option != 4);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement