Add os.c and "os.h", replacing mkdirs.c

The new header "os.h" defines a supplemental API around existing basic
operating system services (system calls and standard library functions).

Moved some function prototypes from serval.h and net.h into os.h.

This allows non-servald executables to take advantage of this API without
having to include serval.h and bringing in all the other servald link-time
baggage.
This commit is contained in:
Andrew Bettison 2012-12-04 10:12:35 +10:30
parent 5139d8d34d
commit d3c2205d44
9 changed files with 131 additions and 96 deletions

View File

@ -19,7 +19,7 @@ SRCS= $(NACL_SOURCES) $(SERVAL_SOURCES)
MONITORCLIENTSRCS=conf.c \
log.c \
mkdir.c \
os.c \
mem.c \
monitor-client.c \
net.c \
@ -29,7 +29,7 @@ MONITORCLIENTSRCS=conf.c \
MDPCLIENTSRCS=conf.c \
dataformats.c \
mkdir.c \
os.c \
mem.c \
log.c \
mdp_client.c \

View File

@ -7,6 +7,7 @@ HDRS= fifo.h \
serval.h \
str.h \
mem.h \
os.h \
strbuf.h \
strbuf_helpers.h \
sha2.h \

60
net.c
View File

@ -173,63 +173,3 @@ ssize_t recvwithttl(int sock,unsigned char *buffer, size_t bufferlen,int *ttl,
return len;
}
int urandombytes(unsigned char *x, unsigned long long xlen)
{
static int urandomfd = -1;
int tries = 0;
if (urandomfd == -1) {
for (tries = 0; tries < 4; ++tries) {
urandomfd = open("/dev/urandom",O_RDONLY);
if (urandomfd != -1) break;
sleep(1);
}
if (urandomfd == -1) {
WHY_perror("open(/dev/urandom)");
return -1;
}
}
tries = 0;
while (xlen > 0) {
int i = (xlen < 1048576) ? xlen : 1048576;
i = read(urandomfd, x, i);
if (i == -1) {
if (++tries > 4) {
WHY_perror("read(/dev/urandom)");
return -1;
}
sleep(1);
} else {
tries = 0;
x += i;
xlen -= i;
}
}
return 0;
}
time_ms_t gettime_ms()
{
struct timeval nowtv;
// If gettimeofday() fails or returns an invalid value, all else is lost!
if (gettimeofday(&nowtv, NULL) == -1)
FATAL_perror("gettimeofday");
if (nowtv.tv_sec < 0 || nowtv.tv_usec < 0 || nowtv.tv_usec >= 1000000)
FATALF("gettimeofday returned tv_sec=%ld tv_usec=%ld", nowtv.tv_sec, nowtv.tv_usec);
return nowtv.tv_sec * 1000LL + nowtv.tv_usec / 1000;
}
// Returns sleep time remaining.
time_ms_t sleep_ms(time_ms_t milliseconds)
{
if (milliseconds <= 0)
return 0;
struct timespec delay;
struct timespec remain;
delay.tv_sec = milliseconds / 1000;
delay.tv_nsec = (milliseconds % 1000) * 1000000;
if (nanosleep(&delay, &remain) == -1 && errno != EINTR)
FATALF_perror("nanosleep(tv_sec=%ld, tv_nsec=%ld)", delay.tv_sec, delay.tv_nsec);
return remain.tv_sec * 1000 + remain.tv_nsec / 1000000;
}

2
net.h
View File

@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define __SERVALD_NET_H
#include <sys/types.h> // for size_t, ssize_t
#include <sys/socket.h> // for struct sockaddr, socklen_t
#include "log.h" // for __WHENCE__ and struct __sourceloc
#define set_nonblock(fd) (_set_nonblock(fd, __WHENCE__))
@ -39,5 +40,6 @@ ssize_t _write_nonblock(int fd, const void *buf, size_t len, struct __sourceloc
ssize_t _write_all_nonblock(int fd, const void *buf, size_t len, struct __sourceloc __whence);
ssize_t _write_str(int fd, const char *str, struct __sourceloc __whence);
ssize_t _write_str_nonblock(int fd, const char *str, struct __sourceloc __whence);
ssize_t recvwithttl(int sock, unsigned char *buffer, size_t bufferlen, int *ttl, struct sockaddr *recvaddr, socklen_t *recvaddrlen);
#endif // __SERVALD_NET_H

View File

@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <sys/types.h>
#include <alloca.h>
#include <dirent.h>
#include <time.h>
#include "serval.h"
int mkdirs(const char *path, mode_t mode)
@ -62,3 +63,61 @@ int mkdirsn(const char *path, size_t len, mode_t mode)
return WHYF("cannot mkdir %s", pathfrag);
}
int urandombytes(unsigned char *buf, unsigned long long len)
{
static int urandomfd = -1;
int tries = 0;
if (urandomfd == -1) {
for (tries = 0; tries < 4; ++tries) {
urandomfd = open("/dev/urandom",O_RDONLY);
if (urandomfd != -1) break;
sleep(1);
}
if (urandomfd == -1) {
WHY_perror("open(/dev/urandom)");
return -1;
}
}
tries = 0;
while (len > 0) {
int i = (len < 1048576) ? len : 1048576;
i = read(urandomfd, buf, i);
if (i == -1) {
if (++tries > 4) {
WHY_perror("read(/dev/urandom)");
return -1;
}
sleep(1);
} else {
tries = 0;
buf += i;
len -= i;
}
}
return 0;
}
time_ms_t gettime_ms()
{
struct timeval nowtv;
// If gettimeofday() fails or returns an invalid value, all else is lost!
if (gettimeofday(&nowtv, NULL) == -1)
FATAL_perror("gettimeofday");
if (nowtv.tv_sec < 0 || nowtv.tv_usec < 0 || nowtv.tv_usec >= 1000000)
FATALF("gettimeofday returned tv_sec=%ld tv_usec=%ld", nowtv.tv_sec, nowtv.tv_usec);
return nowtv.tv_sec * 1000LL + nowtv.tv_usec / 1000;
}
// Returns sleep time remaining.
time_ms_t sleep_ms(time_ms_t milliseconds)
{
if (milliseconds <= 0)
return 0;
struct timespec delay;
struct timespec remain;
delay.tv_sec = milliseconds / 1000;
delay.tv_nsec = (milliseconds % 1000) * 1000000;
if (nanosleep(&delay, &remain) == -1 && errno != EINTR)
FATALF_perror("nanosleep(tv_sec=%ld, tv_nsec=%ld)", delay.tv_sec, delay.tv_nsec);
return remain.tv_sec * 1000 + remain.tv_nsec / 1000000;
}

64
os.h Normal file
View File

@ -0,0 +1,64 @@
/*
Serval DNA native Operating System interface
Copyright (C) 2012 Serval Project Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#ifndef __SERVALDNA_OS_H
#define __SERVALDNA_OS_H
/* All wall clock times in the Serval daemon are represented in milliseconds
* since the Unix epoch. The gettime_ms() function uses gettimeofday(2) to
* return this value when called. The time_ms_t typedef should be used
* wherever this time value is handled or stored.
*
* This type could perfectly well be unsigned, but is defined as signed to
* avoid the need to cast or define a special signed timedelta_ms_t type at **
* (1):
*
* static time_ms_t then = 0;
* time_ms_t now = gettime_ms();
* time_ms_t ago = now - then; // ** (1)
* if (then && ago < 0) {
* ... time going backwards ...
* } else {
* ... time has advanced ...
* then = now;
* }
*/
typedef long long time_ms_t;
time_ms_t gettime_ms();
time_ms_t sleep_ms(time_ms_t milliseconds);
/* bzero(3) is deprecated in favour of memset(3). */
#define bzero(addr,len) memset((addr), 0, (len))
/* OpenWRT libc doesn't have bcopy, but has memmove */
#define bcopy(A,B,C) memmove(B,A,C)
int mkdirs(const char *path, mode_t mode);
int mkdirsn(const char *path, size_t len, mode_t mode);
void srandomdev();
int urandombytes(unsigned char *buf, unsigned long long len);
#endif //__SERVALDNA_OS_H

View File

@ -115,38 +115,12 @@ struct in_addr {
#include "log.h"
#include "net.h"
#include "conf.h"
/* All wall clock times in the Serval daemon are represented in milliseconds
* since the Unix epoch. The gettime_ms() function uses gettimeofday(2) to
* return this value when called. The time_ms_t typedef should be used
* wherever this time value is handled or stored.
*
* This type could perfectly well be unsigned, but is defined as signed to
* avoid the need to cast or define a special signed timedelta_ms_t type at **
* (1):
*
* static time_ms_t then = 0;
* time_ms_t now = gettime_ms();
* time_ms_t ago = now - then; // ** (1)
* if (then && ago < 0) {
* ... time going backwards ...
* } else {
* ... time has advanced ...
* then = now;
* }
*/
typedef long long time_ms_t;
/* bzero(3) is deprecated in favour of memset(3). */
#define bzero(addr,len) memset((addr), 0, (len))
#include "os.h"
/* UDP Port numbers for various Serval services.
The overlay mesh works over DNA */
#define PORT_DNA 4110
/* OpenWRT libc doesn't have bcopy, but has memmove */
#define bcopy(A,B,C) memmove(B,A,C)
#define BATCH 1
#define NONBATCH 0
@ -440,9 +414,6 @@ int str_is_did(const char *did);
int strn_is_did(const char *did, size_t *lenp);
int stowSid(unsigned char *packet, int ofs, const char *sid);
void srandomdev();
time_ms_t gettime_ms();
time_ms_t sleep_ms(time_ms_t milliseconds);
int server_pid();
void server_save_argv(int argc, const char *const *argv);
int server(char *backing_file);
@ -620,8 +591,6 @@ int overlay_mdp_dnalookup_reply(const sockaddr_mdp *dstaddr, const unsigned char
int dump_payload(struct overlay_frame *p, char *message);
int urandombytes(unsigned char *x,unsigned long long xlen);
struct vomp_call_state;
void set_codec_flag(int codec, unsigned char *flags);

View File

@ -16,7 +16,7 @@ SERVAL_SOURCES = $(SERVAL_BASE)audiodevices.c \
$(SERVAL_BASE)lsif.c \
$(SERVAL_BASE)main.c \
$(SERVAL_BASE)mdp_client.c \
$(SERVAL_BASE)mkdir.c \
$(SERVAL_BASE)os.c \
$(SERVAL_BASE)mem.c \
$(SERVAL_BASE)monitor.c \
$(SERVAL_BASE)monitor-client.c \

View File

@ -55,7 +55,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <unistd.h>
#endif
#include "serval.h"
#include "os.h"
#include <fcntl.h>
#include <stdlib.h>
#include <time.h>