Advertisement
paulogp

SISTC T3 - Criação dinâmica de processos

Jul 13th, 2011
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.11 KB | None | 0 0
  1. /* SISTC T3 - Criação dinâmica de processos
  2. Utilização das funções fork() e wait() para lidar com a criação e terminação de processos a partir de um programa */
  3.  
  4. // Apple Xcode
  5.  
  6.  
  7. //  func.c
  8. //  servidor / cliente
  9.  
  10. #include "func.h"
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <signal.h>
  15. #include <sys/wait.h>
  16. #include <errno.h>
  17.  
  18. void ler_registo(veiculo_t *v)
  19. {
  20.     char the_aux[8];
  21.  
  22.     printf("\nmatricula: ");
  23.     // get a line from a stream
  24.     fgets(the_aux, 8, stdin);
  25.     // copy memory area
  26.     memcpy(v->matricula, the_aux, 6);
  27.  
  28.     printf("\nproprietario: ");
  29.     // get a line from a stream
  30.     fgets(v->proprietario, NAME_BUFFER_SIZE, stdin);
  31.  
  32.     v->apagado = '0';
  33. }
  34.  
  35. void imprimir_registo(veiculo_t *v)
  36. {  
  37.     if (v->apagado == '0')
  38.     {
  39.         printf("\nproprietario\n %s ", v->proprietario);
  40.         printf("\n matricula\n");
  41.         fwrite(v->matricula, 6, 1, stdout);
  42.     }
  43. }
  44.  
  45. void apagar_registo(char matricula[], FILE *the_record)
  46. {  
  47.     veiculo_t v1;
  48.  
  49.     // binary stream input/output
  50.     while (fread(&v1, sizeof(v1), 1, the_record) != 0)
  51.     {
  52.         // compare strings
  53.         if (strncmp(matricula, v1.matricula, 6) == 0)
  54.         {
  55.             v1.apagado = '1';
  56.             // reposition a stream
  57.             fseek(the_record, -sizeof(v1), SEEK_CUR);
  58.             fwrite(&v1, sizeof(v1), 1, the_record);
  59.         }
  60.     }  
  61. }
  62.  
  63.  
  64. //
  65. //  func.h
  66. //  servidor / cliente
  67.  
  68. #include <stdio.h>
  69.  
  70. #define NAME_BUFFER_SIZE 80
  71.  
  72. typedef struct
  73. {
  74.     char matricula[6];
  75.     char proprietario[NAME_BUFFER_SIZE];
  76.     char apagado;
  77. } veiculo_t;
  78.  
  79. void ler_registo(veiculo_t *);
  80. void imprimir_registo(veiculo_t *);
  81. void apagar_registo(char *, FILE *);
  82.  
  83. void sigchld_handler(int );
  84.  
  85.  
  86.  
  87. //
  88. //  main.c
  89. //  servidor
  90.  
  91. #include "func.h"
  92.  
  93. #include <stdio.h>
  94. #include <stdlib.h>
  95. #include <netinet/in.h>
  96. #include <unistd.h>
  97. #include <string.h>
  98. #include <signal.h>
  99. #include <sys/wait.h>
  100. #include <errno.h>
  101. #include <arpa/inet.h>
  102.  
  103. #define PROP "proprietario"
  104.  
  105. void atende_pedido(int);
  106. int prepara_socket_servidor(int the_port);
  107.  
  108. int the_ncontrol = 0;
  109.  
  110. void sigchld_handler(int signum)
  111. {
  112.     int the_pid; // the process identification
  113.  
  114.     // wait for process termination
  115.     while((the_pid = waitpid(-1, NULL, WNOHANG)) > 0)
  116.     {
  117.         printf("processo filho %d terminado\n", the_pid);
  118.         the_ncontrol--;
  119.     }  
  120. }
  121.  
  122. // server socket PF_INET
  123. // communication type SOCK_STREAM
  124. int main (int argc, const char * argv[])
  125. {
  126.     int the_ns;
  127.  
  128.     struct sockaddr_in the_client_address;
  129.     unsigned int the_client_length;
  130.  
  131.     struct sigaction the_signal;
  132.  
  133.     the_signal.sa_handler = sigchld_handler;
  134.     the_signal.sa_flags = SA_NOCLDSTOP;
  135.     sigemptyset(&(the_signal.sa_mask));
  136.     sigaction(SIGCHLD, &the_signal, NULL);
  137.  
  138.     if (argc != 2)
  139.     {
  140.         printf("utilizacao: %s numero_porta\n", argv[0]);
  141.         exit(1);
  142.     }
  143.  
  144.     // atoi: convert ASCII string to integer
  145.     int the_socket = prepara_socket_servidor(atoi(argv[1]));
  146.    
  147.     the_client_length = sizeof(the_client_address);
  148.  
  149.     while(1)
  150.     {
  151.         printf("aguardar ligacao\n");
  152.  
  153.         // accept/reject jobs sent to a destination
  154.         the_ns = accept(the_socket, (struct sockaddr *) &the_client_address, &the_client_length);
  155.  
  156.         // accept interrupt control
  157.         if ((the_ns < 0) && (errno == EINTR))
  158.         {
  159.             continue;
  160.         }
  161.  
  162.         printf("ligacao de %s\n", inet_ntoa(*((struct in_addr *) &(the_client_address.sin_addr))));
  163.         atende_pedido(the_ns);
  164.     }
  165.  
  166.     return 0;
  167. }
  168.  
  169. int prepara_socket_servidor(int the_port)
  170. {
  171.     struct sockaddr_in the_server_address;
  172.  
  173.     // create an endpoint for communication
  174.     int the_socket = socket(PF_INET, SOCK_STREAM, 0);
  175.  
  176.     if (the_socket < 0)
  177.     {
  178.         perror("erro no socket");
  179.         exit(1);
  180.     }
  181.  
  182.     // fill a byte string with a byte value
  183.     memset(&the_server_address, 0, sizeof(the_server_address));
  184.     the_server_address.sin_family = AF_INET;
  185.     the_server_address.sin_addr.s_addr = INADDR_ANY;
  186.     the_server_address.sin_port = htons(the_port);
  187.  
  188.     if (bind(the_socket, (struct sockaddr *)&the_server_address, sizeof(the_server_address)) < 0)
  189.     {
  190.         perror("erro na ligacao");
  191.         exit(1);
  192.     }    
  193.  
  194.     // listen for connections on a socket
  195.     listen(the_socket, 5);
  196.  
  197.     return the_socket;
  198. }
  199.  
  200. void atende_pedido(int ns)
  201. {
  202.     veiculo_t v1;
  203.     char matricula[8];
  204.     int the_pid; // the process identification
  205.  
  206.     struct sigaction the_signal;
  207.     the_signal.sa_handler = sigchld_handler;
  208.     the_signal.sa_flags = SA_NOCLDSTOP;
  209.     sigemptyset(&(the_signal.sa_mask));
  210.  
  211.     FILE *the_record;
  212.  
  213.     // stream open function
  214.     FILE *the_fp = fdopen(ns, "r+");
  215.  
  216.     if (the_fp == NULL)
  217.     {
  218.         perror("fdopen");
  219.         close(ns);
  220.         return;
  221.     }
  222.  
  223.     // get next character or word from input stream
  224.     char the_option = fgetc(the_fp);
  225.  
  226.     switch(the_option)
  227.     {
  228.         case '1':
  229.             the_record = fopen(PROP, "a+");
  230.             fread(&v1, sizeof(v1), 1, the_fp);
  231.  
  232.             // simplified software signal facilities
  233.             signal(SIGCHLD, SIG_DFL);
  234.  
  235.             while(the_ncontrol > 0)
  236.             {
  237.                 wait(NULL);
  238.                 the_ncontrol--;
  239.             }
  240.  
  241.             fwrite(&v1, sizeof(v1), 1, the_record);
  242.             fclose(the_record);
  243.  
  244.             // software signal facilities
  245.             sigaction(SIGCHLD, &the_signal, NULL); 
  246.         break;
  247.  
  248.         case'2':
  249.             the_ncontrol++;
  250.  
  251.             // create a new process
  252.             the_pid = fork();
  253.  
  254.             if (the_pid == 0)
  255.             {
  256.                 the_record = fopen(PROP, "a+");
  257.  
  258.                 // binary stream input/output
  259.                 while(fread(&v1, sizeof(v1), 1, the_record) != 0)
  260.                 {  
  261.                     if (v1.apagado == '0')
  262.                     {
  263.                         fwrite(&v1, sizeof(v1), 1, the_fp);
  264.  
  265.                         // flush a stream
  266.                         fflush(the_fp);
  267.  
  268.                         // suspend execution for an interval of time
  269.                         sleep(5);
  270.                     }
  271.                 }
  272.  
  273.                 fclose(the_record);
  274.                 fclose(the_fp);
  275.  
  276.                 exit(0);
  277.             }
  278.         break;
  279.  
  280.         case'3':
  281.             // binary stream input/output
  282.             fread(matricula, 8, 1, the_fp);
  283.  
  284.             the_record = fopen(PROP, "r+");
  285.             apagar_registo(matricula, the_record);
  286.  
  287.             fclose(the_record);    
  288.         break;
  289.     }
  290.  
  291.     fclose(the_fp);
  292. }
  293.  
  294.  
  295.  
  296. //
  297. //  main.c
  298. //  cliente
  299.  
  300. #include "func.h"
  301.  
  302. #include <stdio.h>
  303. #include <stdlib.h>
  304. #include <netinet/in.h>
  305. #include <netdb.h>
  306. #include <unistd.h>
  307. #include <string.h>
  308.  
  309. FILE *ligar_ao_servidor(struct hostent* the_host_info, int the_port)
  310. {
  311.     // create an endpoint for communication
  312.     int the_socket = socket(PF_INET, SOCK_STREAM, 0);
  313.  
  314.     if (the_socket < 0)
  315.     {
  316.         perror("erro no socket");
  317.         return NULL;
  318.     }
  319.  
  320.     struct sockaddr_in the_address;
  321.     // fill a byte string with a byte value
  322.     memset(&the_address, 0, sizeof(the_address));
  323.     the_address.sin_family = AF_INET;
  324.     the_address.sin_addr = *((struct in_addr *)the_host_info->h_addr);
  325.     the_address.sin_port = htons(the_port);
  326.  
  327.     // initiate a connection on a socket
  328.     if (connect(the_socket, (struct sockaddr *) &the_address, sizeof(struct sockaddr_in)) < 0)
  329.     {
  330.         perror("erro na ligacao");
  331.         return NULL;
  332.     }
  333.  
  334.     // stream open function
  335.     FILE *the_fp = fdopen(the_socket, "r+");
  336.  
  337.     if (the_fp == NULL)
  338.     {
  339.         close(the_socket);
  340.     }
  341.  
  342.     return the_fp;
  343. }
  344.  
  345. int main (int argc, const char * argv[])
  346. {
  347.     veiculo_t v1;
  348.  
  349.     char the_matricula[8];
  350.     FILE *the_fp;
  351.  
  352.     if (argc != 3)
  353.     {
  354.         printf("utilizacao: %s ip_servidor numero_porta\n",argv[0]);
  355.         exit(1);
  356.     }
  357.  
  358.     // do it once
  359.     struct hostent *the_host_info = gethostbyname(argv[1]);  
  360.     int the_port = atoi(argv[2]);
  361.  
  362.     int the_option;
  363.  
  364.     do
  365.     {  
  366.         printf("\n1: inserir registo");
  367.         printf("\n2: visualizar registos");
  368.         printf("\n3: apagar registo");
  369.         printf("\n\n4: sair do programa\n");
  370.  
  371.         scanf("%d", &the_option);
  372.         getchar();
  373.  
  374.         switch(the_option)
  375.         {
  376.             case 1:
  377.                 ler_registo(&v1);
  378.                 the_fp = ligar_ao_servidor(the_host_info, the_port);
  379.                 fputc('1', the_fp);
  380.                 fwrite(&v1, sizeof(v1), 1, the_fp);
  381.                 fclose(the_fp);    
  382.             break;
  383.  
  384.             case 2:
  385.                 the_fp = ligar_ao_servidor(the_host_info, the_port);
  386.                 fputc('2', the_fp);
  387.                 while(fread(&v1, sizeof(v1), 1, the_fp) !=0)
  388.                 {
  389.                     imprimir_registo(&v1);
  390.                 }
  391.                 fclose(the_fp);
  392.             break;
  393.  
  394.             case 3:
  395.                 printf("\nmatricula: ");
  396.                 fgets(the_matricula, 8, stdin);
  397.                 the_fp = ligar_ao_servidor(the_host_info, the_port);
  398.                 fputc('3', the_fp);
  399.                 fwrite(the_matricula, 8, 1, the_fp);
  400.                 fclose(the_fp);
  401.             break;
  402.  
  403.             case 4:
  404.                 break;
  405.  
  406.             default:
  407.                 printf("opcao invalida");
  408.             break;
  409.         }
  410.     } while (the_option != 4);
  411.  
  412.     return 0;
  413. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement