Mac OS X Tiger & 64-Bits
by Rodney Mach

Listing One

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <inttypes.h>
#include <unistd.h>
#include "absoft.h"

int main(int argc, char *argv[])
{
    int listenfd,/* listen socket descriptor        */
    clientfd,    /* socket descriptor from connect  */
    i;
    int32_t x;   /* array index from the client */
    uint64_t result;  /* result sent to client */
    static uint64_t  bigarray_[ARRAY_SIZE];
    socklen_t clientlen;
    struct sockaddr_un server, client;
    /* Initialize array with random values */
    for ( i = 0 ; i < ARRAY_SIZE ; i++ ) {
        bigarray_[i] = 10000000000000000000ULL + i;
    }
    /* AF_LOCAL is Unix Domain Socket */
    if ((listenfd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) {
        perror("socket");
        exit(1);
    }
    /* Setup socket info */
    bzero((char *) &server, sizeof(server));
    server.sun_family = AF_LOCAL;
    strncpy(server.sun_path, SOCK_ADDR, sizeof(server.sun_path));

    /* Unlink file to make sure bind succeeds. Ignore error */
    unlink(SOCK_ADDR);

    /* Bind to socket */
    if (bind(listenfd, (struct sockaddr *)&server, sizeof(server)) < 0 ) {
        perror("bind");
        exit(2);
    }
    /* Listen on socket */
    if (listen(listenfd, LISTENQ) < 0 ) {
        perror("listen");
        exit(3);
    }
    for(;;) {
        printf("Waiting for a connection...\n");
        clientlen = sizeof(client);
        if ((clientfd = accept(listenfd, (struct sockaddr *)&client, &clientlen)) < 0) {
            perror("accept");
            exit(4);
        }
        /* Read the array index UI has requested */
        readn(clientfd, &x, sizeof(x));
        printf("Read in request for array element %d\n", x);
        if ( x > ARRAY_SIZE || x < 0 ) {
            /* Error */
            result = 0;
        } else {
            result = bigarray_[x];
        }
        /* Print specifier for unsigned 64-bit integer*/
        printf ("Server sending back to client: %llu\n", result);
        if (writen(clientfd, &result, sizeof(result))  < 0 ) {
            exit(5);
        }
        close(clientfd);
    }
    exit(0);
}


Listing Two

 1 #ifndef ABSOFT_H
 2 #define ABSOFT_H
 3 #include <stdint.h>
 4 #include <stdlib.h>
 5 #define SOCK_ADDR "/tmp/sock"
 6 #define LISTENQ 5
 7 /* When compiled as 64-bit, use larger array
 8  * (for demo the size is just 1 larger then 32-bit
 9  */
10 #ifdef __LP64__
11 #define ARRAY_SIZE 1001
12 #else
13 #define ARRAY_SIZE 1000
14 #endif /* __LP64__ */
15 /* Protos */
16 ssize_t readn(int fd, void *vptr, size_t n);
17 ssize_t writen(int fd, const void *vptr, size_t n);
18 uint64_t lookupValue(int32_t x);
19 #endif

Listing Three

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <errno.h>
 4 #include <string.h>
 5 #include <sys/types.h>
 6 #include <sys/socket.h>
 7 #include <sys/un.h>
 8 #include <sys/uio.h>
 9 #include <sys/fcntl.h>
10 #include <inttypes.h>
11 #include <stdint.h>
12 #include <unistd.h>
13 #include "absoft.h"
14 /* Lookup array value at index x
15  * by connecting to unix domain socket
16  */
17 uint64_t lookupValue(int32_t x)
18 {
19     int s;
20     struct sockaddr_un remote;
21     uint64_t result;
22     if ((s = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0 ) {
23         perror("socket");
24         return(0);
25     }
26     bzero(&remote, sizeof(remote));
27     printf("Trying to connect...\n");
28     remote.sun_family = AF_LOCAL;
29     strcpy(remote.sun_path, SOCK_ADDR);
30     if (connect(s, (struct sockaddr *)&remote, sizeof(remote)) < 0) {
31         perror("connect");
32         return(0);
33     }
34     printf("Connected and sending %d\n", x);
35     if (writen(s, &x, sizeof(x)) < 0 ) {
36         perror("send");
37         return(0);
38     }
39     readn(s, &result, sizeof(result));
40     printf ("Client received result from server = %llu\n", result);
41     close(s);
42     return  result;
43 }


Listing Four

 1 #include "FetchDataThread.h"
 2 FetchDataThread::FetchDataThread(QObject *parent)
 3         : QThread(parent)
 4 {
 5 }
 6 FetchDataThread::~FetchDataThread()
 7 {
 8     cond.wakeOne();
 9     wait();
10 }
11 void FetchDataThread::fetchData(const int32_t x)
12 {
13     // Hold mutex until function exits
14     QMutexLocker locker(&mutex);
15     this->x = x;
16     if (!isRunning())
17         start();
18     else
19         cond.wakeOne();
20 }
21 void FetchDataThread::run()
22 {
23     QMutexLocker locker(&mutex);
24     int32_t xv = x;
25     // This is the call that blocks
26     uint64_t result = lookupValue(xv);
27     /* Minimal error checking. Returns 0 if error */
28     if ( result == 0  ) {
29         emit errorOccured("Error looking up value");
30         return;
31     } else {
32         QString str;
33         emit fetchedData( str.setNum(result) );
34     }
35 }

Listing Five

CFLAGS= -Wall -Wformat -Wmissing-prototypes -Wconversion 
                                    -Wsign-compare -Wpointer-arith
      all: server
      server32: util.c server.c
          gcc $(CFLAGS) -m32 util.c server.c -o server32
      server64: util.c server.c
          gcc $(CFLAGS) -m64 util.c server.c -o server64
      server: server32 server64
          lipo -create server32 server64 -output server
      clean:
          rm -rf server32 server64 server 

Listing Six

# Use The Qt utility "qmake" to build
# a Makefile from this file
TEMPLATE = app 
CONFIG += qt  release 
TARGET += 
DEPENDPATH += .
INCLUDEPATH += .
DEFINES += DIVORCE_UI
HEADERS += Viewer.h
HEADERS += absoft.h 
HEADERS += FetchDataThread.h
SOURCES += client.c
SOURCES += util.c
SOURCES += Viewer.cpp
SOURCES += FetchDataThread.cpp 



4


