Wednesday, February 27, 2013

System Programming

I see! Linux system programming involves writing code that interacts closely with the Linux operating system. Here are some small examples of Linux system programming concepts:

System Calls:

Opening and Reading a File (C):


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
int main() {
    int fd = open("my_file.txt", O_RDONLY);
    if (fd == -1) {
        perror("open");
        exit(1);
    }
    char buffer[1024];
    ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
    if (bytes_read == -1) {
        perror("read");
        exit(1);
    }
    printf("Read from file: %s\\n", buffer);
    close(fd);
    return 0;
}

Processes and Forking:

Creating a Child Process (C):


#include <stdio.h>
#include <unistd.h>
int main() {
    pid_t child_pid = fork();
    if (child_pid == -1) {
        perror("fork");
        return 1;
    }
    if (child_pid == 0) {
        printf("This is the child process.\\n");
    } else {
        printf("This is the parent process.\\n");
    }
    return 0;
}

Signals:

Handling Signals (C):


#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void sigint_handler(int signum) {
    printf("Received SIGINT (Ctrl+C)\\n");
    exit(1);
}
int main() {
    signal(SIGINT, sigint_handler);
    printf("Waiting for SIGINT...\\n");
    while (1) {
        // Do nothing, waiting for SIGINT
    }
    return 0;
}

File I/O and System Calls:

Using read() and write() System Calls (C):


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
    int fd = open("my_file.txt", O_WRONLY | O_CREAT, 0644);
    if (fd == -1) {
        perror("open");
        exit(1);
    }
    char data[] = "Hello, Linux System Programming!";
    ssize_t bytes_written = write(fd, data, sizeof(data));
    if (bytes_written == -1) {
        perror("write");
        exit(1);
    }
    close(fd);
    return 0;
}

These examples illustrate some key concepts in Linux system programming, including system calls, processes, signals, and file I/O.

Inter-Process Communication (IPC):

Here are small examples of Linux system programming concepts related to Inter-Process Communication (IPC), multithreading, and various IPC mechanisms like sockets, pipes, and message queues:

IPC with Pipes (C):

This example demonstrates communication between two processes using pipes.


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
    int pipe_fds[2];
    char buffer[20];
    if (pipe(pipe_fds) == -1) {
        perror("pipe");
        exit(1);
    }
    pid_t child_pid = fork();
    if (child_pid == -1) {
        perror("fork");
        exit(1);
    }
    if (child_pid == 0) {
        // Child process
        close(pipe_fds[1]);
        // Close write end
        read(pipe_fds[0], buffer, sizeof(buffer));
        printf("Child received: %s\\n", buffer);
        close(pipe_fds[0]);
    } else {
        // Parent process
        close(pipe_fds[0]);
        // Close read end
        const char* message = "Hello, Pipe!";
        write(pipe_fds[1], message, strlen(message) + 1);
        close(pipe_fds[1]);
    }
    return 0;
}

IPC with Message Queues (C):

This example demonstrates communication between two processes using message queues.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct message {
    long mtype;
    char mtext[100];
};
int main() {
    key_t key = ftok("/tmp", 'A');
    int msgid = msgget(key, 0666 | IPC_CREAT);
    struct message msg;
    // Send a message
    msg.mtype = 1;
    strcpy(msg.mtext, "Hello, Message Queue!");
    msgsnd(msgid, &msg, sizeof(msg), 0);
    // Receive a message
    msgrcv(msgid, &msg, sizeof(msg), 1, 0);
    printf("Received: %s\\n", msg.mtext);
    msgctl(msgid, IPC_RMID, NULL);
    return 0;
}

Multithreading (C):

This example creates two threads that run concurrently.


#include <stdio.h>
#include <pthread.h>
void* thread_function(void* arg) {
    printf("Thread ID: %ld\\n", pthread_self());
    return NULL;
}
int main() {
    pthread_t thread1, thread2;
    pthread_create(&thread1, NULL, thread_function, NULL);
    pthread_create(&thread2, NULL, thread_function, NULL);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    return 0;
}

Socket Programming (C):

This example demonstrates a simple server and client using sockets for communication. Here's an example of socket programming in C for a simple client-server communication. This example consists of two separate programs: one for the server (server.c) and one for the client (client.c). This code demonstrates how a client can send a message to the server using sockets.

server.c (Socket Server)


#include 
#include 
#include 
#include 
#include 

#define PORT 12345
#define MAX_BUFFER_SIZE 1024

int main() {
    int server_socket, new_socket;
    struct sockaddr_in server_addr, new_addr;
    socklen_t addr_size;
    char buffer[MAX_BUFFER_SIZE];

    // Create the socket
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket < 0) {
        perror("Error in socket creation");
        exit(1);
    }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = PORT;
    server_addr.sin_addr.s_addr = INADDR_ANY;

    // Bind the socket to the IP address and port
    if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("Error in binding");
        exit(1);
    }

    // Listen for incoming connections
    if (listen(server_socket, 10) == 0) {
        printf("Listening...\n");
    } else {
        perror("Error in listening");
        exit(1);
    }

    addr_size = sizeof(new_addr);
    new_socket = accept(server_socket, (struct sockaddr*)&new_addr, &addr_size); // Accept a connection

    // Receive data from the client
    recv(new_socket, buffer, MAX_BUFFER_SIZE, 0);
    printf("Received from client: %s\n", buffer);

    // Send a response to the client
    char* server_response = "Hello, client! Your message was received.";
    send(new_socket, server_response, strlen(server_response), 0);
    printf("Response sent to client.\n");

    close(new_socket);
    close(server_socket);

    return 0;
}

client.c (Socket Client)


#include 
#include 
#include 
#include 
#include 

#define PORT 12345
#define MAX_BUFFER_SIZE 1024

int main() {
    int client_socket;
    struct sockaddr_in server_addr;
    char buffer[MAX_BUFFER_SIZE];

    // Create the socket
    client_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (client_socket < 0) {
        perror("Error in socket creation");
        exit(1);
    }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = PORT;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Use the server's IP address

    // Connect to the server
    if (connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("Error in connection");
        exit(1);
    }

    // Send a message to the server
    char* client_message = "Hello, server! This is the client.";
    send(client_socket, client_message, strlen(client_message), 0);
    printf("Message sent to server.\n");

    // Receive a response from the server
    recv(client_socket, buffer, MAX_BUFFER_SIZE, 0);
    printf("Received from server: %s\n", buffer);

    close(client_socket);

    return 0;
}

In this example, the server and client communicate over the loopback address (127.0.0.1), but you can modify the client code to connect to a different server IP address as needed. To run this code, compile server.c and client.c separately using a C compiler (e.g., gcc) and run the server before the client.

For reference: 1. Linux Systems Programming by Jonathan Macey 2. Linux System Programming by Robert Love

No comments:

Post a Comment