├── README.md ├── SUMMARY.md ├── code ├── unpv22e.tar.gz └── unpv22e │ ├── DISCLAIMER │ ├── Make.defines │ ├── Make.defines.in │ ├── Makefile │ ├── Makefile.in │ ├── README │ ├── aclocal.m4 │ ├── bench │ ├── Mail.todo.bobf │ ├── Makefile │ ├── README │ ├── bw_door.c │ ├── bw_lat.sh │ ├── bw_pipe.c │ ├── bw_pxmsg.c │ ├── bw_sunrpc.x │ ├── bw_sunrpc_client.c │ ├── bw_sunrpc_server.c │ ├── bw_svmsg.c │ ├── graph.1 │ ├── graph.2 │ ├── incr.sh │ ├── incr_fcntl1.c │ ├── incr_fcntl5.c │ ├── incr_pxmutex0.c │ ├── incr_pxmutex1.c │ ├── incr_pxmutex5.c │ ├── incr_pxsem1.c │ ├── incr_pxsem2.c │ ├── incr_pxsem5.c │ ├── incr_pxsem6.c │ ├── incr_pxsem7.c │ ├── incr_pxsem8.c │ ├── incr_pxsem9.c │ ├── incr_rwlock1.c │ ├── incr_rwlock2.c │ ├── incr_rwlock5.c │ ├── incr_svsem1.c │ ├── incr_svsem2.c │ ├── incr_svsem5.c │ ├── incr_svsem6.c │ ├── lat_door.c │ ├── lat_pipe.c │ ├── lat_pxmsg.c │ ├── lat_signal.c │ ├── lat_sigqueue.c │ ├── lat_sigwait.c │ ├── lat_sunrpc.h │ ├── lat_sunrpc.x │ ├── lat_sunrpc_client.c │ ├── lat_sunrpc_server.c │ ├── lat_svmsg.c │ ├── test1.c │ ├── test1.c.save │ └── unpipc.h │ ├── config.cache │ ├── config.guess │ ├── config.h │ ├── config.h.in │ ├── config.log │ ├── config.status │ ├── config.sub │ ├── configure │ ├── configure.in │ ├── doors │ ├── Makefile │ ├── client1.c │ ├── client2.c │ ├── client3.c │ ├── client4.c │ ├── client5.c │ ├── client6.c │ ├── client7.c │ ├── client8.c │ ├── client9.c │ ├── clientfd1.c │ ├── clientintr1.c │ ├── clientintr2.c │ ├── clientintr3.c │ ├── clientintr4.c │ ├── clientunref1.c │ ├── clientunref2.c │ ├── doorinfo.c │ ├── server1.c │ ├── server2.c │ ├── server3.c │ ├── server4.c │ ├── server5.c │ ├── server6.c │ ├── server7.c │ ├── server8.c │ ├── server9.c │ ├── serverfd1.c │ ├── serverintr1.c │ ├── serverintr2.c │ ├── serverintr3.c │ ├── serverintr4.c │ ├── serverunref1.c │ ├── serverunref2.c │ ├── sqrtproc.h │ ├── squareproc.h │ ├── tclient1.c │ ├── tserver1.c │ └── unpipc.h │ ├── fifocliserv │ ├── Makefile │ ├── fifo.h │ ├── mainclient.c │ ├── mainserver.c │ └── unpipc.h │ ├── install-sh │ ├── lib │ ├── .exrc │ ├── Makefile │ ├── daemon_inetd.c │ ├── daemon_init.c │ ├── error.c │ ├── gf_time.c │ ├── isfdtype.c │ ├── lock_reg.c │ ├── lock_test.c │ ├── my_shm.c │ ├── pselect.c │ ├── px_ipc_name.c │ ├── readable_timeo.c │ ├── readline.c │ ├── readn.c │ ├── set_concurrency.c │ ├── set_nonblock.c │ ├── signal.c │ ├── signal_intr.c │ ├── signal_rt.c │ ├── signal_rt_intr.c │ ├── sleep_us.c │ ├── snprintf.c │ ├── timing.c │ ├── tv_sub.c │ ├── unpipc.h │ ├── wrapdoor.c │ ├── wrappthread.c │ ├── wrapstdio.c │ ├── wrapsunrpc.c │ ├── wrapunix.c │ ├── writable_timeo.c │ └── writen.c │ ├── lock │ ├── Makefile │ ├── lockfcntl.c │ ├── locklink.c │ ├── lockmain.c │ ├── lockmainubuf.c │ ├── locknone.c │ ├── lockopen.c │ ├── lockopen2.c │ ├── lockpxsem.c │ ├── locksvsem.c │ ├── locksvsemrace1.c │ ├── loop1.sh │ ├── loop2.sh │ ├── loopmain.c │ ├── loopmainnonb.c │ ├── onedaemon.c │ ├── pidfile │ ├── seqno │ ├── test1.c │ ├── test1.data │ ├── test2.c │ ├── test3.c │ ├── test4.c │ └── unpipc.h │ ├── mutex │ ├── Makefile │ ├── prodcons1.c │ ├── prodcons2.c │ ├── prodcons3.c │ ├── prodcons4.c │ ├── prodcons5.c │ ├── prodcons6.c │ ├── prodcons7.c │ ├── test1.c │ ├── test2.c │ ├── test3.c │ ├── test4.c │ └── unpipc.h │ ├── my_pxmsg_mmap │ ├── Makefile │ ├── README │ ├── mq_close.c │ ├── mq_getattr.c │ ├── mq_notify.c │ ├── mq_open.c │ ├── mq_receive.c │ ├── mq_send.c │ ├── mq_setattr.c │ ├── mq_unlink.c │ ├── mqcreate.c │ ├── mqgetattr.c │ ├── mqnotify1.c │ ├── mqreceive.c │ ├── mqsend.c │ ├── mqueue.h │ ├── mqunlink.c │ ├── new │ │ └── mymq_receive.c │ ├── test1.c │ ├── test2.c │ ├── testmq.c │ └── unpipc.h │ ├── my_pxsem_fifo │ ├── Makefile │ ├── README │ ├── prodcons1.c │ ├── sem_close.c │ ├── sem_open.c │ ├── sem_post.c │ ├── sem_unlink.c │ ├── sem_wait.c │ ├── semaphore.h │ ├── testeintr.c │ └── unpipc.h │ ├── my_pxsem_mmap │ ├── Makefile │ ├── README │ ├── prodcons1.c │ ├── sem_close.c │ ├── sem_getvalue.c │ ├── sem_open.c │ ├── sem_post.c │ ├── sem_trywait.c │ ├── sem_unlink.c │ ├── sem_wait.c │ ├── semaphore.h │ ├── testeintr.c │ ├── testsem.c │ └── unpipc.h │ ├── my_pxsem_svsem │ ├── Makefile │ ├── README │ ├── prodcons1.c │ ├── sem_close.c │ ├── sem_getvalue.c │ ├── sem_open.c │ ├── sem_post.c │ ├── sem_trywait.c │ ├── sem_unlink.c │ ├── sem_wait.c │ ├── semaphore.h │ ├── testeintr.c │ ├── testsem.c │ └── unpipc.h │ ├── my_rwlock │ ├── Makefile │ ├── incr_rwlock1.c │ ├── pthread_rwlock.h │ ├── pthread_rwlock_destroy.c │ ├── pthread_rwlock_init.c │ ├── pthread_rwlock_rdlock.c │ ├── pthread_rwlock_tryrdlock.c │ ├── pthread_rwlock_trywrlock.c │ ├── pthread_rwlock_unlock.c │ ├── pthread_rwlock_wrlock.c │ ├── test1.c │ ├── test1.time.sh │ ├── testcancel.c │ └── unpipc.h │ ├── my_rwlock_cancel │ ├── Makefile │ ├── README │ ├── incr_rwlock1.c │ ├── pthread_rwlock.h │ ├── pthread_rwlock_destroy.c │ ├── pthread_rwlock_init.c │ ├── pthread_rwlock_rdlock.c │ ├── pthread_rwlock_tryrdlock.c │ ├── pthread_rwlock_trywrlock.c │ ├── pthread_rwlock_unlock.c │ ├── pthread_rwlock_wrlock.c │ ├── test1.c │ ├── testcancel.c │ └── unpipc.h │ ├── pipe │ ├── Makefile │ ├── client.c │ ├── client_main.c │ ├── fduplex.c │ ├── fifo.h │ ├── mainfifo.c │ ├── mainpipe.c │ ├── mainpopen.c │ ├── pipeconf.c │ ├── server.c │ ├── server_main.c │ ├── test1.c │ ├── test2.c │ └── unpipc.h │ ├── pipemesg │ ├── Makefile │ ├── client.c │ ├── mainfifo.c │ ├── mainpipe.c │ ├── mesg.h │ ├── mesg_recv.c │ ├── mesg_send.c │ ├── server.c │ └── unpipc.h │ ├── pxmsg │ ├── Makefile │ ├── mqcreate.c │ ├── mqcreate1.c │ ├── mqgetattr.c │ ├── mqnotify3.c │ ├── mqnotifysig1.c │ ├── mqnotifysig2.c │ ├── mqnotifysig3.c │ ├── mqnotifysig4.c │ ├── mqnotifysig5.c │ ├── mqnotifythread1.c │ ├── mqnotifythread1.c.sun │ ├── mqreceive.c │ ├── mqsend.c │ ├── mqsysconf.c │ ├── mqunlink.c │ ├── test1.c │ └── unpipc.h │ ├── pxsem │ ├── Makefile │ ├── deadlock.c │ ├── mycat1.c │ ├── mycat2.c │ ├── prodcons1.c │ ├── prodcons2.c │ ├── prodcons3.c │ ├── prodcons4.c │ ├── semcreate.c │ ├── semgetvalue.c │ ├── sempost.c │ ├── semsysconf.c │ ├── semunlink.c │ ├── semwait.c │ ├── testeintr.c │ └── unpipc.h │ ├── pxshm │ ├── Makefile │ ├── client1.c │ ├── client2.c │ ├── cliserv2.h │ ├── server1.c │ ├── server2.c │ ├── shmcreate.c │ ├── shmread.c │ ├── shmunlink.c │ ├── shmwrite.c │ ├── test1.c │ ├── test2.c │ ├── test3.c │ └── unpipc.h │ ├── rtsignals │ ├── Makefile │ ├── test1.c │ ├── test2.c │ ├── test3.c │ └── unpipc.h │ ├── shm │ ├── Makefile │ ├── incr1.c │ ├── incr2.c │ ├── incr2private.c │ ├── incr3.c │ ├── incr_dev_zero.c │ ├── incr_map_anon.c │ ├── svmsgread.c │ ├── test.data │ ├── test1.c │ ├── test2.c │ ├── test3.c │ └── unpipc.h │ ├── sparc-sun-solaris2.6 │ ├── Make.defines │ ├── Makefile │ ├── config.cache │ ├── config.h │ └── config.status │ ├── sunrpc │ ├── Make.defines │ ├── Makefile │ ├── config.h │ ├── square1 │ │ ├── Makefile │ │ ├── client.c │ │ ├── server.c │ │ ├── square.x │ │ └── unpipc.h │ ├── square10 │ │ ├── Makefile │ │ ├── client.c │ │ ├── server.c │ │ ├── square.x │ │ └── unpipc.h │ ├── square2 │ │ ├── Makefile │ │ ├── client.c │ │ ├── server.c │ │ ├── square.x │ │ └── unpipc.h │ ├── square3 │ │ ├── Makefile │ │ ├── client.c │ │ ├── server.c │ │ ├── square.x │ │ └── unpipc.h │ ├── square4 │ │ ├── Makefile │ │ ├── client.c │ │ ├── server.c │ │ ├── square.x │ │ └── unpipc.h │ ├── square5 │ │ ├── Makefile │ │ ├── client.c │ │ ├── server.c │ │ ├── square.x │ │ └── unpipc.h │ ├── square6 │ │ ├── Makefile │ │ ├── client.c │ │ ├── server.c │ │ ├── square.x │ │ └── unpipc.h │ ├── square7 │ │ ├── Makefile │ │ ├── client.c │ │ ├── server.c │ │ ├── square.x │ │ └── unpipc.h │ ├── square8 │ │ ├── Makefile │ │ ├── client.c │ │ ├── server.c │ │ ├── square.x │ │ └── unpipc.h │ ├── square9 │ │ ├── Makefile │ │ ├── client.c │ │ ├── script.1.save │ │ ├── server.c │ │ ├── square.x │ │ └── unpipc.h │ ├── test1 │ │ ├── Makefile │ │ ├── data.x │ │ ├── main.c │ │ ├── nullargs.h │ │ ├── nullargs.x │ │ └── unpipc.h │ └── xdr1 │ │ ├── Makefile │ │ ├── alpha.data │ │ ├── data.save.h │ │ ├── data.x │ │ ├── example.c │ │ ├── example.x │ │ ├── opt1.c │ │ ├── opt1.h │ │ ├── opt1.save.h │ │ ├── opt1.x │ │ ├── opt1z.c │ │ ├── opt2.c │ │ ├── opt2.h │ │ ├── opt2.save.h │ │ ├── opt2.x │ │ ├── opt2z.c │ │ ├── read.c │ │ ├── sparc.data │ │ ├── test1.h │ │ ├── test1.x │ │ ├── unpipc.h │ │ └── write.c │ ├── svipc │ ├── Makefile │ ├── ftok.c │ ├── ftok1.c │ └── unpipc.h │ ├── svmsg │ ├── Makefile │ ├── ctl.c │ ├── limits.c │ ├── msgcreate.c │ ├── msgrcv.c │ ├── msgrcvid.c │ ├── msgrmid.c │ ├── msgsnd.c │ ├── slot.c │ ├── slotseq.c │ ├── testumask.c │ ├── twoqueues.c │ └── unpipc.h │ ├── svmsgcliserv │ ├── Makefile │ ├── client.c │ ├── client_main.c │ ├── mesg.h │ ├── mesg_recv.c │ ├── mesg_send.c │ ├── server.c │ ├── server_main.c │ ├── svmsg.h │ └── unpipc.h │ ├── svmsgmpx1q │ ├── Makefile │ ├── client.c │ ├── client_main.c │ ├── mesg.h │ ├── mesg_recv.c │ ├── mesg_send.c │ ├── server.c │ ├── server_main.c │ ├── svmsg.h │ └── unpipc.h │ ├── svmsgmpxnq │ ├── Makefile │ ├── client.c │ ├── client_main.c │ ├── mesg.h │ ├── mesg_recv.c │ ├── mesg_send.c │ ├── server.c │ ├── server_main.c │ ├── sigchldwaitpid.c │ ├── svmsg.h │ └── unpipc.h │ ├── svsem │ ├── Makefile │ ├── initval.c │ ├── limits.c │ ├── semcreate.c │ ├── semgetvalues.c │ ├── semops.c │ ├── semopsid.c │ ├── semrmid.c │ ├── semsetvalues.c │ └── unpipc.h │ └── svshm │ ├── Makefile │ ├── limits.c │ ├── shmget.c │ ├── shmread.c │ ├── shmreadid.c │ ├── shmrmid.c │ ├── shmwrite.c │ └── unpipc.h ├── docs ├── 第10章-Posix信号量 │ └── 第10章-Posix信号量.md ├── 第11章-System_V信号量 │ └── 第11章-System_V信号量.md ├── 第12章-共享内存区介绍 │ └── 第12章-共享内存区介绍.md ├── 第13章-Posix共享内存区 │ └── 第13章-Posix共享内存区.md ├── 第14章-System_V共享内存区 │ └── 第14章-System_V共享内存区.md ├── 第15章-门 │ └── 第15章-门.md ├── 第16章-Sun_RPC │ └── 第16章-Sun_RPC.md ├── 第1章-简介 │ └── 第1章-简介.md ├── 第2章-Posix_IPC │ └── 第2章-Posix_IPC.md ├── 第3章-System_V_IPC │ └── 第3章-System_V_IPC.md ├── 第4章-管道和FIFO │ └── 第4章-管道和FIFO.md ├── 第5章-Posix消息队列 │ └── 第5章-Posix消息队列.md ├── 第6章-System_V消息队列 │ └── 第6章-System_V消息队列.md ├── 第7章-互斥锁和条件变量 │ └── 第7章-互斥锁和条件变量.md ├── 第8章-读写锁 │ └── 第8章-读写锁.md └── 第9章-记录上锁 │ └── 第9章-记录上锁.md └── image ├── 1533732492938.png └── 1533732533595.png /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | * [learn-unp2](README.md) 4 | * [第1章-简介](docs/第1章-简介/第1章-简介.md) 5 | * [第2章-Posix_IPC](docs/第2章-Posix_IPC/第2章-Posix_IPC.md) 6 | * [第3章-System_V_IPC](docs/第3章-System_V_IPC/第3章-System_V_IPC.md) 7 | * [第4章-管道和FIFO](docs/第4章-管道和FIFO/第4章-管道和FIFO.md) 8 | * [第5章-Posix消息队列](docs/第5章-Posix消息队列/第5章-Posix消息队列.md) 9 | * [第6章-System_V消息队列](docs/第6章-System_V消息队列/第6章-System_V消息队列.md) 10 | * [第7章-互斥锁和条件变量](docs/第7章-互斥锁和条件变量/第7章-互斥锁和条件变量.md) 11 | * [第8章-读写锁](docs/第8章-读写锁/第8章-读写锁.md) 12 | * [第9章-记录上锁](docs/第9章-记录上锁/第9章-记录上锁.md) 13 | * [第10章-Posix信号量](docs/第10章-Posix信号量/第10章-Posix信号量.md) 14 | * [第11章-System_V信号量](docs/第11章-System_V信号量/第11章-System_V信号量.md) 15 | * [第12章-共享内存区介绍](docs/第12章-共享内存区介绍/第12章-共享内存区介绍.md) 16 | * [第13章-Posix共享内存区](docs/第13章-Posix共享内存区/第13章-Posix共享内存区.md) 17 | * [第14章-System_V共享内存区](docs/第14章-System_V共享内存区/第14章-System_V共享内存区.md) 18 | * [第15章-门](docs/第15章-门/第15章-门.md) 19 | * [第16章-Sun_RPC](docs/第16章-Sun_RPC/第16章-Sun_RPC.md) 20 | 21 | -------------------------------------------------------------------------------- /code/unpv22e.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yifengyou/learn-unp2/12c1fd4e6f43524f0b173e9385321b67bcb7d653/code/unpv22e.tar.gz -------------------------------------------------------------------------------- /code/unpv22e/DISCLAIMER: -------------------------------------------------------------------------------- 1 | LIMITS OF LIABILITY AND DISCLAIMER OF WARRANTY 2 | 3 | The author and publisher of the book "UNIX Network Programming" have 4 | used their best efforts in preparing this software. These efforts 5 | include the development, research, and testing of the theories and 6 | programs to determine their effectiveness. The author and publisher 7 | make no warranty of any kind, express or implied, with regard to 8 | these programs or the documentation contained in the book. The author 9 | and publisher shall not be liable in any event for incidental or 10 | consequential damages in connection with, or arising out of, the 11 | furnishing, performance, or use of these programs. 12 | -------------------------------------------------------------------------------- /code/unpv22e/Make.defines.in: -------------------------------------------------------------------------------- 1 | # 2 | # This file is generated by autoconf from "Make.defines.in". 3 | # 4 | # This is the "Make.defines" file that almost every "Makefile" in the 5 | # source directories below this directory include. 6 | # The "../" in the pathnames actually refer to this directory, since 7 | # "make" is executed in all the subdirectories of this directory. 8 | # 9 | # System = @host@ 10 | 11 | CC = @CC@ 12 | CFLAGS = @CFLAGS@ 13 | LIBS = @LIBUNPIPC@ @LIBS@ 14 | LIBS_RPC = @LIBS_RPC@ 15 | RANLIB = @RANLIB@ 16 | RPCGEN_OPTS = @RPCGEN_OPTS@ 17 | 18 | # Following is the main library, built from all the object files 19 | # in the lib/ directories. 20 | LIBUNPIPC_NAME = @LIBUNPIPC_NAME@ 21 | 22 | # Following are all the object files to create in the lib/ directory. 23 | LIB_OBJS = @LIB_OBJS@ 24 | 25 | CLEANFILES = core core.* *.core *.o temp.* *.out typescript* \ 26 | *.[234]c *.[234]h *.bsdi *.sparc *.uw 27 | -------------------------------------------------------------------------------- /code/unpv22e/Makefile: -------------------------------------------------------------------------------- 1 | # Generated automatically from Makefile.in by configure. 2 | include ./Make.defines 3 | 4 | all: 5 | @echo "Nothing to make in this directory" 6 | @echo "Please read the README file" 7 | 8 | clean: 9 | rm -f $(CLEANFILES) 10 | 11 | distclean: 12 | rm -f $(CLEANFILES) config.cache config.log config.status 13 | -------------------------------------------------------------------------------- /code/unpv22e/Makefile.in: -------------------------------------------------------------------------------- 1 | include ./Make.defines 2 | 3 | all: 4 | @echo "Nothing to make in this directory" 5 | @echo "Please read the README file" 6 | 7 | clean: 8 | rm -f $(CLEANFILES) 9 | 10 | distclean: 11 | rm -f $(CLEANFILES) config.cache config.log config.status 12 | -------------------------------------------------------------------------------- /code/unpv22e/bench/README: -------------------------------------------------------------------------------- 1 | Not all of the tests in this directory run on all systems. 2 | First execute "make clean" and then build all the programs that will 3 | compile: "make -i". You will get an error for every program that will 4 | not compile, but at the end the only executables are the ones that will 5 | run. 6 | 7 | Then run "bw_lat.sh" and "incr.sh" to measure the bandwidth, 8 | latency, and synchronization times. Notice that these two shell scripts 9 | require at least the 1993 KornShell (ksh93) and they skip any executable 10 | that does not exist. 11 | 12 | The three files "lat_signal.c", "lat_sigwait.c", and 13 | "lat_sigqueue.c" were developed after the book was published and 14 | were not in the source code tar ball until Sept. 21, 1998. These 15 | three programs measure the latency involved when using signals as 16 | a form of IPC (which should not really be done). 17 | -------------------------------------------------------------------------------- /code/unpv22e/bench/bw_sunrpc.x: -------------------------------------------------------------------------------- 1 | /* *INDENT-OFF* */ 2 | %#define DEBUG /* so server runs in foreground */ 3 | 4 | struct data_in { 5 | opaque data<>; /* variable-length opaque data */ 6 | }; 7 | 8 | program BW_SUNRPC_PROG { 9 | version BW_SUNRPC_VERS { 10 | void BW_SUNRPC(data_in) = 1; 11 | } = 1; 12 | } = 0x31230001; 13 | /* *INDENT-ON* */ 14 | -------------------------------------------------------------------------------- /code/unpv22e/bench/bw_sunrpc_server.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "bw_sunrpc.h" 3 | 4 | #ifndef RPCGEN_ANSIC 5 | #define bw_sunrpc_1_svc bw_sunrpc_1 6 | #endif 7 | 8 | void * 9 | bw_sunrpc_1_svc(data_in *inp, struct svc_req *rqstp) 10 | { 11 | static int nbytes; 12 | 13 | nbytes = inp->data.data_len; 14 | return(&nbytes); /* must be nonnull, but xdr_void() will ignore */ 15 | } 16 | -------------------------------------------------------------------------------- /code/unpv22e/bench/graph.1: -------------------------------------------------------------------------------- 1 | 1024 6.3 2 | 2048 8.7 3 | 4096 9.8 4 | 8192 12.7 5 | 16384 13.1 6 | 32768 13.2 7 | 65536 13.7 8 | break 9 | 1024 3.7 10 | 2048 5.3 11 | 4096 8.4 12 | 8192 10.2 13 | 16384 11.6 14 | 32768 13.4 15 | 65536 14.4 16 | break 17 | 1024 4.9 18 | 2048 6.3 19 | 4096 6.6 20 | 8192 5.8 21 | 16384 6.1 22 | -------------------------------------------------------------------------------- /code/unpv22e/bench/graph.2: -------------------------------------------------------------------------------- 1 | 1 0.7 "Posix mutex" 2 | 2 1.5 3 | 3 2.2 4 | 4 2.9 5 | 5 3.7 6 | break 7 | 8 | 1 2.0 "Posix read-write lock" 9 | 2 5.4 10 | 3 7.5 11 | 4 13.7 12 | 5 19.7 13 | break 14 | 15 | 1 4.5 "Posix memory-based semaphore" 16 | 2 9.0 17 | 3 14.4 18 | 4 18.2 19 | 5 22.8 20 | break 21 | 22 | 1 15.4 "Posix named semaphore" 23 | 2 31.1 24 | 3 46.5 25 | 4 62.5 26 | 5 76.8 27 | break 28 | 29 | 1 16.3 "System V semaphore, w/out UNDO" 30 | 2 31.5 31 | 3 48.3 32 | 4 65.8 33 | 5 81.8 34 | break 35 | 36 | 1 21.1 "System V semaphore, with UNDO" 37 | 2 37.5 38 | 3 57.7 39 | 4 75.8 40 | 5 90.0 41 | break 42 | 43 | 1 89.4 "fcntl" 44 | break 45 | -------------------------------------------------------------------------------- /code/unpv22e/bench/lat_pipe.c: -------------------------------------------------------------------------------- 1 | /* include lat_pipe1 */ 2 | #include "unpipc.h" 3 | 4 | void 5 | doit(int readfd, int writefd) 6 | { 7 | char c; 8 | 9 | Write(writefd, &c, 1); 10 | if (Read(readfd, &c, 1) != 1) 11 | err_quit("read error"); 12 | } 13 | 14 | int 15 | main(int argc, char **argv) 16 | { 17 | int i, nloop, pipe1[2], pipe2[2]; 18 | char c; 19 | pid_t childpid; 20 | 21 | if (argc != 2) 22 | err_quit("usage: lat_pipe <#loops>"); 23 | nloop = atoi(argv[1]); 24 | 25 | Pipe(pipe1); 26 | Pipe(pipe2); 27 | 28 | if ( (childpid = Fork()) == 0) { 29 | for ( ; ; ) { /* child */ 30 | if (Read(pipe1[0], &c, 1) != 1) 31 | err_quit("read error"); 32 | Write(pipe2[1], &c, 1); 33 | } 34 | exit(0); 35 | } 36 | /* 4parent */ 37 | doit(pipe2[0], pipe1[1]); 38 | 39 | Start_time(); 40 | for (i = 0; i < nloop; i++) 41 | doit(pipe2[0], pipe1[1]); 42 | printf("latency: %.3f usec\n", Stop_time() / nloop); 43 | 44 | Kill(childpid, SIGTERM); 45 | exit(0); 46 | } 47 | /* end lat_pipe1 */ 48 | -------------------------------------------------------------------------------- /code/unpv22e/bench/lat_sigwait.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i, nloop, signo; 7 | pid_t childpid, parentpid; 8 | sigset_t newmask; 9 | 10 | if (argc != 2) 11 | err_quit("usage: lat_sigwait <#loops>"); 12 | nloop = atoi(argv[1]); 13 | 14 | Sigemptyset(&newmask); 15 | Sigaddset(&newmask, SIGUSR1); 16 | Sigprocmask(SIG_BLOCK, &newmask, NULL); /* block SIGUSR1 */ 17 | 18 | parentpid = getpid(); 19 | if ( (childpid = Fork()) == 0) { 20 | for (i = 0; i < nloop; i++) { /* child */ 21 | Sigwait(&newmask, &signo); 22 | Kill(parentpid, SIGUSR1); 23 | } 24 | exit(0); 25 | } 26 | /* 4parent */ 27 | Start_time(); 28 | for (i = 0; i < nloop; i++) { 29 | Kill(childpid, SIGUSR1); 30 | Sigwait(&newmask, &signo); 31 | } 32 | printf("latency: %.3f usec\n", Stop_time() / nloop); 33 | exit(0); 34 | } 35 | -------------------------------------------------------------------------------- /code/unpv22e/bench/lat_sunrpc.x: -------------------------------------------------------------------------------- 1 | /* *INDENT-OFF* */ 2 | %#define DEBUG /* so server runs in foreground */ 3 | 4 | struct data_in { 5 | opaque data<>; /* variable-length opaque data */ 6 | }; 7 | 8 | program BW_SUNRPC_PROG { 9 | version BW_SUNRPC_VERS { 10 | void BW_SUNRPC(data_in) = 1; 11 | } = 1; 12 | } = 0x31230001; 13 | /* *INDENT-ON* */ 14 | -------------------------------------------------------------------------------- /code/unpv22e/bench/lat_sunrpc_client.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "lat_sunrpc.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | int i, nloop; 8 | CLIENT *cl; 9 | struct timeval tv; 10 | 11 | if (argc != 4) 12 | err_quit("usage: lat_sunrpc_client <#loops> "); 13 | nloop = atoi(argv[2]); 14 | 15 | cl = Clnt_create(argv[1], BW_SUNRPC_PROG, BW_SUNRPC_VERS, argv[3]); 16 | 17 | tv.tv_sec = 10; 18 | tv.tv_usec = 0; 19 | Start_time(); 20 | for (i = 0; i < nloop; i++) { 21 | if (clnt_call(cl, NULLPROC, xdr_void, NULL, 22 | xdr_void, NULL, tv) != RPC_SUCCESS) 23 | err_quit("%s", clnt_sperror(cl, argv[1])); 24 | } 25 | printf("latency: %.3f usec\n", Stop_time() / nloop); 26 | exit(0); 27 | } 28 | -------------------------------------------------------------------------------- /code/unpv22e/bench/lat_sunrpc_server.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "lat_sunrpc.h" 3 | 4 | #ifndef RPCGEN_ANSIC 5 | #define bw_sunrpc_1_svc bw_sunrpc_1 6 | #endif 7 | 8 | void * 9 | bw_sunrpc_1_svc(data_in *inp, struct svc_req *rqstp) 10 | { 11 | static int nbytes; 12 | 13 | nbytes = inp->data.data_len; 14 | return(&nbytes); /* must be nonnull, but xdr_void() will ignore */ 15 | } 16 | -------------------------------------------------------------------------------- /code/unpv22e/doors/client1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd; 7 | long ival, oval; 8 | door_arg_t arg; 9 | 10 | if (argc != 3) 11 | err_quit("usage: client1 "); 12 | 13 | fd = Open(argv[1], O_RDWR); /* open the door */ 14 | 15 | /* 4set up the arguments and pointer to result */ 16 | ival = atol(argv[2]); 17 | arg.data_ptr = (char *) &ival; /* data arguments */ 18 | arg.data_size = sizeof(long); /* size of data arguments */ 19 | arg.desc_ptr = NULL; 20 | arg.desc_num = 0; 21 | arg.rbuf = (char *) &oval; /* data results */ 22 | arg.rsize = sizeof(long); /* size of data results */ 23 | 24 | /* 4call server procedure and print result */ 25 | Door_call(fd, &arg); 26 | printf("result: %ld\n", oval); 27 | 28 | exit(0); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/doors/client2.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd; 7 | long ival, oval; 8 | door_arg_t arg; 9 | 10 | if (argc != 3) 11 | err_quit("usage: client2 "); 12 | 13 | fd = Open(argv[1], O_RDWR); /* open the door */ 14 | 15 | /* 4set up the arguments and pointer to result */ 16 | ival = atol(argv[2]); 17 | arg.data_ptr = (char *) &ival; /* data arguments */ 18 | arg.data_size = sizeof(long); /* size of data arguments */ 19 | arg.desc_ptr = NULL; 20 | arg.desc_num = 0; 21 | arg.rbuf = (char *) &oval; /* data results */ 22 | arg.rsize = sizeof(long); /* size of data results */ 23 | 24 | /* 4call server procedure and print result */ 25 | Door_call(fd, &arg); 26 | printf("&oval = %p, data_ptr = %p, rbuf = %p, rsize = %d\n", 27 | &oval, arg.data_ptr, arg.rbuf, arg.rsize); 28 | printf("result: %ld\n", *((long *) arg.data_ptr)); 29 | 30 | exit(0); 31 | } 32 | -------------------------------------------------------------------------------- /code/unpv22e/doors/client3.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd; 7 | long ival, oval; 8 | door_arg_t arg; 9 | 10 | if (argc != 3) 11 | err_quit("usage: client3 "); 12 | 13 | fd = Open(argv[1], O_RDWR); /* open the door */ 14 | 15 | /* 4set up the arguments and pointer to result */ 16 | ival = atol(argv[2]); 17 | arg.data_ptr = (char *) &ival; /* data arguments */ 18 | arg.data_size = sizeof(long); /* size of data arguments */ 19 | arg.desc_ptr = NULL; 20 | arg.desc_num = 0; 21 | arg.rbuf = (char *) &oval; /* data results */ 22 | arg.rsize = sizeof(long) - 1; /* size of data results */ 23 | 24 | /* 4call server procedure and print result */ 25 | Door_call(fd, &arg); 26 | printf("&oval = %p, data_ptr = %p, rbuf = %p, rsize = %d\n", 27 | &oval, arg.data_ptr, arg.rbuf, arg.rsize); 28 | printf("result: %ld\n", *((long *) arg.data_ptr)); 29 | 30 | exit(0); 31 | } 32 | -------------------------------------------------------------------------------- /code/unpv22e/doors/client4.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd; 7 | long ival, oval; 8 | door_arg_t arg; 9 | 10 | if (argc != 3) 11 | err_quit("usage: client4 "); 12 | 13 | fd = Open(argv[1], O_RDWR); /* open the door */ 14 | 15 | /* 4set up the arguments and pointer to result */ 16 | ival = atol(argv[2]); 17 | arg.data_ptr = (char *) &ival; /* data arguments */ 18 | arg.data_size = sizeof(long); /* size of data arguments */ 19 | arg.desc_ptr = NULL; 20 | arg.desc_num = 0; 21 | arg.rbuf = (char *) &oval; /* data results */ 22 | arg.rsize = sizeof(long); /* size of data results */ 23 | 24 | /* 4call server procedure and print result */ 25 | Door_call(fd, &arg); 26 | printf("result: %ld\n", *((long *) arg.data_ptr)); 27 | 28 | exit(0); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/doors/client5.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd; 7 | long ival, oval; 8 | door_arg_t arg; 9 | 10 | if (argc != 3) 11 | err_quit("usage: client5 "); 12 | 13 | fd = Open(argv[1], O_RDWR); /* open the door */ 14 | 15 | /* 4set up the arguments and pointer to result */ 16 | ival = atol(argv[2]); 17 | arg.data_ptr = (char *) &ival; /* data arguments */ 18 | arg.data_size = sizeof(long); /* size of data arguments */ 19 | arg.desc_ptr = NULL; 20 | arg.desc_num = 0; 21 | arg.rbuf = (char *) &oval; /* data results */ 22 | arg.rsize = sizeof(long); /* size of data results */ 23 | 24 | /* 4call server procedure and print result */ 25 | Door_call(fd, &arg); 26 | printf("result: %ld\n", *((long *) arg.data_ptr)); 27 | 28 | exit(0); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/doors/client6.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd; 7 | long ival, oval; 8 | door_arg_t arg; 9 | 10 | if (argc != 3) 11 | err_quit("usage: client6 "); 12 | 13 | fd = Open(argv[1], O_RDWR); /* open the door */ 14 | 15 | /* 4set up the arguments and pointer to result */ 16 | ival = atol(argv[2]); 17 | arg.data_ptr = (char *) &ival; /* data arguments */ 18 | arg.data_size = sizeof(long); /* size of data arguments */ 19 | arg.desc_ptr = NULL; 20 | arg.desc_num = 0; 21 | arg.rbuf = (char *) &oval; /* data results */ 22 | arg.rsize = sizeof(long); /* size of data results */ 23 | 24 | /* 4call server procedure and print result */ 25 | Door_call(fd, &arg); 26 | printf("result: %ld\n", *((long *) arg.data_ptr)); 27 | 28 | exit(0); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/doors/client8.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd; 7 | long ival, oval; 8 | door_arg_t arg; 9 | 10 | if (argc != 3) 11 | err_quit("usage: client8 "); 12 | 13 | fd = Open(argv[1], O_RDWR); /* open the door */ 14 | 15 | /* 4set up the arguments and pointer to result */ 16 | ival = atol(argv[2]); 17 | arg.data_ptr = (char *) &ival; /* data arguments */ 18 | arg.data_size = sizeof(long); /* size of data arguments */ 19 | arg.desc_ptr = NULL; 20 | arg.desc_num = 0; 21 | arg.rbuf = (char *) &oval; /* data results */ 22 | arg.rsize = sizeof(long); /* size of data results */ 23 | 24 | /* 4call server procedure and print result */ 25 | Door_call(fd, &arg); 26 | printf("result: %ld\n", oval); 27 | 28 | exit(0); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/doors/client9.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd; 7 | long ival, oval; 8 | door_arg_t arg; 9 | 10 | if (argc != 3) 11 | err_quit("usage: client9 "); 12 | 13 | fd = Open(argv[1], O_RDWR); /* open the door */ 14 | 15 | /* 4set up the arguments and pointer to result */ 16 | ival = atol(argv[2]); 17 | arg.data_ptr = (char *) &ival; /* data arguments */ 18 | arg.data_size = sizeof(long); /* size of data arguments */ 19 | arg.desc_ptr = NULL; 20 | arg.desc_num = 0; 21 | arg.rbuf = (char *) &oval; /* data results */ 22 | arg.rsize = sizeof(long); /* size of data results */ 23 | 24 | /* 4call server procedure and print result */ 25 | Door_call(fd, &arg); 26 | printf("result: %ld\n", oval); 27 | 28 | exit(0); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/doors/clientintr1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd; 7 | long ival, oval; 8 | door_arg_t arg; 9 | 10 | if (argc != 3) 11 | err_quit("usage: clientintr1 "); 12 | 13 | fd = Open(argv[1], O_RDWR); /* open the door */ 14 | 15 | /* 4set up the arguments and pointer to result */ 16 | ival = atol(argv[2]); 17 | arg.data_ptr = (char *) &ival; /* data arguments */ 18 | arg.data_size = sizeof(long); /* size of data arguments */ 19 | arg.desc_ptr = NULL; 20 | arg.desc_num = 0; 21 | arg.rbuf = (char *) &oval; /* data results */ 22 | arg.rsize = sizeof(long); /* size of data results */ 23 | 24 | /* 4call server procedure and print result */ 25 | Door_call(fd, &arg); 26 | printf("result: %ld\n", oval); 27 | 28 | exit(0); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/doors/clientintr4.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd; 7 | long ival, oval; 8 | door_arg_t arg; 9 | 10 | if (argc != 3) 11 | err_quit("usage: clientintr4 "); 12 | 13 | fd = Open(argv[1], O_RDWR); /* open the door */ 14 | 15 | /* 4set up the arguments and pointer to result */ 16 | ival = atol(argv[2]); 17 | arg.data_ptr = (char *) &ival; /* data arguments */ 18 | arg.data_size = sizeof(long); /* size of data arguments */ 19 | arg.desc_ptr = NULL; 20 | arg.desc_num = 0; 21 | arg.rbuf = (char *) &oval; /* data results */ 22 | arg.rsize = sizeof(long); /* size of data results */ 23 | 24 | /* 4call server procedure and print result */ 25 | alarm(3); 26 | Door_call(fd, &arg); 27 | printf("result: %ld\n", oval); 28 | 29 | exit(0); 30 | } 31 | -------------------------------------------------------------------------------- /code/unpv22e/doors/clientunref1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd; 7 | long ival, oval; 8 | door_arg_t arg; 9 | 10 | if (argc != 3) 11 | err_quit("usage: client1 "); 12 | 13 | fd = Open(argv[1], O_RDWR); /* open the door */ 14 | 15 | /* 4set up the arguments and pointer to result */ 16 | ival = atol(argv[2]); 17 | arg.data_ptr = (char *) &ival; /* data arguments */ 18 | arg.data_size = sizeof(long); /* size of data arguments */ 19 | arg.desc_ptr = NULL; 20 | arg.desc_num = 0; 21 | arg.rbuf = (char *) &oval; /* data results */ 22 | arg.rsize = sizeof(long); /* size of data results */ 23 | 24 | /* 4call server procedure and print result */ 25 | Door_call(fd, &arg); 26 | printf("result: %ld\n", oval); 27 | 28 | exit(0); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/doors/clientunref2.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd; 7 | long ival, oval; 8 | door_arg_t arg; 9 | 10 | if (argc != 3) 11 | err_quit("usage: client1 "); 12 | 13 | fd = Open(argv[1], O_RDWR); /* open the door */ 14 | 15 | /* 4set up the arguments and pointer to result */ 16 | ival = atol(argv[2]); 17 | arg.data_ptr = (char *) &ival; /* data arguments */ 18 | arg.data_size = sizeof(long); /* size of data arguments */ 19 | arg.desc_ptr = NULL; 20 | arg.desc_num = 0; 21 | arg.rbuf = (char *) &oval; /* data results */ 22 | arg.rsize = sizeof(long); /* size of data results */ 23 | 24 | /* 4call server procedure and print result */ 25 | Door_call(fd, &arg); 26 | printf("result: %ld\n", oval); 27 | 28 | exit(0); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/doors/doorinfo.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd; 7 | struct stat stat; 8 | struct door_info info; 9 | 10 | if (argc != 2) 11 | err_quit("usage: doorinfo "); 12 | 13 | fd = Open(argv[1], O_RDONLY); 14 | Fstat(fd, &stat); 15 | if (S_ISDOOR(stat.st_mode) == 0) 16 | err_quit("pathname is not a door"); 17 | 18 | Door_info(fd, &info); 19 | printf("server PID = %ld, uniquifier = %ld", 20 | (long) info.di_target, (long) info.di_uniquifier); 21 | if (info.di_attributes & DOOR_LOCAL) 22 | printf(", DOOR_LOCAL"); 23 | if (info.di_attributes & DOOR_PRIVATE) 24 | printf(", DOOR_PRIVATE"); 25 | if (info.di_attributes & DOOR_REVOKED) 26 | printf(", DOOR_REVOKED"); 27 | if (info.di_attributes & DOOR_UNREF) 28 | printf(", DOOR_UNREF"); 29 | printf("\n"); 30 | 31 | exit(0); 32 | } 33 | -------------------------------------------------------------------------------- /code/unpv22e/doors/server1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | void 4 | servproc(void *cookie, char *dataptr, size_t datasize, 5 | door_desc_t *descptr, size_t ndesc) 6 | { 7 | long arg, result; 8 | 9 | arg = *((long *) dataptr); 10 | result = arg * arg; 11 | Door_return((char *) &result, sizeof(result), NULL, 0); 12 | } 13 | 14 | int 15 | main(int argc, char **argv) 16 | { 17 | int fd; 18 | 19 | if (argc != 2) 20 | err_quit("usage: server1 "); 21 | 22 | /* 4create a door descriptor and attach to pathname */ 23 | fd = Door_create(servproc, NULL, 0); 24 | 25 | unlink(argv[1]); 26 | Close(Open(argv[1], O_CREAT | O_RDWR, FILE_MODE)); 27 | Fattach(fd, argv[1]); 28 | 29 | /* 4servproc() handles all client requests */ 30 | for ( ; ; ) 31 | pause(); 32 | } 33 | -------------------------------------------------------------------------------- /code/unpv22e/doors/server2.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | void 4 | servproc(void *cookie, char *dataptr, size_t datasize, 5 | door_desc_t *descptr, size_t ndesc) 6 | { 7 | long arg, result; 8 | 9 | arg = *((long *) dataptr); 10 | result = arg * arg; 11 | Door_return((char *) &result, sizeof(result), NULL, 0); 12 | } 13 | 14 | int 15 | main(int argc, char **argv) 16 | { 17 | int fd; 18 | 19 | if (argc != 2) 20 | err_quit("usage: server2 "); 21 | 22 | /* 4create a door descriptor and attach to pathname */ 23 | fd = Door_create(servproc, NULL, 0); 24 | 25 | unlink(argv[1]); 26 | Close(Open(argv[1], O_CREAT | O_RDWR, FILE_MODE)); 27 | Fattach(fd, argv[1]); 28 | 29 | /* 4servproc() handles all client requests */ 30 | for ( ; ; ) 31 | pause(); 32 | } 33 | -------------------------------------------------------------------------------- /code/unpv22e/doors/server3.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | void 4 | servproc(void *cookie, char *dataptr, size_t datasize, 5 | door_desc_t *descptr, size_t ndesc) 6 | { 7 | long arg, result; 8 | 9 | arg = *((long *) dataptr); 10 | result = arg * arg; 11 | Door_return((char *) &result, sizeof(result), NULL, 0); 12 | } 13 | 14 | int 15 | main(int argc, char **argv) 16 | { 17 | int fd; 18 | 19 | if (argc != 2) 20 | err_quit("usage: server3 "); 21 | 22 | /* 4create a door descriptor and attach to pathname */ 23 | fd = Door_create(servproc, NULL, 0); 24 | 25 | unlink(argv[1]); 26 | Close(Open(argv[1], O_CREAT | O_RDWR, FILE_MODE)); 27 | Fattach(fd, argv[1]); 28 | 29 | /* 4servproc() handles all client requests */ 30 | for ( ; ; ) 31 | pause(); 32 | } 33 | -------------------------------------------------------------------------------- /code/unpv22e/doors/server5.c: -------------------------------------------------------------------------------- 1 | /* include servproc */ 2 | #include "unpipc.h" 3 | 4 | void 5 | servproc(void *cookie, char *dataptr, size_t datasize, 6 | door_desc_t *descptr, size_t ndesc) 7 | { 8 | long arg, result; 9 | 10 | arg = *((long *) dataptr); 11 | printf("thread id %ld, arg = %ld\n", pr_thread_id(NULL), arg); 12 | sleep(5); 13 | 14 | result = arg * arg; 15 | Door_return((char *) &result, sizeof(result), NULL, 0); 16 | } 17 | /* end servproc */ 18 | 19 | int 20 | main(int argc, char **argv) 21 | { 22 | int fd; 23 | 24 | if (argc != 2) 25 | err_quit("usage: server5 "); 26 | 27 | /* 4create a door descriptor and attach to pathname */ 28 | fd = Door_create(servproc, NULL, 0); 29 | 30 | unlink(argv[1]); 31 | Close(Open(argv[1], O_CREAT | O_RDWR, FILE_MODE)); 32 | Fattach(fd, argv[1]); 33 | 34 | /* 4servproc() handles all client requests */ 35 | for ( ; ; ) 36 | pause(); 37 | } 38 | -------------------------------------------------------------------------------- /code/unpv22e/doors/server8.c: -------------------------------------------------------------------------------- 1 | /* include servproc */ 2 | #include "unpipc.h" 3 | 4 | int fd; 5 | 6 | void 7 | servproc(void *cookie, char *dataptr, size_t datasize, 8 | door_desc_t *descptr, size_t ndesc) 9 | { 10 | long arg, result; 11 | 12 | Door_revoke(fd); 13 | arg = *((long *) dataptr); 14 | printf("thread id %ld, arg = %ld\n", pr_thread_id(NULL), arg); 15 | 16 | result = arg * arg; 17 | Door_return((char *) &result, sizeof(result), NULL, 0); 18 | } 19 | /* end servproc */ 20 | 21 | int 22 | main(int argc, char **argv) 23 | { 24 | if (argc != 2) 25 | err_quit("usage: server8 "); 26 | 27 | /* 4create a door descriptor and attach to pathname */ 28 | fd = Door_create(servproc, NULL, 0); 29 | 30 | unlink(argv[1]); 31 | Close(Open(argv[1], O_CREAT | O_RDWR, FILE_MODE)); 32 | Fattach(fd, argv[1]); 33 | 34 | /* 4servproc() handles all client requests */ 35 | for ( ; ; ) 36 | pause(); 37 | } 38 | -------------------------------------------------------------------------------- /code/unpv22e/doors/server9.c: -------------------------------------------------------------------------------- 1 | /* include servproc */ 2 | #include "unpipc.h" 3 | 4 | void 5 | servproc(void *cookie, char *dataptr, size_t datasize, 6 | door_desc_t *descptr, size_t ndesc) 7 | { 8 | long arg, result; 9 | 10 | Door_revoke(*((int *) cookie)); 11 | arg = *((long *) dataptr); 12 | printf("thread id %ld, arg = %ld\n", pr_thread_id(NULL), arg); 13 | 14 | result = arg * arg; 15 | Door_return((char *) &result, sizeof(result), NULL, 0); 16 | } 17 | /* end servproc */ 18 | 19 | int 20 | main(int argc, char **argv) 21 | { 22 | int fd; 23 | 24 | if (argc != 2) 25 | err_quit("usage: server9 "); 26 | 27 | /* 4create a door descriptor and attach to pathname */ 28 | fd = Door_create(servproc, &fd, 0); 29 | 30 | unlink(argv[1]); 31 | Close(Open(argv[1], O_CREAT | O_RDWR, FILE_MODE)); 32 | Fattach(fd, argv[1]); 33 | 34 | /* 4servproc() handles all client requests */ 35 | for ( ; ; ) 36 | pause(); 37 | } 38 | -------------------------------------------------------------------------------- /code/unpv22e/doors/serverintr1.c: -------------------------------------------------------------------------------- 1 | /* include servproc */ 2 | #include "unpipc.h" 3 | 4 | void 5 | servproc(void *cookie, char *dataptr, size_t datasize, 6 | door_desc_t *descptr, size_t ndesc) 7 | { 8 | long arg, result; 9 | 10 | pthread_exit(NULL); /* and see what happens at client */ 11 | arg = *((long *) dataptr); 12 | result = arg * arg; 13 | Door_return((char *) &result, sizeof(result), NULL, 0); 14 | } 15 | /* end servproc */ 16 | 17 | int 18 | main(int argc, char **argv) 19 | { 20 | int fd; 21 | 22 | if (argc != 2) 23 | err_quit("usage: serverintr1 "); 24 | 25 | /* 4create a door descriptor and attach to pathname */ 26 | fd = Door_create(servproc, NULL, 0); 27 | 28 | unlink(argv[1]); 29 | Close(Open(argv[1], O_CREAT | O_RDWR, FILE_MODE)); 30 | Fattach(fd, argv[1]); 31 | 32 | /* 4servproc() handles all client requests */ 33 | for ( ; ; ) 34 | pause(); 35 | } 36 | -------------------------------------------------------------------------------- /code/unpv22e/doors/serverintr2.c: -------------------------------------------------------------------------------- 1 | /* include servproc */ 2 | #include "unpipc.h" 3 | 4 | void 5 | servproc(void *cookie, char *dataptr, size_t datasize, 6 | door_desc_t *descptr, size_t ndesc) 7 | { 8 | long arg, result; 9 | 10 | sleep(6); /* let client catch SIGCHLD */ 11 | arg = *((long *) dataptr); 12 | result = arg * arg; 13 | Door_return((char *) &result, sizeof(result), NULL, 0); 14 | } 15 | /* end servproc */ 16 | 17 | int 18 | main(int argc, char **argv) 19 | { 20 | int fd; 21 | 22 | if (argc != 2) 23 | err_quit("usage: serverintr2 "); 24 | 25 | /* 4create a door descriptor and attach to pathname */ 26 | fd = Door_create(servproc, NULL, 0); 27 | 28 | unlink(argv[1]); 29 | Close(Open(argv[1], O_CREAT | O_RDWR, FILE_MODE)); 30 | Fattach(fd, argv[1]); 31 | 32 | /* 4servproc() handles all client requests */ 33 | for ( ; ; ) 34 | pause(); 35 | } 36 | -------------------------------------------------------------------------------- /code/unpv22e/doors/serverintr3.c: -------------------------------------------------------------------------------- 1 | /* include servproc */ 2 | #include "unpipc.h" 3 | 4 | void 5 | servproc(void *cookie, char *dataptr, size_t datasize, 6 | door_desc_t *descptr, size_t ndesc) 7 | { 8 | long arg, result; 9 | 10 | printf("thread id %ld called\n", pr_thread_id(NULL)); 11 | sleep(6); /* let client catch SIGCHLD */ 12 | arg = *((long *) dataptr); 13 | result = arg * arg; 14 | printf("thread id %ld returning\n", pr_thread_id(NULL)); 15 | Door_return((char *) &result, sizeof(result), NULL, 0); 16 | } 17 | /* end servproc */ 18 | 19 | int 20 | main(int argc, char **argv) 21 | { 22 | int fd; 23 | 24 | if (argc != 2) 25 | err_quit("usage: serverintr3 "); 26 | 27 | /* 4create a door descriptor and attach to pathname */ 28 | fd = Door_create(servproc, NULL, 0); 29 | 30 | unlink(argv[1]); 31 | Close(Open(argv[1], O_CREAT | O_RDWR, FILE_MODE)); 32 | Fattach(fd, argv[1]); 33 | 34 | /* 4servproc() handles all client requests */ 35 | for ( ; ; ) 36 | pause(); 37 | } 38 | -------------------------------------------------------------------------------- /code/unpv22e/doors/serverunref1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | void 4 | servproc(void *cookie, char *dataptr, size_t datasize, 5 | door_desc_t *descptr, size_t ndesc) 6 | { 7 | long arg, result; 8 | 9 | if (dataptr == DOOR_UNREF_DATA) { 10 | printf("door unreferenced\n"); 11 | Door_return(NULL, 0, NULL, 0); 12 | } 13 | 14 | arg = *((long *) dataptr); 15 | printf("thread id %ld, arg = %ld\n", pr_thread_id(NULL), arg); 16 | sleep(6); 17 | 18 | result = arg * arg; 19 | Door_return((char *) &result, sizeof(result), NULL, 0); 20 | } 21 | 22 | int 23 | main(int argc, char **argv) 24 | { 25 | int fd; 26 | 27 | if (argc != 2) 28 | err_quit("usage: server1 "); 29 | 30 | /* 4create a door descriptor and attach to pathname */ 31 | fd = Door_create(servproc, NULL, DOOR_UNREF); 32 | 33 | unlink(argv[1]); 34 | Close(Open(argv[1], O_CREAT | O_RDWR, FILE_MODE)); 35 | Fattach(fd, argv[1]); 36 | Close(fd); 37 | 38 | /* 4servproc() handles all client requests */ 39 | for ( ; ; ) 40 | pause(); 41 | } 42 | -------------------------------------------------------------------------------- /code/unpv22e/doors/sqrtproc.h: -------------------------------------------------------------------------------- 1 | #define PATH_SQRT_DOOR "/tmp/sqrtproc_door" 2 | 3 | typedef struct { /* input to sqrtproc() */ 4 | long arg1; 5 | } sqrtproc_in_t; 6 | 7 | typedef struct { /* output from sqrtproc() */ 8 | double res1; 9 | } sqrtproc_out_t; 10 | -------------------------------------------------------------------------------- /code/unpv22e/doors/squareproc.h: -------------------------------------------------------------------------------- 1 | #define PATH_SQUARE_DOOR "/tmp/squareproc_door" 2 | 3 | typedef struct { /* input to squareproc() */ 4 | long arg1; 5 | } squareproc_in_t; 6 | 7 | typedef struct { /* output from squareproc() */ 8 | long res1; 9 | } squareproc_out_t; 10 | -------------------------------------------------------------------------------- /code/unpv22e/fifocliserv/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = mainclient mainserver 4 | 5 | all: ${PROGS} 6 | 7 | mainclient: mainclient.o 8 | ${CC} ${CFLAGS} -o $@ mainclient.o ${LIBS} 9 | 10 | mainserver: mainserver.o 11 | ${CC} ${CFLAGS} -o $@ mainserver.o ${LIBS} 12 | 13 | clean: 14 | rm -f ${PROGS} ${CLEANFILES} 15 | -------------------------------------------------------------------------------- /code/unpv22e/fifocliserv/fifo.h: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define SERV_FIFO "/tmp/fifo.serv" 4 | -------------------------------------------------------------------------------- /code/unpv22e/lib/.exrc: -------------------------------------------------------------------------------- 1 | set shell=/bin/ksh optimize redraw nowrapscan showmode 2 | map [11~ ahttp://www.noao.edu/~rstevensa 3 | map [12~ o.RS .2 .REO 4 | map [13~ O.sp 1.0v\"foo 5 | map [14~ :set tabstop=4 6 | map [17~ :w 7 | map [19~ :set tabstop=8 8 | map [20~ :e # 9 | map [21~ :n 10 | map [99~ f 11 | -------------------------------------------------------------------------------- /code/unpv22e/lib/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | # Following required by Solaris 2.x for Posix version of sigwait(). 4 | CFLAGS += -D_POSIX_PTHREAD_SEMANTICS 5 | 6 | all: ${LIB_OBJS} 7 | ar rv ${LIBUNPIPC_NAME} $? 8 | ${RANLIB} ${LIBUNPIPC_NAME} 9 | 10 | clean: 11 | rm -f ${PROGS} ${CLEANFILES} 12 | -------------------------------------------------------------------------------- /code/unpv22e/lib/daemon_inetd.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include 3 | 4 | extern int daemon_proc; /* defined in error.c */ 5 | 6 | void 7 | daemon_inetd(const char *pname, int facility) 8 | { 9 | daemon_proc = 1; /* for our err_XXX() functions */ 10 | openlog(pname, LOG_PID, facility); 11 | } 12 | -------------------------------------------------------------------------------- /code/unpv22e/lib/daemon_init.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include 3 | 4 | #define MAXFD 64 5 | 6 | extern int daemon_proc; /* defined in error.c */ 7 | 8 | void 9 | daemon_init(const char *pname, int facility) 10 | { 11 | int i; 12 | pid_t pid; 13 | 14 | if ( (pid = Fork()) != 0) 15 | exit(0); /* parent terminates */ 16 | 17 | /* 41st child continues */ 18 | setsid(); /* become session leader */ 19 | 20 | Signal(SIGHUP, SIG_IGN); 21 | if ( (pid = Fork()) != 0) 22 | exit(0); /* 1st child terminates */ 23 | 24 | /* 42nd child continues */ 25 | daemon_proc = 1; /* for our err_XXX() functions */ 26 | 27 | chdir("/"); /* change working directory */ 28 | 29 | umask(0); /* clear our file mode creation mask */ 30 | 31 | for (i = 0; i < MAXFD; i++) 32 | close(i); 33 | 34 | openlog(pname, LOG_PID, facility); 35 | } 36 | -------------------------------------------------------------------------------- /code/unpv22e/lib/gf_time.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include 3 | 4 | char * 5 | gf_time(void) 6 | { 7 | struct timeval tv; 8 | static char str[30]; 9 | char *ptr; 10 | 11 | if (gettimeofday(&tv, NULL) < 0) 12 | err_sys("gettimeofday error"); 13 | 14 | ptr = ctime(&tv.tv_sec); 15 | strcpy(str, &ptr[11]); 16 | /* Fri Sep 13 00:00:00 1986\n\0 */ 17 | /* 0123456789012345678901234 5 */ 18 | snprintf(str+8, sizeof(str)-8, ".%06ld", tv.tv_usec); 19 | 20 | return(str); 21 | } 22 | 23 | char * 24 | Gf_time(void) 25 | { 26 | return(gf_time()); 27 | } 28 | -------------------------------------------------------------------------------- /code/unpv22e/lib/isfdtype.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #ifndef S_IFSOCK 4 | #error S_IFSOCK not defined 5 | #endif 6 | 7 | int 8 | isfdtype(int fd, int fdtype) 9 | { 10 | struct stat buf; 11 | 12 | if (fstat(fd, &buf) < 0) 13 | return(-1); 14 | 15 | if ((buf.st_mode & S_IFMT) == fdtype) 16 | return(1); 17 | else 18 | return(0); 19 | } 20 | -------------------------------------------------------------------------------- /code/unpv22e/lib/lock_reg.c: -------------------------------------------------------------------------------- 1 | /* include lock_reg */ 2 | #include "unpipc.h" 3 | 4 | int 5 | lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len) 6 | { 7 | struct flock lock; 8 | 9 | lock.l_type = type; /* F_RDLCK, F_WRLCK, F_UNLCK */ 10 | lock.l_start = offset; /* byte offset, relative to l_whence */ 11 | lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */ 12 | lock.l_len = len; /* #bytes (0 means to EOF) */ 13 | 14 | return( fcntl(fd, cmd, &lock) ); /* -1 upon error */ 15 | } 16 | /* end lock_reg */ 17 | 18 | void 19 | Lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len) 20 | { 21 | if (lock_reg(fd, cmd, type, offset, whence, len) == -1) 22 | err_sys("lock_reg error"); 23 | } 24 | -------------------------------------------------------------------------------- /code/unpv22e/lib/lock_test.c: -------------------------------------------------------------------------------- 1 | /* include lock_test */ 2 | #include "unpipc.h" 3 | 4 | pid_t 5 | lock_test(int fd, int type, off_t offset, int whence, off_t len) 6 | { 7 | struct flock lock; 8 | 9 | lock.l_type = type; /* F_RDLCK or F_WRLCK */ 10 | lock.l_start = offset; /* byte offset, relative to l_whence */ 11 | lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */ 12 | lock.l_len = len; /* #bytes (0 means to EOF) */ 13 | 14 | if (fcntl(fd, F_GETLK, &lock) == -1) 15 | return(-1); /* unexpected error */ 16 | 17 | if (lock.l_type == F_UNLCK) 18 | return(0); /* false, region not locked by another proc */ 19 | return(lock.l_pid); /* true, return positive PID of lock owner */ 20 | } 21 | /* end lock_test */ 22 | 23 | pid_t 24 | Lock_test(int fd, int type, off_t offset, int whence, off_t len) 25 | { 26 | pid_t pid; 27 | 28 | if ( (pid = lock_test(fd, type, offset, whence, len)) == -1) 29 | err_sys("lock_test error"); 30 | return(pid); 31 | } 32 | -------------------------------------------------------------------------------- /code/unpv22e/lib/my_shm.c: -------------------------------------------------------------------------------- 1 | /* include my_shm */ 2 | #include "unpipc.h" 3 | 4 | void * 5 | my_shm(size_t nbytes) 6 | { 7 | void *shared; 8 | 9 | #if defined(MAP_ANON) 10 | shared = mmap(NULL, nbytes, PROT_READ | PROT_WRITE, 11 | MAP_ANON | MAP_SHARED, -1, 0); 12 | 13 | #elif defined(HAVE_DEV_ZERO) 14 | int fd; 15 | 16 | /* 4memory map /dev/zero */ 17 | if ( (fd = open("/dev/zero", O_RDWR)) == -1) 18 | return(MAP_FAILED); 19 | shared = mmap(NULL, nbytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 20 | close(fd); 21 | 22 | # else 23 | # error cannot determine what type of anonymous shared memory to use 24 | # endif 25 | return(shared); /* MAP_FAILED on error */ 26 | } 27 | /* end my_shm */ 28 | 29 | void * 30 | My_shm(size_t nbytes) 31 | { 32 | void *shared; 33 | 34 | if ( (shared = my_shm(nbytes)) == MAP_FAILED) 35 | err_sys("my_shm error"); 36 | return(shared); 37 | } 38 | -------------------------------------------------------------------------------- /code/unpv22e/lib/px_ipc_name.c: -------------------------------------------------------------------------------- 1 | /* include px_ipc_name */ 2 | #include "unpipc.h" 3 | 4 | char * 5 | px_ipc_name(const char *name) 6 | { 7 | char *dir, *dst, *slash; 8 | 9 | if ( (dst = malloc(PATH_MAX)) == NULL) 10 | return(NULL); 11 | 12 | /* 4can override default directory with environment variable */ 13 | if ( (dir = getenv("PX_IPC_NAME")) == NULL) { 14 | #ifdef POSIX_IPC_PREFIX 15 | dir = POSIX_IPC_PREFIX; /* from "config.h" */ 16 | #else 17 | dir = "/tmp/"; /* default */ 18 | #endif 19 | } 20 | /* 4dir must end in a slash */ 21 | slash = (dir[strlen(dir) - 1] == '/') ? "" : "/"; 22 | snprintf(dst, PATH_MAX, "%s%s%s", dir, slash, name); 23 | 24 | return(dst); /* caller can free() this pointer */ 25 | } 26 | /* end px_ipc_name */ 27 | 28 | char * 29 | Px_ipc_name(const char *name) 30 | { 31 | char *ptr; 32 | 33 | if ( (ptr = px_ipc_name(name)) == NULL) 34 | err_sys("px_ipc_name error for %s", name); 35 | return(ptr); 36 | } 37 | -------------------------------------------------------------------------------- /code/unpv22e/lib/readable_timeo.c: -------------------------------------------------------------------------------- 1 | /* include readable_timeo */ 2 | #include "unpipc.h" 3 | 4 | int 5 | readable_timeo(int fd, int sec) 6 | { 7 | fd_set rset; 8 | struct timeval tv; 9 | 10 | FD_ZERO(&rset); 11 | FD_SET(fd, &rset); 12 | 13 | tv.tv_sec = sec; 14 | tv.tv_usec = 0; 15 | 16 | return(select(fd+1, &rset, NULL, NULL, &tv)); 17 | /* 4> 0 if descriptor is readable */ 18 | } 19 | /* end readable_timeo */ 20 | 21 | int 22 | Readable_timeo(int fd, int sec) 23 | { 24 | int n; 25 | 26 | if ( (n = readable_timeo(fd, sec)) < 0) 27 | err_sys("readable_timeo error"); 28 | return(n); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/lib/readn.c: -------------------------------------------------------------------------------- 1 | /* include readn */ 2 | #include "unpipc.h" 3 | 4 | ssize_t /* Read "n" bytes from a descriptor. */ 5 | readn(int fd, void *vptr, size_t n) 6 | { 7 | size_t nleft; 8 | ssize_t nread; 9 | char *ptr; 10 | 11 | ptr = vptr; 12 | nleft = n; 13 | while (nleft > 0) { 14 | if ( (nread = read(fd, ptr, nleft)) < 0) { 15 | if (errno == EINTR) 16 | nread = 0; /* and call read() again */ 17 | else 18 | return(-1); 19 | } else if (nread == 0) 20 | break; /* EOF */ 21 | 22 | nleft -= nread; 23 | ptr += nread; 24 | } 25 | return(n - nleft); /* return >= 0 */ 26 | } 27 | /* end readn */ 28 | 29 | ssize_t 30 | Readn(int fd, void *ptr, size_t nbytes) 31 | { 32 | ssize_t n; 33 | 34 | if ( (n = readn(fd, ptr, nbytes)) < 0) 35 | err_sys("readn error"); 36 | return(n); 37 | } 38 | -------------------------------------------------------------------------------- /code/unpv22e/lib/set_concurrency.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | set_concurrency(int level) 5 | { 6 | #ifdef HAVE_THR_SETCONCURRENCY_PROTO 7 | int thr_setconcurrency(int); 8 | 9 | return(thr_setconcurrency(level)); 10 | #else 11 | return(0); 12 | #endif 13 | } 14 | 15 | void 16 | Set_concurrency(int level) 17 | { 18 | if (set_concurrency(level) != 0) 19 | err_sys("set_concurrency error"); 20 | } 21 | -------------------------------------------------------------------------------- /code/unpv22e/lib/set_nonblock.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | set_nonblock(int fd) 5 | { 6 | int flags; 7 | 8 | if ( (flags = fcntl(fd, F_GETFL, 0)) < 0) 9 | return(-1); 10 | if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) 11 | return(-1); 12 | return(0); 13 | } 14 | 15 | void 16 | Set_nonblock(int fd) 17 | { 18 | if (set_nonblock(fd) < 0) 19 | err_sys("set_nonblock error"); 20 | } 21 | -------------------------------------------------------------------------------- /code/unpv22e/lib/signal.c: -------------------------------------------------------------------------------- 1 | /* include signal */ 2 | #include "unpipc.h" 3 | 4 | Sigfunc * 5 | signal(int signo, Sigfunc *func) 6 | { 7 | struct sigaction act, oact; 8 | 9 | act.sa_handler = func; 10 | sigemptyset(&act.sa_mask); 11 | act.sa_flags = 0; 12 | if (signo == SIGALRM) { 13 | #ifdef SA_INTERRUPT 14 | act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */ 15 | #endif 16 | } else { 17 | #ifdef SA_RESTART 18 | act.sa_flags |= SA_RESTART; /* SVR4, 44BSD */ 19 | #endif 20 | } 21 | if (sigaction(signo, &act, &oact) < 0) 22 | return(SIG_ERR); 23 | return(oact.sa_handler); 24 | } 25 | /* end signal */ 26 | 27 | Sigfunc * 28 | Signal(int signo, Sigfunc *func) /* for our signal() function */ 29 | { 30 | Sigfunc *sigfunc; 31 | 32 | if ( (sigfunc = signal(signo, func)) == SIG_ERR) 33 | err_sys("signal error"); 34 | return(sigfunc); 35 | } 36 | -------------------------------------------------------------------------------- /code/unpv22e/lib/signal_intr.c: -------------------------------------------------------------------------------- 1 | /* include signal_intr */ 2 | #include "unpipc.h" 3 | 4 | Sigfunc * 5 | signal_intr(int signo, Sigfunc *func) 6 | { 7 | struct sigaction act, oact; 8 | 9 | act.sa_handler = func; 10 | sigemptyset(&act.sa_mask); 11 | act.sa_flags = 0; 12 | #ifdef SA_INTERRUPT /* SunOS */ 13 | act.sa_flags |= SA_INTERRUPT; 14 | #endif 15 | if (sigaction(signo, &act, &oact) < 0) 16 | return(SIG_ERR); 17 | return(oact.sa_handler); 18 | } 19 | /* end signal_intr */ 20 | 21 | Sigfunc * 22 | Signal_intr(int signo, Sigfunc *func) 23 | { 24 | Sigfunc *sigfunc; 25 | 26 | if ( (sigfunc = signal_intr(signo, func)) == SIG_ERR) 27 | err_sys("signal_intr error"); 28 | return(sigfunc); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/lib/signal_rt.c: -------------------------------------------------------------------------------- 1 | /* include signal_rt */ 2 | #include "unpipc.h" 3 | 4 | Sigfunc_rt * 5 | signal_rt(int signo, Sigfunc_rt *func) 6 | { 7 | struct sigaction act, oact; 8 | 9 | act.sa_sigaction = func; /* must store function addr here */ 10 | sigemptyset(&act.sa_mask); 11 | act.sa_flags = SA_SIGINFO; /* must specify this for realtime */ 12 | if (signo == SIGALRM) { 13 | #ifdef SA_INTERRUPT 14 | act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */ 15 | #endif 16 | } else { 17 | #ifdef SA_RESTART 18 | act.sa_flags |= SA_RESTART; /* SVR4, 44BSD */ 19 | #endif 20 | } 21 | if (sigaction(signo, &act, &oact) < 0) 22 | return((Sigfunc_rt *) SIG_ERR); 23 | return(oact.sa_sigaction); 24 | } 25 | /* end signal_rt */ 26 | 27 | Sigfunc_rt * 28 | Signal_rt(int signo, Sigfunc_rt *func) 29 | { 30 | Sigfunc_rt *sigfunc; 31 | 32 | if ( (sigfunc = signal_rt(signo, func)) == (Sigfunc_rt *) SIG_ERR) 33 | err_sys("signal_rt error"); 34 | return(sigfunc); 35 | } 36 | -------------------------------------------------------------------------------- /code/unpv22e/lib/signal_rt_intr.c: -------------------------------------------------------------------------------- 1 | /* include signal_rt_intr */ 2 | #include "unpipc.h" 3 | 4 | Sigfunc_rt * 5 | signal_rt_intr(int signo, Sigfunc_rt *func) 6 | { 7 | struct sigaction act, oact; 8 | 9 | act.sa_sigaction = func; 10 | sigemptyset(&act.sa_mask); 11 | act.sa_flags = SA_SIGINFO; /* must specify this for realtime */ 12 | #ifdef SA_INTERRUPT 13 | act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */ 14 | #endif 15 | if (sigaction(signo, &act, &oact) < 0) 16 | return((Sigfunc_rt *) SIG_ERR); 17 | return(oact.sa_sigaction); 18 | } 19 | /* end signal_rt_intr */ 20 | 21 | Sigfunc_rt * 22 | Signal_rt_intr(int signo, Sigfunc_rt *func) 23 | { 24 | Sigfunc_rt *sigfunc; 25 | 26 | if ( (sigfunc = signal_rt_intr(signo, func)) == (Sigfunc_rt *) SIG_ERR) 27 | err_sys("signal_rt_intr error"); 28 | return(sigfunc); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/lib/sleep_us.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | sleep_us(unsigned int nusecs) 5 | { 6 | struct timeval tval; 7 | 8 | if (nusecs == 0) 9 | return(0); 10 | 11 | for ( ; ; ) { 12 | tval.tv_sec = nusecs / 1000000; 13 | tval.tv_usec = nusecs % 1000000; 14 | if (select(0, NULL, NULL, NULL, &tval) == 0) 15 | return(0); /* all OK */ 16 | /* 17 | * Note than on an interrupted system call there's not 18 | * much we can do, since the timeval{} isn't updated with the time 19 | * remaining. We could obtain the clock time before the call, and 20 | * then obtain the clock time here, subtracting them to determine 21 | * how long select() blocked before it was interrupted, but that 22 | * seems like too much work :-) 23 | */ 24 | if (errno != EINTR) 25 | return(-1); 26 | /* else go around again */ 27 | } 28 | } 29 | 30 | void 31 | Sleep_us(unsigned int nusecs) 32 | { 33 | if (sleep_us(nusecs) == -1) 34 | err_sys("sleep_us error"); 35 | } 36 | -------------------------------------------------------------------------------- /code/unpv22e/lib/snprintf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Throughout the book I use snprintf() because it's safer than sprintf(). 3 | * But as of the time of this writing, not all systems provide this 4 | * function. The function below should only be built on those systems 5 | * that do not provide a real snprintf(). 6 | * The function below just acts like sprintf(); it is not safe, but it 7 | * tries to detect overflow. 8 | */ 9 | 10 | #include "unpipc.h" 11 | 12 | #include /* ANSI C header file */ 13 | 14 | int 15 | snprintf(char *buf, size_t size, const char *fmt, ...) 16 | { 17 | int n; 18 | va_list ap; 19 | 20 | va_start(ap, fmt); 21 | vsprintf(buf, fmt, ap); /* Sigh, some vsprintf's return ptr, not length */ 22 | n = strlen(buf); 23 | va_end(ap); 24 | if (n >= size) 25 | err_quit("snprintf: '%s' overflowed array", fmt); 26 | return(n); 27 | } 28 | -------------------------------------------------------------------------------- /code/unpv22e/lib/tv_sub.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | void 4 | tv_sub(struct timeval *out, struct timeval *in) 5 | { 6 | if ( (out->tv_usec -= in->tv_usec) < 0) { /* out -= in */ 7 | --out->tv_sec; 8 | out->tv_usec += 1000000; 9 | } 10 | out->tv_sec -= in->tv_sec; 11 | } 12 | -------------------------------------------------------------------------------- /code/unpv22e/lib/wrapsunrpc.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | CLIENT * 4 | Clnt_create(const char *host, u_long prog, u_long vers, const char *proto) 5 | { 6 | CLIENT *cl; 7 | 8 | if ( (cl = clnt_create(host, prog, vers, proto)) == NULL) { 9 | clnt_pcreateerror(host); 10 | err_quit("clnt_create error"); 11 | } 12 | return(cl); 13 | } 14 | 15 | void 16 | Clnt_control(CLIENT *cl, u_int req, char *ptr) 17 | { 18 | if (clnt_control(cl, req, ptr) == FALSE) { 19 | err_quit("clnt_control error"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /code/unpv22e/lib/writable_timeo.c: -------------------------------------------------------------------------------- 1 | /* include writable_timeo */ 2 | #include "unpipc.h" 3 | 4 | int 5 | writable_timeo(int fd, int sec) 6 | { 7 | fd_set wset; 8 | struct timeval tv; 9 | 10 | FD_ZERO(&wset); 11 | FD_SET(fd, &wset); 12 | 13 | tv.tv_sec = sec; 14 | tv.tv_usec = 0; 15 | 16 | return(select(fd+1, NULL, &wset, NULL, &tv)); 17 | /* > 0 if descriptor is writable */ 18 | } 19 | /* end writable_timeo */ 20 | 21 | int 22 | Writable_timeo(int fd, int sec) 23 | { 24 | int n; 25 | 26 | if ( (n = writable_timeo(fd, sec)) < 0) 27 | err_sys("writable_timeo error"); 28 | return(n); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/lib/writen.c: -------------------------------------------------------------------------------- 1 | /* include writen */ 2 | #include "unpipc.h" 3 | 4 | ssize_t /* Write "n" bytes to a descriptor. */ 5 | writen(int fd, const void *vptr, size_t n) 6 | { 7 | size_t nleft; 8 | ssize_t nwritten; 9 | const char *ptr; 10 | 11 | ptr = vptr; 12 | nleft = n; 13 | while (nleft > 0) { 14 | if ( (nwritten = write(fd, ptr, nleft)) <= 0) { 15 | if (errno == EINTR) 16 | nwritten = 0; /* and call write() again */ 17 | else 18 | return(-1); /* error */ 19 | } 20 | 21 | nleft -= nwritten; 22 | ptr += nwritten; 23 | } 24 | return(n); 25 | } 26 | /* end writen */ 27 | 28 | void 29 | Writen(int fd, void *ptr, size_t nbytes) 30 | { 31 | if (writen(fd, ptr, nbytes) != nbytes) 32 | err_sys("writen error"); 33 | } 34 | -------------------------------------------------------------------------------- /code/unpv22e/lock/lockfcntl.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | void 4 | my_lock(int fd) 5 | { 6 | struct flock lock; 7 | 8 | lock.l_type = F_WRLCK; 9 | lock.l_whence = SEEK_SET; 10 | lock.l_start = 0; 11 | lock.l_len = 0; /* write lock entire file */ 12 | 13 | Fcntl(fd, F_SETLKW, &lock); 14 | } 15 | 16 | void 17 | my_unlock(int fd) 18 | { 19 | struct flock lock; 20 | 21 | lock.l_type = F_UNLCK; 22 | lock.l_whence = SEEK_SET; 23 | lock.l_start = 0; 24 | lock.l_len = 0; /* unlock entire file */ 25 | 26 | Fcntl(fd, F_SETLK, &lock); 27 | } 28 | -------------------------------------------------------------------------------- /code/unpv22e/lock/locklink.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define LOCKFILE "/tmp/seqno.lock" 4 | #define PREFIX "/tmp" /* prefix for temp pathname */ 5 | 6 | void 7 | my_lock(int fd) 8 | { 9 | char *ptr; 10 | 11 | ptr = tempnam(PREFIX, NULL); 12 | /* create/open and then close */ 13 | Close(Open(ptr, O_CREAT | O_RDWR | O_TRUNC, FILE_MODE)); 14 | 15 | while (link(ptr, LOCKFILE) < 0) { 16 | if (errno != EEXIST) 17 | err_sys("link error for lock file"); 18 | /* someone else has the lock, loop around and try again */ 19 | } 20 | Unlink(ptr); /* linked the file, we have the lock */ 21 | free(ptr); /* tempnam() calls malloc() */ 22 | } 23 | 24 | void 25 | my_unlock(int fd) 26 | { 27 | Unlink(LOCKFILE); /* release lock by removing file */ 28 | } 29 | -------------------------------------------------------------------------------- /code/unpv22e/lock/lockmain.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define SEQFILE "seqno" /* filename */ 4 | 5 | void my_lock(int), my_unlock(int); 6 | 7 | int 8 | main(int argc, char **argv) 9 | { 10 | int fd; 11 | long i, seqno; 12 | pid_t pid; 13 | ssize_t n; 14 | char line[MAXLINE + 1]; 15 | 16 | pid = getpid(); 17 | fd = Open(SEQFILE, O_RDWR, FILE_MODE); 18 | 19 | for (i = 0; i < 20; i++) { 20 | my_lock(fd); /* lock the file */ 21 | 22 | Lseek(fd, 0L, SEEK_SET); /* rewind before read */ 23 | n = Read(fd, line, MAXLINE); 24 | line[n] = '\0'; /* null terminate for sscanf */ 25 | 26 | n = sscanf(line, "%ld\n", &seqno); 27 | printf("%s: pid = %ld, seq# = %ld\n", argv[0], (long) pid, seqno); 28 | 29 | seqno++; /* increment sequence number */ 30 | 31 | snprintf(line, sizeof(line), "%ld\n", seqno); 32 | Lseek(fd, 0L, SEEK_SET); /* rewind before write */ 33 | Write(fd, line, strlen(line)); 34 | 35 | my_unlock(fd); /* unlock the file */ 36 | } 37 | exit(0); 38 | } 39 | -------------------------------------------------------------------------------- /code/unpv22e/lock/locknone.c: -------------------------------------------------------------------------------- 1 | void 2 | my_lock(int fd) 3 | { 4 | return; 5 | } 6 | 7 | void 8 | my_unlock(int fd) 9 | { 10 | return; 11 | } 12 | -------------------------------------------------------------------------------- /code/unpv22e/lock/lockopen.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define LOCKFILE "/tmp/seqno.lock" 4 | 5 | void 6 | my_lock(int fd) 7 | { 8 | int tempfd; 9 | 10 | while ( (tempfd = open(LOCKFILE, O_RDWR|O_CREAT|O_EXCL, FILE_MODE)) < 0) { 11 | if (errno != EEXIST) 12 | err_sys("open error for lock file"); 13 | /* someone else has the lock, loop around and try again */ 14 | } 15 | Close(tempfd); /* opened the file, we have the lock */ 16 | } 17 | 18 | void 19 | my_unlock(int fd) 20 | { 21 | Unlink(LOCKFILE); /* release lock by removing file */ 22 | } 23 | -------------------------------------------------------------------------------- /code/unpv22e/lock/lockopen2.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define LOCKFILE "/tmp/seqno.lock" 4 | 5 | void 6 | my_lock(int fd) 7 | { 8 | int tempfd; 9 | 10 | /* create with O_TRUNC and no permission bits */ 11 | while ( (tempfd = open(LOCKFILE, O_CREAT | O_WRONLY | O_TRUNC, 0)) < 0) { 12 | if (errno != EACCES) 13 | err_sys("open error for lock file"); 14 | /* someone else has the lock, loop around and try again */ 15 | } 16 | Close(tempfd); /* opened the file, we have the lock */ 17 | } 18 | 19 | void 20 | my_unlock(int fd) 21 | { 22 | Unlink(LOCKFILE); /* release lock by removing file */ 23 | } 24 | -------------------------------------------------------------------------------- /code/unpv22e/lock/lockpxsem.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define LOCK_PATH "pxsemlock" 4 | 5 | sem_t *locksem; 6 | int initflag; 7 | 8 | void 9 | my_lock(int fd) 10 | { 11 | if (initflag == 0) { 12 | locksem = Sem_open(Px_ipc_name(LOCK_PATH), O_CREAT, FILE_MODE, 1); 13 | initflag = 1; 14 | } 15 | Sem_wait(locksem); 16 | } 17 | 18 | void 19 | my_unlock(int fd) 20 | { 21 | Sem_post(locksem); 22 | } 23 | -------------------------------------------------------------------------------- /code/unpv22e/lock/loop1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/ksh 2 | 3 | cat > seqno < seqno <"); 17 | nloop = atol(argv[1]); 18 | 19 | fd = Open(SEQFILE, O_RDWR, FILE_MODE); 20 | 21 | for (i = 0; i < nloop; i++) { 22 | my_lock(fd); /* lock the file */ 23 | 24 | Lseek(fd, 0L, SEEK_SET); /* rewind before read */ 25 | n = Read(fd, line, MAXLINE); 26 | line[n] = '\0'; /* null terminate for sscanf */ 27 | 28 | n = sscanf(line, "%ld\n", &seqno); 29 | seqno++; /* increment sequence number */ 30 | 31 | snprintf(line, sizeof(line), "%ld\n", seqno); 32 | Lseek(fd, 0L, SEEK_SET); /* rewind before write */ 33 | Write(fd, line, strlen(line)); 34 | 35 | my_unlock(fd); /* unlock the file */ 36 | } 37 | exit(0); 38 | } 39 | -------------------------------------------------------------------------------- /code/unpv22e/lock/loopmainnonb.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define SEQFILE "seqno" /* filename */ 4 | 5 | void my_lock(int), my_unlock(int); 6 | 7 | int 8 | main(int argc, char **argv) 9 | { 10 | int fd; 11 | long i, nloop, seqno; 12 | ssize_t n; 13 | char line[MAXLINE + 1]; 14 | 15 | if (argc != 2) 16 | err_quit("usage: loopmain "); 17 | nloop = atol(argv[1]); 18 | 19 | fd = Open(SEQFILE, O_RDWR | O_NONBLOCK, FILE_MODE); 20 | 21 | for (i = 0; i < nloop; i++) { 22 | my_lock(fd); /* lock the file */ 23 | 24 | Lseek(fd, 0L, SEEK_SET); /* rewind before read */ 25 | n = Read(fd, line, MAXLINE); 26 | line[n] = '\0'; /* null terminate for sscanf */ 27 | 28 | n = sscanf(line, "%ld\n", &seqno); 29 | seqno++; /* increment sequence number */ 30 | 31 | snprintf(line, sizeof(line), "%ld\n", seqno); 32 | Lseek(fd, 0L, SEEK_SET); /* rewind before write */ 33 | Write(fd, line, strlen(line)); 34 | 35 | my_unlock(fd); /* unlock the file */ 36 | } 37 | exit(0); 38 | } 39 | -------------------------------------------------------------------------------- /code/unpv22e/lock/onedaemon.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define PATH_PIDFILE "pidfile" 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int pidfd; 9 | char line[MAXLINE]; 10 | 11 | /* 4open the PID file, create if nonexistent */ 12 | pidfd = Open(PATH_PIDFILE, O_RDWR | O_CREAT, FILE_MODE); 13 | 14 | /* 4try to write lock the entire file */ 15 | if (write_lock(pidfd, 0, SEEK_SET, 0) < 0) { 16 | if (errno == EACCES || errno == EAGAIN) 17 | err_quit("unable to lock %s, is %s already running?", 18 | PATH_PIDFILE, argv[0]); 19 | else 20 | err_sys("unable to lock %s", PATH_PIDFILE); 21 | } 22 | 23 | /* 4write my PID, leave file open to hold the write lock */ 24 | snprintf(line, sizeof(line), "%ld\n", (long) getpid()); 25 | Ftruncate(pidfd, 0); 26 | Write(pidfd, line, strlen(line)); 27 | 28 | /* then do whatever the daemon does ... */ 29 | 30 | pause(); 31 | } 32 | -------------------------------------------------------------------------------- /code/unpv22e/lock/pidfile: -------------------------------------------------------------------------------- 1 | 22388 2 | -------------------------------------------------------------------------------- /code/unpv22e/lock/seqno: -------------------------------------------------------------------------------- 1 | 1601 2 | -------------------------------------------------------------------------------- /code/unpv22e/lock/test1.c: -------------------------------------------------------------------------------- 1 | /* Verify that two readers can lock the same region */ 2 | #include "unpipc.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | int fd; 8 | 9 | fd = Open("test1.data", O_RDWR | O_CREAT, (mode_t) FILE_MODE); 10 | 11 | Read_lock(fd, 0, SEEK_SET, 0); /* parent read locks entire file */ 12 | printf("%s: parent has read lock\n", Gf_time()); 13 | 14 | if (Fork() == 0) { 15 | /* 4child */ 16 | Read_lock(fd, 0, SEEK_SET, 0); /* this should work */ 17 | printf("%s: child has read lock\n", Gf_time()); 18 | sleep(2); 19 | Un_lock(fd, 0, SEEK_SET, 0); 20 | printf("%s: child releases read lock\n", Gf_time()); 21 | 22 | Read_lock(fd, 0, SEEK_SET, 0); /* this should work */ 23 | printf("%s: child has read lock\n", Gf_time()); 24 | sleep(2); 25 | exit(0); 26 | } 27 | 28 | /* parent */ 29 | sleep(4); 30 | Un_lock(fd, 0, SEEK_SET, 0); 31 | printf("%s: parent releases read lock\n", Gf_time()); 32 | exit(0); 33 | } 34 | -------------------------------------------------------------------------------- /code/unpv22e/lock/test1.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yifengyou/learn-unp2/12c1fd4e6f43524f0b173e9385321b67bcb7d653/code/unpv22e/lock/test1.data -------------------------------------------------------------------------------- /code/unpv22e/mutex/test1.c: -------------------------------------------------------------------------------- 1 | /* verify that not calling pthread_*attr_destroy() causes memory leak */ 2 | 3 | #include "unpipc.h" 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | pthread_mutexattr_t mattr; 9 | pthread_condattr_t cattr; 10 | 11 | for ( ; ; ) { 12 | Pthread_mutexattr_init(&mattr); 13 | Pthread_condattr_init(&cattr); 14 | } 15 | 16 | exit(0); 17 | } 18 | -------------------------------------------------------------------------------- /code/unpv22e/mutex/test2.c: -------------------------------------------------------------------------------- 1 | /* verify that calling pthread_*attr_destroy() avoids memory leak */ 2 | 3 | #include "unpipc.h" 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | pthread_mutexattr_t mattr; 9 | pthread_condattr_t cattr; 10 | 11 | for ( ; ; ) { 12 | Pthread_mutexattr_init(&mattr); 13 | Pthread_mutexattr_destroy(&mattr); 14 | Pthread_condattr_init(&cattr); 15 | Pthread_condattr_destroy(&cattr); 16 | } 17 | 18 | exit(0); 19 | } 20 | -------------------------------------------------------------------------------- /code/unpv22e/mutex/test3.c: -------------------------------------------------------------------------------- 1 | /* verify that not calling pthread_attr_destroy() causes memory leak */ 2 | 3 | #include "unpipc.h" 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | pthread_attr_t attr; 9 | 10 | for ( ; ; ) { 11 | Pthread_attr_init(&attr); 12 | } 13 | 14 | exit(0); 15 | } 16 | -------------------------------------------------------------------------------- /code/unpv22e/mutex/test4.c: -------------------------------------------------------------------------------- 1 | /* verify that calling pthread_attr_destroy() avoids memory leak */ 2 | 3 | #include "unpipc.h" 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | pthread_attr_t attr; 9 | 10 | for ( ; ; ) { 11 | Pthread_attr_init(&attr); 12 | Pthread_attr_destroy(&attr); 13 | } 14 | 15 | exit(0); 16 | } 17 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxmsg_mmap/README: -------------------------------------------------------------------------------- 1 | The following directories contain implementations of Posix message queues 2 | of Posix semaphores, using some other technique: 3 | 4 | my_pxmsg_mmap/ implements Posix message queues using mmap 5 | my_pxsem_fifo/ implements Posix semaphores using FIFOs 6 | my_pxsem_mmap/ implements Posix semaphores using mmap 7 | my_pxsem_svsem/ implements Posix semaphores using System V semaphores 8 | 9 | In these directories the functions, structures, and datatypes are all 10 | prefixed with the two characters "my". This makes it much easier to 11 | include the headers and functions along with the normal system headers 12 | and libraries. But in the source code shown in the book, the "my" 13 | is removed, to make the code more readable. 14 | 15 | Also assumed in each of these directories is that an #include of a 16 | filename in double quotes looks in that directory, and not in a 17 | system directory. 18 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxmsg_mmap/mq_close.c: -------------------------------------------------------------------------------- 1 | /* include mq_close */ 2 | #include "unpipc.h" 3 | #include "mqueue.h" 4 | 5 | int 6 | mymq_close(mymqd_t mqd) 7 | { 8 | long msgsize, filesize; 9 | struct mymq_hdr *mqhdr; 10 | struct mymq_attr *attr; 11 | struct mymq_info *mqinfo; 12 | 13 | mqinfo = mqd; 14 | if (mqinfo->mqi_magic != MQI_MAGIC) { 15 | errno = EBADF; 16 | return(-1); 17 | } 18 | mqhdr = mqinfo->mqi_hdr; 19 | attr = &mqhdr->mqh_attr; 20 | 21 | if (mymq_notify(mqd, NULL) != 0) /* unregister calling process */ 22 | return(-1); 23 | 24 | msgsize = MSGSIZE(attr->mq_msgsize); 25 | filesize = sizeof(struct mymq_hdr) + (attr->mq_maxmsg * 26 | (sizeof(struct mymsg_hdr) + msgsize)); 27 | if (munmap(mqinfo->mqi_hdr, filesize) == -1) 28 | return(-1); 29 | 30 | mqinfo->mqi_magic = 0; /* just in case */ 31 | free(mqinfo); 32 | return(0); 33 | } 34 | /* end mq_close */ 35 | 36 | void 37 | Mymq_close(mymqd_t mqd) 38 | { 39 | if (mymq_close(mqd) == -1) 40 | err_sys("mymq_close error"); 41 | } 42 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxmsg_mmap/mq_unlink.c: -------------------------------------------------------------------------------- 1 | /* include mq_unlink */ 2 | #include "unpipc.h" 3 | #include "mqueue.h" 4 | 5 | int 6 | mymq_unlink(const char *pathname) 7 | { 8 | if (unlink(pathname) == -1) 9 | return(-1); 10 | return(0); 11 | } 12 | /* end mq_unlink */ 13 | 14 | void 15 | Mymq_unlink(const char *pathname) 16 | { 17 | if (mymq_unlink(pathname) == -1) 18 | err_sys("mymq_unlink error"); 19 | } 20 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxmsg_mmap/mqcreate.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "mqueue.h" 3 | 4 | struct mq_attr attr; /* mq_maxmsg and mq_msgsize both init to 0 */ 5 | 6 | int 7 | main(int argc, char **argv) 8 | { 9 | int c, flags; 10 | mqd_t mqd; 11 | 12 | flags = O_RDWR | O_CREAT; 13 | while ( (c = Getopt(argc, argv, "em:z:")) != -1) { 14 | switch (c) { 15 | case 'e': 16 | flags |= O_EXCL; 17 | break; 18 | 19 | case 'm': 20 | attr.mq_maxmsg = atol(optarg); 21 | break; 22 | 23 | case 'z': 24 | attr.mq_msgsize = atol(optarg); 25 | break; 26 | } 27 | } 28 | if (optind != argc - 1) 29 | err_quit("usage: mqcreate [ -e ] [ -m maxmsg -z msgsize ] "); 30 | 31 | if ((attr.mq_maxmsg != 0 && attr.mq_msgsize == 0) || 32 | (attr.mq_maxmsg == 0 && attr.mq_msgsize != 0)) 33 | err_quit("must specify both -m maxmsg and -z msgsize"); 34 | 35 | mqd = Mymq_open(argv[optind], flags, FILE_MODE, 36 | (attr.mq_maxmsg != 0) ? &attr : NULL); 37 | 38 | Mymq_close(mqd); 39 | exit(0); 40 | } 41 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxmsg_mmap/mqgetattr.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "mqueue.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | mqd_t mqd; 8 | struct mymq_attr attr; 9 | 10 | if (argc != 2) 11 | err_quit("usage: mqgetattr "); 12 | 13 | mqd = Mymq_open(argv[1], O_RDONLY); 14 | 15 | Mymq_getattr(mqd, &attr); 16 | printf("max #msgs = %ld, max #bytes/msg = %ld, " 17 | "#currently on queue = %ld\n", 18 | attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs); 19 | 20 | Mymq_close(mqd); 21 | exit(0); 22 | } 23 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxmsg_mmap/mqnotify1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "mqueue.h" 3 | 4 | mymqd_t mqd; 5 | struct sigevent sigev; 6 | 7 | void sig_usr1(int); 8 | 9 | int 10 | main(int argc, char **argv) 11 | { 12 | if (argc != 2) 13 | err_quit("usage: mqnotify1 "); 14 | 15 | mqd = Mymq_open(argv[1], O_RDONLY); 16 | 17 | Signal(SIGUSR1, sig_usr1); 18 | 19 | sigev.sigev_notify = SIGEV_SIGNAL; 20 | sigev.sigev_signo = SIGUSR1; 21 | Mymq_notify(mqd, &sigev); 22 | 23 | for ( ; ; ) 24 | pause(); 25 | 26 | exit(0); 27 | } 28 | 29 | void 30 | sig_usr1(int signo) 31 | { 32 | printf("SIGUSR1 received\n"); 33 | Mymq_notify(mqd, &sigev); /* reregister */ 34 | return; 35 | } 36 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxmsg_mmap/mqreceive.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "mqueue.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | int c, flags; 8 | mqd_t mqd; 9 | size_t n; 10 | uint_t prio; 11 | void *buff; 12 | struct mymq_attr attr; 13 | 14 | flags = O_RDONLY; 15 | while ( (c = Getopt(argc, argv, "n")) != -1) { 16 | switch (c) { 17 | case 'n': 18 | flags |= O_NONBLOCK; 19 | break; 20 | } 21 | } 22 | if (optind != argc - 1) 23 | err_quit("usage: mqreceive [ -n ] "); 24 | 25 | mqd = Mymq_open(argv[optind], flags); 26 | Mymq_getattr(mqd, &attr); 27 | 28 | buff = Malloc(attr.mq_msgsize); 29 | 30 | n = Mymq_receive(mqd, buff, attr.mq_msgsize, &prio); 31 | printf("read %d bytes, priority = %u\n", n, prio); 32 | 33 | exit(0); 34 | } 35 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxmsg_mmap/mqsend.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "mqueue.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | mqd_t mqd; 8 | void *ptr; 9 | size_t len; 10 | uint_t prio; 11 | 12 | if (argc != 4) 13 | err_quit("usage: mqsend <#bytes> "); 14 | len = atoi(argv[2]); 15 | prio = atoi(argv[3]); 16 | 17 | mqd = Mymq_open(argv[1], O_WRONLY); 18 | 19 | ptr = Malloc(len); 20 | Mymq_send(mqd, ptr, len, prio); 21 | 22 | exit(0); 23 | } 24 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxmsg_mmap/mqunlink.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "mqueue.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | if (argc != 2) 8 | err_quit("usage: mqunlink "); 9 | 10 | Mymq_unlink(argv[1]); 11 | 12 | exit(0); 13 | } 14 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxmsg_mmap/test2.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("sizeof(pthread_mutex_t) = %d\n", sizeof(pthread_mutex_t)); 7 | printf("sizeof(pthread_cond_t) = %d\n", sizeof(pthread_cond_t)); 8 | printf("sizeof(struct sigevent) = %d\n", sizeof(struct sigevent)); 9 | exit(0); 10 | } 11 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_fifo/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = prodcons1 testeintr 4 | FUNCS = sem_close.o sem_open.o sem_post.o sem_unlink.o sem_wait.o 5 | 6 | all: ${PROGS} 7 | 8 | prodcons1: prodcons1.o ${FUNCS} 9 | ${CC} ${CFLAGS} -o $@ prodcons1.o ${FUNCS} ${LIBS} 10 | 11 | testeintr: testeintr.o ${FUNCS} 12 | ${CC} ${CFLAGS} -o $@ testeintr.o ${FUNCS} ${LIBS} 13 | 14 | clean: 15 | rm -f ${PROGS} ${CLEANFILES} 16 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_fifo/README: -------------------------------------------------------------------------------- 1 | The following directories contain implementations of Posix message queues 2 | of Posix semaphores, using some other technique: 3 | 4 | my_pxmsg_mmap/ implements Posix message queues using mmap 5 | my_pxsem_fifo/ implements Posix semaphores using FIFOs 6 | my_pxsem_mmap/ implements Posix semaphores using mmap 7 | my_pxsem_svsem/ implements Posix semaphores using System V semaphores 8 | 9 | In these directories the functions, structures, and datatypes are all 10 | prefixed with the two characters "my". This makes it much easier to 11 | include the headers and functions along with the normal system headers 12 | and libraries. But in the source code shown in the book, the "my" 13 | is removed, to make the code more readable. 14 | 15 | Also assumed in each of these directories is that an #include of a 16 | filename in double quotes looks in that directory, and not in a 17 | system directory. 18 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_fifo/sem_close.c: -------------------------------------------------------------------------------- 1 | /* include sem_close */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_close(mysem_t *sem) 7 | { 8 | if (sem->sem_magic != SEM_MAGIC) { 9 | errno = EINVAL; 10 | return(-1); 11 | } 12 | 13 | sem->sem_magic = 0; /* in case caller tries to use it later */ 14 | if (close(sem->sem_fd[0]) == -1 || close(sem->sem_fd[1]) == -1) { 15 | free(sem); 16 | return(-1); 17 | } 18 | free(sem); 19 | return(0); 20 | } 21 | /* end sem_close */ 22 | 23 | void 24 | Mysem_close(mysem_t *sem) 25 | { 26 | if (mysem_close(sem) == -1) 27 | err_sys("mysem_close error"); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_fifo/sem_post.c: -------------------------------------------------------------------------------- 1 | /* include sem_post */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_post(mysem_t *sem) 7 | { 8 | char c; 9 | 10 | if (sem->sem_magic != SEM_MAGIC) { 11 | errno = EINVAL; 12 | return(-1); 13 | } 14 | 15 | if (write(sem->sem_fd[1], &c, 1) == 1) 16 | return(0); 17 | return(-1); 18 | } 19 | /* end sem_post */ 20 | 21 | void 22 | Mysem_post(mysem_t *sem) 23 | { 24 | if (mysem_post(sem) == -1) 25 | err_sys("mysem_post error"); 26 | } 27 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_fifo/sem_unlink.c: -------------------------------------------------------------------------------- 1 | /* include sem_unlink */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_unlink(const char *pathname) 7 | { 8 | return(unlink(pathname)); 9 | } 10 | /* end sem_unlink */ 11 | 12 | void 13 | Mysem_unlink(const char *pathname) 14 | { 15 | if (mysem_unlink(pathname) == -1) 16 | err_sys("mysem_unlink error"); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_fifo/sem_wait.c: -------------------------------------------------------------------------------- 1 | /* include sem_wait */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_wait(mysem_t *sem) 7 | { 8 | char c; 9 | 10 | if (sem->sem_magic != SEM_MAGIC) { 11 | errno = EINVAL; 12 | return(-1); 13 | } 14 | 15 | if (read(sem->sem_fd[0], &c, 1) == 1) 16 | return(0); 17 | return(-1); 18 | } 19 | /* end sem_wait */ 20 | 21 | void 22 | Mysem_wait(mysem_t *sem) 23 | { 24 | if (mysem_wait(sem) == -1) 25 | err_sys("mysem_wait error"); 26 | } 27 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_fifo/semaphore.h: -------------------------------------------------------------------------------- 1 | /* include semaphoreh */ 2 | /* 4the fundamental datatype */ 3 | typedef struct { 4 | int sem_fd[2]; /* two fds: [0] for reading, [1] for writing */ 5 | int sem_magic; /* magic number if open */ 6 | } mysem_t; 7 | 8 | #define SEM_MAGIC 0x89674523 9 | 10 | #ifdef SEM_FAILED 11 | #undef SEM_FAILED 12 | #define SEM_FAILED ((mysem_t *)(-1)) /* avoid compiler warnings */ 13 | #endif 14 | /* end semaphoreh */ 15 | 16 | /* 4our functions */ 17 | int mysem_close(mysem_t *); 18 | mysem_t *mysem_open(const char *, int, ... ); 19 | int mysem_post(mysem_t *); 20 | int mysem_unlink(const char *); 21 | int mysem_wait(mysem_t *); 22 | 23 | /* 4and the corresponding wrapper functions */ 24 | void Mysem_close(mysem_t *); 25 | mysem_t *Mysem_open(const char *, int, ... ); 26 | void Mysem_post(mysem_t *); 27 | void Mysem_unlink(const char *); 28 | void Mysem_wait(mysem_t *); 29 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_fifo/testeintr.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "semaphore.h" 3 | 4 | #define NAME "testeintr" 5 | 6 | static void sig_alrm(int); 7 | 8 | int 9 | main(int argc, char **argv) 10 | { 11 | mysem_t *sem1; 12 | 13 | /* 4test a named semaphore */ 14 | mysem_unlink(Px_ipc_name(NAME)); 15 | sem1 = Mysem_open(Px_ipc_name(NAME), O_RDWR | O_CREAT | O_EXCL, 16 | FILE_MODE, 0); 17 | 18 | Signal(SIGALRM, sig_alrm); 19 | alarm(2); 20 | if (mysem_wait(sem1) == 0) 21 | printf("mysem_wait returned 0?\n"); 22 | else 23 | err_ret("mysem_wait error"); 24 | Mysem_close(sem1); 25 | 26 | exit(0); 27 | } 28 | 29 | static void 30 | sig_alrm(int signo) 31 | { 32 | printf("SIGALRM caught\n"); 33 | return; 34 | } 35 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_mmap/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = prodcons1 testsem testeintr 4 | FUNCS = sem_close.o sem_getvalue.o sem_open.o sem_post.o \ 5 | sem_trywait.o sem_unlink.o sem_wait.o 6 | 7 | all: ${PROGS} 8 | 9 | prodcons1: prodcons1.o ${FUNCS} 10 | ${CC} ${CFLAGS} -o $@ prodcons1.o ${FUNCS} ${LIBS} 11 | 12 | testsem: testsem.o ${FUNCS} 13 | ${CC} ${CFLAGS} -o $@ testsem.o ${FUNCS} ${LIBS} 14 | 15 | testeintr: testeintr.o ${FUNCS} 16 | ${CC} ${CFLAGS} -o $@ testeintr.o ${FUNCS} ${LIBS} 17 | 18 | clean: 19 | rm -f ${PROGS} ${CLEANFILES} 20 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_mmap/README: -------------------------------------------------------------------------------- 1 | The following directories contain implementations of Posix message queues 2 | of Posix semaphores, using some other technique: 3 | 4 | my_pxmsg_mmap/ implements Posix message queues using mmap 5 | my_pxsem_fifo/ implements Posix semaphores using FIFOs 6 | my_pxsem_mmap/ implements Posix semaphores using mmap 7 | my_pxsem_svsem/ implements Posix semaphores using System V semaphores 8 | 9 | In these directories the functions, structures, and datatypes are all 10 | prefixed with the two characters "my". This makes it much easier to 11 | include the headers and functions along with the normal system headers 12 | and libraries. But in the source code shown in the book, the "my" 13 | is removed, to make the code more readable. 14 | 15 | Also assumed in each of these directories is that an #include of a 16 | filename in double quotes looks in that directory, and not in a 17 | system directory. 18 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_mmap/sem_close.c: -------------------------------------------------------------------------------- 1 | /* include sem_close */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_close(mysem_t *sem) 7 | { 8 | if (sem->sem_magic != SEM_MAGIC) { 9 | errno = EINVAL; 10 | return(-1); 11 | } 12 | 13 | /* *INDENT-OFF* */ 14 | if (munmap(sem, sizeof(mysem_t)) == -1) 15 | return(-1); 16 | /* *INDENT-ON* */ 17 | return(0); 18 | } 19 | /* end sem_close */ 20 | 21 | void 22 | Mysem_close(mysem_t *sem) 23 | { 24 | if (mysem_close(sem) == -1) 25 | err_sys("mysem_close error"); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_mmap/sem_getvalue.c: -------------------------------------------------------------------------------- 1 | /* include sem_getvalue */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_getvalue(mysem_t *sem, int *pvalue) 7 | { 8 | int n; 9 | 10 | if (sem->sem_magic != SEM_MAGIC) { 11 | errno = EINVAL; 12 | return(-1); 13 | } 14 | 15 | if ( (n = pthread_mutex_lock(&sem->sem_mutex)) != 0) { 16 | errno = n; 17 | return(-1); 18 | } 19 | *pvalue = sem->sem_count; 20 | pthread_mutex_unlock(&sem->sem_mutex); 21 | return(0); 22 | } 23 | /* end sem_getvalue */ 24 | 25 | void 26 | Mysem_getvalue(mysem_t *sem, int *pvalue) 27 | { 28 | if (mysem_getvalue(sem, pvalue) == -1) 29 | err_sys("mysem_getvalue error"); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_mmap/sem_post.c: -------------------------------------------------------------------------------- 1 | /* include sem_post */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_post(mysem_t *sem) 7 | { 8 | int n; 9 | 10 | if (sem->sem_magic != SEM_MAGIC) { 11 | errno = EINVAL; 12 | return(-1); 13 | } 14 | 15 | if ( (n = pthread_mutex_lock(&sem->sem_mutex)) != 0) { 16 | errno = n; 17 | return(-1); 18 | } 19 | if (sem->sem_count == 0) 20 | pthread_cond_signal(&sem->sem_cond); 21 | sem->sem_count++; 22 | pthread_mutex_unlock(&sem->sem_mutex); 23 | return(0); 24 | } 25 | /* end sem_post */ 26 | 27 | void 28 | Mysem_post(mysem_t *sem) 29 | { 30 | if (mysem_post(sem) == -1) 31 | err_sys("mysem_post error"); 32 | } 33 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_mmap/sem_trywait.c: -------------------------------------------------------------------------------- 1 | /* include sem_trywait */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_trywait(mysem_t *sem) 7 | { 8 | int n, rc; 9 | 10 | if (sem->sem_magic != SEM_MAGIC) { 11 | errno = EINVAL; 12 | return(-1); 13 | } 14 | 15 | if ( (n = pthread_mutex_lock(&sem->sem_mutex)) != 0) { 16 | errno = n; 17 | return(-1); 18 | } 19 | if (sem->sem_count > 0) { 20 | sem->sem_count--; 21 | rc = 0; 22 | } else { 23 | rc = -1; 24 | errno = EAGAIN; 25 | } 26 | pthread_mutex_unlock(&sem->sem_mutex); 27 | return(rc); 28 | } 29 | /* end sem_trywait */ 30 | 31 | int 32 | Mysem_trywait(mysem_t *sem) 33 | { 34 | int rc; 35 | 36 | if ( (rc = mysem_trywait(sem)) == -1 && errno != EAGAIN) 37 | err_sys("mysem_trywait error"); 38 | return(rc); 39 | } 40 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_mmap/sem_unlink.c: -------------------------------------------------------------------------------- 1 | /* include sem_unlink */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_unlink(const char *pathname) 7 | { 8 | if (unlink(pathname) == -1) 9 | return(-1); 10 | return(0); 11 | } 12 | /* end sem_unlink */ 13 | 14 | void 15 | Mysem_unlink(const char *pathname) 16 | { 17 | if (mysem_unlink(pathname) == -1) 18 | err_sys("mysem_unlink error"); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_mmap/sem_wait.c: -------------------------------------------------------------------------------- 1 | /* include sem_wait */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_wait(mysem_t *sem) 7 | { 8 | int n; 9 | 10 | if (sem->sem_magic != SEM_MAGIC) { 11 | errno = EINVAL; 12 | return(-1); 13 | } 14 | 15 | if ( (n = pthread_mutex_lock(&sem->sem_mutex)) != 0) { 16 | errno = n; 17 | return(-1); 18 | } 19 | while (sem->sem_count == 0) 20 | pthread_cond_wait(&sem->sem_cond, &sem->sem_mutex); 21 | sem->sem_count--; 22 | pthread_mutex_unlock(&sem->sem_mutex); 23 | return(0); 24 | } 25 | /* end sem_wait */ 26 | 27 | void 28 | Mysem_wait(mysem_t *sem) 29 | { 30 | if (mysem_wait(sem) == -1) 31 | err_sys("mysem_wait error"); 32 | } 33 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_mmap/testeintr.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "semaphore.h" 3 | 4 | #define NAME "testeintr" 5 | 6 | static void sig_alrm(int); 7 | 8 | int 9 | main(int argc, char **argv) 10 | { 11 | mysem_t *sem1; 12 | 13 | /* 4test a named semaphore */ 14 | mysem_unlink(Px_ipc_name(NAME)); 15 | sem1 = Mysem_open(Px_ipc_name(NAME), O_RDWR | O_CREAT | O_EXCL, 16 | FILE_MODE, 0); 17 | 18 | Signal(SIGALRM, sig_alrm); 19 | alarm(2); 20 | if (mysem_wait(sem1) == 0) 21 | printf("mysem_wait returned 0?\n"); 22 | else 23 | err_ret("mysem_wait error"); 24 | Mysem_close(sem1); 25 | 26 | exit(0); 27 | } 28 | 29 | static void 30 | sig_alrm(int signo) 31 | { 32 | printf("SIGALRM caught\n"); 33 | return; 34 | } 35 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_svsem/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = prodcons1 testsem testeintr 4 | FUNCS = sem_close.o sem_getvalue.o sem_open.o sem_post.o \ 5 | sem_trywait.o sem_unlink.o sem_wait.o 6 | 7 | all: ${PROGS} 8 | 9 | prodcons1: prodcons1.o ${FUNCS} 10 | ${CC} ${CFLAGS} -o $@ prodcons1.o ${FUNCS} ${LIBS} 11 | 12 | testsem: testsem.o ${FUNCS} 13 | ${CC} ${CFLAGS} -o $@ testsem.o ${FUNCS} ${LIBS} 14 | 15 | testeintr: testeintr.o ${FUNCS} 16 | ${CC} ${CFLAGS} -o $@ testeintr.o ${FUNCS} ${LIBS} 17 | 18 | clean: 19 | rm -f ${PROGS} ${CLEANFILES} 20 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_svsem/README: -------------------------------------------------------------------------------- 1 | The following directories contain implementations of Posix message queues 2 | of Posix semaphores, using some other technique: 3 | 4 | my_pxmsg_mmap/ implements Posix message queues using mmap 5 | my_pxsem_fifo/ implements Posix semaphores using FIFOs 6 | my_pxsem_mmap/ implements Posix semaphores using mmap 7 | my_pxsem_svsem/ implements Posix semaphores using System V semaphores 8 | 9 | In these directories the functions, structures, and datatypes are all 10 | prefixed with the two characters "my". This makes it much easier to 11 | include the headers and functions along with the normal system headers 12 | and libraries. But in the source code shown in the book, the "my" 13 | is removed, to make the code more readable. 14 | 15 | Also assumed in each of these directories is that an #include of a 16 | filename in double quotes looks in that directory, and not in a 17 | system directory. 18 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_svsem/sem_close.c: -------------------------------------------------------------------------------- 1 | /* include sem_close */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_close(mysem_t *sem) 7 | { 8 | if (sem->sem_magic != SEM_MAGIC) { 9 | errno = EINVAL; 10 | return(-1); 11 | } 12 | sem->sem_magic = 0; /* just in case */ 13 | 14 | free(sem); 15 | return(0); 16 | } 17 | /* end sem_close */ 18 | 19 | void 20 | Mysem_close(mysem_t *sem) 21 | { 22 | if (mysem_close(sem) == -1) 23 | err_sys("mysem_close error"); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_svsem/sem_getvalue.c: -------------------------------------------------------------------------------- 1 | /* include sem_getvalue */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_getvalue(mysem_t *sem, int *pvalue) 7 | { 8 | int val; 9 | 10 | if (sem->sem_magic != SEM_MAGIC) { 11 | errno = EINVAL; 12 | return(-1); 13 | } 14 | 15 | if ( (val = semctl(sem->sem_semid, 0, GETVAL)) < 0) 16 | return(-1); 17 | *pvalue = val; 18 | return(0); 19 | } 20 | /* end sem_getvalue */ 21 | 22 | void 23 | Mysem_getvalue(mysem_t *sem, int *pvalue) 24 | { 25 | if (mysem_getvalue(sem, pvalue) == -1) 26 | err_sys("mysem_getvalue error"); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_svsem/sem_post.c: -------------------------------------------------------------------------------- 1 | /* include sem_post */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_post(mysem_t *sem) 7 | { 8 | struct sembuf op; 9 | 10 | if (sem->sem_magic != SEM_MAGIC) { 11 | errno = EINVAL; 12 | return(-1); 13 | } 14 | 15 | op.sem_num = 0; 16 | op.sem_op = 1; 17 | op.sem_flg = 0; 18 | if (semop(sem->sem_semid, &op, 1) < 0) 19 | return(-1); 20 | return(0); 21 | } 22 | /* end sem_post */ 23 | 24 | void 25 | Mysem_post(mysem_t *sem) 26 | { 27 | if (mysem_post(sem) == -1) 28 | err_sys("mysem_post error"); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_svsem/sem_trywait.c: -------------------------------------------------------------------------------- 1 | /* include sem_trywait */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_trywait(mysem_t *sem) 7 | { 8 | struct sembuf op; 9 | 10 | if (sem->sem_magic != SEM_MAGIC) { 11 | errno = EINVAL; 12 | return(-1); 13 | } 14 | 15 | op.sem_num = 0; 16 | op.sem_op = -1; 17 | op.sem_flg = IPC_NOWAIT; 18 | if (semop(sem->sem_semid, &op, 1) < 0) 19 | return(-1); 20 | return(0); 21 | } 22 | /* end sem_trywait */ 23 | 24 | int 25 | Mysem_trywait(mysem_t *sem) 26 | { 27 | int rc; 28 | 29 | if ( (rc = mysem_trywait(sem)) == -1 && errno != EAGAIN) 30 | err_sys("mysem_trywait error"); 31 | return(rc); 32 | } 33 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_svsem/sem_unlink.c: -------------------------------------------------------------------------------- 1 | /* include sem_unlink */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_unlink(const char *pathname) 7 | { 8 | int semid; 9 | key_t key; 10 | 11 | if ( (key = ftok(pathname, 0)) == (key_t) -1) 12 | return(-1); 13 | if (unlink(pathname) == -1) 14 | return(-1); 15 | if ( (semid = semget(key, 1, SVSEM_MODE)) == -1) 16 | return(-1); 17 | if (semctl(semid, 0, IPC_RMID) == -1) 18 | return(-1); 19 | return(0); 20 | } 21 | /* end sem_unlink */ 22 | 23 | void 24 | Mysem_unlink(const char *pathname) 25 | { 26 | if (mysem_unlink(pathname) == -1) 27 | err_sys("mysem_unlink error"); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_svsem/sem_wait.c: -------------------------------------------------------------------------------- 1 | /* include sem_wait */ 2 | #include "unpipc.h" 3 | #include "semaphore.h" 4 | 5 | int 6 | mysem_wait(mysem_t *sem) 7 | { 8 | struct sembuf op; 9 | 10 | if (sem->sem_magic != SEM_MAGIC) { 11 | errno = EINVAL; 12 | return(-1); 13 | } 14 | 15 | op.sem_num = 0; 16 | op.sem_op = -1; 17 | op.sem_flg = 0; 18 | if (semop(sem->sem_semid, &op, 1) < 0) 19 | return(-1); 20 | return(0); 21 | } 22 | /* end sem_wait */ 23 | 24 | void 25 | Mysem_wait(mysem_t *sem) 26 | { 27 | if (mysem_wait(sem) == -1) 28 | err_sys("mysem_wait error"); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/my_pxsem_svsem/testeintr.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "semaphore.h" 3 | 4 | #define NAME "testeintr" 5 | 6 | static void sig_alrm(int); 7 | 8 | int 9 | main(int argc, char **argv) 10 | { 11 | mysem_t *sem1; 12 | 13 | /* 4test a named semaphore */ 14 | mysem_unlink(Px_ipc_name(NAME)); 15 | sem1 = Mysem_open(Px_ipc_name(NAME), O_RDWR | O_CREAT | O_EXCL, 16 | FILE_MODE, 0); 17 | 18 | Signal(SIGALRM, sig_alrm); 19 | alarm(2); 20 | if (mysem_wait(sem1) == 0) 21 | printf("mysem_wait returned 0?\n"); 22 | else 23 | err_ret("mysem_wait error"); 24 | Mysem_close(sem1); 25 | 26 | exit(0); 27 | } 28 | 29 | static void 30 | sig_alrm(int signo) 31 | { 32 | printf("SIGALRM caught\n"); 33 | return; 34 | } 35 | -------------------------------------------------------------------------------- /code/unpv22e/my_rwlock/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = test1 testcancel incr_rwlock1 4 | FUNCS = pthread_rwlock_destroy.o pthread_rwlock_init.o \ 5 | pthread_rwlock_rdlock.o pthread_rwlock_tryrdlock.o \ 6 | pthread_rwlock_trywrlock.o pthread_rwlock_unlock.o \ 7 | pthread_rwlock_wrlock.o 8 | 9 | all: ${PROGS} 10 | 11 | test1: test1.o ${FUNCS} 12 | ${CC} ${CFLAGS} -o $@ test1.o ${FUNCS} ${LIBS} 13 | 14 | testcancel: testcancel.o ${FUNCS} 15 | ${CC} ${CFLAGS} -o $@ testcancel.o ${FUNCS} ${LIBS} 16 | 17 | incr_rwlock1: incr_rwlock1.o ${FUNCS} 18 | ${CC} ${CFLAGS} -o $@ incr_rwlock1.o ${FUNCS} ${LIBS} 19 | 20 | clean: 21 | rm -f ${PROGS} ${CLEANFILES} 22 | -------------------------------------------------------------------------------- /code/unpv22e/my_rwlock/pthread_rwlock_destroy.c: -------------------------------------------------------------------------------- 1 | /* include destroy */ 2 | #include "unpipc.h" 3 | #include "pthread_rwlock.h" 4 | 5 | int 6 | pthread_rwlock_destroy(pthread_rwlock_t *rw) 7 | { 8 | if (rw->rw_magic != RW_MAGIC) 9 | return(EINVAL); 10 | if (rw->rw_refcount != 0 || 11 | rw->rw_nwaitreaders != 0 || rw->rw_nwaitwriters != 0) 12 | return(EBUSY); 13 | 14 | pthread_mutex_destroy(&rw->rw_mutex); 15 | pthread_cond_destroy(&rw->rw_condreaders); 16 | pthread_cond_destroy(&rw->rw_condwriters); 17 | rw->rw_magic = 0; 18 | 19 | return(0); 20 | } 21 | /* end destroy */ 22 | 23 | void 24 | Pthread_rwlock_destroy(pthread_rwlock_t *rw) 25 | { 26 | int n; 27 | 28 | if ( (n = pthread_rwlock_destroy(rw)) == 0) 29 | return; 30 | errno = n; 31 | err_sys("pthread_rwlock_destroy error"); 32 | } 33 | -------------------------------------------------------------------------------- /code/unpv22e/my_rwlock/pthread_rwlock_rdlock.c: -------------------------------------------------------------------------------- 1 | /* include rdlock */ 2 | #include "unpipc.h" 3 | #include "pthread_rwlock.h" 4 | 5 | int 6 | pthread_rwlock_rdlock(pthread_rwlock_t *rw) 7 | { 8 | int result; 9 | 10 | if (rw->rw_magic != RW_MAGIC) 11 | return(EINVAL); 12 | 13 | if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != 0) 14 | return(result); 15 | 16 | /* 4give preference to waiting writers */ 17 | while (rw->rw_refcount < 0 || rw->rw_nwaitwriters > 0) { 18 | rw->rw_nwaitreaders++; 19 | result = pthread_cond_wait(&rw->rw_condreaders, &rw->rw_mutex); 20 | rw->rw_nwaitreaders--; 21 | if (result != 0) 22 | break; 23 | } 24 | if (result == 0) 25 | rw->rw_refcount++; /* another reader has a read lock */ 26 | 27 | pthread_mutex_unlock(&rw->rw_mutex); 28 | return (result); 29 | } 30 | /* end rdlock */ 31 | 32 | void 33 | Pthread_rwlock_rdlock(pthread_rwlock_t *rw) 34 | { 35 | int n; 36 | 37 | if ( (n = pthread_rwlock_rdlock(rw)) == 0) 38 | return; 39 | errno = n; 40 | err_sys("pthread_rwlock_rdlock error"); 41 | } 42 | -------------------------------------------------------------------------------- /code/unpv22e/my_rwlock/pthread_rwlock_tryrdlock.c: -------------------------------------------------------------------------------- 1 | /* include tryrdlock */ 2 | #include "unpipc.h" 3 | #include "pthread_rwlock.h" 4 | 5 | int 6 | pthread_rwlock_tryrdlock(pthread_rwlock_t *rw) 7 | { 8 | int result; 9 | 10 | if (rw->rw_magic != RW_MAGIC) 11 | return(EINVAL); 12 | 13 | if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != 0) 14 | return(result); 15 | 16 | if (rw->rw_refcount < 0 || rw->rw_nwaitwriters > 0) 17 | result = EBUSY; /* held by a writer or waiting writers */ 18 | else 19 | rw->rw_refcount++; /* increment count of reader locks */ 20 | 21 | pthread_mutex_unlock(&rw->rw_mutex); 22 | return(result); 23 | } 24 | /* end tryrdlock */ 25 | 26 | int 27 | Pthread_rwlock_tryrdlock(pthread_rwlock_t *rw) 28 | { 29 | int n; 30 | 31 | if ( (n = pthread_rwlock_tryrdlock(rw)) != 0) { 32 | errno = n; 33 | err_sys("pthread_rwlock_tryrdlock error"); 34 | } 35 | return(n); 36 | } 37 | -------------------------------------------------------------------------------- /code/unpv22e/my_rwlock/pthread_rwlock_trywrlock.c: -------------------------------------------------------------------------------- 1 | /* include trywrlock */ 2 | #include "unpipc.h" 3 | #include "pthread_rwlock.h" 4 | 5 | int 6 | pthread_rwlock_trywrlock(pthread_rwlock_t *rw) 7 | { 8 | int result; 9 | 10 | if (rw->rw_magic != RW_MAGIC) 11 | return(EINVAL); 12 | 13 | if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != 0) 14 | return(result); 15 | 16 | if (rw->rw_refcount != 0) 17 | result = EBUSY; /* held by either writer or reader(s) */ 18 | else 19 | rw->rw_refcount = -1; /* available, indicate a writer has it */ 20 | 21 | pthread_mutex_unlock(&rw->rw_mutex); 22 | return(result); 23 | } 24 | /* end trywrlock */ 25 | 26 | int 27 | Pthread_rwlock_trywrlock(pthread_rwlock_t *rw) 28 | { 29 | int n; 30 | 31 | if ( (n = pthread_rwlock_trywrlock(rw)) != 0) { 32 | errno = n; 33 | err_sys("pthread_rwlock_trywrlock error"); 34 | } 35 | return(n); 36 | } 37 | -------------------------------------------------------------------------------- /code/unpv22e/my_rwlock/pthread_rwlock_wrlock.c: -------------------------------------------------------------------------------- 1 | /* include wrlock */ 2 | #include "unpipc.h" 3 | #include "pthread_rwlock.h" 4 | 5 | int 6 | pthread_rwlock_wrlock(pthread_rwlock_t *rw) 7 | { 8 | int result; 9 | 10 | if (rw->rw_magic != RW_MAGIC) 11 | return(EINVAL); 12 | 13 | if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != 0) 14 | return(result); 15 | 16 | while (rw->rw_refcount != 0) { 17 | rw->rw_nwaitwriters++; 18 | result = pthread_cond_wait(&rw->rw_condwriters, &rw->rw_mutex); 19 | rw->rw_nwaitwriters--; 20 | if (result != 0) 21 | break; 22 | } 23 | if (result == 0) 24 | rw->rw_refcount = -1; 25 | 26 | pthread_mutex_unlock(&rw->rw_mutex); 27 | return(result); 28 | } 29 | /* end wrlock */ 30 | 31 | void 32 | Pthread_rwlock_wrlock(pthread_rwlock_t *rw) 33 | { 34 | int n; 35 | 36 | if ( (n = pthread_rwlock_wrlock(rw)) == 0) 37 | return; 38 | errno = n; 39 | err_sys("pthread_rwlock_wrlock error"); 40 | } 41 | -------------------------------------------------------------------------------- /code/unpv22e/my_rwlock/test1.time.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "10 readers, 0 writers" 4 | /bin/time ./test1 -r 10 -w 0 -n 1000000 > /dev/null 5 | /bin/time ./test1 -r 10 -w 0 -n 1000000 > /dev/null 6 | 7 | echo "8 readers, 2 writers" 8 | /bin/time ./test1 -r 8 -w 2 -n 1000000 > /dev/null 9 | /bin/time ./test1 -r 8 -w 2 -n 1000000 > /dev/null 10 | 11 | echo "6 readers, 4 writers" 12 | /bin/time ./test1 -r 6 -w 4 -n 1000000 > /dev/null 13 | /bin/time ./test1 -r 6 -w 4 -n 1000000 > /dev/null 14 | 15 | echo "4 readers, 6 writers" 16 | /bin/time ./test1 -r 4 -w 6 -n 1000000 > /dev/null 17 | /bin/time ./test1 -r 4 -w 6 -n 1000000 > /dev/null 18 | 19 | echo "2 readers, 8 writers" 20 | /bin/time ./test1 -r 2 -w 8 -n 1000000 > /dev/null 21 | /bin/time ./test1 -r 2 -w 8 -n 1000000 > /dev/null 22 | 23 | echo "0 readers, 10 writers" 24 | /bin/time ./test1 -r 0 -w 10 -n 1000000 > /dev/null 25 | /bin/time ./test1 -r 0 -w 10 -n 1000000 > /dev/null 26 | -------------------------------------------------------------------------------- /code/unpv22e/my_rwlock_cancel/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = test1 testcancel incr_rwlock1 4 | FUNCS = pthread_rwlock_destroy.o pthread_rwlock_init.o \ 5 | pthread_rwlock_rdlock.o pthread_rwlock_tryrdlock.o \ 6 | pthread_rwlock_trywrlock.o pthread_rwlock_unlock.o \ 7 | pthread_rwlock_wrlock.o 8 | 9 | all: ${PROGS} 10 | 11 | test1: test1.o ${FUNCS} 12 | ${CC} ${CFLAGS} -o $@ test1.o ${FUNCS} ${LIBS} 13 | 14 | testcancel: testcancel.o ${FUNCS} 15 | ${CC} ${CFLAGS} -o $@ testcancel.o ${FUNCS} ${LIBS} 16 | 17 | incr_rwlock1: incr_rwlock1.o ${FUNCS} 18 | ${CC} ${CFLAGS} -o $@ incr_rwlock1.o ${FUNCS} ${LIBS} 19 | 20 | clean: 21 | rm -f ${PROGS} ${CLEANFILES} 22 | -------------------------------------------------------------------------------- /code/unpv22e/my_rwlock_cancel/README: -------------------------------------------------------------------------------- 1 | This directory contains a version of the Pthreads read-write lock 2 | functions that implement cancelation handling. 3 | -------------------------------------------------------------------------------- /code/unpv22e/my_rwlock_cancel/pthread_rwlock_destroy.c: -------------------------------------------------------------------------------- 1 | /* include destroy */ 2 | #include "unpipc.h" 3 | #include "pthread_rwlock.h" 4 | 5 | int 6 | pthread_rwlock_destroy(pthread_rwlock_t *rw) 7 | { 8 | if (rw->rw_magic != RW_MAGIC) 9 | return(EINVAL); 10 | if (rw->rw_refcount != 0 || 11 | rw->rw_nwaitreaders != 0 || rw->rw_nwaitwriters != 0) 12 | return(EBUSY); 13 | 14 | pthread_mutex_destroy(&rw->rw_mutex); 15 | pthread_cond_destroy(&rw->rw_condreaders); 16 | pthread_cond_destroy(&rw->rw_condwriters); 17 | rw->rw_magic = 0; 18 | 19 | return(0); 20 | } 21 | /* end destroy */ 22 | 23 | void 24 | Pthread_rwlock_destroy(pthread_rwlock_t *rw) 25 | { 26 | int n; 27 | 28 | if ( (n = pthread_rwlock_destroy(rw)) == 0) 29 | return; 30 | errno = n; 31 | err_sys("pthread_rwlock_destroy error"); 32 | } 33 | -------------------------------------------------------------------------------- /code/unpv22e/my_rwlock_cancel/pthread_rwlock_tryrdlock.c: -------------------------------------------------------------------------------- 1 | /* include tryrdlock */ 2 | #include "unpipc.h" 3 | #include "pthread_rwlock.h" 4 | 5 | int 6 | pthread_rwlock_tryrdlock(pthread_rwlock_t *rw) 7 | { 8 | int result; 9 | 10 | if (rw->rw_magic != RW_MAGIC) 11 | return(EINVAL); 12 | 13 | if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != 0) 14 | return(result); 15 | 16 | if (rw->rw_refcount == -1 || rw->rw_nwaitwriters > 0) 17 | result = EBUSY; /* held by a writer or waiting writers */ 18 | else 19 | rw->rw_refcount++; /* increment count of reader locks */ 20 | 21 | pthread_mutex_unlock(&rw->rw_mutex); 22 | return(result); 23 | } 24 | /* end tryrdlock */ 25 | 26 | int 27 | Pthread_rwlock_tryrdlock(pthread_rwlock_t *rw) 28 | { 29 | int n; 30 | 31 | if ( (n = pthread_rwlock_tryrdlock(rw)) != 0) { 32 | errno = n; 33 | err_sys("pthread_rwlock_tryrdlock error"); 34 | } 35 | return(n); 36 | } 37 | -------------------------------------------------------------------------------- /code/unpv22e/my_rwlock_cancel/pthread_rwlock_trywrlock.c: -------------------------------------------------------------------------------- 1 | /* include trywrlock */ 2 | #include "unpipc.h" 3 | #include "pthread_rwlock.h" 4 | 5 | int 6 | pthread_rwlock_trywrlock(pthread_rwlock_t *rw) 7 | { 8 | int result; 9 | 10 | if (rw->rw_magic != RW_MAGIC) 11 | return(EINVAL); 12 | 13 | if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != 0) 14 | return(result); 15 | 16 | if (rw->rw_refcount != 0) 17 | result = EBUSY; /* held by either writer or reader(s) */ 18 | else 19 | rw->rw_refcount = -1; /* available, indicate a writer has it */ 20 | 21 | pthread_mutex_unlock(&rw->rw_mutex); 22 | return(result); 23 | } 24 | /* end trywrlock */ 25 | 26 | int 27 | Pthread_rwlock_trywrlock(pthread_rwlock_t *rw) 28 | { 29 | int n; 30 | 31 | if ( (n = pthread_rwlock_trywrlock(rw)) != 0) { 32 | errno = n; 33 | err_sys("pthread_rwlock_trywrlock error"); 34 | } 35 | return(n); 36 | } 37 | -------------------------------------------------------------------------------- /code/unpv22e/pipe/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = mainpipe mainpopen mainfifo \ 4 | client_fifo server_fifo pipeconf test1 test2 fduplex 5 | 6 | all: ${PROGS} 7 | 8 | mainpipe: mainpipe.o client.o server.o 9 | ${CC} ${CFLAGS} -o $@ mainpipe.o client.o server.o ${LIBS} 10 | 11 | mainpopen: mainpopen.o 12 | ${CC} ${CFLAGS} -o $@ mainpopen.o ${LIBS} 13 | 14 | mainfifo: mainfifo.o client.o server.o 15 | ${CC} ${CFLAGS} -o $@ mainfifo.o client.o server.o ${LIBS} 16 | 17 | client_fifo: client_main.o client.o 18 | ${CC} ${CFLAGS} -o $@ client_main.o client.o ${LIBS} 19 | 20 | server_fifo: server_main.o server.o 21 | ${CC} ${CFLAGS} -o $@ server_main.o server.o ${LIBS} 22 | 23 | pipeconf: pipeconf.o 24 | ${CC} ${CFLAGS} -o $@ pipeconf.o ${LIBS} 25 | 26 | test1: test1.o 27 | ${CC} ${CFLAGS} -o $@ test1.o ${LIBS} 28 | 29 | test2: test2.o 30 | ${CC} ${CFLAGS} -o $@ test2.o ${LIBS} 31 | 32 | fduplex: fduplex.o 33 | ${CC} ${CFLAGS} -o $@ fduplex.o ${LIBS} 34 | 35 | clean: 36 | rm -f ${PROGS} ${CLEANFILES} 37 | -------------------------------------------------------------------------------- /code/unpv22e/pipe/client.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | void 4 | client(int readfd, int writefd) 5 | { 6 | size_t len; 7 | ssize_t n; 8 | char buff[MAXLINE]; 9 | 10 | /* 4read pathname */ 11 | Fgets(buff, MAXLINE, stdin); 12 | len = strlen(buff); /* fgets() guarantees null byte at end */ 13 | if (buff[len-1] == '\n') 14 | len--; /* delete newline from fgets() */ 15 | 16 | /* 4write pathname to IPC channel */ 17 | Write(writefd, buff, len); 18 | 19 | /* 4read from IPC, write to standard output */ 20 | while ( (n = Read(readfd, buff, MAXLINE)) > 0) 21 | Write(STDOUT_FILENO, buff, n); 22 | } 23 | -------------------------------------------------------------------------------- /code/unpv22e/pipe/client_main.c: -------------------------------------------------------------------------------- 1 | #include "fifo.h" 2 | 3 | void client(int, int); 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int readfd, writefd; 9 | 10 | writefd = Open(FIFO1, O_WRONLY, 0); 11 | readfd = Open(FIFO2, O_RDONLY, 0); 12 | 13 | client(readfd, writefd); 14 | 15 | Close(readfd); 16 | Close(writefd); 17 | 18 | Unlink(FIFO1); 19 | Unlink(FIFO2); 20 | exit(0); 21 | } 22 | -------------------------------------------------------------------------------- /code/unpv22e/pipe/fduplex.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd[2], n; 7 | char c; 8 | pid_t childpid; 9 | 10 | Pipe(fd); /* assumes a full-duplex pipe (e.g., SVR4) */ 11 | if ( (childpid = Fork()) == 0) { /* child */ 12 | sleep(3); 13 | if ( (n = Read(fd[0], &c, 1)) != 1) 14 | err_quit("child: read returned %d", n); 15 | printf("child read %c\n", c); 16 | Write(fd[0], "c", 1); 17 | exit(0); 18 | } 19 | /* 4parent */ 20 | Write(fd[1], "p", 1); 21 | if ( (n = Read(fd[1], &c, 1)) != 1) 22 | err_quit("parent: read returned %d", n); 23 | printf("parent read %c\n", c); 24 | exit(0); 25 | } 26 | -------------------------------------------------------------------------------- /code/unpv22e/pipe/fifo.h: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define FIFO1 "/tmp/fifo.1" 4 | #define FIFO2 "/tmp/fifo.2" 5 | -------------------------------------------------------------------------------- /code/unpv22e/pipe/mainpipe.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | void client(int, int), server(int, int); 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int pipe1[2], pipe2[2]; 9 | pid_t childpid; 10 | 11 | Pipe(pipe1); /* create two pipes */ 12 | Pipe(pipe2); 13 | 14 | if ( (childpid = Fork()) == 0) { /* child */ 15 | Close(pipe1[1]); 16 | Close(pipe2[0]); 17 | 18 | server(pipe1[0], pipe2[1]); 19 | exit(0); 20 | } 21 | /* 4parent */ 22 | Close(pipe1[0]); 23 | Close(pipe2[1]); 24 | 25 | client(pipe2[0], pipe1[1]); 26 | 27 | Waitpid(childpid, NULL, 0); /* wait for child to terminate */ 28 | exit(0); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/pipe/mainpopen.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | size_t n; 7 | char buff[MAXLINE], command[MAXLINE]; 8 | FILE *fp; 9 | 10 | /* 4read pathname */ 11 | Fgets(buff, MAXLINE, stdin); 12 | n = strlen(buff); /* fgets() guarantees null byte at end */ 13 | if (buff[n-1] == '\n') 14 | n--; /* delete newline from fgets() */ 15 | 16 | snprintf(command, sizeof(command), "cat %s", buff); 17 | fp = Popen(command, "r"); 18 | 19 | /* 4copy from pipe to standard output */ 20 | while (Fgets(buff, MAXLINE, fp) != NULL) 21 | Fputs(buff, stdout); 22 | 23 | Pclose(fp); 24 | exit(0); 25 | } 26 | -------------------------------------------------------------------------------- /code/unpv22e/pipe/pipeconf.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | if (argc != 2) 7 | err_quit("usage: pipeconf "); 8 | 9 | printf("PIPE_BUF = %ld, OPEN_MAX = %ld\n", 10 | Pathconf(argv[1], _PC_PIPE_BUF), Sysconf(_SC_OPEN_MAX)); 11 | exit(0); 12 | } 13 | -------------------------------------------------------------------------------- /code/unpv22e/pipe/server.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | void 4 | server(int readfd, int writefd) 5 | { 6 | int fd; 7 | ssize_t n; 8 | char buff[MAXLINE+1]; 9 | 10 | /* 4read pathname from IPC channel */ 11 | if ( (n = Read(readfd, buff, MAXLINE)) == 0) 12 | err_quit("end-of-file while reading pathname"); 13 | buff[n] = '\0'; /* null terminate pathname */ 14 | 15 | if ( (fd = open(buff, O_RDONLY)) < 0) { 16 | /* 4error: must tell client */ 17 | snprintf(buff + n, sizeof(buff) - n, ": can't open, %s\n", 18 | strerror(errno)); 19 | n = strlen(buff); 20 | Write(writefd, buff, n); 21 | 22 | } else { 23 | /* 4open succeeded: copy file to IPC channel */ 24 | while ( (n = Read(fd, buff, MAXLINE)) > 0) 25 | Write(writefd, buff, n); 26 | Close(fd); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /code/unpv22e/pipe/server_main.c: -------------------------------------------------------------------------------- 1 | #include "fifo.h" 2 | 3 | void server(int, int); 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int readfd, writefd; 9 | 10 | /* 4create two FIFOs; OK if they already exist */ 11 | if ((mkfifo(FIFO1, FILE_MODE) < 0) && (errno != EEXIST)) 12 | err_sys("can't create %s", FIFO1); 13 | if ((mkfifo(FIFO2, FILE_MODE) < 0) && (errno != EEXIST)) { 14 | unlink(FIFO1); 15 | err_sys("can't create %s", FIFO2); 16 | } 17 | 18 | readfd = Open(FIFO1, O_RDONLY, 0); 19 | writefd = Open(FIFO2, O_WRONLY, 0); 20 | 21 | server(readfd, writefd); 22 | exit(0); 23 | } 24 | -------------------------------------------------------------------------------- /code/unpv22e/pipe/test1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd[2]; 7 | char buff[7]; 8 | struct stat info; 9 | 10 | if (argc != 2) 11 | err_quit("usage: test1 "); 12 | 13 | Mkfifo(argv[1], FILE_MODE); 14 | fd[0] = Open(argv[1], O_RDONLY | O_NONBLOCK); 15 | fd[1] = Open(argv[1], O_WRONLY | O_NONBLOCK); 16 | 17 | /* 4check sizes when FIFO is empty */ 18 | Fstat(fd[0], &info); 19 | printf("fd[0]: st_size = %ld\n", (long) info.st_size); 20 | Fstat(fd[1], &info); 21 | printf("fd[1]: st_size = %ld\n", (long) info.st_size); 22 | 23 | Write(fd[1], buff, sizeof(buff)); 24 | 25 | /* 4check sizes when FIFO contains 7 bytes */ 26 | Fstat(fd[0], &info); 27 | printf("fd[0]: st_size = %ld\n", (long) info.st_size); 28 | Fstat(fd[1], &info); 29 | printf("fd[1]: st_size = %ld\n", (long) info.st_size); 30 | 31 | exit(0); 32 | } 33 | -------------------------------------------------------------------------------- /code/unpv22e/pipe/test2.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd[2], n; 7 | pid_t childpid; 8 | fd_set wset; 9 | 10 | Pipe(fd); 11 | if ( (childpid = Fork()) == 0) { /* child */ 12 | printf("child closing pipe read descriptor\n"); 13 | Close(fd[0]); 14 | sleep(6); 15 | exit(0); 16 | } 17 | /* 4parent */ 18 | Close(fd[0]); /* in case of a full-duplex pipe */ 19 | sleep(3); 20 | FD_ZERO(&wset); 21 | FD_SET(fd[1], &wset); 22 | n = select(fd[1] + 1, NULL, &wset, NULL, NULL); 23 | printf("select returned %d\n", n); 24 | 25 | if (FD_ISSET(fd[1], &wset)) { 26 | printf("fd[1] writable\n"); 27 | Write(fd[1], "hello", 5); 28 | } 29 | 30 | exit(0); 31 | } 32 | -------------------------------------------------------------------------------- /code/unpv22e/pipemesg/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = mainpipe mainfifo 4 | 5 | all: ${PROGS} 6 | 7 | mainpipe: mainpipe.o client.o server.o mesg_send.o mesg_recv.o 8 | ${CC} ${CFLAGS} -o $@ mainpipe.o client.o server.o \ 9 | mesg_send.o mesg_recv.o ${LIBS} 10 | 11 | mainfifo: mainfifo.o client.o server.o mesg_send.o mesg_recv.o 12 | ${CC} ${CFLAGS} -o $@ mainfifo.o client.o server.o \ 13 | mesg_send.o mesg_recv.o ${LIBS} 14 | 15 | clean: 16 | rm -f ${PROGS} ${CLEANFILES} 17 | -------------------------------------------------------------------------------- /code/unpv22e/pipemesg/client.c: -------------------------------------------------------------------------------- 1 | #include "mesg.h" 2 | 3 | void 4 | client(int readfd, int writefd) 5 | { 6 | size_t len; 7 | ssize_t n; 8 | struct mymesg mesg; 9 | 10 | /* 4read pathname */ 11 | Fgets(mesg.mesg_data, MAXMESGDATA, stdin); 12 | len = strlen(mesg.mesg_data); 13 | if (mesg.mesg_data[len-1] == '\n') 14 | len--; /* delete newline from fgets() */ 15 | mesg.mesg_len = len; 16 | mesg.mesg_type = 1; 17 | 18 | /* 4write pathname to IPC channel */ 19 | Mesg_send(writefd, &mesg); 20 | 21 | /* 4read from IPC, write to standard output */ 22 | while ( (n = Mesg_recv(readfd, &mesg)) > 0) 23 | Write(STDOUT_FILENO, mesg.mesg_data, n); 24 | } 25 | -------------------------------------------------------------------------------- /code/unpv22e/pipemesg/mainpipe.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | void client(int, int), server(int, int); 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int pipe1[2], pipe2[2]; 9 | pid_t childpid; 10 | 11 | Pipe(pipe1); /* create two pipes */ 12 | Pipe(pipe2); 13 | 14 | if ( (childpid = Fork()) > 0) { /* parent */ 15 | Close(pipe1[0]); 16 | Close(pipe2[1]); 17 | 18 | client(pipe2[0], pipe1[1]); 19 | 20 | Waitpid(childpid, NULL, 0); /* wait for child to terminate */ 21 | exit(0); 22 | } 23 | /* 4child */ 24 | Close(pipe1[1]); 25 | Close(pipe2[0]); 26 | 27 | server(pipe1[0], pipe2[1]); 28 | exit(0); 29 | } 30 | -------------------------------------------------------------------------------- /code/unpv22e/pipemesg/mesg.h: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | /* Our own "messages" to use with pipes, FIFOs, and message queues. */ 4 | 5 | /* 4want sizeof(struct mymesg) <= PIPE_BUF */ 6 | #define MAXMESGDATA (PIPE_BUF - 2*sizeof(long)) 7 | 8 | /* 4length of mesg_len and mesg_type */ 9 | #define MESGHDRSIZE (sizeof(struct mymesg) - MAXMESGDATA) 10 | 11 | struct mymesg { 12 | long mesg_len; /* #bytes in mesg_data, can be 0 */ 13 | long mesg_type; /* message type, must be > 0 */ 14 | char mesg_data[MAXMESGDATA]; 15 | }; 16 | 17 | ssize_t mesg_send(int, struct mymesg *); 18 | void Mesg_send(int, struct mymesg *); 19 | ssize_t mesg_recv(int, struct mymesg *); 20 | ssize_t Mesg_recv(int, struct mymesg *); 21 | -------------------------------------------------------------------------------- /code/unpv22e/pipemesg/mesg_recv.c: -------------------------------------------------------------------------------- 1 | /* include mesg_recv */ 2 | #include "mesg.h" 3 | 4 | ssize_t 5 | mesg_recv(int fd, struct mymesg *mptr) 6 | { 7 | size_t len; 8 | ssize_t n; 9 | 10 | /* 4read message header first, to get len of data that follows */ 11 | if ( (n = Read(fd, mptr, MESGHDRSIZE)) == 0) 12 | return(0); /* end of file */ 13 | else if (n != MESGHDRSIZE) 14 | err_quit("message header: expected %d, got %d", MESGHDRSIZE, n); 15 | 16 | if ( (len = mptr->mesg_len) > 0) 17 | if ( (n = Read(fd, mptr->mesg_data, len)) != len) 18 | err_quit("message data: expected %d, got %d", len, n); 19 | return(len); 20 | } 21 | /* end mesg_recv */ 22 | 23 | ssize_t 24 | Mesg_recv(int fd, struct mymesg *mptr) 25 | { 26 | return(mesg_recv(fd, mptr)); 27 | } 28 | -------------------------------------------------------------------------------- /code/unpv22e/pipemesg/mesg_send.c: -------------------------------------------------------------------------------- 1 | /* include mesg_send */ 2 | #include "mesg.h" 3 | 4 | ssize_t 5 | mesg_send(int fd, struct mymesg *mptr) 6 | { 7 | return(write(fd, mptr, MESGHDRSIZE + mptr->mesg_len)); 8 | } 9 | /* end mesg_send */ 10 | 11 | void 12 | Mesg_send(int fd, struct mymesg *mptr) 13 | { 14 | ssize_t n; 15 | 16 | if ( (n = mesg_send(fd, mptr)) != mptr->mesg_len) 17 | err_quit("mesg_send error"); 18 | } 19 | -------------------------------------------------------------------------------- /code/unpv22e/pipemesg/server.c: -------------------------------------------------------------------------------- 1 | #include "mesg.h" 2 | 3 | void 4 | server(int readfd, int writefd) 5 | { 6 | FILE *fp; 7 | ssize_t n; 8 | struct mymesg mesg; 9 | 10 | /* 4read pathname from IPC channel */ 11 | mesg.mesg_type = 1; 12 | if ( (n = Mesg_recv(readfd, &mesg)) == 0) 13 | err_quit("pathname missing"); 14 | mesg.mesg_data[n] = '\0'; /* null terminate pathname */ 15 | 16 | if ( (fp = fopen(mesg.mesg_data, "r")) == NULL) { 17 | /* 4error: must tell client */ 18 | snprintf(mesg.mesg_data + n, sizeof(mesg.mesg_data) - n, 19 | ": can't open, %s\n", strerror(errno)); 20 | mesg.mesg_len = strlen(mesg.mesg_data); 21 | Mesg_send(writefd, &mesg); 22 | 23 | } else { 24 | /* 4fopen succeeded: copy file to IPC channel */ 25 | while (Fgets(mesg.mesg_data, MAXMESGDATA, fp) != NULL) { 26 | mesg.mesg_len = strlen(mesg.mesg_data); 27 | Mesg_send(writefd, &mesg); 28 | } 29 | Fclose(fp); 30 | } 31 | 32 | /* 4send a 0-length message to signify the end */ 33 | mesg.mesg_len = 0; 34 | Mesg_send(writefd, &mesg); 35 | } 36 | -------------------------------------------------------------------------------- /code/unpv22e/pxmsg/mqcreate.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | struct mq_attr attr; /* mq_maxmsg and mq_msgsize both init to 0 */ 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int c, flags; 9 | mqd_t mqd; 10 | 11 | flags = O_RDWR | O_CREAT; 12 | while ( (c = Getopt(argc, argv, "em:z:")) != -1) { 13 | switch (c) { 14 | case 'e': 15 | flags |= O_EXCL; 16 | break; 17 | 18 | case 'm': 19 | attr.mq_maxmsg = atol(optarg); 20 | break; 21 | 22 | case 'z': 23 | attr.mq_msgsize = atol(optarg); 24 | break; 25 | } 26 | } 27 | if (optind != argc - 1) 28 | err_quit("usage: mqcreate [ -e ] [ -m maxmsg -z msgsize ] "); 29 | 30 | if ((attr.mq_maxmsg != 0 && attr.mq_msgsize == 0) || 31 | (attr.mq_maxmsg == 0 && attr.mq_msgsize != 0)) 32 | err_quit("must specify both -m maxmsg and -z msgsize"); 33 | 34 | mqd = Mq_open(argv[optind], flags, FILE_MODE, 35 | (attr.mq_maxmsg != 0) ? &attr : NULL); 36 | 37 | Mq_close(mqd); 38 | exit(0); 39 | } 40 | -------------------------------------------------------------------------------- /code/unpv22e/pxmsg/mqcreate1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int c, flags; 7 | mqd_t mqd; 8 | 9 | flags = O_RDWR | O_CREAT; 10 | while ( (c = Getopt(argc, argv, "e")) != -1) { 11 | switch (c) { 12 | case 'e': 13 | flags |= O_EXCL; 14 | break; 15 | } 16 | } 17 | if (optind != argc - 1) 18 | err_quit("usage: mqcreate [ -e ] "); 19 | 20 | mqd = Mq_open(argv[optind], flags, FILE_MODE, NULL); 21 | 22 | Mq_close(mqd); 23 | exit(0); 24 | } 25 | -------------------------------------------------------------------------------- /code/unpv22e/pxmsg/mqgetattr.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | mqd_t mqd; 7 | struct mq_attr attr; 8 | 9 | if (argc != 2) 10 | err_quit("usage: mqgetattr "); 11 | 12 | mqd = Mq_open(argv[1], O_RDONLY); 13 | 14 | Mq_getattr(mqd, &attr); 15 | printf("max #msgs = %ld, max #bytes/msg = %ld, " 16 | "#currently on queue = %ld\n", 17 | attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs); 18 | 19 | Mq_close(mqd); 20 | exit(0); 21 | } 22 | -------------------------------------------------------------------------------- /code/unpv22e/pxmsg/mqnotify3.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define MYSIG_NOTIFY (SIGRTMIN+2) 4 | 5 | struct sigevent sigev; 6 | 7 | static Sigfunc_rt sig_notify; 8 | 9 | int 10 | main(int argc, char **argv) 11 | { 12 | mqd_t mqd; 13 | 14 | if (argc != 2) 15 | err_quit("usage: mqnotify3 "); 16 | 17 | mqd = Mq_open(argv[1], O_RDONLY); 18 | 19 | Signal_rt(MYSIG_NOTIFY, sig_notify); 20 | 21 | sigev.sigev_notify = SIGEV_SIGNAL; 22 | sigev.sigev_signo = MYSIG_NOTIFY; 23 | sigev.sigev_value.sival_ptr = &mqd; 24 | Mq_notify(mqd, &sigev); 25 | 26 | for ( ; ; ) 27 | pause(); /* signal handler does everything */ 28 | 29 | exit(0); 30 | } 31 | 32 | static void 33 | sig_notify(int signo, siginfo_t *info, void *context) 34 | { 35 | printf("MYSIG_NOTIFY received\n"); 36 | if (info->si_code != SI_MESGQ) 37 | err_quit("si_code = %d", info->si_code); 38 | Mq_notify(*((mqd_t *) info->si_value.sival_ptr), &sigev); 39 | return; 40 | } 41 | -------------------------------------------------------------------------------- /code/unpv22e/pxmsg/mqnotifysig1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | mqd_t mqd; 4 | void *buff; 5 | struct mq_attr attr; 6 | struct sigevent sigev; 7 | 8 | static void sig_usr1(int); 9 | 10 | int 11 | main(int argc, char **argv) 12 | { 13 | if (argc != 2) 14 | err_quit("usage: mqnotifysig1 "); 15 | 16 | /* 4open queue, get attributes, allocate read buffer */ 17 | mqd = Mq_open(argv[1], O_RDONLY); 18 | Mq_getattr(mqd, &attr); 19 | buff = Malloc(attr.mq_msgsize); 20 | 21 | /* 4establish signal handler, enable notification */ 22 | Signal(SIGUSR1, sig_usr1); 23 | sigev.sigev_notify = SIGEV_SIGNAL; 24 | sigev.sigev_signo = SIGUSR1; 25 | Mq_notify(mqd, &sigev); 26 | 27 | for ( ; ; ) 28 | pause(); /* signal handler does everything */ 29 | exit(0); 30 | } 31 | 32 | static void 33 | sig_usr1(int signo) 34 | { 35 | ssize_t n; 36 | 37 | Mq_notify(mqd, &sigev); /* reregister first */ 38 | n = Mq_receive(mqd, buff, attr.mq_msgsize, NULL); 39 | printf("SIGUSR1 received, read %ld bytes\n", (long) n); 40 | return; 41 | } 42 | -------------------------------------------------------------------------------- /code/unpv22e/pxmsg/mqnotifythread1.c.sun: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | struct sigevent sigev; 4 | mqd_t mqd; 5 | 6 | #if defined(sun) && defined(__svr4__) 7 | #define sigev_notify_function _sigev_un._sigev_notify_function 8 | #define sigev_notify_attributes _sigev_notify_attributes 9 | #endif 10 | 11 | static void notify_thread(union sigval); /* our thread function */ 12 | 13 | int 14 | main(int argc, char **argv) 15 | { 16 | if (argc != 2) 17 | err_quit("usage: mqnotify2 "); 18 | 19 | mqd = Mq_open(argv[1], O_RDONLY); 20 | 21 | sigev.sigev_notify = SIGEV_THREAD; 22 | sigev.sigev_value.sival_ptr = NULL; 23 | sigev.sigev_notify_function = notify_thread; 24 | sigev.sigev_notify_attributes = NULL; 25 | Mq_notify(mqd, &sigev); 26 | 27 | for ( ; ; ) 28 | pause(); 29 | 30 | exit(0); 31 | } 32 | 33 | static void 34 | notify_thread(union sigval arg) 35 | { 36 | printf("notify_thread started\n"); 37 | Mq_notify(mqd, &sigev); /* reregister */ 38 | pthread_exit(NULL); 39 | } 40 | -------------------------------------------------------------------------------- /code/unpv22e/pxmsg/mqreceive.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int c, flags; 7 | mqd_t mqd; 8 | ssize_t n; 9 | uint_t prio; 10 | void *buff; 11 | struct mq_attr attr; 12 | 13 | flags = O_RDONLY; 14 | while ( (c = Getopt(argc, argv, "n")) != -1) { 15 | switch (c) { 16 | case 'n': 17 | flags |= O_NONBLOCK; 18 | break; 19 | } 20 | } 21 | if (optind != argc - 1) 22 | err_quit("usage: mqreceive [ -n ] "); 23 | 24 | mqd = Mq_open(argv[optind], flags); 25 | Mq_getattr(mqd, &attr); 26 | 27 | buff = Malloc(attr.mq_msgsize); 28 | 29 | n = Mq_receive(mqd, buff, attr.mq_msgsize, &prio); 30 | printf("read %ld bytes, priority = %u\n", (long) n, prio); 31 | 32 | exit(0); 33 | } 34 | -------------------------------------------------------------------------------- /code/unpv22e/pxmsg/mqsend.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | mqd_t mqd; 7 | void *ptr; 8 | size_t len; 9 | uint_t prio; 10 | 11 | if (argc != 4) 12 | err_quit("usage: mqsend <#bytes> "); 13 | len = atoi(argv[2]); 14 | prio = atoi(argv[3]); 15 | 16 | mqd = Mq_open(argv[1], O_WRONLY); 17 | 18 | ptr = Calloc(len, sizeof(char)); 19 | Mq_send(mqd, ptr, len, prio); 20 | 21 | exit(0); 22 | } 23 | -------------------------------------------------------------------------------- /code/unpv22e/pxmsg/mqsysconf.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("MQ_OPEN_MAX = %ld, MQ_PRIO_MAX = %ld\n", 7 | Sysconf(_SC_MQ_OPEN_MAX), Sysconf(_SC_MQ_PRIO_MAX)); 8 | exit(0); 9 | } 10 | -------------------------------------------------------------------------------- /code/unpv22e/pxmsg/mqunlink.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | if (argc != 2) 7 | err_quit("usage: mqunlink "); 8 | 9 | Mq_unlink(argv[1]); 10 | 11 | exit(0); 12 | } 13 | -------------------------------------------------------------------------------- /code/unpv22e/pxsem/mycat1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd, n; 7 | char buff[BUFFSIZE]; 8 | 9 | if (argc != 2) 10 | err_quit("usage: mycat1 "); 11 | 12 | fd = Open(argv[1], O_RDONLY); 13 | 14 | while ( (n = Read(fd, buff, BUFFSIZE)) > 0) 15 | Write(STDOUT_FILENO, buff, n); 16 | 17 | exit(0); 18 | } 19 | -------------------------------------------------------------------------------- /code/unpv22e/pxsem/semcreate.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int c, flags; 7 | sem_t *sem; 8 | unsigned int value; 9 | 10 | flags = O_RDWR | O_CREAT; 11 | value = 1; 12 | while ( (c = Getopt(argc, argv, "ei:")) != -1) { 13 | switch (c) { 14 | case 'e': 15 | flags |= O_EXCL; 16 | break; 17 | 18 | case 'i': 19 | value = atoi(optarg); 20 | break; 21 | } 22 | } 23 | if (optind != argc - 1) 24 | err_quit("usage: semcreate [ -e ] [ -i initalvalue ] "); 25 | 26 | sem = Sem_open(argv[optind], flags, FILE_MODE, value); 27 | 28 | Sem_close(sem); 29 | exit(0); 30 | } 31 | -------------------------------------------------------------------------------- /code/unpv22e/pxsem/semgetvalue.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | sem_t *sem; 7 | int val; 8 | 9 | if (argc != 2) 10 | err_quit("usage: semgetvalue "); 11 | 12 | sem = Sem_open(argv[1], 0); 13 | Sem_getvalue(sem, &val); 14 | printf("value = %d\n", val); 15 | 16 | exit(0); 17 | } 18 | -------------------------------------------------------------------------------- /code/unpv22e/pxsem/sempost.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | sem_t *sem; 7 | int val; 8 | 9 | if (argc != 2) 10 | err_quit("usage: sempost "); 11 | 12 | sem = Sem_open(argv[1], 0); 13 | Sem_post(sem); 14 | Sem_getvalue(sem, &val); 15 | printf("value = %d\n", val); 16 | 17 | exit(0); 18 | } 19 | -------------------------------------------------------------------------------- /code/unpv22e/pxsem/semsysconf.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("SEM_NSEMS_MAX = %ld, SEM_VALUE_MAX = %ld\n", 7 | Sysconf(_SC_SEM_NSEMS_MAX), Sysconf(_SC_SEM_VALUE_MAX)); 8 | exit(0); 9 | } 10 | -------------------------------------------------------------------------------- /code/unpv22e/pxsem/semunlink.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | if (argc != 2) 7 | err_quit("usage: semunlink "); 8 | 9 | Sem_unlink(argv[1]); 10 | 11 | exit(0); 12 | } 13 | -------------------------------------------------------------------------------- /code/unpv22e/pxsem/semwait.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | sem_t *sem; 7 | int val; 8 | 9 | if (argc != 2) 10 | err_quit("usage: semwait "); 11 | 12 | sem = Sem_open(argv[1], 0); 13 | Sem_wait(sem); 14 | Sem_getvalue(sem, &val); 15 | printf("pid %ld has semaphore, value = %d\n", (long) getpid(), val); 16 | 17 | pause(); /* blocks until killed */ 18 | exit(0); 19 | } 20 | -------------------------------------------------------------------------------- /code/unpv22e/pxsem/testeintr.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define NAME "testeintr" 4 | 5 | static void sig_alrm(int); 6 | 7 | int 8 | main(int argc, char **argv) 9 | { 10 | sem_t *sem1, sem2; 11 | 12 | /* 4first test a named semaphore */ 13 | sem_unlink(Px_ipc_name(NAME)); 14 | sem1 = Sem_open(Px_ipc_name(NAME), O_RDWR | O_CREAT | O_EXCL, 15 | FILE_MODE, 0); 16 | 17 | Signal(SIGALRM, sig_alrm); 18 | alarm(2); 19 | if (sem_wait(sem1) == 0) 20 | printf("sem_wait returned 0?\n"); 21 | else 22 | err_ret("sem_wait error"); 23 | Sem_close(sem1); 24 | 25 | /* 4now a memory-based semaphore with process scope */ 26 | Sem_init(&sem2, 1, 0); 27 | alarm(2); 28 | if (sem_wait(&sem2) == 0) 29 | printf("sem_wait returned 0?\n"); 30 | else 31 | err_ret("sem_wait error"); 32 | Sem_destroy(&sem2); 33 | 34 | exit(0); 35 | } 36 | 37 | static void 38 | sig_alrm(int signo) 39 | { 40 | printf("SIGALRM caught\n"); 41 | return; 42 | } 43 | -------------------------------------------------------------------------------- /code/unpv22e/pxshm/client1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | struct shmstruct { /* struct stored in shared memory */ 4 | int count; 5 | }; 6 | sem_t *mutex; /* pointer to named semaphore */ 7 | 8 | int 9 | main(int argc, char **argv) 10 | { 11 | int fd, i, nloop; 12 | pid_t pid; 13 | struct shmstruct *ptr; 14 | 15 | if (argc != 4) 16 | err_quit("usage: client1 <#loops>"); 17 | nloop = atoi(argv[3]); 18 | 19 | fd = Shm_open(Px_ipc_name(argv[1]), O_RDWR, FILE_MODE); 20 | ptr = Mmap(NULL, sizeof(struct shmstruct), PROT_READ | PROT_WRITE, 21 | MAP_SHARED, fd, 0); 22 | Close(fd); 23 | 24 | mutex = Sem_open(Px_ipc_name(argv[2]), 0); 25 | 26 | pid = getpid(); 27 | for (i = 0; i < nloop; i++) { 28 | Sem_wait(mutex); 29 | printf("pid %ld: %d\n", (long) pid, ptr->count++); 30 | Sem_post(mutex); 31 | } 32 | exit(0); 33 | } 34 | -------------------------------------------------------------------------------- /code/unpv22e/pxshm/cliserv2.h: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define MESGSIZE 256 /* max #bytes per message, incl. null at end */ 4 | #define NMESG 16 /* max #messages */ 5 | 6 | struct shmstruct { /* struct stored in shared memory */ 7 | sem_t mutex; /* three Posix memory-based semaphores */ 8 | sem_t nempty; 9 | sem_t nstored; 10 | int nput; /* index into msgoff[] for next put */ 11 | long noverflow; /* #overflows by senders */ 12 | sem_t noverflowmutex; /* mutex for noverflow counter */ 13 | long msgoff[NMESG]; /* offset in shared memory of each message */ 14 | char msgdata[NMESG * MESGSIZE]; /* the actual messages */ 15 | }; 16 | -------------------------------------------------------------------------------- /code/unpv22e/pxshm/server1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | struct shmstruct { /* struct stored in shared memory */ 4 | int count; 5 | }; 6 | sem_t *mutex; /* pointer to named semaphore */ 7 | 8 | int 9 | main(int argc, char **argv) 10 | { 11 | int fd; 12 | struct shmstruct *ptr; 13 | 14 | if (argc != 3) 15 | err_quit("usage: server1 "); 16 | 17 | shm_unlink(Px_ipc_name(argv[1])); /* OK if this fails */ 18 | /* 4create shm, set its size, map it, close descriptor */ 19 | fd = Shm_open(Px_ipc_name(argv[1]), O_RDWR | O_CREAT | O_EXCL, FILE_MODE); 20 | Ftruncate(fd, sizeof(struct shmstruct)); 21 | ptr = Mmap(NULL, sizeof(struct shmstruct), PROT_READ | PROT_WRITE, 22 | MAP_SHARED, fd, 0); 23 | Close(fd); 24 | 25 | sem_unlink(Px_ipc_name(argv[2])); /* OK if this fails */ 26 | mutex = Sem_open(Px_ipc_name(argv[2]), O_CREAT | O_EXCL, FILE_MODE, 1); 27 | Sem_close(mutex); 28 | 29 | exit(0); 30 | } 31 | -------------------------------------------------------------------------------- /code/unpv22e/pxshm/shmcreate.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int c, fd, flags; 7 | char *ptr; 8 | off_t length; 9 | 10 | flags = O_RDWR | O_CREAT; 11 | while ( (c = Getopt(argc, argv, "e")) != -1) { 12 | switch (c) { 13 | case 'e': 14 | flags |= O_EXCL; 15 | break; 16 | } 17 | } 18 | if (optind != argc - 2) 19 | err_quit("usage: shmcreate [ -e ] "); 20 | length = atoi(argv[optind + 1]); 21 | 22 | fd = Shm_open(argv[optind], flags, FILE_MODE); 23 | Ftruncate(fd, length); 24 | 25 | ptr = Mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 26 | 27 | exit(0); 28 | } 29 | -------------------------------------------------------------------------------- /code/unpv22e/pxshm/shmread.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i, fd; 7 | struct stat stat; 8 | unsigned char c, *ptr; 9 | 10 | if (argc != 2) 11 | err_quit("usage: shmread "); 12 | 13 | /* 4open, get size, map */ 14 | fd = Shm_open(argv[1], O_RDONLY, FILE_MODE); 15 | Fstat(fd, &stat); 16 | ptr = Mmap(NULL, stat.st_size, PROT_READ, 17 | MAP_SHARED, fd, 0); 18 | Close(fd); 19 | 20 | /* 4check that ptr[0] = 0, ptr[1] = 1, etc. */ 21 | for (i = 0; i < stat.st_size; i++) 22 | if ( (c = *ptr++) != (i % 256)) 23 | err_ret("ptr[%d] = %d", i, c); 24 | 25 | exit(0); 26 | } 27 | -------------------------------------------------------------------------------- /code/unpv22e/pxshm/shmunlink.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | if (argc != 2) 7 | err_quit("usage: shmunlink "); 8 | 9 | Shm_unlink(argv[1]); 10 | 11 | exit(0); 12 | } 13 | -------------------------------------------------------------------------------- /code/unpv22e/pxshm/shmwrite.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i, fd; 7 | struct stat stat; 8 | unsigned char *ptr; 9 | 10 | if (argc != 2) 11 | err_quit("usage: shmwrite "); 12 | 13 | /* 4open, get size, map */ 14 | fd = Shm_open(argv[1], O_RDWR, FILE_MODE); 15 | Fstat(fd, &stat); 16 | ptr = Mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, 17 | MAP_SHARED, fd, 0); 18 | Close(fd); 19 | 20 | /* 4set: ptr[0] = 0, ptr[1] = 1, etc. */ 21 | for (i = 0; i < stat.st_size; i++) 22 | *ptr++ = i % 256; 23 | 24 | exit(0); 25 | } 26 | -------------------------------------------------------------------------------- /code/unpv22e/pxshm/test1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd, i; 7 | char *ptr; 8 | size_t shmsize, mmapsize, pagesize; 9 | 10 | if (argc != 4) 11 | err_quit("usage: test1 "); 12 | shmsize = atoi(argv[2]); 13 | mmapsize = atoi(argv[3]); 14 | 15 | /* open shm: create or truncate; set shm size */ 16 | fd = Shm_open(Px_ipc_name(argv[1]), O_RDWR | O_CREAT | O_TRUNC, 17 | FILE_MODE); 18 | Ftruncate(fd, shmsize); 19 | /* $$.bp$$ */ 20 | ptr = Mmap(NULL, mmapsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 21 | Close(fd); 22 | 23 | pagesize = Sysconf(_SC_PAGESIZE); 24 | printf("PAGESIZE = %ld\n", (long) pagesize); 25 | 26 | for (i = 0; i < max(shmsize, mmapsize); i += pagesize) { 27 | printf("ptr[%d] = %d\n", i, ptr[i]); 28 | ptr[i] = 1; 29 | printf("ptr[%d] = %d\n", i + pagesize - 1, ptr[i + pagesize - 1]); 30 | ptr[i + pagesize - 1] = 1; 31 | } 32 | printf("ptr[%d] = %d\n", i, ptr[i]); 33 | 34 | exit(0); 35 | } 36 | -------------------------------------------------------------------------------- /code/unpv22e/pxshm/test2.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define FILE "test.data" 4 | #define SIZE 32768 5 | 6 | int 7 | main(int argc, char **argv) 8 | { 9 | int fd, i; 10 | char *ptr; 11 | 12 | /* 4open shm: create or truncate; then mmap shm */ 13 | fd = Shm_open(Px_ipc_name(FILE), O_RDWR | O_CREAT | O_TRUNC, FILE_MODE); 14 | ptr = Mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 15 | 16 | for (i = 4096; i <= SIZE; i += 4096) { 17 | printf("setting shm size to %d\n", i); 18 | Ftruncate(fd, i); 19 | printf("ptr[%d] = %d\n", i-1, ptr[i-1]); 20 | } 21 | 22 | exit(0); 23 | } 24 | -------------------------------------------------------------------------------- /code/unpv22e/rtsignals/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = test1 test2 test3 4 | 5 | all: ${PROGS} 6 | 7 | test1: test1.o 8 | ${CC} ${CFLAGS} -o $@ test1.o ${LIBS} 9 | 10 | test2: test2.o 11 | ${CC} ${CFLAGS} -o $@ test2.o ${LIBS} 12 | 13 | test3: test3.o 14 | ${CC} ${CFLAGS} -o $@ test3.o ${LIBS} 15 | 16 | clean: 17 | rm -f ${PROGS} ${CLEANFILES} 18 | -------------------------------------------------------------------------------- /code/unpv22e/shm/incr1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define SEM_NAME "mysem" 4 | 5 | int count = 0; 6 | 7 | int 8 | main(int argc, char **argv) 9 | { 10 | int i, nloop; 11 | sem_t *mutex; 12 | 13 | if (argc != 2) 14 | err_quit("usage: incr1 <#loops>"); 15 | nloop = atoi(argv[1]); 16 | 17 | /* 4create, initialize, and unlink semaphore */ 18 | mutex = Sem_open(Px_ipc_name(SEM_NAME), O_CREAT | O_EXCL, FILE_MODE, 1); 19 | Sem_unlink(Px_ipc_name(SEM_NAME)); 20 | 21 | setbuf(stdout, NULL); /* stdout is unbuffered */ 22 | if (Fork() == 0) { /* child */ 23 | for (i = 0; i < nloop; i++) { 24 | Sem_wait(mutex); 25 | printf("child: %d\n", count++); 26 | Sem_post(mutex); 27 | } 28 | exit(0); 29 | } 30 | 31 | /* 4parent */ 32 | for (i = 0; i < nloop; i++) { 33 | Sem_wait(mutex); 34 | printf("parent: %d\n", count++); 35 | Sem_post(mutex); 36 | } 37 | exit(0); 38 | } 39 | -------------------------------------------------------------------------------- /code/unpv22e/shm/test1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd, i; 7 | char *ptr; 8 | size_t filesize, mmapsize, pagesize; 9 | 10 | if (argc != 4) 11 | err_quit("usage: test1 "); 12 | filesize = atoi(argv[2]); 13 | mmapsize = atoi(argv[3]); 14 | 15 | /* 4open file: create or truncate; set file size */ 16 | fd = Open(argv[1], O_RDWR | O_CREAT | O_TRUNC, FILE_MODE); 17 | Lseek(fd, filesize-1, SEEK_SET); 18 | Write(fd, "", 1); 19 | 20 | ptr = Mmap(NULL, mmapsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 21 | Close(fd); 22 | 23 | pagesize = Sysconf(_SC_PAGESIZE); 24 | printf("PAGESIZE = %ld\n", (long) pagesize); 25 | 26 | for (i = 0; i < max(filesize, mmapsize); i += pagesize) { 27 | printf("ptr[%d] = %d\n", i, ptr[i]); 28 | ptr[i] = 1; 29 | printf("ptr[%d] = %d\n", i + pagesize - 1, ptr[i + pagesize - 1]); 30 | ptr[i + pagesize - 1] = 1; 31 | } 32 | printf("ptr[%d] = %d\n", i, ptr[i]); 33 | 34 | exit(0); 35 | } 36 | -------------------------------------------------------------------------------- /code/unpv22e/shm/test2.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define FILE "test.data" 4 | #define SIZE 32768 5 | 6 | int 7 | main(int argc, char **argv) 8 | { 9 | int fd, i; 10 | char *ptr; 11 | 12 | /* 4open: create or truncate; then mmap file */ 13 | fd = Open(FILE, O_RDWR | O_CREAT | O_TRUNC, FILE_MODE); 14 | ptr = Mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 15 | 16 | for (i = 4096; i <= SIZE; i += 4096) { 17 | printf("setting file size to %d\n", i); 18 | Ftruncate(fd, i); 19 | printf("ptr[%d] = %d\n", i-1, ptr[i-1]); 20 | } 21 | 22 | exit(0); 23 | } 24 | -------------------------------------------------------------------------------- /code/unpv22e/shm/test3.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int fd, i, n, val, *ptr; 7 | pid_t childpid; 8 | 9 | if (argc != 2) 10 | err_quit("usage: test3 "); 11 | 12 | unlink(argv[1]); /* error OK */ 13 | fd = Open(argv[1], O_RDWR | O_CREAT | O_EXCL, FILE_MODE); 14 | val = 9999; 15 | Write(fd, &val, sizeof(int)); /* sets file size too */ 16 | 17 | ptr = Mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 18 | Close(fd); 19 | *ptr = 1; 20 | 21 | if ( (childpid = Fork()) == 0) { 22 | fd = Open(argv[1], O_RDONLY); /* child */ 23 | for (i = 0; i < 10; i++) { 24 | Lseek(fd, 0, SEEK_SET); 25 | if ( (n = Read(fd, &val, sizeof(int))) != sizeof(int)) 26 | err_quit("read returned %d", n); 27 | printf("val = %d\n", val); 28 | sleep(1); 29 | } 30 | exit(0); 31 | } 32 | Waitpid(childpid, NULL, 0); 33 | 34 | exit(0); 35 | } 36 | -------------------------------------------------------------------------------- /code/unpv22e/sparc-sun-solaris2.6/Makefile: -------------------------------------------------------------------------------- 1 | # Generated automatically from Makefile.in by configure. 2 | include ./Make.defines 3 | 4 | all: 5 | @echo "Nothing to make in this directory" 6 | @echo "Please read the README file" 7 | 8 | clean: 9 | rm -f $(CLEANFILES) 10 | 11 | distclean: 12 | rm -f $(CLEANFILES) config.cache config.log config.status 13 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/Make.defines: -------------------------------------------------------------------------------- 1 | ../Make.defines -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | DIRS = square1 square2 square3 square4 square5 \ 4 | square6 square7 square8 square9 square10 \ 5 | xdr1 test1 6 | 7 | # All this Makefile does is clean all the subdirectories. 8 | 9 | all: 10 | 11 | clean: 12 | for i in ${DIRS} ; \ 13 | do (cd $$i; make clean) ; \ 14 | done 15 | rm -f ${PROGS} ${CLEANFILES} *_clnt.c *_svc.c *_xdr.c square.h 16 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/config.h: -------------------------------------------------------------------------------- 1 | ../config.h -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square1/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = client server 4 | 5 | all: ${PROGS} 6 | 7 | square.h square_clnt.c square_svc.c square_xdr.c: square.x 8 | rpcgen -C square.x 9 | 10 | square_clnt.o: square_clnt.c square.h 11 | 12 | square_svc.o: square_svc.c square.h 13 | 14 | client: square.h client.o square_clnt.o square_xdr.o 15 | ${CC} ${CFLAGS} -o $@ client.o square_clnt.o square_xdr.o \ 16 | ${LIBS} ${LIBS_RPC} 17 | 18 | server: square.h server.o square_svc.o square_xdr.o 19 | ${CC} ${CFLAGS} -o $@ server.o square_svc.o square_xdr.o \ 20 | ${LIBS} ${LIBS_RPC} 21 | 22 | clean: 23 | rm -f ${PROGS} ${CLEANFILES} *_clnt.c *_svc.c *_xdr.c square.h 24 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square1/client.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" /* our header */ 2 | #include "square.h" /* generated by rpcgen */ 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | CLIENT *cl; 8 | square_in in; 9 | square_out *outp; 10 | 11 | if (argc != 3) 12 | err_quit("usage: client "); 13 | 14 | cl = Clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, "tcp"); 15 | 16 | in.arg1 = atol(argv[2]); 17 | if ( (outp = squareproc_1(&in, cl)) == NULL) 18 | err_quit("%s", clnt_sperror(cl, argv[1])); 19 | 20 | printf("result: %ld\n", outp->res1); 21 | exit(0); 22 | } 23 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square1/server.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | square_out * 5 | squareproc_1_svc(square_in *inp, struct svc_req *rqstp) 6 | { 7 | static square_out out; 8 | 9 | out.res1 = inp->arg1 * inp->arg1; 10 | return(&out); 11 | } 12 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square1/square.x: -------------------------------------------------------------------------------- 1 | struct square_in { /* input (argument) */ 2 | long arg1; 3 | }; 4 | 5 | struct square_out { /* output (result) */ 6 | long res1; 7 | }; 8 | 9 | program SQUARE_PROG { 10 | version SQUARE_VERS { 11 | square_out SQUAREPROC(square_in) = 1; /* procedure number = 1 */ 12 | } = 1; /* version number */ 13 | } = 0x31230000; /* program number */ 14 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square10/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = client server 4 | 5 | all: ${PROGS} 6 | 7 | square.h square_clnt.c square_svc.c square_xdr.c: square.x 8 | rpcgen -C square.x 9 | 10 | square_clnt.o: square_clnt.c square.h 11 | 12 | square_svc.o: square_svc.c square.h 13 | 14 | client: square.h client.o square_clnt.o square_xdr.o 15 | ${CC} ${CFLAGS} -o $@ client.o square_clnt.o square_xdr.o \ 16 | ${LIBS} ${LIBS_RPC} 17 | 18 | server: square.h server.o square_svc.o square_xdr.o 19 | ${CC} ${CFLAGS} -o $@ server.o square_svc.o square_xdr.o \ 20 | ${LIBS} ${LIBS_RPC} 21 | 22 | clean: 23 | rm -f ${PROGS} ${CLEANFILES} *_clnt.c *_svc.c *_xdr.c square.h 24 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square10/client.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" /* our header */ 2 | #include "square.h" /* generated by rpcgen */ 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | CLIENT *cl; 8 | struct timeval tv; 9 | 10 | if (argc != 3) 11 | err_quit("usage: client "); 12 | 13 | cl = Clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, argv[2]); 14 | 15 | tv.tv_sec = 10; 16 | tv.tv_usec = 0; 17 | if (clnt_call(cl, NULLPROC, xdr_void, NULL, 18 | xdr_void, NULL, tv) != RPC_SUCCESS) 19 | err_quit("%s", clnt_sperror(cl, argv[1])); 20 | 21 | exit(0); 22 | } 23 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square10/server.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | square_out * 5 | squareproc_1_svc(square_in *inp, struct svc_req *rqstp) 6 | { 7 | static square_out out; 8 | 9 | out.res1 = inp->arg1 * inp->arg1; 10 | return(&out); 11 | } 12 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square10/square.x: -------------------------------------------------------------------------------- 1 | struct square_in { /* input (argument) */ 2 | long arg1; 3 | }; 4 | 5 | struct square_out { /* output (result) */ 6 | long res1; 7 | }; 8 | 9 | program SQUARE_PROG { 10 | version SQUARE_VERS { 11 | square_out SQUAREPROC(square_in) = 1; /* procedure number = 1 */ 12 | } = 1; /* version number */ 13 | } = 0x31230000; /* program number */ 14 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square2/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = client server 4 | CFLAGS += -DDEBUG 5 | 6 | all: ${PROGS} 7 | 8 | square.h square_clnt.c square_svc.c square_xdr.c: square.x 9 | rpcgen -C square.x 10 | 11 | square_clnt.o: square_clnt.c square.h 12 | 13 | square_svc.o: square_svc.c square.h 14 | 15 | client: square.h client.o square_clnt.o square_xdr.o 16 | ${CC} ${CFLAGS} -o $@ client.o square_clnt.o square_xdr.o \ 17 | ${LIBS} ${LIBS_RPC} 18 | 19 | server: square.h server.o square_svc.o square_xdr.o 20 | ${CC} ${CFLAGS} -o $@ server.o square_svc.o square_xdr.o \ 21 | ${LIBS} ${LIBS_RPC} 22 | 23 | clean: 24 | rm -f ${PROGS} ${CLEANFILES} *_clnt.c *_svc.c *_xdr.c square.h 25 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square2/client.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | CLIENT *cl; 8 | square_in in; 9 | square_out *outp; 10 | 11 | if (argc != 3) 12 | err_quit("usage: client "); 13 | 14 | cl = Clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, "tcp"); 15 | 16 | in.arg1 = atol(argv[2]); 17 | if ( (outp = squareproc_1(&in, cl)) == NULL) 18 | err_quit("%s", clnt_sperror(cl, argv[1])); 19 | 20 | printf("result: %ld\n", outp->res1); 21 | exit(0); 22 | } 23 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square2/server.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | square_out * 5 | squareproc_1_svc(square_in *inp, struct svc_req *rqstp) 6 | { 7 | static square_out out; 8 | 9 | printf("thread %ld started, arg = %ld\n", 10 | pr_thread_id(NULL), inp->arg1); 11 | sleep(5); 12 | out.res1 = inp->arg1 * inp->arg1; 13 | printf("thread %ld done\n", pr_thread_id(NULL)); 14 | 15 | return(&out); 16 | } 17 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square2/square.x: -------------------------------------------------------------------------------- 1 | struct square_in { 2 | long arg1; 3 | }; 4 | 5 | struct square_out { 6 | long res1; 7 | }; 8 | 9 | program SQUARE_PROG { 10 | version SQUARE_VERS { 11 | square_out SQUAREPROC(square_in) = 1; 12 | /* procedure number = 1 */ 13 | } = 1; /* version number = 1 */ 14 | } = 0x31230000; /* program number = 0x31230000 */ 15 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square3/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = client server 4 | CFLAGS += -DDEBUG 5 | 6 | all: ${PROGS} 7 | 8 | square.h square_clnt.c square_svc.c square_xdr.c: square.x 9 | rpcgen -C -M -A square.x 10 | 11 | square_clnt.o: square_clnt.c square.h 12 | 13 | square_svc.o: square_svc.c square.h 14 | 15 | client: square.h client.o square_clnt.o square_xdr.o 16 | ${CC} ${CFLAGS} -o $@ client.o square_clnt.o square_xdr.o \ 17 | ${LIBS} ${LIBS_RPC} 18 | 19 | server: square.h server.o square_svc.o square_xdr.o 20 | ${CC} ${CFLAGS} -o $@ server.o square_svc.o square_xdr.o \ 21 | ${LIBS} ${LIBS_RPC} 22 | 23 | clean: 24 | rm -f ${PROGS} ${CLEANFILES} *_clnt.c *_svc.c *_xdr.c square.h 25 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square3/client.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | CLIENT *cl; 8 | square_in in; 9 | square_out out; 10 | 11 | if (argc != 3) 12 | err_quit("usage: client "); 13 | 14 | cl = Clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, "tcp"); 15 | 16 | in.arg1 = atol(argv[2]); 17 | if (squareproc_2(&in, &out, cl) != RPC_SUCCESS) 18 | err_quit("%s", clnt_sperror(cl, argv[1])); 19 | 20 | printf("result: %ld\n", out.res1); 21 | exit(0); 22 | } 23 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square3/server.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | bool_t 5 | squareproc_2_svc(square_in *inp, square_out *outp, struct svc_req *rqstp) 6 | { 7 | printf("thread %ld started, arg = %ld\n", 8 | pr_thread_id(NULL), inp->arg1); 9 | sleep(5); 10 | outp->res1 = inp->arg1 * inp->arg1; 11 | printf("thread %ld done\n", pr_thread_id(NULL)); 12 | return(TRUE); 13 | } 14 | 15 | int 16 | square_prog_2_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, 17 | caddr_t result) 18 | { 19 | xdr_free(xdr_result, result); 20 | return(1); 21 | } 22 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square3/square.x: -------------------------------------------------------------------------------- 1 | struct square_in { 2 | long arg1; 3 | }; 4 | 5 | struct square_out { 6 | long res1; 7 | }; 8 | 9 | program SQUARE_PROG { 10 | version SQUARE_VERS { 11 | square_out SQUAREPROC(square_in) = 1; 12 | /* procedure number = 1 */ 13 | } = 2; /* version number = 2 */ 14 | } = 0x31230000; /* program number = 0x31230000 */ 15 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square4/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = client server 4 | CFLAGS += -DDEBUG 5 | 6 | all: ${PROGS} 7 | 8 | square.h square_clnt.c square_svc.c square_xdr.c: square.x 9 | rpcgen -C -M -A square.x 10 | 11 | square_clnt.o: square_clnt.c square.h 12 | 13 | square_svc.o: square_svc.c square.h 14 | 15 | client: square.h client.o square_clnt.o square_xdr.o 16 | ${CC} ${CFLAGS} -o $@ client.o square_clnt.o square_xdr.o \ 17 | ${LIBS} ${LIBS_RPC} 18 | 19 | server: square.h server.o square_svc.o square_xdr.o 20 | ${CC} ${CFLAGS} -o $@ server.o square_svc.o square_xdr.o \ 21 | ${LIBS} ${LIBS_RPC} 22 | 23 | clean: 24 | rm -f ${PROGS} ${CLEANFILES} *_clnt.c *_svc.c *_xdr.c square.h 25 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square4/client.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | CLIENT *cl; 8 | square_in in; 9 | square_out out; 10 | 11 | if (argc != 3) 12 | err_quit("usage: client "); 13 | 14 | cl = Clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, "tcp"); 15 | 16 | auth_destroy(cl->cl_auth); 17 | cl->cl_auth = authsys_create_default(); 18 | 19 | in.arg1 = atol(argv[2]); 20 | if (squareproc_2(&in, &out, cl) != RPC_SUCCESS) 21 | err_quit("%s", clnt_sperror(cl, argv[1])); 22 | 23 | printf("result: %ld\n", out.res1); 24 | exit(0); 25 | } 26 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square4/server.c: -------------------------------------------------------------------------------- 1 | /* include servproc */ 2 | #include "unpipc.h" 3 | #include "square.h" 4 | 5 | bool_t 6 | squareproc_2_svc(square_in *inp, square_out *outp, struct svc_req *rqstp) 7 | { 8 | printf("thread %ld started, arg = %ld, auth = %d\n", 9 | pr_thread_id(NULL), inp->arg1, rqstp->rq_cred.oa_flavor); 10 | if (rqstp->rq_cred.oa_flavor == AUTH_SYS) { 11 | struct authsys_parms *au; 12 | 13 | au = (struct authsys_parms *)rqstp->rq_clntcred; 14 | printf("AUTH_SYS: host %s, uid %ld, gid %ld\n", 15 | au->aup_machname, (long) au->aup_uid, (long) au->aup_gid); 16 | } 17 | 18 | sleep(5); 19 | outp->res1 = inp->arg1 * inp->arg1; 20 | printf("thread %ld done\n", pr_thread_id(NULL)); 21 | return(TRUE); 22 | } 23 | /* end servproc */ 24 | 25 | int 26 | square_prog_2_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, 27 | caddr_t result) 28 | { 29 | xdr_free(xdr_result, result); 30 | return(1); 31 | } 32 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square4/square.x: -------------------------------------------------------------------------------- 1 | struct square_in { 2 | long arg1; 3 | }; 4 | 5 | struct square_out { 6 | long res1; 7 | }; 8 | 9 | program SQUARE_PROG { 10 | version SQUARE_VERS { 11 | square_out SQUAREPROC(square_in) = 1; 12 | /* procedure number = 1 */ 13 | } = 2; /* version number = 2 */ 14 | } = 0x31230000; /* program number = 0x31230000 */ 15 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square5/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = client server 4 | CFLAGS += -DDEBUG 5 | 6 | all: ${PROGS} 7 | 8 | square.h square_clnt.c square_svc.c square_xdr.c: square.x 9 | rpcgen -C square.x 10 | 11 | square_clnt.o: square_clnt.c square.h 12 | 13 | square_svc.o: square_svc.c square.h 14 | 15 | client: square.h client.o square_clnt.o square_xdr.o 16 | ${CC} ${CFLAGS} -o $@ client.o square_clnt.o square_xdr.o \ 17 | ${LIBS} ${LIBS_RPC} 18 | 19 | server: square.h server.o square_svc.o square_xdr.o 20 | ${CC} ${CFLAGS} -o $@ server.o square_svc.o square_xdr.o \ 21 | ${LIBS} ${LIBS_RPC} 22 | 23 | clean: 24 | rm -f ${PROGS} ${CLEANFILES} *_clnt.c *_svc.c *_xdr.c square.h 25 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square5/client.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | CLIENT *cl; 8 | square_in in; 9 | square_out *outp; 10 | struct timeval tv; 11 | 12 | if (argc != 4) 13 | err_quit("usage: client "); 14 | 15 | cl = Clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, argv[3]); 16 | 17 | Clnt_control(cl, CLGET_TIMEOUT, (char *) &tv); 18 | printf("timeout = %ld sec, %ld usec\n", tv.tv_sec, tv.tv_usec); 19 | if (clnt_control(cl, CLGET_RETRY_TIMEOUT, (char *) &tv) == TRUE) 20 | printf("retry timeout = %ld sec, %ld usec\n", tv.tv_sec, tv.tv_usec); 21 | 22 | in.arg1 = atol(argv[2]); 23 | if ( (outp = squareproc_1(&in, cl)) == NULL) 24 | err_quit("%s", clnt_sperror(cl, argv[1])); 25 | 26 | printf("result: %ld\n", outp->res1); 27 | exit(0); 28 | } 29 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square5/server.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | square_out * 5 | squareproc_1_svc(square_in *inp, struct svc_req *rqstp) 6 | { 7 | static square_out out; 8 | 9 | printf("thread %ld started, arg = %ld\n", 10 | pr_thread_id(NULL), inp->arg1); 11 | sleep(10000); 12 | out.res1 = inp->arg1 * inp->arg1; 13 | printf("thread %ld done\n", pr_thread_id(NULL)); 14 | 15 | return(&out); 16 | } 17 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square5/square.x: -------------------------------------------------------------------------------- 1 | struct square_in { 2 | long arg1; 3 | }; 4 | 5 | struct square_out { 6 | long res1; 7 | }; 8 | 9 | program SQUARE_PROG { 10 | version SQUARE_VERS { 11 | square_out SQUAREPROC(square_in) = 1; 12 | /* procedure number = 1 */ 13 | } = 1; /* version number = 1 */ 14 | } = 0x31230000; /* program number = 0x31230000 */ 15 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square6/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = client server 4 | 5 | all: ${PROGS} 6 | 7 | square.h square_clnt.c square_svc.c square_xdr.c: square.x 8 | rpcgen -C square.x 9 | 10 | square_clnt.o: square_clnt.c square.h 11 | 12 | square_svc.o: square_svc.c square.h 13 | 14 | client: square.h client.o square_clnt.o square_xdr.o 15 | ${CC} ${CFLAGS} -o $@ client.o square_clnt.o square_xdr.o \ 16 | ${LIBS} ${LIBS_RPC} 17 | 18 | server: square.h server.o square_svc.o square_xdr.o 19 | ${CC} ${CFLAGS} -o $@ server.o square_svc.o square_xdr.o \ 20 | ${LIBS} ${LIBS_RPC} 21 | 22 | clean: 23 | rm -f ${PROGS} ${CLEANFILES} *_clnt.c *_svc.c *_xdr.c square.h 24 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square6/client.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | CLIENT *cl; 8 | square_in in; 9 | square_out *outp; 10 | 11 | if (argc != 4) 12 | err_quit("usage: client "); 13 | 14 | cl = Clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, argv[3]); 15 | 16 | in.arg1 = atol(argv[2]); 17 | if ( (outp = squareproc_1(&in, cl)) == NULL) 18 | err_quit("%s", clnt_sperror(cl, argv[1])); 19 | 20 | printf("result: %ld\n", outp->res1); 21 | exit(0); 22 | } 23 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square6/server.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | square_out * 5 | squareproc_1_svc(square_in *inp, struct svc_req *rqstp) 6 | { 7 | static square_out out; 8 | 9 | printf("server procedure started\n"); 10 | out.res1 = inp->arg1 * inp->arg1; 11 | abort(); 12 | return(&out); 13 | } 14 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square6/square.x: -------------------------------------------------------------------------------- 1 | struct square_in { 2 | long arg1; 3 | }; 4 | 5 | struct square_out { 6 | long res1; 7 | }; 8 | 9 | program SQUARE_PROG { 10 | version SQUARE_VERS { 11 | square_out SQUAREPROC(square_in) = 1; 12 | /* procedure number = 1 */ 13 | } = 1; /* version number = 1 */ 14 | } = 0x31230000; /* program number = 0x31230000 */ 15 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square7/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = client server 4 | CFLAGS += -DDEBUG 5 | 6 | all: ${PROGS} 7 | 8 | square.h square_clnt.c square_svc.c square_xdr.c: square.x 9 | rpcgen -C -M -A square.x 10 | 11 | square_clnt.o: square_clnt.c square.h 12 | 13 | square_svc.o: square_svc.c square.h 14 | 15 | client: square.h client.o square_clnt.o square_xdr.o 16 | ${CC} ${CFLAGS} -o $@ client.o square_clnt.o square_xdr.o \ 17 | ${LIBS} ${LIBS_RPC} 18 | 19 | server: square.h server.o square_svc.o square_xdr.o 20 | ${CC} ${CFLAGS} -o $@ server.o square_svc.o square_xdr.o \ 21 | ${LIBS} ${LIBS_RPC} 22 | 23 | clean: 24 | rm -f ${PROGS} ${CLEANFILES} *_clnt.c *_svc.c *_xdr.c square.h 25 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square7/client.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | CLIENT *cl; 8 | square_in in; 9 | square_out out; 10 | 11 | if (argc != 4) 12 | err_quit("usage: client "); 13 | 14 | cl = Clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, argv[3]); 15 | 16 | in.arg1 = atol(argv[2]); 17 | if (squareproc_2(&in, &out, cl) != RPC_SUCCESS) 18 | err_quit("%s", clnt_sperror(cl, argv[1])); 19 | 20 | printf("result: %ld\n", out.res1); 21 | exit(0); 22 | } 23 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square7/server.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | bool_t 5 | squareproc_2_svc(square_in *inp, square_out *outp, struct svc_req *rqstp) 6 | { 7 | printf("thread %ld started, arg = %ld\n", 8 | pr_thread_id(NULL), inp->arg1); 9 | outp->res1 = inp->arg1 * inp->arg1; 10 | pthread_exit(NULL); /* and see what happens at client */ 11 | return(TRUE); 12 | } 13 | 14 | int 15 | square_prog_2_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, 16 | caddr_t result) 17 | { 18 | xdr_free(xdr_result, result); 19 | return(1); 20 | } 21 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square7/square.x: -------------------------------------------------------------------------------- 1 | struct square_in { 2 | long arg1; 3 | }; 4 | 5 | struct square_out { 6 | long res1; 7 | }; 8 | 9 | program SQUARE_PROG { 10 | version SQUARE_VERS { 11 | square_out SQUAREPROC(square_in) = 1; 12 | /* procedure number = 1 */ 13 | } = 2; /* version number = 2 */ 14 | } = 0x31230000; /* program number = 0x31230000 */ 15 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square8/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = client server 4 | CFLAGS += -DDEBUG 5 | 6 | all: ${PROGS} 7 | 8 | square.h square_clnt.c square_svc.c square_xdr.c: square.x 9 | rpcgen -C square.x 10 | 11 | square_clnt.o: square_clnt.c square.h 12 | 13 | square_svc.o: square_svc.c square.h 14 | 15 | client: square.h client.o square_clnt.o square_xdr.o 16 | ${CC} ${CFLAGS} -o $@ client.o square_clnt.o square_xdr.o \ 17 | ${LIBS} ${LIBS_RPC} 18 | 19 | server: square.h server.o square_svc.o square_xdr.o 20 | ${CC} ${CFLAGS} -o $@ server.o square_svc.o square_xdr.o \ 21 | ${LIBS} ${LIBS_RPC} 22 | 23 | clean: 24 | rm -f ${PROGS} ${CLEANFILES} *_clnt.c *_svc.c *_xdr.c square.h 25 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square8/client.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | CLIENT *cl; 8 | square_in in; 9 | square_out *outp; 10 | 11 | if (argc != 4) 12 | err_quit("usage: client "); 13 | 14 | cl = Clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, argv[3]); 15 | 16 | alarm(3); 17 | in.arg1 = atol(argv[2]); 18 | if ( (outp = squareproc_1(&in, cl)) == NULL) 19 | err_quit("%s", clnt_sperror(cl, argv[1])); 20 | 21 | printf("result: %ld\n", outp->res1); 22 | exit(0); 23 | } 24 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square8/server.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | square_out * 5 | squareproc_1_svc(square_in *inp, struct svc_req *rqstp) 6 | { 7 | static square_out out; 8 | 9 | printf("server procedure started\n"); 10 | out.res1 = inp->arg1 * inp->arg1; 11 | sleep(6); 12 | printf("server procedure returning\n"); 13 | return(&out); 14 | } 15 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square8/square.x: -------------------------------------------------------------------------------- 1 | struct square_in { 2 | long arg1; 3 | }; 4 | 5 | struct square_out { 6 | long res1; 7 | }; 8 | 9 | program SQUARE_PROG { 10 | version SQUARE_VERS { 11 | square_out SQUAREPROC(square_in) = 1; 12 | /* procedure number = 1 */ 13 | } = 1; /* version number = 1 */ 14 | } = 0x31230000; /* program number = 0x31230000 */ 15 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square9/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = client server 4 | 5 | all: ${PROGS} 6 | 7 | square.h square_clnt.c square_svc.c square_xdr.c: square.x 8 | rpcgen -C square.x 9 | 10 | square_clnt.o: square_clnt.c square.h 11 | 12 | square_svc.o: square_svc.c square.h 13 | 14 | client: square.h client.o square_clnt.o square_xdr.o 15 | ${CC} ${CFLAGS} -o $@ client.o square_clnt.o square_xdr.o \ 16 | ${LIBS} ${LIBS_RPC} 17 | 18 | server: square.h server.o square_svc.o square_xdr.o 19 | ${CC} ${CFLAGS} -o $@ server.o square_svc.o square_xdr.o \ 20 | ${LIBS} ${LIBS_RPC} 21 | 22 | clean: 23 | rm -f ${PROGS} ${CLEANFILES} *_clnt.c *_svc.c *_xdr.c square.h 24 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square9/client.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" /* our header */ 2 | #include "square.h" /* generated by rpcgen */ 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | CLIENT *cl; 8 | square_in in; 9 | square_out *outp; 10 | 11 | if (argc != 3) 12 | err_quit("usage: client "); 13 | 14 | cl = Clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, "tcp"); 15 | 16 | in.arg1 = atol(argv[2]); 17 | if ( (outp = squareproc_1(&in, cl)) == NULL) 18 | err_quit("%s", clnt_sperror(cl, argv[1])); 19 | printf("result: %ld\n", outp->res1); 20 | 21 | in.arg1 *= 2; 22 | if ( (outp = squareproc_1(&in, cl)) == NULL) 23 | err_quit("%s", clnt_sperror(cl, argv[1])); 24 | printf("result: %ld\n", outp->res1); 25 | 26 | clnt_destroy(cl); 27 | 28 | pause(); 29 | 30 | exit(0); 31 | } 32 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square9/server.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "square.h" 3 | 4 | square_out * 5 | squareproc_1_svc(square_in *inp, struct svc_req *rqstp) 6 | { 7 | static square_out out; 8 | 9 | out.res1 = inp->arg1 * inp->arg1; 10 | return(&out); 11 | } 12 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/square9/square.x: -------------------------------------------------------------------------------- 1 | struct square_in { /* input (argument) */ 2 | long arg1; 3 | }; 4 | 5 | struct square_out { /* output (result) */ 6 | long res1; 7 | }; 8 | 9 | program SQUARE_PROG { 10 | version SQUARE_VERS { 11 | square_out SQUAREPROC(square_in) = 1; /* procedure number = 1 */ 12 | } = 1; /* version number */ 13 | } = 0x31230000; /* program number */ 14 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/test1/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = data 4 | 5 | all: ${PROGS} 6 | 7 | data.h data_xdr.c: data.x 8 | rpcgen -C data.x 9 | 10 | data: data.h main.o data_xdr.o 11 | ${CC} ${CFLAGS} -o $@ main.o data_xdr.o ${LIBS} ${LIBS_RPC} 12 | 13 | clean: 14 | rm -f ${PROGS} ${CLEANFILES} *_clnt.c *_svc.c *_xdr.c data.h 15 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/test1/main.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "data.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | XDR xhandle; 8 | char *buff; 9 | 10 | /* if (argc != 2) 11 | err_quit("usage: udpcli "); */ 12 | 13 | buff = Malloc(BUFFSIZE); /* must be aligned on 4-byte boundary */ 14 | xdrmem_create(&xhandle, buff, BUFFSIZE, XDR_ENCODE); 15 | 16 | exit(0); 17 | } 18 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/test1/nullargs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Please do not edit this file. 3 | * It was generated using rpcgen. 4 | */ 5 | 6 | #ifndef _NULLARGS_H_RPCGEN 7 | #define _NULLARGS_H_RPCGEN 8 | 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | 16 | #define SQUARE_PROG ((unsigned long)(0x31230000)) 17 | #define SQUARE_VERS ((unsigned long)(1)) 18 | 19 | #if defined(__STDC__) || defined(__cplusplus) 20 | #define SQUAREPROC ((unsigned long)(1)) 21 | extern void * squareproc_1(void *, CLIENT *); 22 | extern void * squareproc_1_svc(void *, struct svc_req *); 23 | extern int square_prog_1_freeresult(SVCXPRT *, xdrproc_t, caddr_t); 24 | 25 | #else /* K&R C */ 26 | #define SQUAREPROC ((unsigned long)(1)) 27 | extern void * squareproc_1(); 28 | extern void * squareproc_1_svc(); 29 | extern int square_prog_1_freeresult(); 30 | #endif /* K&R C */ 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | 36 | #endif /* !_NULLARGS_H_RPCGEN */ 37 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/test1/nullargs.x: -------------------------------------------------------------------------------- 1 | program SQUARE_PROG { 2 | version SQUARE_VERS { 3 | void SQUAREPROC(void) = 1; /* procedure number = 1 */ 4 | } = 1; /* version number */ 5 | } = 0x31230000; /* program number */ 6 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/alpha.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yifengyou/learn-unp2/12c1fd4e6f43524f0b173e9385321b67bcb7d653/code/unpv22e/sunrpc/xdr1/alpha.data -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/data.x: -------------------------------------------------------------------------------- 1 | enum result_t { RESULT_INT = 1, RESULT_DOUBLE = 2 }; 2 | 3 | union union_arg switch (result_t result) { 4 | case RESULT_INT: 5 | int intval; 6 | case RESULT_DOUBLE: 7 | double doubleval; 8 | default: 9 | void; 10 | }; 11 | 12 | struct data { 13 | short short_arg; 14 | long long_arg; 15 | 16 | string vstring_arg<128>; /* variable-length string */ 17 | opaque fopaque_arg[3]; /* fixed-length opaque */ 18 | opaque vopaque_arg<>; /* variable-length opaque */ 19 | short fshort_arg[4]; /* fixed-length array */ 20 | long vlong_arg<>; /* variable-length array */ 21 | union_arg uarg; 22 | }; 23 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/example.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "example.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | int size; 8 | example foo; 9 | 10 | size = RNDUP(sizeof(foo.a)) + RNDUP(sizeof(foo.b)) + 11 | RNDUP(sizeof(foo.c[0])) * MAXC; 12 | printf("size = %d\n", size); 13 | exit(0); 14 | } 15 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/example.x: -------------------------------------------------------------------------------- 1 | const MAXC = 4; 2 | 3 | struct example { 4 | short a; 5 | double b; 6 | short c[MAXC]; 7 | }; 8 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/opt1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "opt1.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | int i; 8 | XDR xhandle; 9 | char *buff; 10 | long lval2, lval3, *lptr; 11 | args out; 12 | size_t size; 13 | 14 | out.arg1.flag = TRUE; 15 | out.arg1.optlong_u.val = 5; 16 | 17 | lval2 = 9876; 18 | out.arg2.arg2_len = 1; 19 | out.arg2.arg2_val = &lval2; 20 | 21 | lval3 = 123; 22 | out.arg3 = &lval3; 23 | 24 | buff = Malloc(BUFFSIZE); /* must be aligned on 4-byte boundary */ 25 | xdrmem_create(&xhandle, buff, BUFFSIZE, XDR_ENCODE); 26 | 27 | if (xdr_args(&xhandle, &out) != TRUE) 28 | err_quit("xdr_args error"); 29 | size = xdr_getpos(&xhandle); 30 | 31 | lptr = (long *) buff; 32 | for (i = 0; i < size; i += 4) 33 | printf("%ld\n", (long) ntohl(*lptr++)); 34 | 35 | exit(0); 36 | } 37 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/opt1.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Please do not edit this file. 3 | * It was generated using rpcgen. 4 | */ 5 | 6 | #ifndef _OPT1_H_RPCGEN 7 | #define _OPT1_H_RPCGEN 8 | 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | 16 | struct optlong { 17 | bool_t flag; 18 | union { 19 | long val; 20 | } optlong_u; 21 | }; 22 | typedef struct optlong optlong; 23 | 24 | struct args { 25 | optlong arg1; 26 | struct { 27 | u_int arg2_len; 28 | long *arg2_val; 29 | } arg2; 30 | long *arg3; 31 | }; 32 | typedef struct args args; 33 | 34 | /* the xdr functions */ 35 | 36 | #if defined(__STDC__) || defined(__cplusplus) 37 | extern bool_t xdr_optlong(XDR *, optlong*); 38 | extern bool_t xdr_args(XDR *, args*); 39 | 40 | #else /* K&R C */ 41 | extern bool_t xdr_optlong(); 42 | extern bool_t xdr_args(); 43 | 44 | #endif /* K&R C */ 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif /* !_OPT1_H_RPCGEN */ 51 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/opt1.save.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Please do not edit this file. 3 | * It was generated using rpcgen. 4 | */ 5 | 6 | #ifndef _OPT1_H_RPCGEN 7 | #define _OPT1_H_RPCGEN 8 | 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | 16 | /* include opt1h */ 17 | struct optlong { 18 | int flag; 19 | union { 20 | long val; 21 | } optlong_u; 22 | }; 23 | typedef struct optlong optlong; 24 | 25 | struct args { 26 | optlong arg1; 27 | struct { 28 | u_int arg2_len; 29 | long *arg2_val; 30 | } arg2; 31 | long *arg3; 32 | }; 33 | typedef struct args args; 34 | /* end opt1h */ 35 | 36 | /* the xdr functions */ 37 | 38 | #if defined(__STDC__) || defined(__cplusplus) 39 | extern bool_t xdr_optlong(XDR *, optlong*); 40 | extern bool_t xdr_args(XDR *, args*); 41 | 42 | #else /* K&R C */ 43 | extern bool_t xdr_optlong(); 44 | extern bool_t xdr_args(); 45 | 46 | #endif /* K&R C */ 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif /* !_OPT1_H_RPCGEN */ 53 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/opt1.x: -------------------------------------------------------------------------------- 1 | union optlong switch (bool flag) { 2 | case TRUE: 3 | long val; 4 | case FALSE: 5 | void; 6 | }; 7 | 8 | struct args { 9 | optlong arg1; /* union with boolean discriminant */ 10 | long arg2<1>; /* variable-length array with one element */ 11 | long *arg3; /* pointer */ 12 | }; 13 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/opt1z.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "opt1.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | int i; 8 | XDR xhandle; 9 | char *buff; 10 | long *lptr; 11 | args out; 12 | size_t size; 13 | 14 | out.arg1.flag = FALSE; 15 | out.arg2.arg2_len = 0; 16 | out.arg3 = NULL; 17 | 18 | buff = Malloc(BUFFSIZE); /* must be aligned on 4-byte boundary */ 19 | xdrmem_create(&xhandle, buff, BUFFSIZE, XDR_ENCODE); 20 | 21 | if (xdr_args(&xhandle, &out) != TRUE) 22 | err_quit("xdr_args error"); 23 | size = xdr_getpos(&xhandle); 24 | 25 | lptr = (long *) buff; 26 | for (i = 0; i < size; i += 4) 27 | printf("%ld\n", (long) ntohl(*lptr++)); 28 | 29 | exit(0); 30 | } 31 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/opt2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Please do not edit this file. 3 | * It was generated using rpcgen. 4 | */ 5 | 6 | #ifndef _OPT2_H_RPCGEN 7 | #define _OPT2_H_RPCGEN 8 | 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | 16 | struct mylist { 17 | char *name; 18 | long value; 19 | struct mylist *next; 20 | }; 21 | typedef struct mylist mylist; 22 | 23 | struct args { 24 | mylist *list; 25 | }; 26 | typedef struct args args; 27 | 28 | /* the xdr functions */ 29 | 30 | #if defined(__STDC__) || defined(__cplusplus) 31 | extern bool_t xdr_mylist(XDR *, mylist*); 32 | extern bool_t xdr_args(XDR *, args*); 33 | 34 | #else /* K&R C */ 35 | extern bool_t xdr_mylist(); 36 | extern bool_t xdr_args(); 37 | 38 | #endif /* K&R C */ 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | #endif /* !_OPT2_H_RPCGEN */ 45 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/opt2.save.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Please do not edit this file. 3 | * It was generated using rpcgen. 4 | */ 5 | 6 | #ifndef _OPT2_H_RPCGEN 7 | #define _OPT2_H_RPCGEN 8 | 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | 16 | /* include opt2h */ 17 | struct mylist { 18 | char *name; 19 | long value; 20 | struct mylist *next; 21 | }; 22 | typedef struct mylist mylist; 23 | 24 | struct args { 25 | mylist *list; 26 | }; 27 | typedef struct args args; 28 | /* end opt2h */ 29 | 30 | /* the xdr functions */ 31 | 32 | #if defined(__STDC__) || defined(__cplusplus) 33 | extern bool_t xdr_mylist(XDR *, mylist*); 34 | extern bool_t xdr_args(XDR *, args*); 35 | 36 | #else /* K&R C */ 37 | extern bool_t xdr_mylist(); 38 | extern bool_t xdr_args(); 39 | 40 | #endif /* K&R C */ 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #endif /* !_OPT2_H_RPCGEN */ 47 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/opt2.x: -------------------------------------------------------------------------------- 1 | struct mylist { 2 | string name<>; 3 | long value; 4 | mylist *next; 5 | }; 6 | 7 | struct args { 8 | mylist *list; 9 | }; 10 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/opt2z.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | #include "opt2.h" 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | int i; 8 | XDR xhandle; 9 | char *buff; 10 | long *lptr; 11 | args out; 12 | size_t size; 13 | 14 | out.list = NULL; 15 | 16 | buff = Malloc(BUFFSIZE); /* must be aligned on 4-byte boundary */ 17 | xdrmem_create(&xhandle, buff, BUFFSIZE, XDR_ENCODE); 18 | 19 | if (xdr_args(&xhandle, &out) != TRUE) 20 | err_quit("xdr_args error"); 21 | size = xdr_getpos(&xhandle); 22 | 23 | lptr = (long *) buff; 24 | for (i = 0; i < size; i += 4) 25 | printf("%8lx\n", (long) ntohl(*lptr++)); 26 | 27 | exit(0); 28 | } 29 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/sparc.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yifengyou/learn-unp2/12c1fd4e6f43524f0b173e9385321b67bcb7d653/code/unpv22e/sunrpc/xdr1/sparc.data -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/test1.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Please do not edit this file. 3 | * It was generated using rpcgen. 4 | */ 5 | 6 | #ifndef _TEST1_H_RPCGEN 7 | #define _TEST1_H_RPCGEN 8 | 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | 16 | struct optlong { 17 | int discr; 18 | union { 19 | long val; 20 | } optlong_u; 21 | }; 22 | typedef struct optlong optlong; 23 | 24 | struct args { 25 | optlong arg0; 26 | struct { 27 | u_int arg1_len; 28 | long *arg1_val; 29 | } arg1; 30 | short *arg2; 31 | }; 32 | typedef struct args args; 33 | 34 | /* the xdr functions */ 35 | 36 | #if defined(__STDC__) || defined(__cplusplus) 37 | extern bool_t xdr_optlong(XDR *, optlong*); 38 | extern bool_t xdr_args(XDR *, args*); 39 | 40 | #else /* K&R C */ 41 | extern bool_t xdr_optlong(); 42 | extern bool_t xdr_args(); 43 | 44 | #endif /* K&R C */ 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif /* !_TEST1_H_RPCGEN */ 51 | -------------------------------------------------------------------------------- /code/unpv22e/sunrpc/xdr1/test1.x: -------------------------------------------------------------------------------- 1 | union optlong switch (int discr) { 2 | case TRUE: 3 | long val; 4 | case FALSE: 5 | void; 6 | }; 7 | 8 | struct args { 9 | optlong arg0; 10 | long arg1<1>; 11 | short *arg2; 12 | }; 13 | -------------------------------------------------------------------------------- /code/unpv22e/svipc/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = ftok ftok1 ftok2 4 | 5 | all: ${PROGS} 6 | 7 | ftok: ftok.o 8 | ${CC} ${CFLAGS} -o $@ ftok.o ${LIBS} 9 | 10 | ftok1: ftok1.o 11 | ${CC} ${CFLAGS} -o $@ ftok1.o ${LIBS} 12 | 13 | ftok2: ftok2.o 14 | ${CC} ${CFLAGS} -o $@ ftok2.o ${LIBS} 15 | 16 | clean: 17 | rm -f ${PROGS} ${CLEANFILES} 18 | -------------------------------------------------------------------------------- /code/unpv22e/svipc/ftok.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | struct stat stat; 7 | 8 | if (argc != 2) 9 | err_quit("usage: ftok "); 10 | 11 | Stat(argv[1], &stat); 12 | printf("st_dev: %lx, st_ino: %lx, key: %x\n", 13 | (u_long) stat.st_dev, (u_long) stat.st_ino, 14 | Ftok(argv[1], 0x57)); 15 | 16 | exit(0); 17 | } 18 | -------------------------------------------------------------------------------- /code/unpv22e/svipc/ftok1.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | struct stat stat; 7 | 8 | if (argc != 2) 9 | err_quit("usage: ftok1 "); 10 | 11 | Stat(argv[1], &stat); 12 | printf("%x %s\n", Ftok(argv[1], 0x57), argv[1]); 13 | 14 | exit(0); 15 | } 16 | -------------------------------------------------------------------------------- /code/unpv22e/svmsg/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = ctl limits slot slotseq twoqueues testumask \ 4 | msgcreate msgsnd msgrcv msgrcvid msgrmid 5 | 6 | all: ${PROGS} 7 | 8 | msgcreate: msgcreate.o 9 | ${CC} ${CFLAGS} -o $@ msgcreate.o ${LIBS} 10 | 11 | msgsnd: msgsnd.o 12 | ${CC} ${CFLAGS} -o $@ msgsnd.o ${LIBS} 13 | 14 | msgrcv: msgrcv.o 15 | ${CC} ${CFLAGS} -o $@ msgrcv.o ${LIBS} 16 | 17 | msgrcvid: msgrcvid.o 18 | ${CC} ${CFLAGS} -o $@ msgrcvid.o ${LIBS} 19 | 20 | msgrmid: msgrmid.o 21 | ${CC} ${CFLAGS} -o $@ msgrmid.o ${LIBS} 22 | 23 | ctl: ctl.o 24 | ${CC} ${CFLAGS} -o $@ ctl.o ${LIBS} 25 | 26 | limits: limits.o 27 | ${CC} ${CFLAGS} -o $@ limits.o ${LIBS} 28 | 29 | slot: slot.o 30 | ${CC} ${CFLAGS} -o $@ slot.o ${LIBS} 31 | 32 | slotseq: slotseq.o 33 | ${CC} ${CFLAGS} -o $@ slotseq.o ${LIBS} 34 | 35 | twoqueues: twoqueues.o 36 | ${CC} ${CFLAGS} -o $@ twoqueues.o ${LIBS} 37 | 38 | testumask: testumask.o 39 | ${CC} ${CFLAGS} -o $@ testumask.o ${LIBS} 40 | 41 | clean: 42 | rm -f ${PROGS} ${CLEANFILES} 43 | -------------------------------------------------------------------------------- /code/unpv22e/svmsg/ctl.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int msqid; 7 | struct msqid_ds info; 8 | struct msgbuf buf; 9 | 10 | msqid = Msgget(IPC_PRIVATE, SVMSG_MODE | IPC_CREAT); 11 | 12 | buf.mtype = 1; 13 | buf.mtext[0] = 1; 14 | Msgsnd(msqid, &buf, 1, 0); 15 | 16 | Msgctl(msqid, IPC_STAT, &info); 17 | printf("read-write: %03o, cbytes = %lu, qnum = %lu, qbytes = %lu\n", 18 | info.msg_perm.mode & 0777, (ulong_t) info.msg_cbytes, 19 | (ulong_t) info.msg_qnum, (ulong_t) info.msg_qbytes); 20 | 21 | system("ipcs -q"); 22 | 23 | Msgctl(msqid, IPC_RMID, NULL); 24 | exit(0); 25 | } 26 | -------------------------------------------------------------------------------- /code/unpv22e/svmsg/msgcreate.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int c, oflag, mqid; 7 | 8 | oflag = SVMSG_MODE | IPC_CREAT; 9 | while ( (c = Getopt(argc, argv, "e")) != -1) { 10 | switch (c) { 11 | case 'e': 12 | oflag |= IPC_EXCL; 13 | break; 14 | } 15 | } 16 | if (optind != argc - 1) 17 | err_quit("usage: msgcreate [ -e ] "); 18 | 19 | mqid = Msgget(Ftok(argv[optind], 0), oflag); 20 | exit(0); 21 | } 22 | -------------------------------------------------------------------------------- /code/unpv22e/svmsg/msgrcv.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define MAXMSG (8192 + sizeof(long)) 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int c, flag, mqid; 9 | long type; 10 | ssize_t n; 11 | struct msgbuf *buff; 12 | 13 | type = flag = 0; 14 | while ( (c = Getopt(argc, argv, "nt:")) != -1) { 15 | switch (c) { 16 | case 'n': 17 | flag |= IPC_NOWAIT; 18 | break; 19 | 20 | case 't': 21 | type = atol(optarg); 22 | break; 23 | } 24 | } 25 | if (optind != argc - 1) 26 | err_quit("usage: msgrcv [ -n ] [ -t type ] "); 27 | 28 | mqid = Msgget(Ftok(argv[optind], 0), MSG_R); 29 | 30 | buff = Malloc(MAXMSG); 31 | 32 | n = Msgrcv(mqid, buff, MAXMSG, type, flag); 33 | printf("read %d bytes, type = %ld\n", n, buff->mtype); 34 | 35 | exit(0); 36 | } 37 | -------------------------------------------------------------------------------- /code/unpv22e/svmsg/msgrcvid.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define MAXMSG (8192 + sizeof(long)) 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int mqid; 9 | ssize_t n; 10 | struct msgbuf *buff; 11 | 12 | if (argc != 2) 13 | err_quit("usage: msgrcvid "); 14 | mqid = atoi(argv[1]); 15 | 16 | buff = Malloc(MAXMSG); 17 | 18 | n = Msgrcv(mqid, buff, MAXMSG, 0, 0); 19 | printf("read %d bytes, type = %ld\n", n, buff->mtype); 20 | 21 | exit(0); 22 | } 23 | -------------------------------------------------------------------------------- /code/unpv22e/svmsg/msgrmid.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int mqid; 7 | 8 | if (argc != 2) 9 | err_quit("usage: msgrmid "); 10 | 11 | mqid = Msgget(Ftok(argv[1], 0), 0); 12 | Msgctl(mqid, IPC_RMID, NULL); 13 | 14 | exit(0); 15 | } 16 | -------------------------------------------------------------------------------- /code/unpv22e/svmsg/msgsnd.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int mqid; 7 | size_t len; 8 | long type; 9 | struct msgbuf *ptr; 10 | 11 | if (argc != 4) 12 | err_quit("usage: msgsnd <#bytes> "); 13 | len = atoi(argv[2]); 14 | type = atoi(argv[3]); 15 | 16 | mqid = Msgget(Ftok(argv[1], 0), MSG_W); 17 | 18 | ptr = Calloc(sizeof(long) + len, sizeof(char)); 19 | ptr->mtype = type; 20 | 21 | Msgsnd(mqid, ptr, len, 0); 22 | 23 | exit(0); 24 | } 25 | -------------------------------------------------------------------------------- /code/unpv22e/svmsg/slot.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i, msqid; 7 | 8 | for (i = 0; i < 10; i++) { 9 | msqid = Msgget(IPC_PRIVATE, SVMSG_MODE | IPC_CREAT); 10 | printf("msqid = %d\n", msqid); 11 | 12 | Msgctl(msqid, IPC_RMID, NULL); 13 | } 14 | exit(0); 15 | } 16 | -------------------------------------------------------------------------------- /code/unpv22e/svmsg/slotseq.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i, msqid; 7 | struct msqid_ds info; 8 | 9 | for (i = 0; i < 10; i++) { 10 | msqid = Msgget(IPC_PRIVATE, SVMSG_MODE | IPC_CREAT); 11 | Msgctl(msqid, IPC_STAT, &info); 12 | printf("msqid = %d, seq = %lu\n", msqid, info.msg_perm.seq); 13 | 14 | Msgctl(msqid, IPC_RMID, NULL); 15 | } 16 | exit(0); 17 | } 18 | -------------------------------------------------------------------------------- /code/unpv22e/svmsg/testumask.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | Msgget(IPC_PRIVATE, 0666 | IPC_CREAT | IPC_EXCL); 7 | unlink("/tmp/fifo.1"); 8 | Mkfifo("/tmp/fifo.1", 0666); 9 | 10 | exit(0); 11 | } 12 | -------------------------------------------------------------------------------- /code/unpv22e/svmsg/twoqueues.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int msqid1, msqid2; 7 | 8 | msqid1 = Msgget(IPC_PRIVATE, SVMSG_MODE | IPC_CREAT); 9 | msqid2 = Msgget(IPC_PRIVATE, SVMSG_MODE | IPC_CREAT); 10 | printf("msqid1 = %d, msgqid2 = %d\n", msqid1, msqid2); 11 | 12 | exit(0); 13 | } 14 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgcliserv/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = client_main server_main 4 | 5 | all: ${PROGS} 6 | 7 | client_main: client_main.o client.o mesg_recv.o mesg_send.o 8 | ${CC} ${CFLAGS} -o $@ client_main.o client.o \ 9 | mesg_recv.o mesg_send.o ${LIBS} 10 | 11 | server_main: server_main.o server.o mesg_recv.o mesg_send.o 12 | ${CC} ${CFLAGS} -o $@ server_main.o server.o \ 13 | mesg_recv.o mesg_send.o ${LIBS} 14 | 15 | clean: 16 | rm -f ${PROGS} ${CLEANFILES} 17 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgcliserv/client.c: -------------------------------------------------------------------------------- 1 | #include "mesg.h" 2 | 3 | void 4 | client(int readfd, int writefd) 5 | { 6 | size_t len; 7 | ssize_t n; 8 | struct mymesg mesg; 9 | 10 | /* 4read pathname */ 11 | Fgets(mesg.mesg_data, MAXMESGDATA, stdin); 12 | len = strlen(mesg.mesg_data); 13 | if (mesg.mesg_data[len-1] == '\n') 14 | len--; /* delete newline from fgets() */ 15 | mesg.mesg_len = len; 16 | mesg.mesg_type = 1; 17 | 18 | /* 4write pathname to IPC channel */ 19 | Mesg_send(writefd, &mesg); 20 | 21 | /* 4read from IPC, write to standard output */ 22 | while ( (n = Mesg_recv(readfd, &mesg)) > 0) 23 | Write(STDOUT_FILENO, mesg.mesg_data, n); 24 | } 25 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgcliserv/client_main.c: -------------------------------------------------------------------------------- 1 | #include "svmsg.h" 2 | 3 | void client(int, int); 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int readid, writeid; 9 | 10 | /* 4assumes server has created the queues */ 11 | writeid = Msgget(MQ_KEY1, 0); 12 | readid = Msgget(MQ_KEY2, 0); 13 | 14 | client(readid, writeid); 15 | 16 | /* 4now we can delete the queues */ 17 | Msgctl(readid, IPC_RMID, NULL); 18 | Msgctl(writeid, IPC_RMID, NULL); 19 | 20 | exit(0); 21 | } 22 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgcliserv/mesg.h: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | /* Our own "messages" to use with pipes, FIFOs, and message queues. */ 4 | 5 | /* 4want sizeof(struct mymesg) <= PIPE_BUF */ 6 | #define MAXMESGDATA (PIPE_BUF - 2*sizeof(long)) 7 | 8 | /* 4length of mesg_len and mesg_type */ 9 | #define MESGHDRSIZE (sizeof(struct mymesg) - MAXMESGDATA) 10 | 11 | struct mymesg { 12 | long mesg_len; /* #bytes in mesg_data, can be 0 */ 13 | long mesg_type; /* message type, must be > 0 */ 14 | char mesg_data[MAXMESGDATA]; 15 | }; 16 | 17 | ssize_t mesg_send(int, struct mymesg *); 18 | void Mesg_send(int, struct mymesg *); 19 | ssize_t mesg_recv(int, struct mymesg *); 20 | ssize_t Mesg_recv(int, struct mymesg *); 21 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgcliserv/mesg_recv.c: -------------------------------------------------------------------------------- 1 | /* include mesg_recv */ 2 | #include "mesg.h" 3 | 4 | ssize_t 5 | mesg_recv(int id, struct mymesg *mptr) 6 | { 7 | ssize_t n; 8 | 9 | n = msgrcv(id, &(mptr->mesg_type), MAXMESGDATA, mptr->mesg_type, 0); 10 | mptr->mesg_len = n; /* return #bytes of data */ 11 | 12 | return(n); /* -1 on error, 0 at EOF, else >0 */ 13 | } 14 | /* end mesg_recv */ 15 | 16 | ssize_t 17 | Mesg_recv(int id, struct mymesg *mptr) 18 | { 19 | ssize_t n; 20 | 21 | if ( (n = mesg_recv(id, mptr)) == -1) 22 | err_sys("mesg_recv error"); 23 | return(n); 24 | } 25 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgcliserv/mesg_send.c: -------------------------------------------------------------------------------- 1 | /* include mesg_send */ 2 | #include "mesg.h" 3 | 4 | ssize_t 5 | mesg_send(int id, struct mymesg *mptr) 6 | { 7 | return(msgsnd(id, &(mptr->mesg_type), mptr->mesg_len, 0)); 8 | } 9 | /* end mesg_send */ 10 | 11 | void 12 | Mesg_send(int id, struct mymesg *mptr) 13 | { 14 | ssize_t n; 15 | 16 | if ( (n = msgsnd(id, &(mptr->mesg_type), mptr->mesg_len, 0)) == -1) 17 | err_sys("mesg_send error"); 18 | } 19 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgcliserv/server.c: -------------------------------------------------------------------------------- 1 | #include "mesg.h" 2 | 3 | void 4 | server(int readfd, int writefd) 5 | { 6 | FILE *fp; 7 | ssize_t n; 8 | struct mymesg mesg; 9 | 10 | /* 4read pathname from IPC channel */ 11 | mesg.mesg_type = 1; 12 | if ( (n = Mesg_recv(readfd, &mesg)) == 0) 13 | err_quit("pathname missing"); 14 | mesg.mesg_data[n] = '\0'; /* null terminate pathname */ 15 | 16 | if ( (fp = fopen(mesg.mesg_data, "r")) == NULL) { 17 | /* 4error: must tell client */ 18 | snprintf(mesg.mesg_data + n, sizeof(mesg.mesg_data) - n, 19 | ": can't open, %s\n", strerror(errno)); 20 | mesg.mesg_len = strlen(mesg.mesg_data); 21 | Mesg_send(writefd, &mesg); 22 | 23 | } else { 24 | /* 4fopen succeeded: copy file to IPC channel */ 25 | while (Fgets(mesg.mesg_data, MAXMESGDATA, fp) != NULL) { 26 | mesg.mesg_len = strlen(mesg.mesg_data); 27 | Mesg_send(writefd, &mesg); 28 | } 29 | Fclose(fp); 30 | } 31 | 32 | /* 4send a 0-length message to signify the end */ 33 | mesg.mesg_len = 0; 34 | Mesg_send(writefd, &mesg); 35 | } 36 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgcliserv/server_main.c: -------------------------------------------------------------------------------- 1 | #include "svmsg.h" 2 | 3 | void server(int, int); 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int readid, writeid; 9 | 10 | readid = Msgget(MQ_KEY1, SVMSG_MODE | IPC_CREAT); 11 | writeid = Msgget(MQ_KEY2, SVMSG_MODE | IPC_CREAT); 12 | 13 | server(readid, writeid); 14 | 15 | exit(0); 16 | } 17 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgcliserv/svmsg.h: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define MQ_KEY1 1234L 4 | #define MQ_KEY2 2345L 5 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpx1q/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = client_main server_main 4 | 5 | all: ${PROGS} 6 | 7 | client_main: client_main.o client.o mesg_recv.o mesg_send.o 8 | ${CC} ${CFLAGS} -o $@ client_main.o client.o \ 9 | mesg_recv.o mesg_send.o ${LIBS} 10 | 11 | server_main: server_main.o server.o mesg_recv.o mesg_send.o 12 | ${CC} ${CFLAGS} -o $@ server_main.o server.o \ 13 | mesg_recv.o mesg_send.o ${LIBS} 14 | 15 | clean: 16 | rm -f ${PROGS} ${CLEANFILES} 17 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpx1q/client.c: -------------------------------------------------------------------------------- 1 | #include "mesg.h" 2 | 3 | void 4 | client(int readfd, int writefd) 5 | { 6 | size_t len; 7 | ssize_t n; 8 | char *ptr; 9 | struct mymesg mesg; 10 | 11 | /* 4start buffer with pid and a blank */ 12 | snprintf(mesg.mesg_data, MAXMESGDATA, "%ld ", (long) getpid()); 13 | len = strlen(mesg.mesg_data); 14 | ptr = mesg.mesg_data + len; 15 | 16 | /* 4read pathname */ 17 | Fgets(ptr, MAXMESGDATA - len, stdin); 18 | len = strlen(mesg.mesg_data); 19 | if (mesg.mesg_data[len-1] == '\n') 20 | len--; /* delete newline from fgets() */ 21 | mesg.mesg_len = len; 22 | mesg.mesg_type = 1; 23 | 24 | /* 4write PID and pathname to IPC channel */ 25 | Mesg_send(writefd, &mesg); 26 | 27 | /* 4read from IPC, write to standard output */ 28 | mesg.mesg_type = getpid(); 29 | while ( (n = Mesg_recv(readfd, &mesg)) > 0) 30 | Write(STDOUT_FILENO, mesg.mesg_data, n); 31 | } 32 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpx1q/client_main.c: -------------------------------------------------------------------------------- 1 | #include "svmsg.h" 2 | 3 | void client(int, int); 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int msqid; 9 | 10 | /* 4server must create the queue */ 11 | msqid = Msgget(MQ_KEY1, 0); 12 | 13 | client(msqid, msqid); /* same queue for both directions */ 14 | 15 | exit(0); 16 | } 17 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpx1q/mesg.h: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | /* Our own "messages" to use with pipes, FIFOs, and message queues. */ 4 | 5 | /* 4want sizeof(struct mymesg) <= PIPE_BUF */ 6 | #define MAXMESGDATA (PIPE_BUF - 2*sizeof(long)) 7 | 8 | /* 4length of mesg_len and mesg_type */ 9 | #define MESGHDRSIZE (sizeof(struct mymesg) - MAXMESGDATA) 10 | 11 | struct mymesg { 12 | long mesg_len; /* #bytes in mesg_data, can be 0 */ 13 | long mesg_type; /* message type, must be > 0 */ 14 | char mesg_data[MAXMESGDATA]; 15 | }; 16 | 17 | ssize_t mesg_send(int, struct mymesg *); 18 | void Mesg_send(int, struct mymesg *); 19 | ssize_t mesg_recv(int, struct mymesg *); 20 | ssize_t Mesg_recv(int, struct mymesg *); 21 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpx1q/mesg_recv.c: -------------------------------------------------------------------------------- 1 | /* include mesg_recv */ 2 | #include "mesg.h" 3 | 4 | ssize_t 5 | mesg_recv(int id, struct mymesg *mptr) 6 | { 7 | ssize_t n; 8 | 9 | n = msgrcv(id, &(mptr->mesg_type), MAXMESGDATA, mptr->mesg_type, 0); 10 | mptr->mesg_len = n; /* return #bytes of data */ 11 | 12 | return(n); /* -1 on error, 0 at EOF, else >0 */ 13 | } 14 | /* end mesg_recv */ 15 | 16 | ssize_t 17 | Mesg_recv(int id, struct mymesg *mptr) 18 | { 19 | ssize_t n; 20 | 21 | if ( (n = mesg_recv(id, mptr)) == -1) 22 | err_sys("mesg_recv error"); 23 | return(n); 24 | } 25 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpx1q/mesg_send.c: -------------------------------------------------------------------------------- 1 | /* include mesg_send */ 2 | #include "mesg.h" 3 | 4 | ssize_t 5 | mesg_send(int id, struct mymesg *mptr) 6 | { 7 | return(msgsnd(id, &(mptr->mesg_type), mptr->mesg_len, 0)); 8 | } 9 | /* end mesg_send */ 10 | 11 | void 12 | Mesg_send(int id, struct mymesg *mptr) 13 | { 14 | ssize_t n; 15 | 16 | if ( (n = msgsnd(id, &(mptr->mesg_type), mptr->mesg_len, 0)) == -1) 17 | err_sys("mesg_send error"); 18 | } 19 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpx1q/server_main.c: -------------------------------------------------------------------------------- 1 | #include "svmsg.h" 2 | 3 | void server(int, int); 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int msqid; 9 | 10 | msqid = Msgget(MQ_KEY1, SVMSG_MODE | IPC_CREAT); 11 | 12 | server(msqid, msqid); /* same queue for both directions */ 13 | 14 | exit(0); 15 | } 16 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpx1q/svmsg.h: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define MQ_KEY1 1234L 4 | #define MQ_KEY2 2345L 5 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpxnq/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = client_main server_main 4 | 5 | all: ${PROGS} 6 | 7 | client_main: client_main.o client.o mesg_recv.o mesg_send.o 8 | ${CC} ${CFLAGS} -o $@ client_main.o client.o \ 9 | mesg_recv.o mesg_send.o ${LIBS} 10 | 11 | server_main: server_main.o server.o mesg_recv.o mesg_send.o sigchldwaitpid.o 12 | ${CC} ${CFLAGS} -o $@ server_main.o server.o \ 13 | mesg_recv.o mesg_send.o sigchldwaitpid.o ${LIBS} 14 | 15 | clean: 16 | rm -f ${PROGS} ${CLEANFILES} 17 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpxnq/client.c: -------------------------------------------------------------------------------- 1 | #include "mesg.h" 2 | 3 | void 4 | client(int readid, int writeid) 5 | { 6 | size_t len; 7 | ssize_t n; 8 | char *ptr; 9 | struct mymesg mesg; 10 | 11 | /* 4start buffer with msqid and a blank */ 12 | snprintf(mesg.mesg_data, MAXMESGDATA, "%d ", readid); 13 | len = strlen(mesg.mesg_data); 14 | ptr = mesg.mesg_data + len; 15 | 16 | /* 4read pathname */ 17 | Fgets(ptr, MAXMESGDATA - len, stdin); 18 | len = strlen(mesg.mesg_data); 19 | if (mesg.mesg_data[len-1] == '\n') 20 | len--; /* delete newline from fgets() */ 21 | mesg.mesg_len = len; 22 | mesg.mesg_type = 1; 23 | 24 | /* 4write msqid and pathname to server's well-known queue */ 25 | Mesg_send(writeid, &mesg); 26 | 27 | /* 4read from our queue, write to standard output */ 28 | while ( (n = Mesg_recv(readid, &mesg)) > 0) 29 | Write(STDOUT_FILENO, mesg.mesg_data, n); 30 | } 31 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpxnq/client_main.c: -------------------------------------------------------------------------------- 1 | #include "svmsg.h" 2 | 3 | void client(int, int); 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int readid, writeid; 9 | 10 | /* 4server must create its well-known queue */ 11 | writeid = Msgget(MQ_KEY1, 0); 12 | /* 4we create our own private queue */ 13 | readid = Msgget(IPC_PRIVATE, SVMSG_MODE | IPC_CREAT); 14 | 15 | client(readid, writeid); 16 | 17 | /* 4and delete our private queue */ 18 | Msgctl(readid, IPC_RMID, NULL); 19 | 20 | exit(0); 21 | } 22 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpxnq/mesg.h: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | /* Our own "messages" to use with pipes, FIFOs, and message queues. */ 4 | 5 | /* 4want sizeof(struct mymesg) <= PIPE_BUF */ 6 | #define MAXMESGDATA (PIPE_BUF - 2*sizeof(long)) 7 | 8 | /* 4length of mesg_len and mesg_type */ 9 | #define MESGHDRSIZE (sizeof(struct mymesg) - MAXMESGDATA) 10 | 11 | struct mymesg { 12 | long mesg_len; /* #bytes in mesg_data, can be 0 */ 13 | long mesg_type; /* message type, must be > 0 */ 14 | char mesg_data[MAXMESGDATA]; 15 | }; 16 | 17 | ssize_t mesg_send(int, struct mymesg *); 18 | void Mesg_send(int, struct mymesg *); 19 | ssize_t mesg_recv(int, struct mymesg *); 20 | ssize_t Mesg_recv(int, struct mymesg *); 21 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpxnq/mesg_recv.c: -------------------------------------------------------------------------------- 1 | /* include mesg_recv */ 2 | #include "mesg.h" 3 | 4 | ssize_t 5 | mesg_recv(int id, struct mymesg *mptr) 6 | { 7 | ssize_t n; 8 | 9 | n = msgrcv(id, &(mptr->mesg_type), MAXMESGDATA, mptr->mesg_type, 0); 10 | mptr->mesg_len = n; /* return #bytes of data */ 11 | 12 | return(n); /* -1 on error, 0 at EOF, else >0 */ 13 | } 14 | /* end mesg_recv */ 15 | 16 | /* include Mesg_recv */ 17 | ssize_t 18 | Mesg_recv(int id, struct mymesg *mptr) 19 | { 20 | ssize_t n; 21 | 22 | do { 23 | n = mesg_recv(id, mptr); 24 | } while (n == -1 && errno == EINTR); 25 | 26 | if (n == -1) 27 | err_sys("mesg_recv error"); 28 | 29 | return(n); 30 | } 31 | /* end Mesg_recv */ 32 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpxnq/mesg_send.c: -------------------------------------------------------------------------------- 1 | /* include mesg_send */ 2 | #include "mesg.h" 3 | 4 | ssize_t 5 | mesg_send(int id, struct mymesg *mptr) 6 | { 7 | return(msgsnd(id, &(mptr->mesg_type), mptr->mesg_len, 0)); 8 | } 9 | /* end mesg_send */ 10 | 11 | void 12 | Mesg_send(int id, struct mymesg *mptr) 13 | { 14 | ssize_t n; 15 | 16 | if ( (n = msgsnd(id, &(mptr->mesg_type), mptr->mesg_len, 0)) == -1) 17 | err_sys("mesg_send error"); 18 | } 19 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpxnq/server_main.c: -------------------------------------------------------------------------------- 1 | #include "svmsg.h" 2 | 3 | void server(int, int); 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int msqid; 9 | 10 | msqid = Msgget(MQ_KEY1, SVMSG_MODE | IPC_CREAT); 11 | 12 | server(msqid, msqid); /* same queue for both directions */ 13 | 14 | exit(0); 15 | } 16 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpxnq/sigchldwaitpid.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | void 4 | sig_chld(int signo) 5 | { 6 | pid_t pid; 7 | int stat; 8 | 9 | while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) 10 | ; 11 | return; 12 | } 13 | -------------------------------------------------------------------------------- /code/unpv22e/svmsgmpxnq/svmsg.h: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define MQ_KEY1 1234L 4 | #define MQ_KEY2 2345L 5 | -------------------------------------------------------------------------------- /code/unpv22e/svsem/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = semcreate semrmid semgetvalues semsetvalues semops semopsid \ 4 | initval limits 5 | 6 | all: ${PROGS} 7 | 8 | semcreate: semcreate.o 9 | ${CC} ${CFLAGS} -o $@ semcreate.o ${LIBS} 10 | 11 | semrmid: semrmid.o 12 | ${CC} ${CFLAGS} -o $@ semrmid.o ${LIBS} 13 | 14 | semgetvalues: semgetvalues.o 15 | ${CC} ${CFLAGS} -o $@ semgetvalues.o ${LIBS} 16 | 17 | semsetvalues: semsetvalues.o 18 | ${CC} ${CFLAGS} -o $@ semsetvalues.o ${LIBS} 19 | 20 | semops: semops.o 21 | ${CC} ${CFLAGS} -o $@ semops.o ${LIBS} 22 | 23 | semopsid: semopsid.o 24 | ${CC} ${CFLAGS} -o $@ semopsid.o ${LIBS} 25 | 26 | initval: initval.o 27 | ${CC} ${CFLAGS} -o $@ initval.o ${LIBS} 28 | 29 | limits: limits.o 30 | ${CC} ${CFLAGS} -o $@ limits.o ${LIBS} 31 | 32 | clean: 33 | rm -f ${PROGS} ${CLEANFILES} 34 | -------------------------------------------------------------------------------- /code/unpv22e/svsem/initval.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | #define NSEMS 10 /* #semaphores in set */ 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int semid, i, j; 9 | unsigned short *ptr; 10 | union semun arg; 11 | 12 | /* 4allocate memory to hold all the values in the set */ 13 | ptr = Calloc(NSEMS, sizeof(unsigned short)); 14 | arg.array = ptr; 15 | 16 | for (j = 0; j < 1000; j++) { 17 | /* 4create a semaphore set */ 18 | semid = Semget(100, NSEMS, IPC_CREAT | IPC_EXCL | SVSEM_MODE); 19 | 20 | /* 4fetch the "initial" values and print */ 21 | Semctl(semid, 0, GETALL, arg); 22 | for (i = 0; i < NSEMS; i++) 23 | printf("semval[%d] = %d\n", i, ptr[i]); 24 | 25 | /* 4store new values for entire set */ 26 | for (i = 0; i < NSEMS; i++) 27 | ptr[i] = rand(); 28 | Semctl(semid, 0, SETALL, arg); 29 | 30 | /* 4and delete the set */ 31 | Semctl(semid, 0, IPC_RMID); 32 | } 33 | 34 | exit(0); 35 | } 36 | -------------------------------------------------------------------------------- /code/unpv22e/svsem/semcreate.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int c, oflag, semid, nsems; 7 | 8 | oflag = SVSEM_MODE | IPC_CREAT; 9 | while ( (c = Getopt(argc, argv, "e")) != -1) { 10 | switch (c) { 11 | case 'e': 12 | oflag |= IPC_EXCL; 13 | break; 14 | } 15 | } 16 | if (optind != argc - 2) 17 | err_quit("usage: semcreate [ -e ] "); 18 | nsems = atoi(argv[optind + 1]); 19 | 20 | semid = Semget(Ftok(argv[optind], 0), nsems, oflag); 21 | exit(0); 22 | } 23 | -------------------------------------------------------------------------------- /code/unpv22e/svsem/semgetvalues.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int semid, nsems, i; 7 | struct semid_ds seminfo; 8 | unsigned short *ptr; 9 | union semun arg; 10 | 11 | if (argc != 2) 12 | err_quit("usage: semgetvalues "); 13 | 14 | /* 4first get the number of semaphores in the set */ 15 | semid = Semget(Ftok(argv[1], 0), 0, 0); 16 | arg.buf = &seminfo; 17 | Semctl(semid, 0, IPC_STAT, arg); 18 | nsems = arg.buf->sem_nsems; 19 | 20 | /* 4allocate memory to hold all the values in the set */ 21 | ptr = Calloc(nsems, sizeof(unsigned short)); 22 | arg.array = ptr; 23 | 24 | /* 4fetch the values and print */ 25 | Semctl(semid, 0, GETALL, arg); 26 | for (i = 0; i < nsems; i++) 27 | printf("semval[%d] = %d\n", i, ptr[i]); 28 | 29 | exit(0); 30 | } 31 | -------------------------------------------------------------------------------- /code/unpv22e/svsem/semops.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int c, i, flag, semid, nops; 7 | struct sembuf *ptr; 8 | 9 | flag = 0; 10 | while ( (c = Getopt(argc, argv, "nu")) != -1) { 11 | switch (c) { 12 | case 'n': 13 | flag |= IPC_NOWAIT; /* for each operation */ 14 | break; 15 | 16 | case 'u': 17 | flag |= SEM_UNDO; /* for each operation */ 18 | break; 19 | } 20 | } 21 | if (argc - optind < 2) /* argc - optind = #args remaining */ 22 | err_quit("usage: semops [ -n ] [ -u ] operation ..."); 23 | 24 | semid = Semget(Ftok(argv[optind], 0), 0, 0); 25 | optind++; 26 | nops = argc - optind; 27 | 28 | /* 4allocate memory to hold operations, store, and perform */ 29 | ptr = Calloc(nops, sizeof(struct sembuf)); 30 | for (i = 0; i < nops; i++) { 31 | ptr[i].sem_num = i; 32 | ptr[i].sem_op = atoi(argv[optind + i]); /* <0, 0, or >0 */ 33 | ptr[i].sem_flg = flag; 34 | } 35 | Semop(semid, ptr, nops); 36 | 37 | exit(0); 38 | } 39 | -------------------------------------------------------------------------------- /code/unpv22e/svsem/semopsid.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int c, i, flag, semid, nops; 7 | struct sembuf *ptr; 8 | 9 | flag = 0; 10 | while ( (c = Getopt(argc, argv, "nu")) != -1) { 11 | switch (c) { 12 | case 'n': 13 | flag |= IPC_NOWAIT; /* for each operation */ 14 | break; 15 | 16 | case 'u': 17 | flag |= SEM_UNDO; /* for each operation */ 18 | break; 19 | } 20 | } 21 | if (argc - optind < 2) /* argc - optind = #args remaining */ 22 | err_quit("usage: semops [ -n ] [ -u ] operation ..."); 23 | 24 | semid = atol(argv[optind]); 25 | optind++; 26 | nops = argc - optind; 27 | 28 | /* 4allocate memory to hold operations, store, and perform */ 29 | ptr = Calloc(nops, sizeof(struct sembuf)); 30 | for (i = 0; i < nops; i++) { 31 | ptr[i].sem_num = i; 32 | ptr[i].sem_op = atoi(argv[optind + i]); /* <0, 0, or >0 */ 33 | ptr[i].sem_flg = flag; 34 | } 35 | Semop(semid, ptr, nops); 36 | 37 | exit(0); 38 | } 39 | -------------------------------------------------------------------------------- /code/unpv22e/svsem/semrmid.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int semid; 7 | 8 | if (argc != 2) 9 | err_quit("usage: semrmid "); 10 | 11 | semid = Semget(Ftok(argv[1], 0), 0, 0); 12 | Semctl(semid, 0, IPC_RMID); 13 | 14 | exit(0); 15 | } 16 | -------------------------------------------------------------------------------- /code/unpv22e/svsem/semsetvalues.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int semid, nsems, i; 7 | struct semid_ds seminfo; 8 | unsigned short *ptr; 9 | union semun arg; 10 | 11 | if (argc < 2) 12 | err_quit("usage: semsetvalues [ values ... ]"); 13 | 14 | /* 4first get the number of semaphores in the set */ 15 | semid = Semget(Ftok(argv[1], 0), 0, 0); 16 | arg.buf = &seminfo; 17 | Semctl(semid, 0, IPC_STAT, arg); 18 | nsems = arg.buf->sem_nsems; 19 | 20 | /* 4now get the values from the command line */ 21 | if (argc != nsems + 2) 22 | err_quit("%d semaphores in set, %d values specified", nsems, argc-2); 23 | 24 | /* 4allocate memory to hold all the values in the set, and store */ 25 | ptr = Calloc(nsems, sizeof(unsigned short)); 26 | arg.array = ptr; 27 | for (i = 0; i < nsems; i++) 28 | ptr[i] = atoi(argv[i + 2]); 29 | Semctl(semid, 0, SETALL, arg); 30 | 31 | exit(0); 32 | } 33 | -------------------------------------------------------------------------------- /code/unpv22e/svshm/Makefile: -------------------------------------------------------------------------------- 1 | include ../Make.defines 2 | 3 | PROGS = shmget shmrmid shmread shmreadid shmwrite limits 4 | 5 | all: ${PROGS} 6 | 7 | shmget: shmget.o 8 | ${CC} ${CFLAGS} -o $@ shmget.o ${LIBS} 9 | 10 | shmrmid: shmrmid.o 11 | ${CC} ${CFLAGS} -o $@ shmrmid.o ${LIBS} 12 | 13 | shmread: shmread.o 14 | ${CC} ${CFLAGS} -o $@ shmread.o ${LIBS} 15 | 16 | shmreadid: shmreadid.o 17 | ${CC} ${CFLAGS} -o $@ shmreadid.o ${LIBS} 18 | 19 | shmwrite: shmwrite.o 20 | ${CC} ${CFLAGS} -o $@ shmwrite.o ${LIBS} 21 | 22 | limits: limits.o 23 | ${CC} ${CFLAGS} -o $@ limits.o ${LIBS} 24 | 25 | clean: 26 | rm -f ${PROGS} ${CLEANFILES} 27 | -------------------------------------------------------------------------------- /code/unpv22e/svshm/shmget.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int c, id, oflag; 7 | char *ptr; 8 | size_t length; 9 | 10 | oflag = SVSHM_MODE | IPC_CREAT; 11 | while ( (c = Getopt(argc, argv, "e")) != -1) { 12 | switch (c) { 13 | case 'e': 14 | oflag |= IPC_EXCL; 15 | break; 16 | } 17 | } 18 | if (optind != argc - 2) 19 | err_quit("usage: shmget [ -e ] "); 20 | length = atoi(argv[optind + 1]); 21 | 22 | id = Shmget(Ftok(argv[optind], 0), length, oflag); 23 | ptr = Shmat(id, NULL, 0); 24 | 25 | exit(0); 26 | } 27 | -------------------------------------------------------------------------------- /code/unpv22e/svshm/shmread.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i, id; 7 | struct shmid_ds buff; 8 | unsigned char c, *ptr; 9 | 10 | if (argc != 2) 11 | err_quit("usage: shmread "); 12 | 13 | id = Shmget(Ftok(argv[1], 0), 0, SVSHM_MODE); 14 | ptr = Shmat(id, NULL, 0); 15 | Shmctl(id, IPC_STAT, &buff); 16 | 17 | /* 4check that ptr[0] = 0, ptr[1] = 1, etc. */ 18 | for (i = 0; i < buff.shm_segsz; i++) 19 | if ( (c = *ptr++) != (i % 256)) 20 | err_ret("ptr[%d] = %d", i, c); 21 | 22 | exit(0); 23 | } 24 | -------------------------------------------------------------------------------- /code/unpv22e/svshm/shmreadid.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i, id; 7 | struct shmid_ds buff; 8 | unsigned char c, *ptr; 9 | 10 | if (argc != 2) 11 | err_quit("usage: shmread "); 12 | 13 | id = atol(argv[1]); 14 | ptr = Shmat(id, NULL, 0); 15 | Shmctl(id, IPC_STAT, &buff); 16 | 17 | /* 4check that ptr[0] = 0, ptr[1] = 1, etc. */ 18 | for (i = 0; i < buff.shm_segsz; i++) 19 | if ( (c = *ptr++) != (i % 256)) 20 | err_ret("ptr[%d] = %d", i, c); 21 | 22 | exit(0); 23 | } 24 | -------------------------------------------------------------------------------- /code/unpv22e/svshm/shmrmid.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int id; 7 | 8 | if (argc != 2) 9 | err_quit("usage: shmrmid "); 10 | 11 | id = Shmget(Ftok(argv[1], 0), 0, SVSHM_MODE); 12 | Shmctl(id, IPC_RMID, NULL); 13 | 14 | exit(0); 15 | } 16 | -------------------------------------------------------------------------------- /code/unpv22e/svshm/shmwrite.c: -------------------------------------------------------------------------------- 1 | #include "unpipc.h" 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i, id; 7 | struct shmid_ds buff; 8 | unsigned char *ptr; 9 | 10 | if (argc != 2) 11 | err_quit("usage: shmwrite "); 12 | 13 | id = Shmget(Ftok(argv[1], 0), 0, SVSHM_MODE); 14 | ptr = Shmat(id, NULL, 0); 15 | Shmctl(id, IPC_STAT, &buff); 16 | 17 | /* 4set: ptr[0] = 0, ptr[1] = 1, etc. */ 18 | for (i = 0; i < buff.shm_segsz; i++) 19 | *ptr++ = i % 256; 20 | 21 | exit(0); 22 | } 23 | -------------------------------------------------------------------------------- /docs/第10章-Posix信号量/第10章-Posix信号量.md: -------------------------------------------------------------------------------- 1 | # 第10章-Posix信号量 2 | 3 | -------------------------------------------------------------------------------- /docs/第11章-System_V信号量/第11章-System_V信号量.md: -------------------------------------------------------------------------------- 1 | # 第11章-System_V信号量 2 | 3 | -------------------------------------------------------------------------------- /docs/第12章-共享内存区介绍/第12章-共享内存区介绍.md: -------------------------------------------------------------------------------- 1 | # 第12章-共享内存区介绍 2 | 3 | -------------------------------------------------------------------------------- /docs/第13章-Posix共享内存区/第13章-Posix共享内存区.md: -------------------------------------------------------------------------------- 1 | # 第13章-Posix共享内存区 2 | 3 | -------------------------------------------------------------------------------- /docs/第14章-System_V共享内存区/第14章-System_V共享内存区.md: -------------------------------------------------------------------------------- 1 | # 第14章-System_V共享内存区 2 | 3 | -------------------------------------------------------------------------------- /docs/第15章-门/第15章-门.md: -------------------------------------------------------------------------------- 1 | # 第15章-门 2 | 3 | -------------------------------------------------------------------------------- /docs/第16章-Sun_RPC/第16章-Sun_RPC.md: -------------------------------------------------------------------------------- 1 | # 第16章-Sun_RPC 2 | 3 | -------------------------------------------------------------------------------- /docs/第1章-简介/第1章-简介.md: -------------------------------------------------------------------------------- 1 | # 第1章-简介 2 | 3 | -------------------------------------------------------------------------------- /docs/第2章-Posix_IPC/第2章-Posix_IPC.md: -------------------------------------------------------------------------------- 1 | # 第2章-Posix_IPC 2 | 3 | -------------------------------------------------------------------------------- /docs/第3章-System_V_IPC/第3章-System_V_IPC.md: -------------------------------------------------------------------------------- 1 | # 第3章-System_V_IPC 2 | 3 | -------------------------------------------------------------------------------- /docs/第4章-管道和FIFO/第4章-管道和FIFO.md: -------------------------------------------------------------------------------- 1 | # 第4章-管道和FIFO 2 | 3 | -------------------------------------------------------------------------------- /docs/第5章-Posix消息队列/第5章-Posix消息队列.md: -------------------------------------------------------------------------------- 1 | # 第5章-Posix消息队列 2 | 3 | -------------------------------------------------------------------------------- /docs/第6章-System_V消息队列/第6章-System_V消息队列.md: -------------------------------------------------------------------------------- 1 | # 第6章-System_V消息队列 2 | 3 | -------------------------------------------------------------------------------- /docs/第7章-互斥锁和条件变量/第7章-互斥锁和条件变量.md: -------------------------------------------------------------------------------- 1 | # 第7章-互斥锁和条件变量 2 | 3 | -------------------------------------------------------------------------------- /docs/第8章-读写锁/第8章-读写锁.md: -------------------------------------------------------------------------------- 1 | # 第8章-读写锁 2 | 3 | -------------------------------------------------------------------------------- /docs/第9章-记录上锁/第9章-记录上锁.md: -------------------------------------------------------------------------------- 1 | # 第9章-记录上锁 2 | 3 | -------------------------------------------------------------------------------- /image/1533732492938.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yifengyou/learn-unp2/12c1fd4e6f43524f0b173e9385321b67bcb7d653/image/1533732492938.png -------------------------------------------------------------------------------- /image/1533732533595.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yifengyou/learn-unp2/12c1fd4e6f43524f0b173e9385321b67bcb7d653/image/1533732533595.png --------------------------------------------------------------------------------