Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Sebastien Bourdeauducq
committed
Mar 4, 2012
1 parent
8586daf
commit 29859ac
Showing
3 changed files
with
196 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
#include <assert.h> | ||
#include <sys/types.h> | ||
#include <sys/socket.h> | ||
#include <sys/un.h> | ||
#include <unistd.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <stdlib.h> | ||
|
||
#include "ipc.h" | ||
|
||
struct ipc_softc { | ||
int socket; | ||
go_handler h_go; | ||
write_handler h_write; | ||
read_handler h_read; | ||
void *user; | ||
}; | ||
|
||
struct ipc_softc *ipc_connect(const char *sockaddr, | ||
go_handler h_go, write_handler h_write, read_handler h_read, void *user) | ||
{ | ||
struct ipc_softc *sc; | ||
struct sockaddr_un addr; | ||
|
||
sc = malloc(sizeof(struct ipc_softc)); | ||
if(!sc) return NULL; | ||
|
||
sc->h_go = h_go; | ||
sc->h_write = h_write; | ||
sc->h_read = h_read; | ||
sc->user = user; | ||
|
||
sc->socket = socket(AF_UNIX, SOCK_SEQPACKET, 0); | ||
if(sc->socket < 0) { | ||
free(sc); | ||
return NULL; | ||
} | ||
|
||
addr.sun_family = AF_UNIX; | ||
strcpy(addr.sun_path, sockaddr); | ||
if(connect(sc->socket, (struct sockaddr *)&addr, sizeof(addr)) != 0) { | ||
close(sc->socket); | ||
free(sc); | ||
return NULL; | ||
} | ||
|
||
return sc; | ||
} | ||
|
||
void ipc_destroy(struct ipc_softc *sc) | ||
{ | ||
close(sc->socket); | ||
free(sc); | ||
} | ||
|
||
enum { | ||
MESSAGE_TICK = 0, | ||
MESSAGE_GO, | ||
MESSAGE_WRITE, | ||
MESSAGE_READ, | ||
MESSAGE_READ_REPLY | ||
}; | ||
|
||
#define MAX_LEN 2048 | ||
|
||
int ipc_receive(struct ipc_softc *sc) | ||
{ | ||
char buffer[MAX_LEN]; | ||
ssize_t l; | ||
int i; | ||
|
||
l = recv(sc->socket, buffer, MAX_LEN, 0); | ||
if((l <= 0) || (l >= MAX_LEN)) | ||
return 0; | ||
|
||
i = 0; | ||
switch(buffer[i++]) { | ||
case MESSAGE_GO: | ||
assert(l == 1); | ||
return sc->h_go(sc->user); | ||
case MESSAGE_WRITE: { | ||
char *name; | ||
int nchunks; | ||
unsigned char *chunks; | ||
|
||
name = &buffer[i]; | ||
i += strlen(name) + 1; | ||
assert(i < l); | ||
nchunks = buffer[i++]; | ||
assert(i + nchunks == l); | ||
chunks = (unsigned char *)&buffer[i]; | ||
|
||
return sc->h_write(name, nchunks, chunks, sc->user); | ||
} | ||
case MESSAGE_READ: { | ||
char *name; | ||
|
||
name = &buffer[i]; | ||
i += strlen(name) + 1; | ||
assert(i == l); | ||
|
||
return sc->h_read(name, sc->user); | ||
} | ||
default: | ||
return 0; | ||
} | ||
} | ||
|
||
int ipc_tick(struct ipc_softc *sc) | ||
{ | ||
char c; | ||
ssize_t l; | ||
|
||
c = MESSAGE_TICK; | ||
l = send(sc->socket, &c, 1, 0); | ||
if(l != 1) | ||
return 0; | ||
return 1; | ||
} | ||
|
||
int ipc_read_reply(struct ipc_softc *sc, int nchunks, const unsigned char *chunks) | ||
{ | ||
int len; | ||
char buffer[MAX_LEN]; | ||
ssize_t l; | ||
|
||
len = nchunks + 2; | ||
assert(len < MAX_LEN); | ||
assert(nchunks < 256); | ||
|
||
buffer[0] = MESSAGE_READ_REPLY; | ||
buffer[1] = nchunks; | ||
memcpy(&buffer[2], chunks, nchunks); | ||
|
||
l = send(sc->socket, buffer, len, 0); | ||
if(l != len) | ||
return 0; | ||
return 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#ifndef __IPC_H | ||
#define __IPC_H | ||
|
||
struct ipc_softc; | ||
|
||
typedef int(*go_handler)(void *); | ||
typedef int(*write_handler)(char *, int, const unsigned char *, void *); | ||
typedef int(*read_handler)(char *, void *); | ||
|
||
struct ipc_softc *ipc_connect(const char *sockaddr, | ||
go_handler h_go, write_handler h_write, read_handler h_read, void *user); | ||
void ipc_destroy(struct ipc_softc *sc); | ||
|
||
int ipc_receive(struct ipc_softc *sc); | ||
|
||
int ipc_tick(struct ipc_softc *sc); | ||
int ipc_read_reply(struct ipc_softc *sc, int nchunks, const unsigned char *value); | ||
|
||
#endif /* __IPC_H */ |