Create a file with hole in it.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
const char *filename = "sparse_file.dat";
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("Error opening file");
return 1;
// Move the file offset to 10 MB
off_t offset = 10 * 1024 * 1024; // 10 MB
if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
perror("Error seeking in file");
close(fd);
return 1;
// Write a single byte to create a hole
if (write(fd, "", 1) != 1) {
perror("Error writing to file");
close(fd);
return 1;
}
close(fd);
printf("Sparse file '%s' created with a hole at 10 MB.\n", filename);
return 0;
Take multiple files as Command Line Arguments and print their inode number
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
int main(int argc, char *argv[]) {
// Check if at least one file is provided
if (argc < 2) {
fprintf(stderr, "Usage: %s <file1> <file2> ... <fileN>\n", argv[0]);
return EXIT_FAILURE;
// Loop through each provided file argument
for (int i = 1; i < argc; i++) {
struct stat fileStat;
// Get the file status
if (stat(argv[i], &fileStat) < 0) {
perror("stat");
continue; // Skip to the next file if there's an error
}
// Print the inode number
printf("File: %s, Inode Number: %lu\n", argv[i], (unsigned long)fileStat.st_ino);
return EXIT_SUCCESS;
Write a C program to find file properties such as inode number, number of hard link,
File permissions, File size, File access and modification time and so on of a given file
using stat() system call.
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>
void print_file_permissions(mode_t mode) {
printf("File Permissions: ");
printf((mode & S_IRUSR) ? "r" : "-");
printf((mode & S_IWUSR) ? "w" : "-");
printf((mode & S_IXUSR) ? "x" : "-");
printf((mode & S_IRGRP) ? "r" : "-");
printf((mode & S_IWGRP) ? "w" : "-");
printf((mode & S_IXGRP) ? "x" : "-");
printf((mode & S_IROTH) ? "r" : "-");
printf((mode & S_IWOTH) ? "w" : "-");
printf((mode & S_IXOTH) ? "x" : "-");
printf("\n");
int main(int argc, char *argv[]) {
// Check if a file name is provided
if (argc != 2) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
return EXIT_FAILURE;
struct stat fileStat;
// Get the file status
if (stat(argv[1], &fileStat) < 0) {
perror("stat");
return EXIT_FAILURE;
// Print file properties
printf("File: %s\n", argv[1]);
printf("Inode Number: %lu\n", (unsigned long)fileStat.st_ino);
printf("Number of Hard Links: %lu\n", (unsigned long)fileStat.st_nlink);
printf("File Size: %lld bytes\n", (long long)fileStat.st_size);
// Print file permissions
print_file_permissions(fileStat.st_mode);
// Print access time
printf("Last Access Time: %s", ctime(&fileStat.st_atime));
// Print modification time
printf("Last Modification Time: %s", ctime(&fileStat.st_mtime));
// Print change time
printf("Last Status Change Time: %s", ctime(&fileStat.st_ctime));
return EXIT_SUCCESS;
4. Print the type of file where file name accepted through Command Line
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
void print_file_type(mode_t mode) {
if (S_ISREG(mode)) {
printf("File Type: Regular File\n");
} else if (S_ISDIR(mode)) {
printf("File Type: Directory\n");
} else if (S_ISCHR(mode)) {
printf("File Type: Character Device\n");
} else if (S_ISBLK(mode)) {
printf("File Type: Block Device\n");
} else if (S_ISFIFO(mode)) {
printf("File Type: FIFO (Named Pipe)\n");
} else if (S_ISLNK(mode)) {
printf("File Type: Symbolic Link\n");
} else if (S_ISSOCK(mode)) {
printf("File Type: Socket\n");
} else {
printf("File Type: Unknown\n");
int main(int argc, char *argv[]) {
// Check if a file name is provided
if (argc != 2) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
return EXIT_FAILURE;
}
struct stat fileStat;
// Get the file status
if (stat(argv[1], &fileStat) < 0) {
perror("stat");
return EXIT_FAILURE;
// Print the file type
print_file_type(fileStat.st_mode);
return EXIT_SUCCESS;
IMP
S_ISREG(mode): Regular file
S_ISDIR(mode): Directory
S_ISCHR(mode): Character device
S_ISBLK(mode): Block device
S_ISFIFO(mode): FIFO (named pipe)
S_ISLNK(mode): Symbolic link
S_ISSOCK(mode): Socket
5. Write a C program to find whether a given file is present in current directory or not.
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
int main(int argc, char *argv[]) {
// Check if a file name is provided
if (argc != 2) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
return EXIT_FAILURE;
struct stat fileStat;
// Check if the file exists using stat()
if (stat(argv[1], &fileStat) == 0) {
printf("The file '%s' is present in the current directory.\n", argv[1]);
} else {
perror("Error");
printf("The file '%s' is not present in the current directory.\n", argv[1]);
}
return EXIT_SUCCESS;
6. Write a C program that a string as an argument and return all the files that begins with that name
in the current directory. For example > ./a.out foo will return all file names that begins with foo
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
int main(int argc, char *argv[]) {
// Check if a string is provided
if (argc != 2) {
fprintf(stderr, "Usage: %s <string>\n", argv[0]);
return EXIT_FAILURE;
const char *prefix = argv[1];
DIR *dir;
struct dirent *entry;
// Open the current directory
dir = opendir(".");
if (dir == NULL) {
perror("opendir");
return EXIT_FAILURE;
printf("Files in the current directory starting with '%s':\n", prefix);
// Read entries in the directory
while ((entry = readdir(dir)) != NULL) {
// Check if the entry name starts with the given prefix
if (strncmp(entry->d_name, prefix, strlen(prefix)) == 0) {
printf("%s\n", entry->d_name);
// Close the directory
closedir(dir);
return EXIT_SUCCESS;
}
7. Read the current directory and display the name of the files, no of files in current directory
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
int main() {
DIR *dir;
struct dirent *entry;
int fileCount = 0;
// Open the current directory
dir = opendir(".");
if (dir == NULL) {
perror("opendir");
return EXIT_FAILURE;
printf("Files in the current directory:\n");
// Read entries in the directory
while ((entry = readdir(dir)) != NULL) {
// Check if the entry is a regular file
if (entry->d_type == DT_REG) {
printf("%s\n", entry->d_name);
fileCount++;
// Close the directory
closedir(dir);
// Display the number of files
printf("Total number of files: %d\n", fileCount);
return EXIT_SUCCESS;
8. Write a C program which receives file names as command line arguments and display
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
// Check if there are any file names provided
if (argc < 2) {
printf("No file names provided. Usage: %s <file1> <file2> ... <fileN>\n", argv[0]);
return EXIT_FAILURE;
printf("File names provided:\n");
// Loop through the command-line arguments and display them
for (int i = 1; i < argc; i++) {
printf("%s\n", argv[i]);
return EXIT_SUCCESS;
}
9. Display all the files from current directory which are created in particular month
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <time.h>
void display_files_in_month(int month) {
DIR *dir;
struct dirent *entry;
struct stat fileStat;
struct tm *timeinfo;
// Open the current directory
dir = opendir(".");
if (dir == NULL) {
perror("opendir");
return;
printf("Files created in month %d:\n", month);
// Read entries in the directory
while ((entry = readdir(dir)) != NULL) {
// Get file status
if (stat(entry->d_name, &fileStat) == 0) {
// Get the modification time
timeinfo = localtime(&fileStat.st_mtime);
// Check if the month matches
if (timeinfo->tm_mon + 1 == month) { // tm_mon is 0-based (0 = January)
printf("%s\n", entry->d_name);
// Close the directory
closedir(dir);
int main(int argc, char *argv[]) {
// Check if a month is provided
if (argc != 2) {
fprintf(stderr, "Usage: %s <month_number>\n", argv[0]);
return EXIT_FAILURE;
int month = atoi(argv[1]);
// Validate month input
if (month < 1 || month > 12) {
fprintf(stderr, "Please enter a valid month number (1-12).\n");
return EXIT_FAILURE;
display_files_in_month(month);
return EXIT_SUCCESS;
10. Display all the files from current directory whose size is greater that n Bytes Where n is accept
from user.
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
void display_large_files(off_t size_limit) {
DIR *dir;
struct dirent *entry;
struct stat fileStat;
// Open the current directory
dir = opendir(".");
if (dir == NULL) {
perror("opendir");
return;
printf("Files larger than %ld bytes:\n", size_limit);
// Read entries in the directory
while ((entry = readdir(dir)) != NULL) {
// Get file status
if (stat(entry->d_name, &fileStat) == 0) {
// Check if the size is greater than the specified limit
if (fileStat.st_size > size_limit) {
printf("%s (%ld bytes)\n", entry->d_name, fileStat.st_size);
// Close the directory
closedir(dir);
int main() {
long size_limit;
// Prompt user for the size limit
printf("Enter the size limit in bytes: ");
if (scanf("%ld", &size_limit) != 1) {
fprintf(stderr, "Invalid input. Please enter a valid number.\n");
return EXIT_FAILURE;
display_large_files(size_limit);
return EXIT_SUCCESS;
11
. Write a C Program that demonstrates redirection of standard output to a file.
#include <stdio.h>
#include <stdlib.h>
int main() {
// Open a file in write mode and redirect stdout to this file
FILE *file = freopen("output.txt", "w", stdout);
// Check if the file was opened successfully
if (file == NULL) {
perror("Error opening file");
return EXIT_FAILURE;
// Now, anything printed using printf will go to output.txt
printf("This output will be redirected to the file 'output.txt'.\n");
printf("You can write multiple lines to the file using printf.\n");
// Close the file and restore stdout
fclose(file);
// Optionally, restore stdout to the terminal (not necessary here, but good practice)
freopen("/dev/tty", "w", stdout); // For Unix/Linux
// freopen("CON", "w", stdout); // For Windows
printf("Standard output has been restored to the terminal.\n");
return EXIT_SUCCESS;
}
12. Write a C program that will only list all subdirectories in alphabetical order from current directory
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#define MAX_DIRS 1024
int compare(const void *a, const void *b) {
return strcmp(*(const char **)a, *(const char **)b);
int main() {
DIR *dir;
struct dirent *entry;
char *subdirs[MAX_DIRS];
int count = 0;
// Open the current directory
dir = opendir(".");
if (dir == NULL) {
perror("opendir");
return EXIT_FAILURE;
}
// Read entries in the directory
while ((entry = readdir(dir)) != NULL) {
// Check if the entry is a directory
if (entry->d_type == DT_DIR) {
// Ignore the current and parent directory entries
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
// Allocate memory for the directory name and store it
subdirs[count] = malloc(strlen(entry->d_name) + 1);
if (subdirs[count] == NULL) {
perror("malloc");
closedir(dir);
return EXIT_FAILURE;
strcpy(subdirs[count], entry->d_name);
count++;
// Close the directory
closedir(dir);
// Sort the subdirectory names alphabetically
qsort(subdirs, count, sizeof(char *), compare);
// Print the sorted subdirectory names
printf("Subdirectories in alphabetical order:\n");
for (int i = 0; i < count; i++) {
printf("%s\n", subdirs[i]);
free(subdirs[i]); // Free the allocated memory
return EXIT_SUCCESS;
IMP= MAX_DIRS is defined to limit the number of subdirectories that can be stored
qsort() function is used to sort the array
14. Write a C program to Identify the type (Directory, character device, Block device, Regular file,
FIFO or pipe, symbolic link or socket) of given file using stat() system call.
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
void print_file_type(mode_t mode) {
if (S_ISREG(mode)) {
printf("Regular file\n");
} else if (S_ISDIR(mode)) {
printf("Directory\n");
} else if (S_ISCHR(mode)) {
printf("Character device\n");
} else if (S_ISBLK(mode)) {
printf("Block device\n");
} else if (S_ISFIFO(mode)) {
printf("FIFO or pipe\n");
} else if (S_ISLNK(mode)) {
printf("Symbolic link\n");
} else if (S_ISSOCK(mode)) {
printf("Socket\n");
} else {
printf("Unknown file type\n");
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <file_name>\n", argv[0]);
return EXIT_FAILURE;
struct stat fileStat;
// Get file status
if (stat(argv[1], &fileStat) < 0) {
perror("stat");
return EXIT_FAILURE;
}
// Print file type
printf("File: %s\n", argv[1]);
print_file_type(fileStat.st_mode);
return EXIT_SUCCESS;
IMP stat() system call, which retrieves information about the file
15. Generate parent process to write unnamed pipe and will read from it
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUFFER_SIZE 100
int main() {
int pipefd[2]; // Array to hold the read and write file descriptors
pid_t pid;
char buffer[BUFFER_SIZE];
// Create the pipe
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
// Create a child process
pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
if (pid > 0) { // Parent process
close(pipefd[0]); // Close the read end of the pipe
const char *message = "Hello from the parent process!";
write(pipefd[1], message, strlen(message) + 1); // Write to the pipe
close(pipefd[1]); // Close the write end after writing
printf("Parent: Sent message to child process.\n");
} else { // Child process
close(pipefd[1]); // Close the write end of the pipe
// Read from the pipe
read(pipefd[0], buffer, BUFFER_SIZE);
close(pipefd[0]); // Close the read end after reading
printf("Child: Received message: %s\n", buffer);
return EXIT_SUCCESS;
IMP
} An unnamed pipe is created using the pipe() system call, which populates the pipefd array
with two file descriptors: pipefd[0] for reading and pipefd[1] for writing.
fork() system call is used to create a new process.
17. Demonstrate the use of atexit() function.
#include <stdio.h>
#include <stdlib.h>
// Function to be called at exit
void cleanup1() {
printf("Cleanup function 1 called.\n");
void cleanup2() {
printf("Cleanup function 2 called.\n");
void cleanup3() {
printf("Cleanup function 3 called.\n");
int main() {
// Register cleanup functions
atexit(cleanup1);
atexit(cleanup2);
atexit(cleanup3);
printf("Main function is executing.\n");
// You can also simulate an exit with a return statement
// return 0; // Uncommenting this will call the cleanup functions
// Alternatively, you can exit with an exit status
exit(0); // This will trigger the cleanup functions
// Note: Any code after exit() will not be executed
IMP
Three cleanup functions (cleanup1, cleanup2, cleanup3) are defined.
The atexit() function is called to register each cleanup FUNCTION
18.Write a C program to demonstrates the different behaviour that can be seen with automatic,
global, register, static and volatile variables (Use setjmp() and longjmp() system call).
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
jmp_buf buffer;
// Global variable
int global_var = 0;
// Function to demonstrate variable behaviors
void test_variables() {
// Automatic variable
int auto_var = 0;
// Register variable
register int reg_var = 0;
// Static variable
static int static_var = 0;
// Volatile variable
volatile int volatile_var = 0;
// Incrementing variables
global_var++;
auto_var++;
reg_var++;
static_var++;
volatile_var++;
printf("In test_variables():\n");
printf("Global variable: %d\n", global_var);
printf("Automatic variable: %d\n", auto_var);
printf("Register variable: %d\n", reg_var);
printf("Static variable: %d\n", static_var);
printf("Volatile variable: %d\n", volatile_var);
// Long jump back to where setjmp was called
longjmp(buffer, 1);
int main() {
if (setjmp(buffer) != 0) {
// This code runs after longjmp is called
printf("Returned to main after longjmp.\n");
printf("Global variable after longjmp: %d\n", global_var);
return 0; // Exit the program
// Call the function
test_variables();
return 0; // This will never be reached due to longjmp
IMP auto_var is defined within the function and is automatically allocated on the stack
reg_var is also defined within the function and is suggested to be stored in a register for faster access
static_var is defined as static, meaning it retains its value between function calls.
volatile_var is defined as volatile, indicating that it may be changed unexpectedly
1. longjmp(buffer, 1), which jumps back to the point .
setjmp() was called in the main() function.
2. Global Variable: Retains its value across function calls and is accessible
throughout the program.
3. Automatic Variable: Resets to its initial value each time the function is called.
4. Register Variable: Similar to automatic variables but may be stored in a
register (compiler-dependent).
5. Static Variable: Retains its value between function calls.
6. Volatile Variable: Indicates to the compiler that the variable can change
unexpectedly, preventing optimization on it.
19.Implement the following unix/linux command (use fork, pipe and exec system call) ls –l | wc –l
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
int pipefd[2]; // Array to hold the read and write file descriptors
pid_t pid1, pid2;
// Create a pipe
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
// Fork the first child process for 'ls -l'
pid1 = fork();
if (pid1 == -1) {
perror("fork");
exit(EXIT_FAILURE);
if (pid1 == 0) { // Child process 1
// Close the read end of the pipe
close(pipefd[0]);
// Redirect stdout to the write end of the pipe
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]); // Close the original write end
// Execute 'ls -l'
execlp("ls", "ls", "-l", NULL);
// If execlp fails
perror("execlp");
exit(EXIT_FAILURE);
// Fork the second child process for 'wc -l'
pid2 = fork();
if (pid2 == -1) {
perror("fork");
exit(EXIT_FAILURE);
if (pid2 == 0) { // Child process 2
// Close the write end of the pipe
close(pipefd[1]);
// Redirect stdin to the read end of the pipe
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[0]); // Close the original read end
// Execute 'wc -l'
execlp("wc", "wc", "-l", NULL);
// If execlp fails
perror("execlp");
exit(EXIT_FAILURE);
// Parent process closes both ends of the pipe
close(pipefd[0]);
close(pipefd[1]);
// Wait for both child processes to finish
wait(NULL); // Wait for the first child
wait(NULL); // Wait for the second child
return 0;
IMP The execlp() function is called to execute the ls -l command.
20.Write a C program to create „n‟ child processes. When all „n‟ child processes terminates, Display
total cumulative time children spent in user and kernel mode.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/times.h>
#include <sys/wait.h>
#include <time.h>
int main() {
int n, i;
printf("Enter the number of child processes to create: ");
scanf("%d", &n);
pid_t pids[n];
struct tms start_times[n], end_times[n];
clock_t start_clock, end_clock;
// Create n child processes
for (i = 0; i < n; i++) {
pids[i] = fork();
if (pids[i] < 0) {
perror("fork");
exit(EXIT_FAILURE);
} else if (pids[i] == 0) {
// Child process
// Simulate some work
sleep(1); // Simulate some processing time
exit(0); // Exit child process
// Parent process: Wait for all child processes to terminate
for (i = 0; i < n; i++) {
waitpid(pids[i], NULL, 0);
// Get the cumulative time spent in user and kernel mode
for (i = 0; i < n; i++) {
// Get the times for each child process
times(&end_times[i]);
// The child process times are not directly accessible,
// so we will just use the parent process times for demonstration
// Calculate the total time spent
clock_t total_user_time = 0;
clock_t total_system_time = 0;
// Get the times of the parent process
struct tms parent_times;
times(&parent_times);
total_user_time = parent_times.tms_utime; // User time
total_system_time = parent_times.tms_stime; // System time
printf("Total cumulative time spent in user mode: %ld clock ticks\n", total_user_time);
printf("Total cumulative time spent in kernel mode: %ld clock ticks\n", total_system_time);
return 0;
IMP parent process waits for all child processes to terminate using waitpid()
The user time (tms_utime) and system time (tms_stime) are printed
22.Write a C program to get and set the resource limits such as files, memory associated with a
process
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <unistd.h>
void print_limits(const char *description, struct rlimit *limit) {
printf("%s:\n", description);
printf(" Soft limit: %lu\n", limit->rlim_cur);
printf(" Hard limit: %lu\n", limit->rlim_max);
int main() {
struct rlimit limit;
// Get current limits for the maximum number of open files
if (getrlimit(RLIMIT_NOFILE, &limit) == 0) {
print_limits("Current limits for open files", &limit);
} else {
perror("getrlimit");
exit(EXIT_FAILURE);
// Set new limits for the maximum number of open files
limit.rlim_cur = 1024; // Set soft limit to 1024
limit.rlim_max = 2048; // Set hard limit to 2048
if (setrlimit(RLIMIT_NOFILE, &limit) == 0) {
printf("Successfully set new limits for open files.\n");
} else {
perror("setrlimit");
exit(EXIT_FAILURE);
// Get and print the updated limits for open files
if (getrlimit(RLIMIT_NOFILE, &limit) == 0) {
print_limits("Updated limits for open files", &limit);
} else {
perror("getrlimit");
exit(EXIT_FAILURE);
// Get current limits for the maximum virtual memory size
if (getrlimit(RLIMIT_AS, &limit) == 0) {
print_limits("Current limits for virtual memory size", &limit);
} else {
perror("getrlimit");
exit(EXIT_FAILURE);
}
// Set new limits for the maximum virtual memory size
limit.rlim_cur = 1024 * 1024 * 1024; // Set soft limit to 1 GB
limit.rlim_max = 2 * 1024 * 1024 * 1024; // Set hard limit to 2 GB
if (setrlimit(RLIMIT_AS, &limit) == 0) {
printf("Successfully set new limits for virtual memory size.\n");
} else {
perror("setrlimit");
exit(EXIT_FAILURE);
// Get and print the updated limits for virtual memory size
if (getrlimit(RLIMIT_AS, &limit) == 0) {
print_limits("Updated limits for virtual memory size", &limit);
} else {
perror("getrlimit");
exit(EXIT_FAILURE);
return 0;
IMP print_limits is defined to print the soft and hard limits of the specified resource.
23.Write a program that illustrates how to execute two commands concurrently with a pipe.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
int pipefd[2]; // Array to hold the read and write file descriptors
pid_t pid1, pid2;
// Create a pipe
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
// Fork the first child process for 'ls'
pid1 = fork();
if (pid1 == -1) {
perror("fork");
exit(EXIT_FAILURE);
if (pid1 == 0) { // Child process 1
// Close the read end of the pipe
close(pipefd[0]);
// Redirect stdout to the write end of the pipe
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]); // Close the original write end
// Execute 'ls'
execlp("ls", "ls", NULL);
// If execlp fails
perror("execlp");
exit(EXIT_FAILURE);
// Fork the second child process for 'grep'
pid2 = fork();
if (pid2 == -1) {
perror("fork");
exit(EXIT_FAILURE);
if (pid2 == 0) { // Child process 2
// Close the write end of the pipe
close(pipefd[1]);
// Redirect stdin to the read end of the pipe
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[0]); // Close the original read end
// Execute 'grep a'
execlp("grep", "grep", "a", NULL);
// If execlp fails
perror("execlp");
exit(EXIT_FAILURE);
// Parent process closes both ends of the pipe
close(pipefd[0]);
close(pipefd[1]);
// Wait for both child processes to finish
wait(NULL); // Wait for the first child
wait(NULL); // Wait for the second child
return 0;
}
24.Write a C program that print the exit status of a terminated child process
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
pid_t pid;
int status;
// Create a child process
pid = fork();
if (pid < 0) {
// Fork failed
perror("fork");
exit(EXIT_FAILURE);
if (pid == 0) {
// Child process
printf("Child process (PID: %d) is running...\n", getpid());
// Simulate some work in the child process
sleep(2); // Sleep for 2 seconds
// Exit with a specific status code
exit(42); // Child exits with status code 42
} else {
// Parent process
printf("Parent process (PID: %d) waiting for child to terminate...\n", getpid());
// Wait for the child process to terminate
waitpid(pid, &status, 0);
// Check if the child terminated normally
if (WIFEXITED(status)) {
// Get the exit status
int exit_status = WEXITSTATUS(status);
printf("Child process terminated with exit status: %d\n", exit_status);
} else {
printf("Child process did not terminate normally.\n");
return 0;
}
25.Write a C program that catches the ctrl-c (SIGINT) signal for the first time and display the
appropriate message and exits on pressing ctrl-c again.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
// Signal handler function
void sigint_handler(int signum) {
// Display a message only for the first time SIGINT is received
if (signum == SIGINT && flag == 0) {
printf("\nReceived SIGINT (Ctrl+C). Press Ctrl+C again to exit.\n");
fflush(stdout); // Make sure the message is printed immediately
flag = 1;
int flag = 0; // Global flag to track if SIGINT has been received
int main() {
// Set the signal handler for SIGINT
signal(SIGINT, sigint_handler);
printf("Press Ctrl+C to see the message and exit.\n");
while (1){
// Keep the main process running in an infinite loop
pause(); // Pause the main process and wait for a signal
return 0;
IMP sigint_handler function is defined to handle the SIGINT signal
1.
flag variable is a global variable that tracks whether SIGINT has been received for the
first time.
2. The fflush(stdout) function is used to ensure that the message is printed
immediately when SIGINT is received.
26.Write a C program which creates a child process and child process catches a signal SIGHUP,
SIGINT and SIGQUIT. The Parent process send a SIGHUP or SIGINT signal after every 3 seconds, at
the end of 15 second parent send SIGQUIT signal to child and child terminates by displaying
message "My Papa has Killed me!!!”.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
void sighup_handler(int signum) {
printf("Child: Received SIGHUP signal.\n");
void sigint_handler(int signum) {
printf("Child: Received SIGINT signal.\n");
void sigquit_handler(int signum) {
printf("Child: My Papa has Killed me!!!\n");
exit(0); // Terminate the child process
int main() {
pid_t pid = fork(); // Create a child process
if (pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
if (pid == 0) { // Child process
// Set up signal handlers
signal(SIGHUP, sighup_handler);
signal(SIGINT, sigint_handler);
signal(SIGQUIT, sigquit_handler);
// Keep the child process running
while (1) {
pause(); // Wait for signals
} else { // Parent process
// Send SIGHUP or SIGINT every 3 seconds
for (int i = 0; i < 5; i++) {
if (i % 2 == 0) {
kill(pid, SIGHUP); // Send SIGHUP
} else {
kill(pid, SIGINT); // Send SIGINT
sleep(3); // Wait for 3 seconds
// After 15 seconds, send SIGQUIT
sleep(3); // Wait for an additional 3 seconds
kill(pid, SIGQUIT); // Send SIGQUIT to child
// Optionally wait for the child to terminate
wait(NULL);
return 0;
IMP
27.Write a C program to send SIGALRM signal by child process to parent process and parent
process make a provision to catch the signal and display alarm is fired.(Use Kill, fork, signal and
sleep system call)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
// Signal handler for SIGALRM
void sigalrm_handler(int signum) {
printf("Parent: Alarm is fired!\n");
int main() {
pid_t pid;
// Create a child process
pid = fork();
if (pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
if (pid == 0) { // Child process
// Sleep for 5 seconds
sleep(5);
// Send SIGALRM signal to the parent process
kill(getppid(), SIGALRM);
exit(0); // Terminate the child process
} else { // Parent process
// Set up the signal handler for SIGALRM
signal(SIGALRM, sigalrm_handler);
printf("Parent: Waiting for the alarm signal...\n");
// Wait for the child process to finish
wait(NULL);
return 0;
}
28. Write a C program that illustrates suspending and resuming processes using signals.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <wait.h>
// Function to handle SIGUSR1 signal for suspending the process
void suspend_handler(int signum) {
printf("Process %d: Received SIGUSR1, suspending...\n", getpid());
// Suspend the process
raise(SIGSTOP);
// Function to handle SIGUSR2 signal for resuming the process
void resume_handler(int signum) {
printf("Process %d: Received SIGUSR2, resuming...\n", getpid());
int main() {
pid_t pid;
// Create a child process
pid = fork();
if (pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
if (pid == 0) { // Child process
// Set up signal handlers
signal(SIGUSR1, suspend_handler);
signal(SIGUSR2, resume_handler);
printf("Child Process %d: Running...\n", getpid());
while (1) {
// Child process does some work
printf("Child Process %d: Working...\n", getpid());
sleep(2); // Simulate work by sleeping
} else { // Parent process
sleep(5); // Let the child run for a while
// Send SIGUSR1 to suspend the child process
printf("Parent Process %d: Sending SIGUSR1 to suspend child...\n", getpid());
kill(pid, SIGUSR1);
sleep(5); // Wait for 5 seconds while the child is suspended
// Send SIGUSR2 to resume the child process
printf("Parent Process %d: Sending SIGUSR2 to resume child...\n", getpid());
kill(pid, SIGUSR2);
sleep(5); // Let the child run again
// Terminate the child process
printf("Parent Process %d: Terminating child...\n", getpid());
kill(pid, SIGTERM);
wait(NULL); // Wait for the child to terminate
return 0;
IMP SIGSTOP signal to suspend a process and the SIGCONT signal to resume it
SIGUSR1 signal, which is used to suspend the child process.
SIGUSR2 signal, which is used to indicate that the child should resume its execution.
29.Write a C program which create a child process which catch a signal sighup, sigint and sigquit.
The Parent process send a sighup or sigint signal after every 3 seconds, at the end of 30 second
parent send sigquit signal to child and child terminates my displaying message “My DADDY has
Killed me!!!”.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
void sighup_handler(int signum) {
printf("Child: Received SIGHUP signal.\n");
void sigint_handler(int signum) {
printf("Child: Received SIGINT signal.\n");
void sigquit_handler(int signum) {
printf("Child: My DADDY has Killed me!!!\n");
exit(0); // Terminate the child process
int main() {
pid_t pid = fork(); // Create a child process
if (pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
if (pid == 0) { // Child process
// Set up signal handlers
signal(SIGHUP, sighup_handler);
signal(SIGINT, sigint_handler);
signal(SIGQUIT, sigquit_handler);
// Keep the child process running
while (1) {
pause(); // Wait for signals
} else { // Parent process
// Send SIGHUP or SIGINT every 3 seconds
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
kill(pid, SIGHUP); // Send SIGHUP
} else {
kill(pid, SIGINT); // Send SIGINT
sleep(3); // Wait for 3 seconds
// After 30 seconds, send SIGQUIT
kill(pid, SIGQUIT); // Send SIGQUIT to child
// Optionally wait for the child to terminate
wait(NULL);
return 0;
IMP
sighup_handler: Handles SIGHUP and prints a message when received.
sigint_handler: Handles SIGINT and prints a message when received.
sigquit_handler: Handles SIGQUIT, prints the termination message, and exits the child
process.
30. Write a C program to implement the following unix/linux command (use fork, pipe
and exec system call). Your program should block the signal Ctrl-C and Ctrl-\ signal
during the execution. i. Ls –l | wc –l
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
void block_signals() {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT); // Block Ctrl-C
sigaddset(&set, SIGQUIT); // Block Ctrl-\
sigprocmask(SIG_BLOCK, &set, NULL); // Apply the signal mask
void unblock_signals() {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGQUIT);
sigprocmask(SIG_UNBLOCK, &set, NULL); // Unblock the signals
}
int main() {
int pipefd[2]; // File descriptors for the pipe
pid_t pid1, pid2;
// Create the pipe
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
// Block signals
block_signals();
// Fork the first child to execute "ls -l"
pid1 = fork();
if (pid1 < 0) {
perror("fork");
exit(EXIT_FAILURE);
if (pid1 == 0) { // First child process
// Redirect stdout to the write end of the pipe
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[0]); // Close unused read end
close(pipefd[1]); // Close the write end after duplicating
// Execute "ls -l"
execlp("ls", "ls", "-l", NULL);
perror("execlp"); // If exec fails
exit(EXIT_FAILURE);
// Fork the second child to execute "wc -l"
pid2 = fork();
if (pid2 < 0) {
perror("fork");
exit(EXIT_FAILURE);
if (pid2 == 0) { // Second child process
// Redirect stdin to the read end of the pipe
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[1]); // Close unused write end
close(pipefd[0]); // Close the read end after duplicating
// Execute "wc -l"
execlp("wc", "wc", "-l", NULL);
perror("execlp"); // If exec fails
exit(EXIT_FAILURE);
// Parent process
close(pipefd[0]); // Close read end of the pipe
close(pipefd[1]); // Close write end of the pipe
// Wait for both child processes to finish
wait(NULL);
wait(NULL);
// Unblock signals
unblock_signals();
return 0;