









Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Examples and explanations of various unix system concepts, including file i/o using open, read, write, lseek, and close functions, standard i/o using fopen, fread, fwrite, fseek, and fclose functions, unix directory structure, basic signal handling, using signals for timeouts, process creation, file sharing between processes, and executing processes. Examples of c programs illustrating these concepts.
Typology: Study notes
1 / 17
This page cannot be seen from the preview
Don't miss anything!










UNIX Systems Programming
(lectures programs)
Part 1: UNIX File System
Example 1: append.c
main(int argc, char **argv) { int n, in, out; char buf[1024];
/* Open the first file for reading */ in = open (argv[1], O_RDONLY);
/* Open the second file for writing */ out = open (argv[2], O_WRONLY | O_APPEND);
/* Copy data from the first file to the second */ while ((n = read (in, buf, sizeof(buf))) > 0) write out, buf, n); }
Examples of usage:
% touch t // creat empty file t % append append.c t // copies append.c to t % append append.c t // make another copy of append.c to t % append t t // endlessly copies t to t!
Example 2: seeker.c #define NSTRINGS 5 #define STRSIZE 3
char *strings[] = { "aaa", "bbb", "ccc", "ddd", "eee" };
main ....
{
int fd; fd = open ( fname, O_RDWR | O_CREAT | O_TRUNC, 0666 ); for (n = 0; n < NSTRINGS; n++) write(fd, strings[n], STRSIZE);
/* user provides the value of n */
lseek ( fd, (n-1) * STRSIZE, SEEK_SET );
read ( fd, buf, STRSIZE ); write(1, buf, STRSIZE);
}
Example 3: fseeker.c main .... { FILE *fp; fp = fopen(fname, "w+");
for (n = 0; n < NSTRINGS; n++) fwrite(strings[n], sizeof(char), STRSIZE, fp);
fseek(fp, (n-1) * STRSIZE, SEEK_SET);
fread(buf, sizeof(char), STRSIZE, fp);
printf("String %d = %.*s\n\n", n, STRSIZE, buf); } NOTE: you may use fdopen(fd) & fileno(fp) to convert between file pointer (fp) and file descriptor (fd).
Example: int fd; FILE *fp; fd = open ("filename", O_TRUNC | O_CREAT | O_WRONLY, 0777 ); fp = fdopen(fd, "w+"); fd = fileno(fp);
lstat(filename, &st); outputStatInfo(filename, d->d_name, &st); } }
Part 2: Signals
o kill (pid, sig)
To send a signal sig to a process pid (To list all available signals type: % kill -l )
o pause()
To wait for a signal
o signal (sig, handler)
To call the function handler when the signal sig occurs.
Example 6: signal1.c
main ... { signal(SIGUSR1, handler); signal(SIGUSR2, handler); for (;;) pause(); }
handler(int sig) { /* Print out what we received */ psignal(sig, "Received signal"); } Examples of usage:
% kill -l HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM USR1 USR CLD PWR WINCH URG POLL STOP TSTP CONT TTIN TTOU VTALRM PROF XCPU XFSZ WAITING LWP FREEZE THAW CANCEL LOST RTMIN RTMIN+1 RTMIN+2 RTMIN+ RTMAX-3 RTMAX- RTMAX-1 RTMAX
% kill -USR1 12345 Recived signal: User Signal 1
% kill -16 12345 //signal #16 is USR Recived signal: User Signal 1
% kill -KILL 12345 Killed
To send the ALRM signal to the current process after T seconds. alarm (0) will cancel the alarm signal.
Example 7: timeout1.c main ... { signal(SIGALRM, handler); alarm (atoi(argv[1])); printf("Enter a string: "); fgets(buf, sizeof(buf), stdin); alarm(0); }
handler(int sig) { printf("inside intr hand\n"); }
Example of usage:
% timeout1 3
Example of usage:
% fork
Example 9: killparent.c This example shows that when the child kills its parent, it is inherited by the init process (pid # 1).
main ... { pid_t pid;
pid = fork();
if (pid == 0) { printf("my real parent id is: %d\n", getppid()); kill ( getppid(), 9); sleep(1); printf("my foster parent id is: %d\n", getppid());
} pause(); }
Example of usage:
% killparent
Example 10: fileshare.c This example shows that both parent and child share the same file pointer. main () { int in; pid_t pid; char buf[1024];
system ("echo abc123 > junk"); in = open("junk", O_RDONLY);
pid = fork(); if (pid == 0) { read(in, buf, 3);
in = open("junk", O_RDONLY); pid = fork()) ; if (pid == 0) execl("./fileread", "fileread", 0); else execl("./fileread", "fileread", 0); } The program exec a file called: fileread.c main() { char buf[1024]; read(3, buf, 3); write(1, buf, 3); write(1,"\n", 1); }
Example 13: execsignal.c
This example shows that exec preserves some siganl settings (e.g., SIG_IGN). main() { pid_t pid;
signal(SIGINT, SIG_IGN);
pid = fork();
if (pid == 0) execl("./waitsig1", "waitsig1", 0);
else execl("./waitsig2", "waitsig2", 0);
} The exec a file called: waitsig1.c & waitsig2.c main() { pause(); }
& main() { signal(SIGINT, SIG_DFL)
pause(); } Use: % ps -a to find the pid of waitsig1 and waitsig2 and Use % kill -INT
Example 14: forkexecwait.c
main() { pid_t pid; char *args[4]; int status;
pid = fork(); if (pid == 0) execl("/bin/echo", "echo", "Today's date is:", NULL);
while ( wait (&status) != pid) continue;
execl("/bin/date", "date", "+%m/%d/%y", NULL); }
Example of usage:
% forkexecwait
Example 15: wsh.c main() { int status; pid_t pid; char command[BUFSIZ];
for (;;) { printf("wsh> "); if (fgets(command, sizeof(command), stdin) == NULL) {
for (cp = args; cp != NULL; cp++) { if (strcmp(cp, "<") == 0) { *cp++ = NULL; infile = cp; } else if (strcmp(cp, ">") == 0) { *cp++ = NULL; outfile = *cp; } } status = execute(args, infile, outfile); } }
int execute(char **args, char *infile, char *outfile) { int status; pid_t p, pid; int infd, outfd; extern int errno; infd = -1; outfd = -1;
if (infile != NULL) { if ((infd = open(infile, O_RDONLY)) < 0) { perror(infile); return(-1); } }
if (outfile != NULL) { if ((outfd = creat(outfile, 0666)) < 0) { perror(outfile); close(infd); return(-1); } }
/* Ignore keyboard signals; and SIG_CHLD signals */ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGCHLD, SIG_IGN);
/* Start a child process*/ if ((pid = fork()) < 0)
status = -1;
if (pid == 0) {
signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGCHLD, SIG_DFL);
if (infd > 0) dup2(infd, 0);
if (outfd > 0) dup2(outfd, 1);
execvp(*args, args); perror("exec"); _exit(127); }
waitpid(pid, &status, 0);
signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGCHLD, SIG_DFL);
close(outfd); close(infd);
return(status); }
size_t bufsplit(char *buf, size_t n, char **a) { .......... } Example use: % mshell msh> ls -lt (......long listing of files .....)
--> execsignal (CTRL-C will kill the command not the shell).
pipe(pfd);
pid = fork();
if (pid == 0) { dup2(pfd[1], 1); close(pfd[1]); close(pfd[0]);
execl("/bin/date", "date", 0); }
close(pfd[1]);
read (pfd[0], line, sizeof(line)); printf("date from child is: %s\n", line);
close(pfd[0]); waitpid(pid, &status, 0); exit(0); }
Example 18: parent writes to child pipemail.c
main() { pid_t pid; int pfd[2]; int i, status; char *username;
username = cuserid(NULL);
pipe(pfd);
pid = fork();
if (pid == 0) {
dup2(pfd[0], 0); close(pfd[1]);
execl("/bin/mail", "mail", username, 0); }
close(pfd[0]);
write(pfd[1], "Greetings and salutations,\n\n", 28); write(pfd[1], "This is your program saying hello.\n", 35); write(pfd[1], "Have a nice day.\n\n", 18); write(pfd[1], "Bye.\n", 5);
close(pfd[1]); waitpid(pid, &status, 0); exit(0); }