Você está na página 1de 44

Cc ni dung cn n tp vi

Kin thc chung


Kin thc lp trnh c trong UNIX v c bn cng ging nh hc lp trnh trong Borland c 3.1
cn gi l phin bn BC cho DOS) cho nn cc bn c th tham kho cc c php cng nh cc
hm trong BC.
Tuy nhin chng ta cng cn nhn mnh 1 cht v cc vn sau:
Program Arguments. int main(int argc, char *argv[]) .
o Ch rng argv[0] lun c v chnh l tn chng trnh,
o ly cc tham s v cc i s mt cch y th cn dng cc hm v bin
mi trng nh sau:
#include <unistd.h>
int getopt(int argc, char *const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;

Environment Variables. Lit k hoc thit lp cc bin mi trng thng qua cc hm v


bin ton cc nh sau:
extern char **environ;
char *getenv(const char *name);
int putenv(const char *string);

C 1 s bi tp nh sau:
1. Gi s c 1 chng trnh cn chy vi 1 so options nh -i, -1, -r, -f v sau -f s c 1
argument. Khi chng trnh chy nh sau:
$ ./argopt -i -lr 'hi there' -f fred.c -q

option: i
option: 1
option: r
option: f
filename: fred.c
argopt: invalid option q
unknown option: q
argument: hi there

Hy vit chng trnh minh ha ra kt qu nh trn.


#include <stdio.h>
iinclude <unistd.h>
int main(int argc, char *argv[])

{
int opt;
while((opt = getopt(argc, argv, "if:lr"))
switch(opt) {
case 'i ':
case '1 ':
case 'r ':
printf("option: %c\n", opt);
break;

1/44

!= -1) {

case 1f ':
printf("filename: %s\n", optarg);
break;
case ':':
printf ("option needs a value\n");
break;
case '? ':
printf("unknown option: %c\n", optopt);
break;

}
for(; optind < argc; optind++)
printf("argument: %s\n", argv[optind]);
return (0);

}
2. Hy vit chng trnh lm vic vi bin mi trng nh sau:
a. Lit k cc bin mi trng ca tin trnh hin ti thng qua bin ton cc
environ.
#include <stdlib.h>
#include <stdio.h>
int main()

{
char **env = environ;
while(*env) {
printf("%s\n",*env);
env++;

}
return (0);

}
b. Ly thng tin ca bin mi trng thng qua hm getenv. V d nh cc bin
PATH, HOME,...______________________________________
#include <stdlib.h>
iinclude <stdio.h>
#include <string.h>
int main(int argc, char *argv[])

{
char *var, *value;
if (argc == 1 II argc > 3)
fprintf (stderr,"usage: environ var [value]\n");
exit (1);

>
var = argv[1];
value = getenv(var);
i f (value)
printf("Variable %s has value %s\n", var, value);
else
printf("Variable %s has no value\n", var);

i f (argc == 3) {
char *string;
value = argv[2];

2/44

string = malloc(strlen(var)+strlen(value)+2);
i f (string) {
fprintf(stderr,"out of memory\n");
exit (1);

}
strcpy(string,var);
strcat(string,"=");
strcat(string,value);
printf("Calling putenv with: %s\n",string);
i f (putenv(string) != 0) {
fprintf(stderr,"putenv failed\n");
free(string);
exit (1);

}
value = getenv(var);
i f (value)
printf("New value of %s is %s\n", var, value);
else
printf("New value of %s is null??\n", var);

}
return (0);

Lam viec v<yi File


Co hai ca che lam viec voi File.
Truy cap va thao tac vai File thong qua cac loi goi he thong. File Descriptor chuan:
STDIN FILENO, STDOUT FILENO, va STDERR FILENO
Truy cap va thao tac voi File thong qua cac ham chuan thu vien. con tro chuan kieu FILE
nhu: FILE * stdin, stdout, stderr.
Cac ham lam viec cr muc thap - muc loi goi he thong truy cap den noi dung file:
#include <unistd.h>
int
creat(const char *pathname, mode_t mode);
int
open(const char *pathname, int oflag, mode t mode);
int
close(int filedes);
off_t
seek(int filedes, off t offset, int whence);
ssize_t
read(int filedes, void *buf, size_t nbytes);
ssize_t
write(int filedes, const void *buf, size_t nbytes);
int
dup(int filedes);
int
dup2(int filedes, int filedes2);
Cac ham truy cap den thuoc tinh cua file

3/44

#include <sys/stat.h>
int stat(const char *restrict pathname, struct stat *restrict buf);
int fstat(int filedes, struct stat *buf);
struct stat {
m o d e t stm ode;
/* file type & mode (permissions) */
ino_t st ino;
/* i-node number (serial number) */
dev t st dev;
/* device number (file system) */
dev_t st rdev; /* device number for special files */
nlink t st_nlink; /* number of links */
uid_t st uid;
/* user ID of owner */
gid_t st gid;
/* group ID of owner */
off t stsize ;
/* size in bytes, for regular files *1
time t st atime; /* time of last access */
time_t stjmtime; /* time of last modification */
time_t st_ctime; /* time of last file status change */
blksize t st blksize; /* best I/O block size */
blkcnt_t st blocks; /* number of disk blocks allocated */
};

Cc hm lm vic vi thuc tnh ca file :


int
access(const char *pathname, int mode);
int
chmod(const char *pathname, mode t mode);
int
fchmod(int filedes, mode t mode);
int
chown(const char *pathname, uid t owner, gid t group);
int
fchown(int filedes, uid_t owner, gid t group);
int
link(const char *existingpath, const char *newpath);
int
unlink(const char *pathname);
int
remove(const char *pathname);
int
rename(const char *oldname, const char *newname);
int
symlink(const char *actualpath, const char *sympath);
ssiz e t readlink(const char* restrict pathname, char *restrict buf,size_t bufsize);
Th mc cng l 1 kiu File c bit trong Unix. truy cp th mc Unix cung cp cc li gi
h thng v cu trc nh sau:

4/44

int
int

mkdir(const char *pathname, mode_t mode);


rmdir(const char *pathname);

struct dirent
{
ino_t d ino;
/* i-node number */
char d_name[NAME_MAX + 1];
/* null-terminated filename */
}
DIR
*opendir(const char *pathname);
struct dirent *readdir(DIR *dp);
void
rewinddir(DIR *dp);
int
closcdir(DIR *dp);
long
telldir(DIR *dp);
void
seekdir(DIR *dp, long loc);
int
int
char

chdir(const char *pathname);


fchdir(int filedes);
*getcwd(char *buf, size_t size);

Cc hm lm vic vi File trong thu vin chun:


#include <stdio.h>
FILE
sizet
sizet
int
int
int
int
int
int
int
int
int
char
char
int
int
int
int
int
int
int
int
void
int
FILE

*fopen(const char *filename, const char *mode);


fread(void *ptr, size_t size, size_t nitems, FILE *stream);
fwrite (const void *ptr, size t size, size t nitems, FILE *stream);
fclose(FILE *stream);
fflush(FILE *stream);
fseek(FILE *stream, long int offset, int whence);
fgetc(FILE *stream);
getc(FILE *stream);
getchar();
fputc(int c, FILE *stream);
putc(int c, FILE *stream);
putchar(int c);
*fgets(char *s, int n, FILE *stream);
*gets(char *s);
printf(const char *format,...);
sprintf(char *s, const char *format,...);
fprintf(FILE *stream, const char *format,...);
scanf(const char *format,...);
fscanf(FILE *stream, const char *format,...);
sscanf(const char *s, const char *format,...);
ferror(FILE *stream);
feof(FILE *stream);
clearerr(FILE *stream);
fileno(FILE *stream);
*fdopen(int tildes, const char *mode);

5/44

Vi cc hm nh vy chng ta c 1 s bi tp mu nh sau:
3. Vit chng trnh m phng cc lnh cp, rm, mv trong Unix (s dng cc li gi h
thng hoc cc hm th vin).
Lnh copy:
#include <stdio.h>
#define MAX_LINE_LEN 1000
void main(int argc, char* argv[])

{
char* file_path_from;
/* source path */
char* file_path_to;
/* target path */
FILE* f_from;
/* source stream */
FILE* f_to;
/* target stream */
char buf[MAX_LINE_LEN+1];
if (argc != 3 || !argv[l] || !argv[2]) {
fprintf(stderr, "Usage:

%s <source tile path>


<target file path>\n",argv[0]);

exit (1);

}
file_path_from = argv[l];
file_path_to = argv[2];
f_from = fopen(file_path_from, "r");
if (!f_from) {
fprintf(stderr, "Cannot open source file: ");
perror("");
exit (1);

}
f_to = fopen(file_path_to, "w+");
if (!f_from) {
fprintf(stderr, "Cannot open target file: ");
perror ("");
exit (1);

}
while (fgets(buf, MAX_LINE_LEN+1, f_from)) {
if (fputs(buf, f_to) == EOF) {
fprintf(stderr, "Error writing to target file:
perror("");
exit (1);

}
}
if (!feof(f_from)) {
fprintf(stderr, "Error reading from source file: ");
perror("");
exit (1);

}
if (fclose(f_from) == EOF) {
fprintf(stderr, "Error when closing source file: ");
perror ("");

}
if (fclose(f_to) == EOF) {
fprintf(stderr, "Error when closing target file: ") ;
perror("");

6/44

4. Xc nh thuc tnh ca cc file, m phng cng vic nh khi chy: $ Is -1 file name.
#include
#include
#include
#include
#include
#include

<ss/stat.h>
<stdio.h>
<time.h>
<io.h>
<sys/types.h>
<fcntl.h>

int main(int argc, char * argv[])

{
struct stat statbuf;
int stream;
char mode[20]="-rwxrwxrwx";
char output[200]
char temp[20]="";
if (argc==l)

{
printf("Usage: %s <file_n
return 1;

}
if ((stream = _open(argv[1', _0

{
perror("Error:");
return 1;

}
fstat(stream, Sstatbuf);
close(stream);
II Kiem tra quyen
if (!S_IRUSR(statbuf.st_mode) )
mode[1]='-';
if (!S_IWUSR(statbuf.st_mode) )
mode[ 2 ] ;
if (!S_IXUSR(statbuf.st_mode) )
mode[3]='-' ;
if (!S_IRGRP(statbuf.st_mode) )
mode[4]='-';
if (!S_IWGRP(statbuf.st_mode))
mode [ 5 ] =' - ' ;
if (!S_IXGRP(statbuf.st_mode))
mode[6]='-';
if (!S_IROTH(statbuf.st_mode) )
mode[7]='-';
if (!S_IWOTH(statbuf.st_mode))
mode[8]='-';
if (!S_IXOTH(statbuf.st_mode))
mode[9]='-';
// kiem tra loai file
if (S_ISLNK(statbuf.st_mode))
mode[0] = '1' ;
else if (S_ISCHR(statbuf.st_node) )
mode[0]='c ';
else if (S_ISBLK(statbuf.st_node))
mode[0]='b';
else if (S_ISSOCK(statbuf.stjnode))
mode[0]='s ';
else if (S_ISFIFO(statbuf.st_mode))
mode[0]='p';
strcat(output,mode); sprintf(temp," %s ", ctime(Sstatbuf.st_ctime));
strcat(output,temp); strcat(output," "); strcat(output,argv[0]); return
0;

7/44

}
5. M phng chng trnh thay i s hu hay quyn truy cp nh: chmod, chown, chgrp.
6. S dng cc hm dup, dup2 thay i hng vo ra d liu. V d khi thc hin hm
_____ printf th kt qu khng phi hin ra mn hnh m ghi vo file no ._________________
#include <ss/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)

{
int fd = open(argv[1]/ 0_CREAT I 0_WR0NLY);
//luu stdout
int oldstdout = dup(l);
//chuyen huong
dup2(fd, 1);
close(fd);
//in ra file tha vi stdout:
printf("test");
//khoi phuc stdout
dup2(oldstdout, 1);
close(oldstdout);
return 0;

2____________________ ______________ ______________________________________ _____________

7. Chng ta c 2 kiu to file lin kt (LINK). Hy dng cc hm lin quan c ni dung


_____ cc file lin kt . Ch vi file lin kt mm.___________________________________
#include
#include
#include
#include
#include

<ss/stat.h>
<fcntl.h>
<unistd.h>
<ss/types.h>
<stdio.h>

int main(int argc,char *argv'])

{
int fd = open(argv[1], 0_RD0NLY);
struct stat statbuf;
char buf[256];
fstat(fd, Sstatbuf);
if (S_ISLNK(statbuf.st_mode) )

{
// doc ten file chua trong file lien ket mem nay
read(fd,buf,200);
close(fd);
fd = open(buf,0_RD0NLY);
printf("\n %s is symbolic link to %s", argv[1],buf);

}
while (read(fd,buf,256))
printf("%s",buf);
close(fd);
return 0;

2_______________________________________________________________________________________

8. Viet chng nh c ni dung ca th mc, lit k cc file v th mc con ca n theo


dng cy th mc vi mc su cho trc. V d: nu lit k th mc TEMP vi su
l 2 th ta lit k cc file, th mc trong th mc TEMP v cc file v th mc trong cc
th muc con ca th muc TEMP.
#include
#include
#include
#include

<unistd.h>
<stdio.h>
<dirent.h>
<strinq.h>__________________________________________________________

8/44

#include <sys/stat.h>
void printdir(char *dir, int depth)

{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
i f ((dp = opendir(dir)) == NULL) {
fprintf(stderr,"cannot open directory: %s\n", dir) ;
return;

}
chdir(dir);
while((entry = readdir(dp)) != NULL) {
stat(entry->d_name,&statbuf);
i f (S_ISDIR(statbuf.st_mode)) {
i f (strcmp(".",entry->d_name) == 0 ||
strcmp("..",entry->d_name) == 0)
continue;
printf("%*s%s/\n",depth,entry->d_name);
printdir(entry->d_name,depth+4);

}
else printf("%*s%s\n",depth,entry->d_name);

}
chdir("..");
closedir(dp);

}
int main()

{
printf("Directory scan of /home:\n");
printdir("/home",0);
printf("done.\n");
exit(0);

}
#include
#include
#include
#include

<sys\stat.h>
<fcntl.h>
<unistd.h>
<dirent.h>

void printdir(char *dir,int aaxdepth)

{
static int depth = 0;
Dir *dp;
struct dirent *entry;
struct stat statbuf;
if ((dp= opendir(dir))==NULL)

{
perror("open:");
return;

}
chdir(dir);
// tang do sau
depth ++;
while ((entry= readdir(dp))!=NULL)

{
stat(entry->d_name,Sstatbuf);
______ if (S ISDIR(statbuf.st mode))

9/44

{
if ( (strcmp (".",entrv->_name)==0) II
strcmpC'. .", entry->d_name) ==0)
{
continue;
}
printf ("%s/\n",entry->d_name);
II neu dat do sau lon nhat thi dung de qui
if (depth < maxdepth)
{
printdir(entry->d_name,maxdepth);
}
}
else
{
// in ten file
printf("\t%s",entry->d_name);
}
}
closedir(dp);
>
int main(int argc,char *argv'])
{
if (argc < 3)
{
printf("\n Usage: %s <dir_name> <max_depth>",argvt0;);
return 1;
>
int maxdepth = atoi(argv[2]);
printdir(argv[1],maxdepth) ;
printf("\n done! \n") ;
return 0;
}

9. Gi s c 1 file vi ng dn y , hy xc nh quyn c c ca file. Nu file


khng c quyn c c i vi ngi dng hin ti, hy xc nh xem nguyn nhn bt
ngun t u (do th mc cha,ng no cu n khng cho quyn c hay thc hin). Cng
lm cng vic nh trn nhng vi ng dn bt k, c th l tuyt i ,c th l tng
i.
#include
finclude
finclude
#include

<stdio.h>
<unistd.h>
<string.h>
<malloc.h>

void main(int arge, char* argv[])


{
char* file_path;
char* dir_path;
char* p_slash;
if (arge != 2 || !argv[i;) {
fprintf(stderr,
"Usage: %s <full file path>\n", argv[0]);
exit (1);

}
file_path = argv[l];
dir_path = (char*)malloc(strlen(file_path)+1);
if (!dir_path) {
_______ fprintf(stderr, "out of memory\n");______________________

10/44

exit (1);

}
p_slash = file_path;
while ( (p_slash = strchr(p_slash, '/')) != NULL) {
strncpy(dir_path, file_path, p_slash-file_path+l);
dir_path[p_slash-file_path+l] = '\0';
if (access(dir_path, F_OK) == -1) {
printf ("%s: Directory '%s' in the path does
not exist.\n","ACCESS DENIED", dir_path);
exit(2);
}
if (access(dir_path, X_OK) == -1) {
printf ("%s: Directory '%s' in the path - no 'X'
permission.\n","ACCESS DENIED", dir_path);
exit (2);
}
p_slash++;
}

if (access(file_path, F_OK) == -1) {


printf("%s: File does not exist.\n",
"ACCESS DENIED");
exit(2);
}
if (access(file_path, R_OK) == -1) {
printf("%s: no read access to file.\n",
"ACCESS
DENIED");
exit(2);
>
printf("Permission OK\n");

tinclude <sys\stat.h>
#include <fcntl.h>
tinclude <unistd.h>
#include <io.h>
int main(int argc,char *argv[])
{
if (argc < 2)
{
printf(\n Usage: %s <file_name>",argv[0]);
return 1;
}
if (access(argv[1],F_0K)==-1)
{
printf("\n File doesnot exists");
return 1;
}
if (access(argv[1],R_OK)==0)
{
printf("\n file access OK");
return 0;
}
// tim thu muc cha hoac ong khong cho phep doc hoac thuc thi
char buf[100];
char *ptr;
char parent[100];

11/44

int reason=0;
int len=0;
struct stat statbuf;
//lay vi tri cuoi cung cua /
ptr = strrchr(argv[ 1 ;
len= ptr - argv[l];
//lay thu muc cha cua file argvfl]
strncpy(buf,argv[1], len) ;
//strcpy(parent,buf);
while (len !=0)
{
stat(buf,Sstatbuf);
if (! (statbuf.st_mode & S_IREAD) )
{
strcpy(parent,buf); //luu thu muc gay loi
reason = 0 ;
//khong C O quyen doc
}
else if (! (statbuf.st_mode & S_IEXEC))
{
strcpy(parent,buf); //luu thu muc gay loi
reason = 1;
//khong CO quyen thuc thi
}
ptr = strrchr(buf,'/');
len= ptr - buf;
//lay thu muc cha cua buf
strncpy(buf,buf,len);
>
if (reason)
{
printf("\n Thu muc %s khong CO quyen thuc thi",parent);
}
else
printf("\n Thu muc %s khong C O quyen doc",parent);
return 0;
}

10. Trong Unix, khi mun thc hin 1 file th h thng s xc nh s tn ti ca file trc.
S kim tra ph thuc vo ng dn ca file. C th l ng dn tuyt i, tng
i hoc ch l 1 tn file cn chy. Trng hp cui th h thng x thng qua bin PATH
xc nh xem file cn thc hin c nm mt trong cc ng dn trong PATH
khng. Hy vit chng trnh minh ha cng vic ny._____________________________
include
#include
#include
#include
#include
#include

<ss\stat.h>
<fcntl.h>
<unistd.h>
<io.h>
<stdlib.h>
<string.h>

int main(int argc,char *argv'])


{
char path[256], *ptr, *buf;
int len = 0;
if (argc < 2)
{
printf("\n Usage: %s <file_name>",argv[0]);
return 1;
>
II kiem tra su ton tai (duong dan tuong doi hoac tuyet doi)
if (access(argv[1],F_OK)==0)
{
______ printf("\n File exists");______________________________________________

12/44

retu rn 0;
}
II neu khong ton tai thi tim kiem trong bien moi truong PATH
buf = (char * ) malloc (256);
strcpy(buf, getenv("PATH"));
// chen them dau : vao cuoi buf cho de XU li
strcat(buf, " : ;
ptr = strchr(buf,':');
while (ptr!=NULL)
{
len = ptr - buf;
//lay path dau tien ke tu vi tri buf
strncpy(path,buf,len);
strcat(path,"/");
strcat(path,argv[1]);
if (access(path,F_OK)==0)
{
printf("\n File exists");
return 0;
}
II khong thay trong path thi tim tiep
buf = ptr;
ptr = strchr(buf,':');
}
// khong tim thay
printf("\n File not exists");
return 0;

J _______________________________________________________________________________________

Lm vic vi tin trnh


Khi lm vic vi tin trnh th trc tin ta quan tm n cc thng tin v tin trnh cng nh cc
cch to ra tin trnh. Cc li gi h thng sau lm vic vi tin trnh:
Xc nh nh danh tin trnh:
pid_t getpid(void);
pid_t getppid(void);
uid_t getud(void);
uid_t geteuid(void);
gid_t getgid(void);
gid_t getegid(void);
To cc tin trnh con:
int
system (const char *string);
pid t fork(void);
pid t wait(int *statloc);
pid t waitpid(pid_t pid, int *stat!oc, int options);
int
int
int
int
int
int

execl(const char *path, const char * a r g 0 , ( c h a r *)0);


execlp(const char *file, const char * a r g 0 , ( c h a r *)0);
execle(const char *path, const char * a r g 0 , ( c h a r *)0, const char *envp[]);
execv(const char *path, const char *argvf]);
execvp(const char *tile, const char *argv[]);
execve(const char *path, const char *argv[], const char *envp[]);

Vi cc hm ny, chng ta c 1 s bi tp n gin nh sau:

13/44

11. To 1 tin trnh con bng hm FORK v xc nh cc thng tin ca tin trnh cha v tin
trnh con. (PID,PPID, UID, EUID, GID, EGID).
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main(int argc,char *argv'])
{
pid_t child_pid;
child_pid = Fork();
switch(child_pid)
{
case -1:
perrorC'Fork fail:");
return 1;
case 0: // tien trinh con
printf("\n child: %d %d %d %d %d %d",
getpid(),getppid{),getuid(),geteuid(), getgid() ,getegid() );
break;
default: // tien trinh cha
printf("\n parent: %d %d %d %d %d %d",
getpid 0 , getppid 0 , getuid 0 , geteuid 0 , getgid 0 , getegid 0);
>
return 0;

}__________________________ ____________________________________________________

12. S dng hm FORK to ra dy cc tin trnh vi quan h cha con nh sau:


a. A -> B -> c -> D : tc l A l cha ca B, B l cha ca c, c l cha ca D.
b. A -> (B, c, D ) : tc l A l cha ca B, c, D.
c. Xy dng cy chu trnh nh sau:

//a
Int main()
{
Pid_t
pA, pB, pC,pD;
pB = fork(); // tach tien trinh B tu A
switch (pB)
{
Case -1: break;
Case 0: pC=fork();// sinh c tu B
Switch(pC)
{
Case -1 : break;
Case 0
: pD= fork();//sinh D tu c
Break;
Default : break;

I_____________________________________________

14/44

Default : break;

}
}

Int main()
{
Pid_t pA, pB,pC,pD;
pB=fork(); //sinh B tu A
switch (pB)
{
Case -1: break;
Case 0: break;
Default: pC=fork(); //sinh c tu A
pD= fork(); // sinh D tu A
}

Int main()
{
Pid_t
pl, p2a, p2b, p3a, p3b, p3c, p3d;
PI = fork() ; // sinh 1 tu 0
Switch(pl)
{
Case -1: break;
Case 0: p3d= fork();
//sinh3d tu 1
P2b= fork();
//sinh2b tu 1
If (p2b = = 0)
P3c =fork();
// sinh 3c tu 2b
Default : p3b = fork(); //sinh 3b tu 0
P2a = fork();
//sinh 2a tu 0
If (p2a = = 0)
p3a = fork.();
//sinh 3a tu 2a
}
}

13. Vit chng trinh m phng hm SYSTEM bng cch s dng cc hm FORK v
EXEC.
#include
finclude
#include
#include

<sys/types.h>
<unistd.h>
<stdio.h>
<sys/wait.h>

int main(){
pid_t child_id;
printf("Statrting process \n");
child_id=fork();
switch (child_id) {
case -1:
printf("fork error");
break;
case 0:
execlp("ps","ps","-af",0);
default:
wait (0) ;
printf("from parent: child finished \n");
_} ___________________________________________

15/44

re tu rn 0;
}
14. Vit chng nh minh ha cng vic chuyn hng vo ra. V d nh: c d liu t
___ file /etc/passwd sau sp xp cc hng theo ct tn ngi dng (ct th nht)._______
#include <unistd.h>
#inclue <stdio.h>
int main(int argc, char *argv[])
{
char *filename;
if (argc 1=2) {
fprintf(stderr, "usage: useupper file\n");
exit (1);
}
filename = argv[l];
i f (!freopen(filename, "r", stdin)) {
fprintf(stderr,
"could not redirect stdin to file %s\n", filename);
exit(2);
}
execlp("sort", "sort", "-0" , "-1" , 0) ;
fprintf(stderr, "could not exec sort!\n");
exit(3);

SIGNAL.
C ch lin lc thng qua Signal. Cc hm h thng sau c s dng:
#include <signal.h>
void (*signal(int sig, void (*func)(int)))(int);
#defme SIG_ERR (void (*)())-1 ; #define SIG DFL (void (*)()) 0;
#define SIG JG N (void (*)()) 1
int
kill(pid_t pid, int sig);
unsigned int alarm(unsigned int seconds);
int
pause(void);

in t
sigaction(int sig, const stru c t sigaction *act, struct sigaction *oact);
struct sigaction
{

void
(*sa_handler)(int);
/* addr of signal handler, */
sigset t sa mask;
I* additional signals to block */
int
sa flags;
/* signal options*/
void (*sa_sigaction)(int, siginfo t *, void *);
};

16/44

int
int
int
int
int
int
int

sigaddset(sigset_t *set, int signo);


sigemptyset(sigset_t *set);
sigfillset(sigset_t *set);
sigdelset(sigset_t *set, int signo);
sigismember(sigset_t *set, int signo);
sigpending(sigset_t *set);
sigsuspend(const sigset t *sigmask);

int sigprocmask(int how, const sigset t *set, sigset_t *oset);


Phn ny chng ta c 1 s bi tp nh sau:
15.
Vit 1 chng trnh chn ngt SIGINT do nhn phm Ctrl+C, ng thi m s ln nhn
Ctrl+C khi chng trnh chy._________________________________________________
include <stdio.h>
ttinclude <signal.h>
void catch(int signum)
{
static int count = 1;
printf("\n An Ctrl-C lan thu:%d",count++);
signal(SIGINT,catch);
}
int maintint arge,char *argv])
{
signal(SIGINT,catch);
while (1) ; //khoiig lam j
return 0;
}

#include <stdio.h>
finclude <unistd.h>
finclude <signal.h>
int ctrl_c_count = 0;
#define

CTRL_C_MAX

void catch_int(int sig_num)


{
sigset_t mask_set;
sigset_t old_set;
signal(SIGINT, catch_int);
sigfillset(&mask_set);
sigprocmask(SIG_SETMASK, &mask_set, &old_set);
ctrl_c_count++;
if (ctrl_c_count >= CTRL_C_MAX)
char answer[30];

printf("\nRealy Exit? [ y / N ] : " ) ;


fflush(stdout);
gets(answer);
_____ if (answer[0] == 'y' || answer[0] == 'Y') {

17/44

printf("\nExiting...\n") ;
fflush(stdout);
exit (0);

}
else {
printf("\nContinuing\n");
fflush(stdout);
ctrl_c_count = 0;
}
}
sigprocmask(SIG_SETMASK, &old_set, NULL);
}
void catch_suspend(int sig_num)
{
sigset_t mask_set;
sigset_t old_set;
signal(SIGTSTP, catch_suspend);
sigfillset(&mask_set);
sigprocmask(SIG_SETMASK, &mask_set, &old_set);
printf("\n\nSo far, '%d'
Ctrl-C presses were counted\n\n", ctrl_c_count);
fflush(stdout);
sigprocmask(SIG_SETMASK, &old_set, NULL);
}
int main()
{
signal(SIGINT, catch_int);
signal(SIGTSTP, catch_suspend);
printf("Please random press Ctrl-C or Ctrl-Z");
while (1) {
sleep (1);
}
return 0;
}

16. Minh ha cho vic s dng cc hm sigaction v sigprocmask chng ta xy dng


chng trnh m phng hm sleep vi tnh nng nh sau: Tin trnh gi hm Sleep s b
tm ngng (block) cho n khi mt trong cc s kin sau xy ra:
a. Thi gian t trong hm Sleep kt thc.
b. Mt Signal khc b bt bi tin trnh v hm thc hin Signal handler tr li kt
qu.
(Bi ny c tnh minh ha cc bn hiu hn v cch s dng)

18/44

static void sig_alrm(int signo)


{

/* nothing to do, just returning wakes up sigsuspendO */


}

unsigned int
sleep(unsigned int nsecs)
{

struct sigaction newact, oldact;


sigset_t
newmask, oldmask, suspmask;
unsigned int
unslept;
/* set our handler, save previous information */
newact.sahandler = sigalrm ;
sigemptyset(&newact.sa_mask);
newact.sa flags = 0;
sigaction(SIGALRM, &newact, &oldact);
/* block SIGALRM and save current signal mask *1
sigemptyset(&newmask);
sigaddset(&newmask, SIGALRM);
sigprocraask(SIG_BLOCK, &newmask, &()Idmask);
alarm(nsecs);

<- s dng hm ALARM v SIGALRM xy dng SLEEP

suspmask = odmask;
sigdelset(&suspmask, SIGALRM); /* make sure SIGALRM isn't blocked */
sigsuspend(&suspmask);
/* wait for any signal to be caught */
/* some signal has been caught, SIGALRM is now blocked */
unslept = alarm(O);
sigaction(SIGALRM, &oldact, NULL); /* reset previous action */
/* reset signal mask, which unblocks SIGALRM */
sigprocmask(SIG_SETMASK, &oldmask, NULL);
return (unslept);
}

PIPE v FIFO
s dng kt qu ca tin trnh ny l u vo ca tin trnh khc th ngoi ta dng PIPE hay
FIFO. Trong Unix c 1 s hm lm vic nh sau:

#incude <stdio.h>
FILE *popen(const char ^command, const char *open_mode);
int
pclose(FILE *stream_to_close);

Hm popen cho php tin trnh ang chy gi 1 chng trnh khc chy (sinh ra 1 tin trnh con)
sau s thc hin vic ly hoc truyn d liu cho tin trnh mi. Tin trnh mi c gi vi
tn chng trnh chy l const char *command. V d sau minh ha cho cch lm vic:
int man()
{

FILE *read_fp;
char buffer[BUFSIZ + 1];
int chars read;
meraset(buffer, '\0', sizeof(buffer));
read fp = popen("ps -ax", "r");
if (read fp != NULL)
{

chars read = fread(bulfer, sizeot'(char), BUFS1Z, read fp);


while (charsread > 0)
{

buffer[chars_read - 1] = '\0';
printf("Reading:-\n %s\n", buffer);
chars read = fread(buffer, sizeof(char), BUFSIZ, read fp);
}

pclose(readfp);
exit(0);
}
exit(0);
}

int
int
int
key t

pipe(int file_descriptor[2]);
mkfifo(const char ^filename, mode_t mode);
mknod(const char *filename, mode t mode I S IFIFO, (dev t) 0);
ftok ( char *pathname, char proj );

Trong phn ny chng ta c 1 s bi tp nh sau:


17.
Vit chng trnh minh ha chuyn i nh hng gia 2 tin trnh cha v con sao cho
u ra chun ca tin trnh ny l u vo chun ca tin trnh kia.
include <stdio.h>
include <unistd.h>
void do_child(int data_pipe[;)
int c;
int rc;

close(data_pipe[1]);
while {(rc = read(data_pipet0], &c, 1)) > 0 )
putchar (c);
>

exit (0);
}
void do_parent(int data_pipe'])
{
int c;
____ int rc;_________________________________________________________________

20/44

close(data_pipe[0]);
while ((c = getcharO) > 0) {
rc = write(data_pipe]1], &c, 1) ;
if (rc == -1) {
perror("Parent: pipe write error");
close(data_pipe[1]) ;
exit(1);
}
}
close(data_pipe[1]);
exit (0);
}
int main()
{
int data_pipe[2];
int pid;
int rc;
rc = pipe(data_pipe);
if (rc == -1) {
perror("pipe create error ");
exit (1);
}
pid = fork();
switch (pid) {
case -1:
perror("fork error");
exit (1);
case 0:
do_child(data_pipe) ;
default:
do_parent(data_pipe) ;
}
return 0;
}
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
int main(int argc,char *argv]])
{
int pipes[2];
int pid;
char buf[100];
if (pipe(pipes) == -1)
{
perror("error:");
return 1;
}
//chuyen huong nhap xuat
dup2(pipes[0],STDIN_FILENO);
close (pipes[0]);
dup2(pipes[1],STDOUT_FILENO) ;
close(pipes[0]);

21/44

pi= fork();
switch(pid)
{
case -1:
perror("fork error:");
return 1;
case 0:
II child ch? d?c ->dng d?u ghi
close (1);
IIghi ra stderr d? hi?n ra mn hnh
gets(buf);
fprintf(stderr,"%s",buf) ;
break;
default:
// parent ch? ghi -> dng d?u d?c:
close (0) ;
printf("from parent: test");
}
return 0;
}

18. Viet 2 chng trnh c nhim v nh sau:


a. Tin trnh A l tin trnh to d liu, v d n to ra cc xu k t.
b. Tin trnh B l tin trinh x l d liu, v d nh in ra mn hnh xu k t
c. Tin trnh A gi d liu cho tin trnh B.
Hy minh ha cng vic trn bng cch s dng FIFO (named pipe).
#include
#include
#include
#include
(include
#include
#include
#include

<unistd.h>
<stdlib.h>
<stdio.h>
<string.h>
<fcntl.h>
<limits.h>
<ss/tpes.h>
<sys/stat.h>

#define FIFO_NAME "/tmp/my_fifo"


#define BUFFER_SIZE PIPE_BUF
#define TEN_MEG (1024 * 1024 * 10)
int main()
{
int pipe_fd;
int res;
int open_mode = 0_WR0NLY;
int bytes_sent = 0;
char buffer[BUFFER_SIZE - 1];
if (access(FIFO_NAME, F_OK) == -1) {
res = mkfifo(FIFO_NAME, 0777);
if (res != 0) {
fprintf (stderr, "Could not create fifo %s\n",
FIF
0 _N A M E );

exit(EXIT_FAILURE) ;
}
}
printf("Process %d opening FIFO 0_WR0NLY\n",

g
etpid()) ;____________________________________________________________________

22/44

pipe_fd = open(FIFO_NAME, open_mode);


printf("Process %d result %d\n", getpid(), pipe_fd);
if (pipe_fd != -1) {
while(bytes_sent < ?EN_MEG) {
res = write (pipe_fd, buffer, BUFFERjSIZE);
if (res == -1) {
fprintf(stderr, "Write error on pipe\n");
exit(EXIT_FAILURE);
}
bytes_sent += res;
}
(void)close(pipe_fd) ;
}
else {
exit(EXIT_FAILURE);
}
printf ("Process %d finished\n", getpidO);
exit(EXIT_SUCCESS);

//include nhu tren


#include <sys/stat.h>
ttdefine FIFO_NAME "/tmp/my_fifo"
#define BUFFER_SIZE PIPE_BUF
int mainO
{
int pipe_fd;
int res;
int open_mode = 0_RD0NLY;
char buffer[BUFFER_SIZE - 1];
int bytes_read = 0;
memset(buffer,

'\0', sizeof(buffer));

printf("Process %d opening FIFO 0_RD0NLY\n",


getpi
d ());
pipe_fd = open(FIFO_NAME, open_mode);
printf ("Process %d result %d\n, getpidO, pipe_fd) ;
if (pipe_fd != -1) {
do {
res = read(pipe_fd, buffer, BUFFER_SIZE);
bytes_read += res;
} while (res > 0 ) ;
(void)close(pipe_fd) ;
}
else {
exit(EXIT_FAILURE);
}
printf("Process %d finished, %d bytes read\n",
getpidO, bytes_read) ;
exit(EXIT_SUCCESS);
}

P r o g A .c
23/44

#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#define FIFO_NAME "/tmp/testfifo"
int main(int argc,char *argv]])
{
int fd;
if (access(FIF0_NAME,F_0K)==-1)
if (mkfifo(FIFO_NAME,0777) != 0 )
{
perror("make fifo:");
return 1;
}
fd = open(FIFO_NAME,0_WR0NLY) ;
if (fd != -1)
{
write(fd, "hello",PIPE_BUF);
close(fd);
}
return 0;
}

ProgB.c
include <unistd.h>
include <stdio.h>
include <signal.h>
define FIFO_NAME "/tmp/testfifo"
int main(int argc,char *argv[])
{
int fd;
char buf[PIPE_BUF+1]
fd = open(FIF0_NAME,0_WR0NLY) ;
if (fd != -1)
{
read(fd,buf,PIPE_BUF);
printf("receive: %s",buf);
close(fd);
}
else
{
fprintf(stderr,"pipe not exist");
return 1;
}
return 0;

Message Queues

24/44

int
int
int
int

msgctl(int msqid, int cmd, struct ms qi dds *buf);


msgget(key_t key, int msgflg);
msgrcv(int msqid, void *msg_ptr, s i z e t ms g s z , long int msgtype, int msgflg);
msgsnd(int msqid, const void *msg_ptr, size t msgsz, int msgflg);

struct msqid ds
{

struct ipc_perm msg perm;


struct msg *msg_first;
/* first message on queue, unused */
struct msg *msg_last;
/* last message in queue, unused */
_kernel_time_t msg stime;
/* last msgsnd time */
_kernel_time_t msg rtime;
/* last msgrcv time *1
_kernel_time_t msg ctime;
/* last change time */
unsigned long msg lcbytes:
/* Reuse junk fields for 32 bit */
unsigned long msglqbytes;
/* ditto */
unsigned short msg cbytes;
/* current # of bytes on queue */
unsigned short msg qnum;
/* number of messages in queue*/
unsigned short msg qbytes;
/* max number of bytes on queue */
__kernel_ipc_pid_t msg lspid; /* pid of last msgsnd */
_kernel_ipc_pid_t msg lrpid; /* last receive pid */
};

struct ipc_perm
{

__k e y t __key;
_uid t uid;
__gid_t gid;
__uid t cuid;
gid t cgid;
unsigned short int mode;

/* Key
*/
/* Owner's user ID. */
/* Owner's group ID. */
/* Creator's user ID. */
/* Creator's group ID. */
/* Access permission. */

};

struct msgbuf
{

long mtype; /* type of message */


char mtextfl]; /* message text */
1;

Trong phn ny chng ta c 1 s bi tp nh sau:


19. Xy dng chng trnh qun l Message Queue nh:
a. To, hy i tng Message Queue.
b. Ghi, c thng ip t hng i.
c. c cc thng tin ca Message Queue nh: quyn truy cp, ngi s dng, ...
20. Vit 2 chng trnh trao i d liu vi nhau thng qua Message Queue.
#include
#include
iinclude
#include
#inclue

<stdio.h>
<stdlib.h>
<ss/tpes-h>
<ss/ipc.h>
<sys/msg.h>

25/44

include "queue defs.h"


struct msgbuf {
long int mtype;
char mtext[1];
};
int main(int argc, char* argv[])
{
int queue id;
struct msgbuf* msg;
int i;
int rc;
queue_id = msgget(QUEUE_ID, IPC_CREAT |

0777);

if (queue_id == -1) {
perror("main: msgget error");
exit (1);
}
printf("message queue created, queue id '%d'.\n",
queue_id);
msg = (struct msgbuf*)malloc(sizeof(
struct
msgbuf)+MAX_MSG_SIZE);
for (i=l; i <= NUM_MESSAGES; i++) {
msg->mtype = (i % 3) + 1;
sprintf(msg->mtext, "hello world - %d", i) ;
rc = msgsnd(queue_id, msg, strlen(msg->mtext)+1, 0);
if (rc == -1) {
perror("main: msgsnd error");
exit (1);
}
}
free(msg);
printf("generated %d messages, exiting.\n",
NU
M_MESSAGES);
return 0;
}

include
include
include
include
include
include

<stdio.h>
<stdlib.h>
<unistd.h>
<sys/types.h>
<sys/ipc.h>
<sys/msg.h>

include "queue_defs.h"
struct msgbuf{
long int mtype;
char mtext[1];
};

26/44

int main(int argc, char *argv[])


{
int queue_id;
struct msgbuf* msg;
int rc;
int msg_type;
if (argc != 2) {
fprintf(stderr, "Usage: %s <message type>\n".
argv[0 ]);
fprintf(stderr,

<message type> must be


between 1 and

3 .\n") ;
exit (1);
}
msg_type = atoi(argv[1]);
if (msg_type < 1 || msg_type > 3 ) {
fprintf(stderr, "Usage: %s <message type>\n",
argv[0]);
fprintf(stderr,

<message type> must be


between 1

and 3.\n");
exit (1) ;
}
queue_id = msgget(QUEUE_ID, 0);
if (queue_id == -1) {
perror("main: msgget error") ;
exit(1);
}
printf("message queue opened, queue id '%d'.\n",
queue_id);
msg = (struct msgbuf*)malloc(sizeof(
struct msgbuf)+MAX_MSG_SIZE) ;
while (1) {
rc = msgrcv(queue_id, msg, MAX_MSG_SIZE+1,
ms
g_type, 0);
if (rc == -1) {
perror("main: msgrcv error");
exit (1);
}
printf("Reader '%d' read message: '%s'\n",
msg_type, msg>mtext);
sleep (1);
}
return 0;

ProgA.c
include <unistd.h>
include <stdio.h>
include <signal.h>

27/44

#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#define MSGQID 1234
#define MAX_LEN 256
struct msgbuf
{
long mtype;
char mtext[1];
} *msg;
int main(int argc,char *argv^])
{
int qid;
int ret;
qid = msgget(MSGQID, IPC_CREAT | 0777);
if (qid == -1)
{
perror("msgget error:");
return 1;
}
msg = (struct msgbuf *) malloc(sizeof(struct msgbuf) + MAX_LEN);
msg->mtype=0;
strcpy(msg->mtext,"From Process A");
ret = msgsnd(qid, msg, strlen(msg->mtext)+1,0);
if (ret == -1)
{
perror("msgsnd error:");
return 1;
}
return 0;

ProgB.c
#include
#include
include
include
include
include

<unistd.h>
<stdio.h>
<signal.h>
<sys/ipc.h>
<sys/msg.h>
<stdlib.h>

define MSGQID 1234


define MAX_LEN 256
struct msgbuf
{
long mtype;
char mtext[1];
} *msg;
int main(int argc,char *argv^])
{
int qid;
int ret;
qid = msgget(MSGQID, 0);
if (qid == -1)
{

28/44

perror{"msgget error:");
return 1;

}
msg = (struct msgbuf *) malloc(sizeof(struct msgbuf) + MAX_LEN);
ret = msgrcv(qid, msg, MAX_LEN + 1,0,0);
if (ret == -1)
{
perror("msgsnd error:");
return 1;
}
printf("Process B received: %s",msgbuf->mtext);
return 0;
}

Tested by HCricket
/'/ProA.c
include
include
include
include
include

<sys/types.h>
<sys/ipc.h>
<sys/msg.h>
<stdio.h>
<string.h>

define MSGSZ

128

/*
* Declare the message structure.
*/
-ypedef struct msgbuf {
long
mtype;
char
mtext[MSGSZ];
} message_buf;
main ()
{
int msqid;
int msgflg = IPC_CREAT | 0666;
key_t key;
message_buf sbuf;
size_t buf_length;
/*
* Get the message queue id for the
* "name" 1234, which was created by
* the server.
*/
key = 1234;
(void) fprintf(stderr, "\nmsgget: Calling msgget(%^lx,\
%#o)\n",
key, msgflg);
if ((msqid = msgget(key, msgflg )) < 0) {
perror("msgget");
exit (1);
}
else
(void) fprintf(stderr,"msgget: msgget succeeded: msqid = %d\n", msqid);

29/44

/*
* We'll send message type 1
*/
sbuf.mtype = 1;
(void) fprintf(stderr,"msgget: msgget succeeded: msqid = %d\n", msqid);
(void) strcpy(sbuf.mtext, "Did you get this?");
(void) fprintf(stderr,"msgget: msgget succeeded: msqid = %d\n", msqid);
buf_length = strlen(sbuf.mtext) + 1 ;

/*
* Send a message.
*/
if (msgsnd(msqid, Ssbuf, buf_length, IPC_NOWAIT) < 0) {
printf ("%d, %d, %s, %d\n", msqid, sbuf.mtype, sbuf.mtext, buf_length);
perror("msgsnd");
exit (1);
}
else
printf("Message: \"%s\" Sent\n", sbuf.mtext);
exit (0);
}

//ProB.c
include
include
include
include

<sys/types.h>
<sys/ipc.h>
<sys/msg.h>
<stdio.h>

define MSGSZ

128

,/*
* Declare the message structure.
*/
typedef struct msgbuf {
long
mtype;
char
mtext[MSGSZ];
} message_buf;

main ()
{
int msqid;
key_t key;
message_buf

rbuf;

/*
* Get the message queue id for the
* "name" 1234, which was created by
* the server.

*/
key = 1234;

30/44

if ((msqid = msgget(key, 0666)) < 0) {


perror("msgget");
exit (1);
}

/*
* Receive an answer of message type 1.
*/
if (msgrcv(msqid, Srbuf, MSGSZ, 1, 0) < 0) {
perror("msgrcv");
exit(1);
}
/*
* Print the answer.
*/
printf("%s\n", rbuf.mtext);
exit (0);

Shared Memory
void
int
int
int

*shmat(int s hmi d, const void *shm_addr, int shmflg);


shmctl(int shm id, int cmd, struct shmi dds *buf);
shmdt(const void *shm_addr);
shmget(key_t key, s i z e t size, int shmflg);

stru ct shm id ds
{

struct ipc_perm shm_perm;


/* operation permission struct */
size t shm segsz;
/* size of segment in bytes
*/
_t i m e t shm atime;
/* time of last shmato
*/
_time t shm dtime;
/* time of last shmdto
*/
_time t shm ctime;
/* time of last change by shmctio */
_pid t shm cpid;
/* pid of creator
*/
_pid t shm lpid;
/* pid of last shmop
*/
shmatt_t shm nattch;
/* number of current attaches
*/

Trong phn ny c 1 s bi tp nh sau:


21. Xy dng chong trnh qun l Shared Memory nh:
a. To, hy i tng Shared Memory.
b. Ghi, c d liu t b nh dng chung.
c. c cc thng tin ca Shared Memory nh: quyn truy cp, ngi s dng,...
22. Vit 2 chng trnh trao i d liu vi nhau thng qua Shared Memory .
include
include
include
include

<stdio.h>
<sys/tpes.h>
<sys/ipc.h>
<ss/shm.h>

31/44

struct country {
char name[30];
char capital_city[30];
char currency[30];
int population;

int main()
{
int shm_id;
char* shm_addr;
int* countries_num;
int* stop;

struct country* countries;


struct shmid_ds shm_desc;
int i;
shm_id = shmget(100, 2048, 0777);
if (shm_id == -1) {
perror ("main: shmget error ");
exit (1);
}
shm_addr = shmat(shm_id, NULL, 0);
if (!shm_addr) {
perror("main: shmat error ");
exit (1);
}
countries_num = (int*) shm_addr;
stop = (int*) ((void*)shn_addr+sizeof(int));
countries = (struct country*)
((void*)shm_addr+sizeof(int)*2);
printf ("Total %d \n", (*countries_num));
for (i=0; i < (*countries_num) ; i++) {
printf("Countery %d:\n", i+1);
printf(" name: %s:\n", countries[i].name);
printf(" capital city: %s:\n",
countries[i].capital_city);
printf(" currency: %s:\n", countries[i].currency);
printf (" population: %d:\n",
countries[i].population);
}
printf("Now try to stop writer \n");
*Stop=l;
return 0;

include <stdio.h>
include <sys/types.h>
include <sys/ipc.h>
include <sys/shm.h>
struct country {
char name[30];
____ char capital city[30];

32/44

char currency[30];
int population;
};
int main()
{
int shm_id;
char* shm_addr;
int* countries_num;

:nt* stop;

struct country* countries;


struct shmid_ds shm_desc;
int i;
shm_id = shmget(10 0, 2048, IPC_CREAT | 0777);
if (shm_id == -1) {
perror("main: shmget error ");
exit (1);
}
shm_addr = shmat(shm_id, NULL, 0);
if (!shm_addr) {
perror("main: shmat error ");
exit (1);
}
countries_num = (int*) shm_addr;
*countries_num = 0;
stop =(int*) ((void*)shm_addr+sizeof(int));
*stop=0;
countries = (struct country*)
((void*)shm_addr+sizeof(int)*2);
strcpy(countries[0].name, "U.S.A");
strcpy(countries[0].capital_city, "Washington");
strcpy(countries[0].currency, "U.S. Dollar");
countries[0].population = 250000000;
(*countries_num)++;
strcpy(countries[1]. name, "Israel");
strcpy(countries[1].capital_city, "Jerusalem");
strcpy(countries[1].currency, "New Israeli Shekel");
countries[1].population = 6000000;
(*countries_num)++;
strcpy (countries[2]. name, "France");
strcpy(countries[2].capital_city, "Paris");
strcpy(countries[2].currency, "Frank");
countries[2].population = 30000000;
(*countries_num)++;
printf("Waiting for other process reading data \n");
fflush(stdout);
while (! (*stop)) {
sleep (1);
}
if (shmdt(shm_addr) == -1) {
perror("main: shmdt: ");
}

33/44

if (shmctl(shm_id, IPC_RMID, &shm_desc) == -1) {


perror("main: shmctl error ");
}
printf("main writer finished \n") ;
return 0;
}
P r o g A .c
include
include
include
include

<unistd.h>
<stdio.h>
<sys/ipc.h>
<sys/shm.h>

define SHMID 1234


define MAX LEN 256
int main(int argc,char *argv]])
{
int id;
int ret;
char * shm addr;
int * size;
char * msg;
// tao vung nho chung
id = shmget(SHMID , MAX LEN, IPC CREAT
if (id == -1)
{
perror("shmget error:");
return 1;
}
// attach
shm addr = shmat(id , NULL , 0);
if ( !shm addr )
{
perror("shmat error:");
return 1;
}
// ghi du lieu vao vung nh
strcpy(msg,"From Process A
size = (int *)shm addr;
*size = sizeof(msg);
strcpy(shm addr + sizeof(i
//detach
ret = shmdt(shm addr);
if (ret == -1)
{
perror("shmdt error:
return 1;
}
return 0;
}

P r o g B .c

34/44

0777);

include <unistd.h>
include <stdio.h>
include <sys/ipc.h>
include <sys/shm.h>
define SHMID 1234
define MAX LEN 256

int main(int argc,char *argv]])


{
int id;
int ret;
char * shm_addr;
int * size;
char * msg;
// tao vung nho chung
id = shmget(SHMID , MAX_LEN,
if (id == -1)
{
perror("shmget error:");
return 1;
}

0777);

II attach
shm_addr = shmat(id , NULL , 0) ;
if ( !shm_addr )
{
perror("shmat error:");
return 1;
}
// doc du lieu tu vung nho chung
size = (int *)shm_addr;
strncpy(msg, shm_addr + sizeof(int) , *size);
printf("Process B received: %s", msg);
//detach
ret = shmdt(shm_addr);
if (ret == -1)
{
perror("shmdt error:");
return 1;
}
return 0;

}____________________________________________

35/44

Tested by HouseCricket
ProgA.c
include
include
include
include

<sys/types.h>
<sys/ipc.h>
<sys/shm.h>
<stdio.h>

define SHMSZ

27

main ()

{
char c;
int shmid;
key_t key;
char *shm, *s;

/*
* We'll name our shared memory segment
* "5678".
*/
key = 567 8;
/*
* Create the segment.
*/
if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {
perror("shmget");
exit (1);
}
/*
* Now we attach the segment to our data space.
*/
if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
perror("shmat");
exit (1);
}
/*
* Now put some things in~o the memory for the
* other process to read.
*/
s = shm;
for (c = 'a'; c <= z'; C++)
*s++ = c;
*s = NULL;

/*
*
*
*
*

Finally, we wait until the other process


changes the first character of our memory
to '*', indicating tha" it has read what
we put there.

*/
while (*shm != '*')
sleep(1);
exit (0);

//ProgB.c

37/44

Semaphores
#include <sys/sem.h>
int
int
int

semctl(int s e mi d, int sem num, int command,...);


semget(key_t key, int numsems, int sem flags);
semop(int sem id, struct sembuf *sem_ops, size_t num sem ops);

Trong phn ny c 1 s bi tp nh sau:


23. Xy dng chong trnh qun l Semaphores nh:
a. To, hy i tng Semaphores.
b. Xy dng cc thao tc lm vic vi Semaphores.
c. c cc thng tin ca Semaphores nh: quyn truy cp, ngi s dng, ...
24. Vit 2 chng trnh trao i d liu vi nhau thng qua Shared Memory v Semaphores.
include
include
include
include
include
include
include
include

<stdio.h>
<sys/types-h>
<ss/ipc.h>
<sys/shm.h>
<ss/sem.h>
<wait.h>
<time.h>
<stdlib.h>

define SEM_ID

include <unistd.h>

250

union semun {
int val;
struct semid_ds *buf;
unsigned short int *array;
};

struct country {
char name[30];
char capital_city[30];
char currency[30];
int population;
};
void
{

random_delay()
static int initialized = 0;
int random_num;
struct timespec delay;
if (initialized) {
srand(time(NULL) );
initialized = 1;
}
random_num = rand() % 10;
delay.tv_sec = 0;
delay.tv_nsec = 10*randon_num;
nanosleep(Sdelay, NULL);

}
void

sem lock(int sem set id)____

38/44

{
struct sembuf sem_op;
sem_op.sem_num = 0;
sem_op.sem_op = -1;
sem_op.sem_flg = 0;
semop(sem_set_id, &sem_op, 1) ;
}
void
{

sem_unlock(int sem_set_id)
struct sembuf sem_op;
sem_op.sem_num = 0;
sem_op.sem_op = 1;
sem_op.sem_flg = 0;
semop(sem_set_id, &sem_op, 1);

}
void

add_country(int sem_set_id, int* countries_num,


struct country* countries,
char* country_name,
char* capital_city,
char* currency,
int population)

{
sem_lock(sem_set_id);
strcpy(countries[*countr:es_num].name,
country_name);
strcpy (countries [*countnes_num] .capital_city,
capital_city);
strcpy (countries [*countnes_num] .currency,
currency);
countries [*countries_nurrf .population = population;
(*countries_num)++;
sem_unlock(sem_set_id) ;
}

void

do_child(int sem_set_id, int* countries_num,


struct country* counties)

{
add_country(sem_set_id, countries_num, counties,
"U.S.A", "Washington",
"U.S. Dollar", 250000000);
random_delay();
add_country(sem_set_id, countries_num, counties,
"Israel", "Jerusalem",
"New Israeli Shekel", 6000000);
random_delay();
add_country(sem_set_id, countries_num, counties,
"France", "Paris",
"Frank", 60000000);

39/44

random_delay();
add_country(sem_set_id, countries_num, counties,
"Great Britain", "London",
"Pound", 55000000);
}
void do_parent(int sem_set_id, int* countries_num,
struct country* countries)
{
int i, num_loops;
for (num_loops=0; num_loops < 5; num_loops++)

sem_lock(sem_set_id);
printf ("------------------------------- \n");
printf("Number Of Countries: %d\n",
*countries_num);
for (i=0; i < (*countries_num); i++) {
printf("Country %d:\n", i+1);
printf(" name: %s:\n", countries[i].name);
printf (" capital city: %s:\n",
countries[i].capital_city);
printf(" currency: %s:\n",
countries[i].currency);
printf (" population: %d:\n",
countries[i].population);
}
sem_unlock(sem_set_id) ;
random_delay();
}
}
int main()
{
int sem_set_id;
union semun sem_val;
int shm_id;
char* shm_addr;
int* countries_num;
struct country* countries;
struct shmid_ds shm_desc;
int rc;
pid_t pid;
sem_set_id = semget(SEM_ID, 1, IPC_CREAT | 0777);
if (sem_set_id == -1) {
perror("main: semget");
exit (1);
}
sem_val.val = 1;
rc = semctl(sem_set_id, 0, SETVAL, sem_val);
if (rc == -1) {
perror("main: semctl");
exit (1);

40/44

}
shm id = shmget(100, 2048,
IPC_CREAT | IPC_EXCL
if (shm id == -1) {
perror("main: shmget error");
exit (1);
}
shm addr = shmat(shm id, NULL, 0);
if (!shm addr) {
perror("main: shmat error ");
exit (1);
}
countries num = (int*) shm addr;
*countries num = 0;
countries = (struct country*)
((void*)shm addr+sizeof(int));
pid = fork();
switch (pid) {
case -1:
perror("fork error ");
exit (In
break;
case 0:
do child(sem set id, countries num, countries);
exit (0);
break;
default:
do parent (sem set id, countries num, countries);
break;
}
{
int child status;
wait(&child status);
}
if (shmdt(shm addr) == -1) {
perror("main: shmdt error ");
}
if (shmctl(shm id, IPC RMID, &shm desc) == -1) {
perror("main: shmctl error ");
}
return 0;
}

P r o g A .c
include
include
include
include
include

<unistd.h>
<stdio.h>
<sys/ipc.h>
<sys/shm.h>
<sys/sem.h>

define SEMID 4321

41/44

0600);

define SHMID 1234


define MAX LEN 256

int main(int argc,char *argv]])


{
int id, semid;
char * shm_addr;
int * size;
char * msg;
union semun semval;
struct sembuf sb;
// tao vung nho chung
id = shmget(SHMID , MAX_LEN, IPC_CREAT |
II attach
shm_addr = shmat(id , NULL , 0);
II tao semaphore
semid = semget(SEMID , 1, 0777);
II khoi tao semaphore = 1
semval.val = 1;
semctl(semid, 0 , SETVAL, semval);
II giam semaphore di 1, cho ghi du lieu
sb.sem_num = 0;
sb.sem_op = -1;
sb. sem_flg = 0;
semop(semid, &sb, 1);

0777);

II ghi du lieu vao vung nho chung


strcpy(msg,"From Process A");
size = (int *)shm_addr;
*size = sizeof(msg);
strcpy (shm_addr + sizeof (int), msg);
II tang semaphore len 1 , cho phep doc du lieu
sb.sem_op = 1;
semop(semid, &sb, 1);
//detach
shmdt(shm_addr);
return 0;
}

ProgB.c
include
include
include
include
include

<unistd.h>
<stdio.h>
<sys/ipc.h>
<sys/shm.h>
<sys/sem.h>

define SEMID 4321


define SHMID 1234
define MAX LEN 256

int main(int argc,char *argv]])


{
int id, semid;
char * shm_addr;
int * size;
char * msg;
union semun semval;
struct sembuf sb;____________

42/44

// tao vung nho chung


id = shmget(SHMID , MAX_LEN,
0777);
II attach
shm_addr = shmat(id , NULL , 0);
II tao semaphore
semid = semget(SEMID , 1, 0777);
II giam semaphore di 1, cho doc du lieu
sb.sem_num = 0;
sb.sem_op = -1;
sb. sem_flg = 0;
semop(semid, &sb, 1);
II doc du lieu tu vung nho chung
size = (int *)shm_addr;
strncpy(msg, shm_addr + sizeof(int) , *size);
II tang semaphore len 1 , cho phep ghi du lieu
sb.sem_op = 1;
semop(semid, &sb, 1);
printf("Process B received: %s", msg);
//detach
shmdt(shm_addr);
return 0;

43/44

Tested by Housecricket
.//ProA. c
include
include
include
include
include
define
define
define
define

<stdio.h>
<string.h>
<sys/ipc.h>
<sys/sem.h>
<sys/shm.h>
SEMKEYPATH "/dev/null"
SEMKEYID 1
SHMKEYPATH "/dev/null"
SHMKEYID 1

/*
/*
/*
/*

Path used on ftok for semget key


Id used on ftok for semget key
Path used on ftok for shmget key
Id used on ftok for shmget key

*/
*/
*/
*/

define NUMSEMS 2
define SIZEOFSHMSEG 50

/* Num of sems in created sem set


/* Size of the shared mem segment

*/
*/

define NUMMSG 2

/* Server only doing two "receives"


on shm segment

*/

int main(int argc, char *argv[])


{
int rc, semid, shmid, i;
key_t semkey, shmkey;
void *shm_address;
struct sembuf operations[2];
struct shmid_ds shmid_struct;
short sarray[NUMSEMS];
/* Generate an IPC key for the semaphore set and the shared
/* memory segment. Typically, an application specific path
/* id would be used to generate the IPC key.
semkey = ftok(SEMKEYPATH,SEMKEYID);
if ( semkey == (key_t)-l )
{
printf("main: ftok() for sem failed\n");
return -1;
}
shmkey = ftok(SHMKEYPATH,SHMKEYID);
if ( shmkey == (key_t)-l )
{
printf("main: ftok() for shm failed\n");
return -1;

*/
and*/
*/

}
/*
/*
/*
/*

Create a semaphore set using the IPC key. The number of


*/
semaphores in the set is two. If a semaphore set already
*/
exists for the key, rezurn an error. The specified permissions*/
give everyone read/write access to the semaphore se~.
*/

semid = semget( semkey, NUMSEMS, 0666 | IPC_CREAT | IPC_EXCL );


if ( semid == -1 )

{
printf("main: semget (| failed\n");
return -1;

}
/*
/*
I*
/*
/*
/*
/*
/*
/*
/*
/*

Initialize the first semaphore in the set to 0 and zhe


second semaphore in the set to 0 .
The first semaphore in the sem set means:
'1' The shared memory segment is being used.
'0' The shared memory segment is freed.
The second semaphore in the sem set means:
'1' The shared memory segment has been changed by
the client.
'0' The shared memory segment has not been
changed by the client.

sarray[0] = 0;
sarray[1] = 0;

44/44

*/
*/
I
*/
*/
*/
*/
*/
*/
*/
*/

Você também pode gostar