KEMBAR78
Module - 4 - Unix System Programming (BCS515C) | PDF | Pointer (Computer Programming) | Computer Architecture
0% found this document useful (0 votes)
68 views54 pages

Module - 4 - Unix System Programming (BCS515C)

unix ppt module 4
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
68 views54 pages

Module - 4 - Unix System Programming (BCS515C)

unix ppt module 4
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 54

CHANGING USER IDs AND GROUP IDs

Prototype
#include <sys/types.h>
#include <unistd.h>
int setuid (uid_t uid);
int setgid (gid_t gid);
Both return: 0 if OK, 1 on error

Rules
1. If the process has superuser privilege, the setuid function sets – real
user ID, effective user ID , saved set-user-ID to uid
2. If the process doesnot have superuser privilege, but uid equals either
real user ID or saved set-user-ID, setuid sets only effective user ID to
uid
3. If neither of the two conditions is true, errno is set to EPERM and an
error is returned

09/28/2025
CHANGING USER IDs AND GROUP IDs
setreuid and setregid Functions
Swapping of the real user ID and the effective user ID with the setreuid function.

#include <sys/types.h>
#include <unistd.h>
int setreuid (uid_t ruid, uid_t euid);
int setregid (gid_t rgid, gid_t egid);
Both return : 0 if OK, -1 on error

seteuid and setegid functions :


POSIX.1 includes the two functions seteuid and setegid. These functions are
similar to setuid and setgid, but only the effective user ID or effective group ID is
changed.
#include <sys/types.h>
#include <unistd.h>
int seteuid (uid_t euid);
int setegid (gid_t egid);
Both return : 0 if OK, 1 on error

09/28/2025
CHANGING USER IDs AND GROUP IDs
Summary of all the functions that set the various user Ids

09/28/2025
INTERPRETER FILES
These files are text files that begin with a line of the form
#! pathname [ optional-argument ]

most common example : #! /bin/bash

The actual file execed by kernel is the one specified in the pathname
A program that execs an interpreter file
#include "apue.h"
#include <sys/wait.h>
int main(void)
{
pid_t pid;
if ((pid = fork()) < 0) {
err_sys("fork error"); }
else if (pid == 0)
{ /* child */
if (execl("/home/sar/bin/testinterp", "testinterp", "myarg1", "MY ARG2", (char *)0) < 0)
err_sys("execl error");
}
if (waitpid(pid, NULL, 0) < 0) /* parent */
err_sys("waitpid error");
exit(0);
} 09/28/2025
INTERPRETER FILES
Uses of interpreter files
1. They hide the fact that certain programs are scripts in some other language
2. They provide an efficiency gain
3. They help us write shell scripts using shells other than /bin/sh

09/28/2025
System function
It helps us execute a command string within a program.
System is implemented by calling fork, exec and waidpid.

#include <stdlib.h>
int system (const char *cmdstring);

Return values of function

-1 – if either fork fails or waitpid returns an error other than EINTR


127 -- If exec fails [as if shell has executed exit ]
termination status of shell -- if all three functions succeed

09/28/2025
System function
/* calling system function*/
#include <sys/types.h>
#include <sys/wait.h>
#include "ourhdr.h"
int main(void)
{
int status;
if ( (status = system("date")) < 0)
err_sys("system() error");
pr_exit(status);
if ( (status = system("nosuchcommand")) < 0)
err_sys("system() error");
pr_exit(status);

if ( (status = system("who; exit 44")) < 0)


err_sys("system() error");
pr_exit(status);

exit(0);
}

09/28/2025
Process accounting
Most UNIX systems provide an option to do process accounting. When enabled, the
kernel writes an accounting record each time a process terminates.

Accounting records : 32 bytes of binary data


These accounting records are typically a small amount of binary data with the name
of the command, the amount of CPU time used, the user ID and group ID, the starting
time, and so on.

Each accounting record is written when the process terminates.

The accounting records correspond to processes, not programs.

A new record is initialized by the kernel for the child after a fork, not when a new
program is executed.

09/28/2025
Process Accounting
The structure of the accounting records is defined in the header <sys/acct.h>

struct acct
{
char ac_flag; /* flag */
char ac_stat; /* termination status (signal & core flag only) */ /* (Solaris only) */
uid_t ac_uid; /* real user ID */
gid_t ac_gid; /* real group ID */
dev_t ac_tty; /* controlling terminal */
time_t ac_btime; /* starting calendar time */
comp_t ac_utime; /* user CPU time (clock ticks) */
comp_t ac_stime; /* system CPU time (clock ticks) */
comp_t ac_etime; /* elapsed time (clock ticks) */
comp_t ac_mem; /* average memory usage */
comp_t ac_io; /* bytes transferred (by read and write) */ /* "blocks" on BSD systems */
comp_t ac_rw; /* blocks read or written */ /* (not present on BSD systems) */
char ac_comm[8]; /* command name: [8] for Solaris, */ /* [10] for Mac OS X, [16]
for FreeBSD, and */ /* [17] for Linux */
};

09/28/2025
Process Accounting

ac_flag Description

AFORK process is the result of fork, but never called exec


ASU process used superuser privileges
ACOMPAT process used compatibility mode
ACORE process dumped core
AXSIG process was killed by a signal
AEXPND expanded accounting entry

09/28/2025
Process Accounting

Program to generate accounting data if ((pid = fork()) < 0)


#include "apue.h" err_sys("fork error");
int main(void) else if (pid != 0)
{ {
pid_t pid; execl("/bin/dd", "dd", "if=/etc/termcap", "of=/dev/null",
if ((pid = fork()) < 0) NULL);
err_sys("fork error"); exit(7); /* shouldn't get here */
else if (pid != 0) } /* third child */
{ /* parent */ if ((pid = fork()) < 0)
sleep(2); exit(2); /* terminate with exit status 2 err_sys("fork error");
*/ else if (pid != 0)
} /* first child */ { sleep(8);
if ((pid = fork()) < 0) exit(0); /* normal exit */
err_sys("fork error"); }/* fourth child */
else if (pid != 0) sleep(6);
{ kill(getpid(), SIGKILL); /* terminate w/signal, no core
sleep(4); dump */
abort(); /* terminate with core dump */ exit(6); /* shouldn't get here */
} /* second child */ }
09/28/2025
User Identification
To obtain the login name
#include <unistd.h>
char *getlogin (void);
Returns : pointer to string giving login name if OK, NULL on error

Note: This function can fail if the process is not attached to a terminal that a user
logged in to.

09/28/2025
PROCESS TIMES
We can measure: wall clock time, user CPU time, and system CPU time.
Any process can call the times function to obtain these values for itself and any terminated
children.
#include <sys/times.h>
clock_t times (struct tms *buf);
Returns : elapsed wall clock time in clock ticks if OK, 1 on error

struct tms
{
clock_t tms_utime; /* user CPU time */
clock_t tms_stime; /* system CPU time */
clock_t tms_cutime; /* user CPU time, terminated children */
clock_t tms_cstime; /* system CPU time, terminated children */
};

09/28/2025
I/O Redirection
The Shell input/output redirections. Most Unix system commands take input from your
terminal and send the resulting output back to your terminal. A command normally reads its
input from the standard input, which happens to be your terminal by default. Similarly, a
command normally writes its output to standard output, which is again your terminal by
default.

Output Redirection
The output from a command normally intended for standard output can be easily diverted to
a file instead. This capability is known as output redirection. If the notation > file is
appended to any command that normally writes its output to standard output, the output of
that command will be written to file instead of your terminal. Check the following who
command which redirects the complete output of the command in the users file.
$ who > users
Notice that no output appears at the terminal. This is because the output has been redirected
from the default standard output device (the terminal) into the specified file. You can check
the users file for the complete content –

09/28/2025
I/O Redirection
If a command has its output redirected to a file and the file already contains some data, that
data will be lost. Consider the following example –

You can use >> operator to append the output in an existing file as follows –

09/28/2025
I/O Redirection
Input Redirection
Just as the output of a command can be redirected to a file, so can the input of a
command be redirected from a file. As the greater-than character > is used for
output redirection, the less-than character < is used to redirect the input of a
command.
The commands that normally take their input from the standard input can have their
input redirected from a file in this manner. For example, to count the number of lines
in the file users generated above, you can execute the command as follows –

Upon execution, you will receive the following output. You can count the number of
lines in the file by redirecting the standard input of the wc command from the file
users –

09/28/2025
I/O Redirection
Note that there is a difference in the output produced by the two forms of the wc
command. In the first case, the name of the file users is listed with the line count; in
the second case, it is not. In the first case, wc knows that it is reading its input from
the file users. In the second case, it only knows that it is reading its input from
standard input so it does not display file name.

09/28/2025
PROCESS TIMES
#include <sys/times.h> static void pr_times (clock_t real, struct tms
#include "ourhdr.h" *tmsstart, struct tms *tmsend)
static void pr_times (clock_t, struct tms *, {
struct tms *); static long clktck = 0;
static void do_cmd(char *); if ( (clktck = sysconf(_SC_CLK_TCK)) < 0)
int main (int argc, char *argv[ ]) err_sys("sysconf error");
{ int i; fprintf (stderr, " real: %7.2f\n", real / (double)
for (i = 1; i < argc; i++) clktck);
do_cmd(argv[i]);
exit(0); fprintf (stderr, " user: %7.2f\n",
}
(tmsend->tms_utime - tmsstart> tms_utime) /
static void do_cmd (char *cmd)
{ (double) clktck);
struct tms tmsstart, tmsend;
clock_t start, end; fprintf(stderr, " sys: %7.2f\n",
int status; (tmsend->tms_stime - tmsstart->tms_stime) /
fprintf(stderr, "\ncommand: %s\n", cmd); (double) clktck);
if ( (start = times(&tmsstart)) == -1)
err_sys("times error"); fprintf(stderr, " child user: %7.2f\n",
if ( (status = system(cmd)) < 0) (tmsend->tms_cutime - tmsstart->
err_sys("system() error");
tms_cutime) / (double) clktck);
if ( (end = times(&tmsend)) == -1)
err_sys("times error");
fprintf (stderr, " child sys: %7.2f\n", (tmsend-
pr_times(end-start, &tmsstart,
>tms_cstime - tmsstart-> tms_cstime) / (double)
&tmsend);
clktck);
pr_exit(status); 09/28/2025
INTRODUCTION
IPC is a set of techniques for processes to communicate each other.

IPC enables one application to control another application, and for several applications
to share the same data without interfering with one another.

IPC is required in all multiprocessing systems, but it is not generally supported by single-
process operating systems.

 The various forms of IPC that are supported on a UNIX system are as follows :
IPC methods for communication between two process running on one Unix system are
1) Half duplex Pipes.
2) FIFO’s
3) Full duplex Pipes.
4) Named full duplex Pipes.
5) Message queues.
6) Shared memory.
7) Semaphores.
IPC methods for communication between two process running on different system are
8) Sockets.
9) STREAMS. Department of Computer Science, RLJIT 28/09/2025
19
PIPES
Pipes are the oldest form of UNIX System IPC.

Basically pipe is a one way communication channel where output of one is fed as input to
other.

A pipe is created by calling the pipe function.


#include <unistd.h>
int pipe(int filedes[2]);
Returns: 0 if OK, 1 on error.

Two file descriptors are returned through the filedes argument:


filedes[0] is open for reading, and
filedes[1] is open for writing.

The output of filedes[1] is the input for filedes[0].

Department of Computer Science, RLJIT 28/09/2025


20
PIPES
Two ways to picture a half-duplex pipe are shown in Figure 1. The left half of the figure
shows the two ends of the pipe connected in a single process. The right half of the figure
emphasizes that the data in the pipe flows through the kernel.

Figure 1. Two ways to view a half-duplex pipe

Department of Computer Science, RLJIT 28/09/2025


21
PIPES

Figure 2 Half-duplex pipe after a fork

Department of Computer Science, RLJIT 28/09/2025


22
PIPES

Figure 3. Pipe from parent to child

When one end of a pipe is closed, the following two rules apply.
If we read from a pipe whose write end has been closed, read returns 0 to indicate an
end of file after all the data has been read.
 If we write to a pipe whose read end has been closed,

Department of Computer Science, RLJIT 28/09/2025


23
PIPES
Pipes have two limitations.
1. Historically, they have been half duplex (i.e., data flows in only one direction).
2. Pipes can be used only between processes that have a common ancestor. Normally,
a pipe is created by a process, that process calls fork, and the pipe is used between
the parent and the child.

Department of Computer Science, RLJIT 28/09/2025


24
PIPES
PROGRAM: shows the code to create a pipe
between a parent and its child and to send
data down the pipe.
#include "apue.h" else
int main(void) { /* child */
{ close(fd[1]);
int n; n = read(fd[0], line, MAXLINE);
int fd[2]; write(STDOUT_FILENO, line, n);
pid_t pid; }
char line[MAXLINE]; exit(0);
if (pipe(fd) < 0) }
err_sys("pipe error");
if ((pid = fork()) < 0)
{
err_sys("fork error");
}
else if (pid > 0)
{ /* parent */
close(fd[0]);
write(fd[1],
Department of Computer Science, RLJIT 28/09/2025
25
"hello world\n", 12);
popen AND pclose FUNCTIONS
These two functions provided by standard I/O library.
These two function handles
 Creation of a pipe
 fork of a child
 Closing unused ends of the pipe
 Executing a shell to run the command
 Waiting for the command to terminate

Prototype:

#include <stdio.h>
FILE *popen(const char *cmdstring, const char *type);
Returns: file pointer if OK, NULL on error

int pclose(FILE *fp);


Returns: termination status of cmdstring, or -1 on error

Department of Computer Science, RLJIT 28/09/2025


26
popen AND pclose FUNCTIONS
The function popen does a fork and exec to execute the cmdstring, and returns a
standard I/O file pointer.
If type is "r", the file pointer is connected to the standard output of cmdstring

Figure 4. Result of fp = popen(cmdstring, "r")

If type is "w", the file pointer is connected to the standard input of cmdstring, as
shown:
Figure 5. Result of fp = popen(cmdstring, "w")

The pclose function closes the standard I/O stream,wait for the command to terminate
Department of Computer Science, RLJIT 28/09/2025
27
and returns the termination status of the shell.
COPROCESSES
A UNIX system filter is a program that reads from standard input and writes to standard
output. Filters are normally connected linearly in shell pipelines.

A filter becomes a coprocess when the same program generates the filter's input and
reads the filter's output.

A coprocess normally runs in the background from a shell, and its standard input and
standard output are connected to another program using a pipe.

The process creates two pipes: one is the standard input of the coprocess, and the
other is the standard output of the coprocess. Figure 6 shows this arrangement.

Figure 6. Driving a coprocess by writing its standard input and reading its standard
output

Department of Computer Science, RLJIT 28/09/2025


28
COPROCESSES
The program is a simple co-process that reads two numbers from its standard
input, computes their sum, and writes the sum to its standard output. We compile
this program and leave the executable in the file add2.
#include "apue.h"
int main(void)
{
int n, int1, int2;
char line[MAXLINE];
while ((n = read(STDIN_FILENO, line, MAXLINE)) > 0) {
line[n] = 0; /* null terminate */
if (sscanf(line, "%d%d", &int1, &int2) == 2) {
sprintf(line, "%d\n", int1 + int2);
n = strlen(line);
if (write(STDOUT_FILENO, line, n) != n)
err_sys("write error");
} else {
if (write(STDOUT_FILENO, "invalid args\n", 13) != 13)
err_sys("write error");
}
}
Department of Computer Science, RLJIT 28/09/2025
29
exit(0);
FIFOs
FIFOs are sometimes called named pipes.
(Pipes can be used only between related processes when a common ancestor has
created the pipe.)
With FIFOs, however unrelated processes can exchange date.

Creating a fifo is similar to creating a file, i.e fifo is just a type of file.

Prototype:
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
Returns: 0 if OK, -1 on error
The specification of the mode argument for the mkfifo function is the same as for the open
function.

Once we have used mkfifo to create a FIFO, we open it using open.

Indeed, the normal file I/O functions (close, read, write, unlink, etc.) all work with FIFOs.

Department of Computer Science, RLJIT 28/09/2025


30
FIFOs
When we open a FIFO, the nonblocking flag (O_NONBLOCK) affects what
happens.
• In the normal case (O_NONBLOCK not specified), an open for read-only blocks
until some other process opens the FIFO for writing. Similarly, an open for write only
blocks until some other process opens the FIFO for reading.
• If O_NONBLOCK is specified, an open for read-only returns immediately. But
an open for write-only returns -1 with errno set to ENXIO if no process has the
FIFO open for reading.
There are two uses for FIFOs.
1. FIFOs are used by shell commands to pass data from one shell pipeline to another
without creating intermediate temporary files.
2. FIFOs are used as rendezvous points in client-server applications to pass data
between the clients and the servers.

Department of Computer Science, RLJIT 28/09/2025


31
FIFOs
Example: Using FIFOs to Duplicate Output Streams
FIFOs can be used to duplicate an output stream in a series of shell commands. This
prevents writing the data to an intermediate disk file. Consider a procedure that needs
to process a filtered input stream twice. Figure 7 shows this arrangement

FIGURE 7 : Procedure that processes a filtered input stream twice

Department of Computer Science, RLJIT 28/09/2025


32
FIFOs
With a FIFO and the UNIX program tee(1), we can accomplish this procedure without
using a temporary file. (The tee program copies its standard input to both its standard
output and to the file named on its command line.)
mkfifo fifo1
prog3 < fifo1 &
prog1 < infile | tee fifo1 | prog2

We create the FIFO and then start prog3 in the background, reading from the FIFO. We
then start prog1 and use tee to send its input to both the FIFO and prog2. Figure 8 shows
the process arrangement.

FIGURE 8 : Using a FIFO and tee to send a stream to two different processes

Department of Computer Science, RLJIT 28/09/2025


33
FIFOs
Example Client-Server Communication Using a FIFO
FIFO’s can be used to send data between a client and a server. If we have a server that
is contacted by numerous clients, each client can write its request to a well-known
FIFO that the server creates. Since there are multiple writers for the FIFO, the requests
sent by the clients to the server need to be less than PIPE_BUF bytes in size.

Figure 9. Clients sending requests to a server using a FIFO


Department of Computer Science, RLJIT 28/09/2025
34
FIFOs
This prevents any interleaving of the client writes. The problem in using FIFOs for this type
of client server communication is how to send replies back from the server to each client.
A single FIFO can’t be used, as the clients would never know when to read their response
versus responses for other clients.
One solution is for each client to send its process ID with the request. The server then creates
a unique FIFO for each client, using a pathname based on the client’sprocess ID.
For example, the server can create a FIFO with the name /vtu/ ser.XXXXX, where XXXXX
is replaced with the client’s process ID.

Department of Computer Science, RLJIT 28/09/2025


35
Figure 10. Client-server communication using FIFOs
XSI IPC
Three more types of IPC originating from system V are
1. Message Queues
2. Semaphores
3. Shared Memory.
Identifiers and Keys:
 Each IPC structure (message queue, semaphore, or shared memory segment) in the
Kernel is referred to by a non-negative integer identifier.
The identifier is an internal name for an IPC object.
 IPC structure is created and then removed, the identifier associated with that
structure
Whenever an IPC structure is being created (by calling msgget, semget, or shmget), a
key must be specified.
 The data type of this key is the primitive system data type key_t, which is often
defined as a long integer in the header <sys/types.h>.
This key is converted into an identifier by the kernel.

Department of Computer Science, RLJIT 28/09/2025


36
XSI IPC
There are various ways for a client and a server to rendezvous at the same IPC structure.
a. The server can create a new IPC structure by specifying a key of IPC_PRIVATE
and store the returned identifier somewhere (such as a file) for the client to obtain.

b. The client and the server can agree on a key by defining the key in a common
header, for example. The server then creates a new IPC structure specifying this
key.

c. The client and the server can agree on a pathname and project ID and call the function
ftok to convert these two values into a key. This key is then used in step 2. The only service
providedby ftok is a way of generating a key from a pathname and project ID

#include <sys/ipc.h>
key_t ftok(const char *path, int id);
Returns: key if OK, (key_t)-1 on error

Department of Computer Science, RLJIT 28/09/2025


37
XSI IPC
Permission Structure:
XSI IPC associates an ipc_perm structure with each IPC structure. This structure defines the
permissions and owner and includes at least the following members:

struct ipc_perm {
uid_t uid; /* owner's effective user id */
gid_t gid; /* owner's effective group id */
uid_t cuid; /* creator's effective user id */
gid_t cgid; /* creator's effective group id */
mode_t mode; /* access modes */
.
.
.
};

Department of Computer Science, RLJIT 28/09/2025


38
XSI IPC
All the fields are initialized when the IPC structure is created. At a later time, we can
modify the uid, gid, and mode fields by calling msgctl, semctl, or shmctl. To change these
values, the calling process must be either the creator of the IPC structure or the superuser.
Changing these fields is similar to calling chown or chmod for a file.

Permission Bit
user-read 0400
user-write (alter) 0200
group-read 0040
group-write (alter) 0020
other-read 0004
other-write (alter) 0002

Configuration Limits:
All three forms of XSI IPC have built-in limits that we may encounter. Most of these limits
can be changed by reconfiguring the kernel.

Department of Computer Science, RLJIT 28/09/2025


39
XSI IPC
Advantages and Disadvantages :
A fundamental problem with XSI IPC is that the IPC structures are system wide and
do not have a reference count.

Another problem with XSI IPC is that these IPC structures are not known by names in the
file system. We can't access them and modify their properties with the functions. Almost a
dozen new system calls (msgget, semop, shmat, and so on) were added to the kernel to
support these IPC objects. We can't see the IPC objects with an ls command, we can't
remove them with the rm command, and we can't change their permissions with the
chmod command. Instead, two new commands ipcs(1) and ipcrm(1)were added.

Since these forms of IPC don't use file descriptors, we can't use the multiplexed I/O
functions (select and poll) with them. This makes it harder to use more than one of these
IPC structures at a time or to use any of these IPC structures with file or device I/O. For
example, we can't have a server wait for a message to be placed on one of two message
queues without some form of busywait loop.

Department of Computer Science, RLJIT 28/09/2025


40
MESSAGE QUEUES
A message queue is a linked list of messages stored within the kernel and identified by a
message queue identifier.
 We'll call the message queue just a queue and its identifier a queue ID.

A new queue is created or an existing queue opened by msgget.


#include <sys/msg.h>
int msgget(key_t key, int flag);
Returns: message queue ID if OK,-1 on error
Each queue has the following msqid_ds structure associated with it:
struct msqid_ds {
struct ipc_perm msg_perm;
msgqnum_t msg_qnum; /* # of messages on queue */
msglen_t msg_qbytes; /* max # of bytes on queue */
pid_t msg_lspid; /* pid of last msgsnd() */
pid_t msg_lrpid; /* pid of last msgrcv() */
time_t msg_stime; /* last-msgsnd() time */
time_t msg_rtime; /* last-msgrcv() time */
time_t msg_ctime; /* last-change time */
.
.
. Department of Computer Science, RLJIT 28/09/2025
41
MESSAGE QUEUES
When a new queue is created, the following members of the msqid_ds structure are
initialized.
The ipc_perm structure is initialized. The mode member of this structure is set to the
corresponding permission bits of flag.
msg_qnum, msg_lspid, msg_lrpid, msg_stime, and msg_rtime are all set to 0.
msg_ctime is set to the current time.
msg_qbytes is set to the system limit.

On success, msgget returns the non-negative queue ID.

Department of Computer Science, RLJIT 28/09/2025


42
MESSAGE QUEUES
Performs various operations on a queue are.
#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf );
Returns: 0 if OK, -1 on error.

The cmd argument specifies the command to be performed on the queue specified by
msqid

Department of Computer Science, RLJIT 28/09/2025


43
MESSAGE QUEUES
Data is placed onto a message queue by calling msgsnd.
#include <sys/msg.h>
int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag);
Returns: 0 if OK, -1 on error

As we mentioned earlier, each message is composed of a positive long integer type


field, a non-negative length (nbytes), and the actual data bytes (corresponding to the
length).

Messages are always placed at the end of the queue.

The ptr argument points to a long integer that contains the positive integer message
type, and it is immediately followed by the message data. (There is no message data if
nbytes is 0.)

If the largest message we send is 512 bytes, we can define the following structure:
struct mymesg {
long mtype; /* positive message type */
char mtext[512]; /* message data, of length nbytes */
};
Department of Computer Science, RLJIT 28/09/2025
44
MESSAGE QUEUES
Messages are retrieved from a queue by msgrcv.
#include <sys/msg.h>
ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);
Returns: size of data portion of message if OK, -1 on error.

The type argument lets us specify which message we want.


type == 0 The first message on the queue is returned.
type > 0 The first message on the queue whose message type equals type is
returned.
type < 0 The first message on the queue whose message type is the lowest
value less than or equal to the absolute value of type is returned.

Department of Computer Science, RLJIT 28/09/2025


45
SEMAPHORES
A semaphore is a counter used to provide access to a shared data object for multiple processes.

To obtain a shared resource, a process needs to do the following:


1. Test the semaphore that controls the resource.
2. If the value of the semaphore is positive, the process can use the resource. In this case, the
process decrements the semaphore value by 1, indicating that it has used one unit of the resource.
3. Otherwise, if the value of the semaphore is 0, the process goes to sleep until the semaphore
value is greater than 0. When the process wakes up, it returns to step 1.

Department of Computer Science, RLJIT 28/09/2025


46
SEMAPHORES
The kernel maintains a semid_ds structure for each semaphore set:
struct semid_ds
{
struct ipc_perm sem_perm;
unsigned short sem_nsems; /* # of semaphores in set */
time_t sem_otime; /* last-semop() time */
time_t sem_ctime; /* last-change time */
.
.
.
};
Each semaphore is represented by an anonymous structure containing at least the following
members:
struct {
unsigned short semval; /* semaphore value, always >= 0 */
pid_t sempid; /* pid for last operation */
unsigned short semncnt; /* # processes awaiting semval>curval */
unsigned short semzcnt; /* # processes awaiting semval==0 */
.
.
}; Department of Computer Science, RLJIT 28/09/2025
47
SEMAPHORES
The first function to call is semget to obtain a semaphore ID.
#include <sys/sem.h>
int semget(key_t key, int nsems, int flag);
Returns: semaphore ID if OK, -1 on error

When a new set is created, the following members of the semid_ds structure are initialized.
 The ipc_perm structure is initialized. The mode member of this structure is set to the
corresponding permission bits of flag.
sem_otime is set to 0.
 sem_ctime is set to the current time.
sem_nsems is set to nsems.

NOTE:The number of semaphores in the set is nsems. If a new set is being created (typically in
the server), we must specify nsems. If we are referencing an existing set (a client), we can
specify nsems as 0.

Department of Computer Science, RLJIT 28/09/2025


48
SEMAPHORES
The semctl function is the catchall for various semaphore operations.
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd,... /* union semun
arg */);

The fourth argument is optional, depending on the command requested, and if present, is
of type semun, a union of various command-specific arguments:

union semun {
int val; /* for SETVAL */
struct semid_ds *buf; /* for IPC_STAT and IPC_SET */
unsigned short *array; /* for GETALL and SETALL */
};

The cmd argument specifies one of the above ten commands to be performed on the set
specified by semid.

Department of Computer Science, RLJIT 28/09/2025


49
SEMAPHORES

Department of Computer Science, RLJIT 28/09/2025


50
SEMAPHORES
The function semop atomically performs an array of operations on a semaphore set.
#include <sys/sem.h>
int semop(int semid, struct sembuf semoparray[], size_t nops);
Returns: 0 if OK, -1 on error.

The semoparray argument is a pointer to an array of semaphore operations,


represented by sembuf structures:
struct sembuf {
unsigned short sem_num; /* member # in set (0, 1, ..., nsems-1) */
short sem_op; /* operation (negative, 0, or positive) */
short sem_flg; /* IPC_NOWAIT, SEM_UNDO */
};

The nops argument specifies the number of operations (elements) in the array.

Department of Computer Science, RLJIT 28/09/2025


51
SEMAPHORES
The sem_op element operations are values specifying the amount by which the semaphore
value is to be changed.

If sem_op is an integer greater than zero, semop adds the value to the corresponding
semaphore element value and awakens all processes that are waiting for the element to
increase.

If sem_op is 0 and the semaphore element value is not 0, semop blocks the calling
process (waiting for 0) and increments the count of processes waiting for a zero value of
that element.

If sem_op is a negative number, semop adds the sem_op value to the corresponding
semaphore element value provided that the result would not be negative. If the operation
would make the element value negative, semop blocks the process on the event that the
semaphore element value increases. If the resulting value is 0, semop wakes the
processes waiting for 0.

Department of Computer Science, RLJIT 28/09/2025


52
Question????
1. Explain the following function
1. setuid and setgid functions.
2. setreuid and setregid functions.

2. What is an interpreter files? Mentions the Uses of interpreter files.

3. Explain the “system” function with its prototype, along with example.

4. Explain how process accounting is done in UNIX system. Write a


program to generate accounting data and give its process structure (10).

5. Explain the “process times” function with its prototype, along with
example.

Department of Computer Science, RLJIT 28/09/2025


53
Question????
Q1. What are pipes? What are its limitations? Write a program to send data from parent to
child over a pipe. (07M)

Q2. Explain popen and pclose functions with prototypes and write a program to
demonstrate popen and pclose function. (10 M)

Q3. Write short notes on the following: (10M)


i) Coprocesses

Q4. What are FIFOs? With a neat diagram, explain the following (10M)
i) Using FIFOs to Duplicate Output Streams
ii) The client-sever communication using FIFOs.

Q5. What are the three different ways in which the client and server
processes are can get access to same IPC structures? ( 05 M)

Q6. What are the advantages and disadvantages of XSI IPC. (05 M)

Q7. List the APIs with their argument details that are used to create, control, send and receive
messages from a message queue. (10M)
OR
What are message queues? Write the structure of the message queue and explain each member,
in detail.
Department of Computer Science, RLJIT 28/09/2025
Q8. What are the different system calls available to create and manipulate54semaphores? (10M)

You might also like