Bokens exempelprogram
This commit is contained in:
commit
9fd3ac4a26
60
daemon-ex1.c
Normal file
60
daemon-ex1.c
Normal file
@ -0,0 +1,60 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
pid_t process_id = 0;
|
||||
pid_t sid = 0;
|
||||
|
||||
/* Skapa barn/child process */
|
||||
process_id = fork();
|
||||
|
||||
/* Hantera eventuellt fel vid fork() */
|
||||
if (process_id < 0)
|
||||
{
|
||||
fprintf(stderr, "fork failed!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Förälderprocessen/parent process.
|
||||
Avsluta den eftersom allt arbete kommer att
|
||||
utföras av demonen. Skriv också ut demonens PID */
|
||||
else if (process_id > 0)
|
||||
{
|
||||
printf("Daemon process: %d \n", process_id);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Sätt umask till 000 så att alla kan komma eventuella
|
||||
filer skapade av demonen. Anpassas efter vad demonen
|
||||
ska användas till */
|
||||
umask(0);
|
||||
/* Starta en ny session */
|
||||
sid = setsid();
|
||||
|
||||
if(sid < 0)
|
||||
{
|
||||
/* Avsluta ifall det inte gick att skapa en ny
|
||||
session */
|
||||
fprintf(stderr, "Failure to set new session\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Ändra aktuell katalog till / */
|
||||
chdir("/");
|
||||
|
||||
/* Stäng stdin, stdout och stderr. Dessa behövs inte
|
||||
i en demonprocess */
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
|
||||
/* Här börjar demonens arbete... */
|
||||
for(;;)
|
||||
{
|
||||
sleep(5);
|
||||
}
|
||||
}
|
96
daemon-sig-ex1.c
Normal file
96
daemon-sig-ex1.c
Normal file
@ -0,0 +1,96 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
|
||||
void sigHandler(int sig);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
pid_t process_id = 0;
|
||||
pid_t sid = 0;
|
||||
FILE *fp;
|
||||
char pidfile[] = "/tmp/daemon-sig-ex.pid";
|
||||
|
||||
/* Skapa barn/child process */
|
||||
process_id = fork();
|
||||
|
||||
/* Hantera eventuellt fel vid fork() */
|
||||
if (process_id < 0)
|
||||
{
|
||||
fprintf(stderr, "fork misslyckades!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Förälderprocessen/parent process.
|
||||
Avsluta den eftersom allt arbete kommer att
|
||||
utföras av demonen. Skriv också ut demonens PID */
|
||||
else if (process_id > 0)
|
||||
{
|
||||
printf("Demonens PID: %d \n", process_id);
|
||||
fp = fopen(pidfile, "w");
|
||||
fprintf(fp, "%d", process_id);
|
||||
fclose(fp);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Sätt umask till 000 så att alla kan komma eventuella
|
||||
filer skapade av demonen. Anpassas efter vad demonen
|
||||
ska användas till */
|
||||
umask(0);
|
||||
/* Starta en ny session */
|
||||
sid = setsid();
|
||||
|
||||
if(sid < 0)
|
||||
{
|
||||
/* Avsluta ifall det inte gick att skapa en ny
|
||||
session */
|
||||
fprintf(stderr, "Misslyckades att skapa en ny session\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Ändra aktuell katalog till / */
|
||||
chdir("/");
|
||||
|
||||
/* Stäng stdin, stdout och stderr. Dessa behövs inte
|
||||
i en demonprocess */
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
|
||||
/* Registrera signalhanterarna, en för varje signal
|
||||
som vi vill fånga upp */
|
||||
signal(SIGUSR1, sigHandler);
|
||||
signal(SIGTERM, sigHandler);
|
||||
|
||||
/* Demonens arbete... */
|
||||
for(;;)
|
||||
{
|
||||
sleep(5);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sigHandler(int sig)
|
||||
{
|
||||
if (sig == SIGUSR1)
|
||||
{
|
||||
/* Skriv till syslog-demonen */
|
||||
syslog(LOG_DAEMON, "Tog emot SIGUSR1");
|
||||
}
|
||||
else if (sig == SIGTERM)
|
||||
{
|
||||
/* Samma som ovan */
|
||||
syslog(LOG_DAEMON, "Tog emot SIGTERM");
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_DAEMON, "Någonting hände med demonen...");
|
||||
}
|
||||
/* Signalhanteraren återställs efter första signalen,
|
||||
vi måste därför sätta den igen */
|
||||
signal(sig, sigHandler);
|
||||
}
|
110
daemon-sig-ex2.c
Normal file
110
daemon-sig-ex2.c
Normal file
@ -0,0 +1,110 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
|
||||
char pidfile[] = "/tmp/daemon-sig-ex.pid";
|
||||
|
||||
void sigHandler(int sig);
|
||||
void shutDown(int sig);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
pid_t process_id = 0;
|
||||
pid_t sid = 0;
|
||||
FILE *fp;
|
||||
|
||||
/* Skapa barn/child process */
|
||||
process_id = fork();
|
||||
|
||||
/* Hantera eventuellt fel vid fork() */
|
||||
if (process_id < 0)
|
||||
{
|
||||
fprintf(stderr, "fork misslyckades!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Förälderprocessen/parent process.
|
||||
Avsluta den eftersom allt arbete kommer att
|
||||
utföras av demonen. Skriv också ut demonens PID */
|
||||
else if (process_id > 0)
|
||||
{
|
||||
printf("Demonens PID: %d \n", process_id);
|
||||
fp = fopen(pidfile, "w");
|
||||
fprintf(fp, "%d", process_id);
|
||||
fclose(fp);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Sätt umask till 000 så att alla kan komma eventuella
|
||||
filer skapade av demonen. Anpassas efter vad demonen
|
||||
ska användas till */
|
||||
umask(0);
|
||||
/* Starta en ny session */
|
||||
sid = setsid();
|
||||
|
||||
if(sid < 0)
|
||||
{
|
||||
/* Avsluta ifall det inte gick att skapa en ny
|
||||
session */
|
||||
fprintf(stderr, "Misslyckades att skapa en ny session\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Ändra aktuell katalog till / */
|
||||
chdir("/");
|
||||
|
||||
/* Stäng stdin, stdout och stderr. Dessa behövs inte
|
||||
i en demonprocess */
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
|
||||
/* Registrera signalhanterarna, en för varje signal
|
||||
som vi vill fånga upp */
|
||||
signal(SIGUSR1, sigHandler);
|
||||
signal(SIGTERM, sigHandler);
|
||||
signal(SIGABRT, shutDown);
|
||||
signal(SIGQUIT, shutDown);
|
||||
signal(SIGINT, shutDown);
|
||||
|
||||
/* Demonens arbete... */
|
||||
for(;;)
|
||||
{
|
||||
sleep(5);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sigHandler(int sig)
|
||||
{
|
||||
if (sig == SIGUSR1)
|
||||
{
|
||||
/* Skriv till syslog-demonen */
|
||||
syslog(LOG_DAEMON, "Tog emot SIGUSR1");
|
||||
}
|
||||
else if (sig == SIGTERM)
|
||||
{
|
||||
/* Samma som ovan */
|
||||
syslog(LOG_DAEMON, "Tog emot SIGTERM");
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_DAEMON, "Någonting hände med demonen...");
|
||||
}
|
||||
/* Signalhanteraren återställs efter första signalen,
|
||||
vi måste därför sätta den igen */
|
||||
signal(sig, sigHandler);
|
||||
}
|
||||
|
||||
void shutDown(int sig)
|
||||
{
|
||||
syslog(LOG_DAEMON, "Demonens avslutas");
|
||||
/* Ta bort PID-filen efter oss */
|
||||
if ( unlink(pidfile) == -1 )
|
||||
syslog(LOG_DAEMON, "Kunde inte ta bort PID-filen");
|
||||
exit(0);
|
||||
}
|
74
fifo-ex1.c
Normal file
74
fifo-ex1.c
Normal file
@ -0,0 +1,74 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define FIFONAM "/tmp/testfifo"
|
||||
|
||||
/* Skapa fifofd i det globala scopet så att
|
||||
vi kan stänga den ifrån signalhanteraren. */
|
||||
int fifofd;
|
||||
|
||||
void cleanUp(int signum);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char msg[] = "Ett meddelande till klienterna\n";
|
||||
|
||||
/* Registrera signalhanterare för vanliga "avsluts-signaler" */
|
||||
signal(SIGINT, cleanUp);
|
||||
signal(SIGQUIT, cleanUp);
|
||||
signal(SIGABRT, cleanUp);
|
||||
signal(SIGTERM, cleanUp);
|
||||
/* Skapa FIFOn. S_IWUSR och S_IRUSR är detsamma som för
|
||||
open() och creat() */
|
||||
if ( mkfifo(FIFONAM, S_IWUSR | S_IRUSR) != 0)
|
||||
{
|
||||
if (errno == EEXIST)
|
||||
{
|
||||
fprintf(stderr, "FIFOn finns redan, använder den\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("mkfifo");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Kör i en oändlig loop */
|
||||
while(1)
|
||||
{
|
||||
fifofd = open(FIFONAM, O_WRONLY);
|
||||
if (fifofd < 0)
|
||||
{
|
||||
perror("open");
|
||||
return 1;
|
||||
}
|
||||
|
||||
write(fifofd, msg, sizeof(msg));
|
||||
sleep(1); /* Vänta en sekund mellan varje körning */
|
||||
}
|
||||
/* Hit bör vi aldrig komma, men fall i fall så städar vi upp */
|
||||
unlink(FIFONAM);
|
||||
close(fifofd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cleanUp(int signum)
|
||||
{
|
||||
/* Ständ fildeskriptorn */
|
||||
if ( close(fifofd) == -1 )
|
||||
perror("cleanUp - close");
|
||||
|
||||
/* Radera FIFO-filen från systemet & avsluta programmet */
|
||||
if ( unlink(FIFONAM) == -1 )
|
||||
{
|
||||
perror("cleanUp - unlink");
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
45
my-msg-recv-rm.c
Normal file
45
my-msg-recv-rm.c
Normal file
@ -0,0 +1,45 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX 100
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Struktur som krävs av msgsnd & msgrcv */
|
||||
struct msgbuf
|
||||
{
|
||||
long mtype;
|
||||
char mtext[MAX];
|
||||
};
|
||||
|
||||
int id;
|
||||
key_t key = 12345;
|
||||
struct msgbuf msg;
|
||||
msg.mtext[0] = '\0';
|
||||
|
||||
/* Kalla msgget för att få ett ID-nummer till kön.
|
||||
Observera att vi här utelämnar IPC_CREAT. */
|
||||
if ( (id = msgget(key, 0660)) < 0 )
|
||||
{
|
||||
fprintf(stderr, "Could not open message queue\n");
|
||||
perror("msgget");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Ta emot meddelandet och spara det i msg */
|
||||
if ( msgrcv(id, &msg, MAX, 1, 0) < 0 )
|
||||
{
|
||||
fprintf(stderr, "Could not receive messages\n");
|
||||
perror("msgrcv");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Skriv ut meddelandet */
|
||||
printf("%s\n", msg.mtext);
|
||||
msgctl(id, IPC_RMID, 0);
|
||||
return 0;
|
||||
}
|
45
my-msg-recv.c
Normal file
45
my-msg-recv.c
Normal file
@ -0,0 +1,45 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX 100
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Struktur som krävs av msgsnd & msgrcv */
|
||||
struct msgbuf
|
||||
{
|
||||
long mtype;
|
||||
char mtext[MAX];
|
||||
};
|
||||
|
||||
int id;
|
||||
key_t key = 12345;
|
||||
struct msgbuf msg;
|
||||
msg.mtext[0] = '\0';
|
||||
|
||||
/* Kalla msgget för att få ett ID-nummer till kön.
|
||||
Observera att vi här utelämnar IPC_CREAT. */
|
||||
if ( (id = msgget(key, 0660)) < 0 )
|
||||
{
|
||||
fprintf(stderr, "Could not open message queue\n");
|
||||
perror("msgget");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Ta emot meddelandet och spara det i msg */
|
||||
if ( msgrcv(id, &msg, MAX, 1, 0) < 0 )
|
||||
{
|
||||
fprintf(stderr, "Could not receive messages\n");
|
||||
perror("msgrcv");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Skriv ut meddelandet */
|
||||
printf("%s\n", msg.mtext);
|
||||
|
||||
return 0;
|
||||
}
|
53
my-msg-send.c
Normal file
53
my-msg-send.c
Normal file
@ -0,0 +1,53 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX 100
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Struktur som krävs av msgsnd & msgrcv */
|
||||
struct msgbuf
|
||||
{
|
||||
long mtype;
|
||||
char mtext[MAX];
|
||||
};
|
||||
|
||||
/* Variabler vi behöver */
|
||||
int id;
|
||||
key_t key = 12345;
|
||||
struct msgbuf msg;
|
||||
size_t msglen;
|
||||
msg.mtext[0] = '\0';
|
||||
|
||||
/* Kalla msgget för att få ett ID-nummer till kön.
|
||||
IPC_CREAT är flaggan för att skapa en kö. 0660
|
||||
är rättigheterna för kön */
|
||||
if ( (id = msgget(key, IPC_CREAT | 0660)) < 0 )
|
||||
{
|
||||
fprintf(stderr, "Could not create message queue\n");
|
||||
perror("msgget");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Komponera ett testmeddelande. mtype är till för att
|
||||
identifiera just detta meddelandet i kön. mtext är
|
||||
det faktiska innehållet och msglen är längden på
|
||||
meddelandet */
|
||||
msg.mtype = 1;
|
||||
strcat(msg.mtext, "Hejsan svejsan");
|
||||
msglen = strlen(msg.mtext) + 1;
|
||||
|
||||
/* Skicka meddelandet */
|
||||
if ( msgsnd(id, &msg, msglen, IPC_NOWAIT) < 0 )
|
||||
{
|
||||
fprintf(stderr, "Could not send message\n");
|
||||
perror("msgsend");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
61
sig-client.c
Normal file
61
sig-client.c
Normal file
@ -0,0 +1,61 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <getopt.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
void printUsage(char *arg);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
FILE *fp;
|
||||
int opt;
|
||||
pid_t process_id;
|
||||
char pidfile[] = "/tmp/daemon-sig-ex.pid";
|
||||
|
||||
/* Kontrollera ifall PID-filen finns */
|
||||
if ( (fp = fopen(pidfile, "r")) == 0 )
|
||||
{
|
||||
fprintf(stderr, "Ingen PID-fil, körs verkligen demonen?\n");
|
||||
return 1;
|
||||
}
|
||||
/* Läs in PID till process_id variabeln */
|
||||
fscanf(fp, "%d", &process_id);
|
||||
|
||||
/* Om inga argument angavs, skriv ut demonens PID */
|
||||
if (argc == 1)
|
||||
printf("Demonen körs med PID: %d\n", process_id);
|
||||
|
||||
/* Behandla argument till programmet */
|
||||
while ((opt = getopt(argc, argv, "utqh")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'u':
|
||||
kill(process_id, SIGUSR1);
|
||||
break;
|
||||
case 't':
|
||||
kill(process_id, SIGTERM);
|
||||
break;
|
||||
case 'q':
|
||||
kill(process_id, SIGQUIT);
|
||||
break;
|
||||
case 'h':
|
||||
printUsage(argv[0]);
|
||||
return 0;
|
||||
default:
|
||||
printUsage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void printUsage(char *arg)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-u] [-t] [-q] [-h]\n"
|
||||
"-u = send SIGUSR1 to daemon\n"
|
||||
"-t = send SIGTERM to daemon\n"
|
||||
"-q = send SIGQUIT to quit the daemon\n"
|
||||
"-h = display help\n", arg);
|
||||
}
|
100
simple-ls-ver1.c
Normal file
100
simple-ls-ver1.c
Normal file
@ -0,0 +1,100 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
void printUsage(char *arg);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int typ;
|
||||
char opt[5] = { 0 };
|
||||
|
||||
/* Skapa pekare och struct */
|
||||
DIR *d;
|
||||
struct dirent *dir;
|
||||
struct stat s;
|
||||
|
||||
/* Läs in aktuell katalog */
|
||||
d = opendir(".");
|
||||
/* Om 'd' INTE är sant (! = inte sant) */
|
||||
if (!d)
|
||||
{
|
||||
printf("Kan inte läsa aktuell katalog\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Behandla arugment */
|
||||
if (argc == 1)
|
||||
{
|
||||
strncpy(opt, "-a", 2);
|
||||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
strncpy(opt, argv[1], 2);
|
||||
|
||||
/* Hjälptext */
|
||||
if ( strcmp(opt, "-h") == 0 )
|
||||
printUsage(argv[0]);
|
||||
|
||||
/* Visa endast filer */
|
||||
else if ( strcmp(opt, "-f") == 0 )
|
||||
{
|
||||
typ = S_IFREG;
|
||||
}
|
||||
|
||||
/* Visa endast kataloger */
|
||||
else if ( strcmp(opt, "-d") == 0 )
|
||||
{
|
||||
typ = S_IFDIR;
|
||||
}
|
||||
|
||||
/* Visa alla filer */
|
||||
else if ( strcmp(opt, "-a") == 0 )
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
/* Om vi angav ett felaktigt argument */
|
||||
else
|
||||
{
|
||||
printUsage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* Om vi angav fel antal argument */
|
||||
else
|
||||
{
|
||||
printUsage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Skriv ut innehållet i katalogen */
|
||||
while ((dir = readdir(d)) != NULL)
|
||||
{
|
||||
if ( strcmp(opt, "-a") == 0 )
|
||||
{
|
||||
printf("%s\n", dir->d_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
stat(dir->d_name, &s);
|
||||
/* Se kapitlet om 'Bitvisa operationer' */
|
||||
if ((s.st_mode & S_IFMT) == typ)
|
||||
printf("%s\n", dir->d_name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Stäng "d" och returnera noll */
|
||||
closedir(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void printUsage(char *arg)
|
||||
{
|
||||
printf("Usage: %s [-a] [-f] [-d]\n"
|
||||
" -a to list all types (default)\n"
|
||||
" -f to list only files\n"
|
||||
" -d to list only directories\n", arg);
|
||||
}
|
75
simple-ls-ver2.c
Normal file
75
simple-ls-ver2.c
Normal file
@ -0,0 +1,75 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
void printUsage(char *arg);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
int typ = -1;
|
||||
char *path = ".";
|
||||
|
||||
/* Skapa pekare och struct */
|
||||
DIR *d;
|
||||
struct dirent *dir;
|
||||
struct stat s;
|
||||
|
||||
/* Behandla argument med getopt */
|
||||
while ((opt = getopt(argc, argv, "hafdp:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'a':
|
||||
typ = -1;
|
||||
break;
|
||||
case 'f':
|
||||
typ = S_IFREG;
|
||||
break;
|
||||
case 'd':
|
||||
typ = S_IFDIR;
|
||||
break;
|
||||
case 'p':
|
||||
path = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
printUsage(argv[0]);
|
||||
return 0;
|
||||
default:
|
||||
printUsage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Byt katalog med chdir() för att stat() ska
|
||||
se filerna i rätt katalog */
|
||||
chdir(path);
|
||||
|
||||
d = opendir(path);
|
||||
while ((dir = readdir(d)) != NULL)
|
||||
{
|
||||
if ( typ == -1 )
|
||||
{
|
||||
printf("%s\n", dir->d_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
stat(dir->d_name, &s);
|
||||
/* Se kapitlet om 'Bitvisa operationer' */
|
||||
if ((s.st_mode & S_IFMT) == typ)
|
||||
printf("%s\n", dir->d_name);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void printUsage(char *arg)
|
||||
{
|
||||
printf("Usage: %s [-a] [-f] [-d] [-p path]\n"
|
||||
" -a to list all types (default)\n"
|
||||
" -f to list only files\n"
|
||||
" -d to list only directories\n"
|
||||
" -p to specify a directory\n", arg);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user