CSci-E28 Section 2019-05-09 Notes

Table of Contents

1 Pipes and Dup

int p[2];       // pipe descriptors, 0 for reading, 1 for writing

if (pipe(p) < 0) {
    perror("pipe");
    exit(1);
}

// parent sending to child example

#ifdef WILL_DUP
if (dup2(p[0], 0) != 0) {
    perror("dup2");
    exit(1);
}
int readfd = 0;
#else
int readfd = p[0];
int writefd = p[1];
#endif

int pid = fork();
if (pid < 0) {
    perror("fork");
    exit(1);
}

if (pid) {
      // parent
    close(readfd);
    ssize_t nb = write(p[1], data, len);
      // error checking
} else {
    close(writefd);
    char buffer[BUFFER_SIZE];

      // exec here in the dup case

      // child
    ssize_t nb = read(readfd, buffer, sizeof(buffer));
    if (nb < 0) {
        perror("read");
        _exit(1);
    } else if  (nb > 0) {
          // read nb bytes
    } else {
          // eof, pipe was closed
    }
}

2 Sockets

Examine wsng's socklib.c for more details.

int domain = PF_INET,    // IP version 4 OR
    PF_LOCAL,            // PF_UNIX OR
    PF_INET6;            // IP version 6

int type = SOCK_STREAM, // TCP for INET (reliable byte-stream) OR
    SOCK_DGRAM,         // UDP for INET (unreliable datagram) OR
    SOCK_SEQPACKET;     // not used in INET

int protocol = 0;       // or use p_proto field of getprotobyname(3)\

int sock = socket(domain, type, protocol);

// in SERVER case

// optionally set socket options: reuse addr is most common
int on = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
    perror("setsockopt");
}

// bind an address
// often on a server address you set the port number but leave the incomming address INADDR_ANY
// low numbered ports in IP are reserved to root
struct sockaddr_in saddr;
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_addr.s_port = htons(YOUR_SERVERS_PORT_NUMBER_YOU_PICKED);

if (bind(sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
    perror("bind");
    exit(1);
}

// htonl converts a long from host to network byte order, htons for short. ntohl and ntohs reverse

// listen for connections
#define QUEUE_LENGTH 5 // a small number between 1 and something
if (listen(sock, QUEUE_LENGTH) < 0) {
    perror("listen");
}

// have an accept loop

// addr and addrlen can be NULL if you don't care who you are talking to
int fd = accept(sock, struct sockaddr *addr, socklen_t *addrlen);

// fd is now something you can use read/write or send/recv, for datagram sendto/recvfrom

// for STREAM types
// You need to have a real IP address for connect, which is usually looked up with
// gethostbyname.
struct sockaddr_in saddr;
memset(&saddr, 0, sizeof(saddr));
addr.sin_family = AF_INET;
saddr.sin_port = htons(YOUR_SERVERS_PORT_NUMBER_YOU_PICKED);

struct hostent *hp = gethostbyname(NAME_OF_SERVER_HOST);
if (hp == NULL) {
    fprintf(stderr, "unknown host name '%s'", NAME_OF_SERVER_HOST);
    exit(1);
}
memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length);

// do connect
if (connect(sock, (const struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
    perror("connect");
    exit(1);
}

// sock is now something you can read/write or send/recv, for datagram sendto/recvfrom

3 Shell Redirection Syntax

my_program >foo
my_program 1>foo
my_program <bar
my_program 0<bar

program 2>&1
program n>&-

for x in a b c
do
    echo foo $x
done >file
{ echo a; echo b; } >file

Author: Alexis Layton

Created: 2019-05-09 Thu 21:34

Validate