ENUNCIADO
Hay que hacer un programa que se llame correo
.
A este programa se le puede pasar tres tipos de opciones por
la línea de órdenes:
- Nada: imprimirá la forma de uso.
-e tipo "mensaje"
: el
programa enviará a un buzón
el mensaje mensaje con el tipo tipo.
-r tipo
: el programa recibirá
un mensaje
del tipo tipo. Si no lo hay, se quedará
bloqueado.
COMENTARIOS
La primera en llegar y que ya reunía los requisitos para ser
publicada es de Caleveríntico (0.25 ptos):
#define _HPUX_SOURCE
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <string.h>
#include <pwd.h>
#define LONGITUD_MAXIMA 80
void error(int,char *[]);
/* Observad cómo, no sé si por error o a
propósito, los nombres de los argumentos
del main están cambiados. Ya debéis saber
que estos nombres son convencionales y no
es obligatorio su uso, aunque sí conveniente.
Espero que esto no os líe. */
int main(int argv,char *argc[])
{
key_t clave;
int buzon,envio,recibo;
char etiqueta[100];
struct passwd *informe;
struct tipo_mensaje
{
long tipo;
char remite[12];
char msg[LONGITUD_MAXIMA];
} mensaje;
if (argv==3 && strcmp(argc[1],"-r")) error(argv,argc);
if (argv==4 && strcmp(argc[1],"-e")) error(argv,argc);
if (argv!=3 && argv!=4) error(argv,argc);
/* consigo clave común */
clave=ftok("/bin/ls",'q');
/* consigo el identificador del buzon común.
permisos: lectura para todos */
buzon=msgget(clave,IPC_CREAT|0444);
if (buzon==-1)
{
perror("No se puede crear/encontrar el buzon");
return 10;
}
/* si envío */
if (!strcmp(argc[1],"-e")) /* strcmp devuelve 0 (falso) si las cadenas son iguales. */
{
mensaje.tipo=strtol(argc[2],NULL,10); /* lo mismo que la función atol. */
/* recupero la estructura passwd donde está el nombre */
informe=getpwuid(getuid());
strcpy(mensaje.remite,informe->pw_name);
strcpy(mensaje.msg,argc[3]);
envio=msgsnd(buzon,&mensaje,sizeof(struct tipo_mensaje)-sizeof(long),
IPC_NOWAIT);
/* Esta función merece un comentario aparte.
La función msgsnd sólo se queda bloqueada si el buzón
está momentáneamente lleno. ¿Qué es lo que queremos?
Que si el buzón está lleno nos dé un error (déjese
entonces como está) o que el programa se quede
bloqueado hasta que pulsemos CTRL+C o se vacíe
(sustitúyase IPC_NOWAIT por 0). */
if (envio==-1)
{
perror("Fallo en el envio");
return 2;
}
}
/* si recibo */
if (!strcmp(argc[1],"-r"))
{
mensaje.tipo=strtol(argc[2],NULL,10);
recibo=msgrcv(buzon,&mensaje,
sizeof(struct tipo_mensaje)-sizeof(long),mensaje.tipo,
MSG_NOERROR);
if (recibo==-1)
{
perror("Fallo en la recepcion");
return 3;
}
printf("%s: %s\n",mensaje.remite,mensaje.msg);
}
}
void error(int argv,char *argc[])
{
fprintf(stderr,"Sintaxis incorrecta\n");
fprintf(stderr,"Uso:\n");
fprintf(stderr,"Envío: correo -e [NÚMERO BUZÓN] \"MENSAJE\"\n");
fprintf(stderr,"Recepción: correo -r [NÚMERO BUZÓN]\n");
exit(1);
}
© 2000 Guillermo González Talaván.