3 Commits
Author SHA1 Message Date
sisungo d65988fcf0 feat: adapt semios filesystem layout
Signed-off-by: sisungo <[email protected]>
2026-07-18 21:20:39 +08:00
sisungo 4360d2fd2e feat: add accountd support
Signed-off-by: sisungo <[email protected]>
2026-07-18 18:32:16 +08:00
sisungo da11edfa02 fix: malloc initialized before tls
Signed-off-by: sisungo <[email protected]>
2026-07-04 22:19:10 +08:00
15 changed files with 4266 additions and 124 deletions
+1 -1
View File
@@ -64,7 +64,7 @@ typedef struct __res_state {
#define __RES 19960801
#ifndef _PATH_RESCONF
#define _PATH_RESCONF "/etc/resolv.conf"
#define _PATH_RESCONF "/var/config/network/resolv.conf"
#endif
struct res_sym {
+2 -2
View File
@@ -36,11 +36,11 @@ void __init_libc(char **envp, char *pn)
__progname = __progname_full = pn;
for (i=0; pn[i]; i++) if (pn[i]=='/') __progname = pn+i+1;
__malloc_process_init();
__init_tls(aux);
__init_ssp((void *)aux[AT_RANDOM]);
__malloc_process_init();
if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID]
&& !aux[AT_SECURE]) return;
+1 -1
View File
@@ -69,7 +69,7 @@
#define ICONV_ERR_ILLEGAL_OPCODE -4
#define ICONV_ERR_MEMORY_OVERFLOW -5
#define ICONV_CHARSET_PATH_PREFIX "/etc/iconv/"
#define ICONV_CHARSET_PATH_PREFIX "/share/iconv/"
static const uint8_t vm_binary_magic[4] = { 'S', 'I', 'C', 'V' };
+3 -3
View File
@@ -47,7 +47,7 @@ static void reverse_hosts(char *buf, const unsigned char *a, unsigned scopeid, i
char line[512], *p, *z;
unsigned char _buf[1032], atmp[16];
struct address iplit;
FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
FILE _f, *f = __fopen_rb_ca("/var/config/network/hosts", &_f, _buf, sizeof _buf);
if (!f) return;
if (family == AF_INET) {
memcpy(atmp+12, a, 4);
@@ -71,7 +71,7 @@ static void reverse_hosts(char *buf, const unsigned char *a, unsigned scopeid, i
if (memcmp(a, iplit.addr, 16) || iplit.scopeid != scopeid)
continue;
for (; *p && isspace(*p); p++);
for (z=p; *z && !isspace(*z); z++);
*z = 0;
@@ -116,7 +116,7 @@ static int dns_parse_callback(void *c, int rr, const void *data, int len, const
data, c, 256) <= 0)
*(char *)c = 0;
return 0;
}
int getnameinfo(const struct sockaddr *restrict sa, socklen_t sl,
+1 -1
View File
@@ -52,7 +52,7 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati
size_t l = strlen(name);
int cnt = 0, badfam = 0, have_canon = 0;
unsigned char _buf[1032];
FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
FILE _f, *f = __fopen_rb_ca("/var/config/network/hosts", &_f, _buf, sizeof _buf);
if (!f) switch (errno) {
case ENOENT:
case ENOTDIR:
+1 -1
View File
@@ -18,7 +18,7 @@ int __get_resolv_conf(struct resolvconf *conf, char *search, size_t search_sz)
conf->attempts = 2;
if (search) *search = 0;
f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
f = __fopen_rb_ca("/var/config/network/resolv.conf", &_f, _buf, sizeof _buf);
if (!f) switch (errno) {
case ENOENT:
case ENOTDIR:
+404
View File
@@ -0,0 +1,404 @@
#include <pwd.h>
#include <grp.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include "spp.h"
#include "json.h"
#ifndef _ACCOUNT_CLIENT
#define _ACCOUNT_CLIENT
#define REQ2(condition, err) if (!(condition)) { errno = err; return -1; }
#define REQ(condition) REQ2(condition, EPERM)
#define REQP2(condition, err) if (!(condition)) { errno = err; return NULL; }
#define REQP(condition) REQP2(condition, EPERM)
#define ITEROBJ(obj, it) for (struct json_object_element_s *it = obj->start; it != NULL; it = it->next)
#define DECLPOOL(pool, buf, size) struct account_memory_pool pool = { .ptr = buf, .len = size, .cursor = 0 }
#ifdef __linux__
static inline int account_connect() {
return spp_connect_linux("verified:org.semilabs.os/accountd");
}
#else
static inline int account_connect() {
return spp_connect_unix("/var/run/accountd.sock");
}
#endif /* __linux__ */
struct account_memory_pool {
void *ptr;
size_t cursor;
size_t len;
};
static inline void *account_allocate_pool(struct account_memory_pool *pool, size_t size) {
if (!pool || !pool->ptr || size == 0) {
return NULL;
}
if (pool->cursor + size > pool->len) {
return NULL;
}
void *result = (char *)pool->ptr + pool->cursor;
pool->cursor += size;
return result;
}
static inline int account_recordpw(
struct json_value_s *root,
struct passwd *passwd,
struct account_memory_pool *pool
) {
passwd->pw_passwd = account_allocate_pool(pool, 2);
REQ2(passwd->pw_passwd, ERANGE);
strcpy(passwd->pw_passwd, "x");
passwd->pw_gecos = account_allocate_pool(pool, 1);
REQ2(passwd->pw_gecos, ERANGE);
strcpy(passwd->pw_gecos, "");
struct json_object_s *object = json_value_as_object(root);
REQ(object);
ITEROBJ(object, it) {
const char *name = it->name->string;
struct json_value_s *value = it->value;
if (strcmp(name, "username") == 0) {
struct json_string_s *username = json_value_as_string(value);
REQ(username);
passwd->pw_name = account_allocate_pool(pool, username->string_size + 1);
REQ2(passwd->pw_name, ERANGE);
strcpy(passwd->pw_name, username->string);
continue;
}
if (strcmp(name, "home_directory") == 0) {
struct json_string_s *homedir = json_value_as_string(value);
REQ(homedir);
passwd->pw_dir = account_allocate_pool(pool, homedir->string_size + 1);
REQ2(passwd->pw_dir, ERANGE);
strcpy(passwd->pw_dir, homedir->string);
continue;
}
if (strcmp(name, "defaults") == 0) {
struct json_object_s *defaults = json_value_as_object(value);
REQ(defaults);
ITEROBJ(defaults, def) {
name = def->name->string;
value = def->value;
if (strcmp(name, "CliLoginShell") == 0) {
struct json_string_s *shell = json_value_as_string(value);
REQ(shell);
passwd->pw_shell = account_allocate_pool(pool, shell->string_size + 1);
REQ2(passwd->pw_shell, ERANGE);
strcpy(passwd->pw_shell, shell->string);
continue;
}
}
continue;
}
if (strcmp(name, "host_uid") == 0) {
struct json_number_s *uid = json_value_as_number(value);
REQ(uid);
passwd->pw_uid = atoi(uid->number);
continue;
}
}
return 0;
}
static inline int account_recordgr(
struct json_value_s *root,
struct group *group,
struct account_memory_pool *pool
) {
group->gr_passwd = account_allocate_pool(pool, 2);
REQ2(group->gr_passwd, ERANGE);
strcpy(group->gr_passwd, "x");
struct json_object_s *object = json_value_as_object(root);
REQ(object);
ITEROBJ(object, it) {
const char *name = it->name->string;
struct json_value_s *value = it->value;
if (strcmp(name, "groupname") == 0) {
struct json_string_s *groupname = json_value_as_string(value);
REQ(groupname);
group->gr_name = account_allocate_pool(pool, groupname->string_size + 1);
REQ2(group->gr_name, ERANGE);
strcpy(group->gr_name, groupname->string);
continue;
}
if (strcmp(name, "host_gid") == 0) {
struct json_number_s *gid = json_value_as_number(value);
REQ(gid);
group->gr_gid = atoi(gid->number);
continue;
}
}
return 0;
}
typedef int (*pwgr_parser_t)(struct json_value_s*, void*, struct account_memory_pool*);
static inline int account_getpwgrkey(
int fd,
const char *method,
const char *key,
const char *valueborder,
const char *name,
pwgr_parser_t parser,
void *pwgr,
struct account_memory_pool *pool
) {
int status;
const char *request_template = "{\"method\": \"%s\", \"params\": {\"%s\": %s%s%s}}";
int request_need = snprintf(NULL, 0, request_template, method, key, valueborder, name, valueborder);
REQ(request_need > 0);
char *request_json = malloc(request_need + 1);
REQ2(request_json, ENOMEM);
snprintf(request_json, request_need + 1, request_template, method, key, valueborder, name, valueborder);
status = spp_send(fd, request_json);
free(request_json);
REQ(status == 0);
const char *reply_str = spp_recv(fd);
REQ(reply_str);
struct json_value_s *reply = json_parse(reply_str, strlen(reply_str));
spp_free((void*)reply_str);
REQ(reply);
struct json_object_s *reply_object = json_value_as_object(reply);
if (!reply_object) goto format_error;
ITEROBJ(reply_object, it) {
if (strcmp(it->name->string, "success") == 0) {
if (json_value_is_false(it->value)) goto not_found;
continue;
}
if (strcmp(it->name->string, "value") == 0) {
status = parser(it->value, pwgr, pool);
if (status != 0) goto not_found;
continue;
}
}
free(reply);
return 0;
format_error:
errno = EPERM;
not_found:
free(reply);
return -1;
}
static inline char *account_list_uuid_next(
int fd,
const char *method,
unsigned int no
) {
int status;
const char *request_template = "{\"method\": \"%s\", \"params\": {\"start\": %u, \"len\": 1}}";
int request_need = snprintf(NULL, 0, request_template, method, no);
REQP(request_need > 0);
char *request_json = malloc(request_need + 1);
REQP2(request_json, ENOMEM);
snprintf(request_json, request_need + 1, request_template, method, no);
status = spp_send(fd, request_json);
free(request_json);
REQP(status == 0);
const char *reply_str = spp_recv(fd);
REQP(reply_str);
struct json_value_s *reply = json_parse(reply_str, strlen(reply_str));
spp_free((void*)reply_str);
REQP(reply);
struct json_object_s *reply_object = json_value_as_object(reply);
if (!reply_object) goto format_error;
ITEROBJ(reply_object, it) {
if (strcmp(it->name->string, "success") == 0) {
if (json_value_is_false(it->value)) goto not_found;
continue;
}
if (strcmp(it->name->string, "value") == 0) {
struct json_array_s *list = json_value_as_array(it->value);
if (!list) goto not_found;
struct json_array_element_s *first = list->start;
if (!first) goto not_found;
struct json_string_s *item = json_value_as_string(first->value);
if (!item) goto format_error;
return strdup(item->string);
}
}
free(reply);
return NULL;
format_error:
errno = EPERM;
not_found:
free(reply);
return NULL;
}
static inline int account_getpwuid(
int fd,
uid_t uid,
struct passwd *passwd,
struct account_memory_pool *pool
) {
char uid_str[32];
int len = snprintf(uid_str, sizeof(uid_str), "%u", (unsigned int)uid);
REQ(len > 0 && (size_t)len < sizeof(uid_str));
return account_getpwgrkey(
fd,
"GetUserInfo",
"host_uid",
"",
uid_str,
(pwgr_parser_t)account_recordpw,
passwd,
pool
);
}
static inline int account_getpwnam(
int fd,
const char *name,
struct passwd *passwd,
struct account_memory_pool *pool
) {
return account_getpwgrkey(
fd,
"GetUserInfo",
"username",
"\"",
name,
(pwgr_parser_t)account_recordpw,
passwd,
pool
);
}
static inline int account_getpwuuid(
int fd,
const char *uuid,
struct passwd *passwd,
struct account_memory_pool *pool
) {
return account_getpwgrkey(
fd,
"GetUserInfo",
"uuid",
"\"",
uuid,
(pwgr_parser_t)account_recordpw,
passwd,
pool
);
}
static inline int account_getgrgid(
int fd,
gid_t gid,
struct group *group,
struct account_memory_pool *pool
) {
char gid_str[32];
int len = snprintf(gid_str, sizeof(gid_str), "%u", (unsigned int)gid);
REQ(len > 0 && (size_t)len < sizeof(gid_str));
return account_getpwgrkey(
fd,
"GetGroupInfo",
"host_gid",
"",
gid_str,
(pwgr_parser_t)account_recordgr,
group,
pool
);
}
static inline int account_getgrnam(
int fd,
const char *name,
struct group *group,
struct account_memory_pool *pool
) {
return account_getpwgrkey(
fd,
"GetGroupInfo",
"groupname",
"\"",
name,
(pwgr_parser_t)account_recordgr,
group,
pool
);
}
static inline int account_getgruuid(
int fd,
const char *uuid,
struct group *group,
struct account_memory_pool *pool
) {
return account_getpwgrkey(
fd,
"GetGroupInfo",
"uuid",
"\"",
uuid,
(pwgr_parser_t)account_recordgr,
group,
pool
);
}
static inline int account_getpwent(
int fd,
unsigned int *no,
struct passwd *passwd,
struct account_memory_pool *pool
) {
int status;
char *next_uuid = account_list_uuid_next(fd, "ListUser", *no);
REQ2(next_uuid, errno);
status = account_getpwuuid(fd, next_uuid, passwd, pool);
free(next_uuid);
REQ(status == 0);
*no += 1;
return 0;
}
static inline int account_getgrent(
int fd,
unsigned int *no,
struct group *group,
struct account_memory_pool *pool
) {
int status;
char *next_uuid = account_list_uuid_next(fd, "ListGroup", *no);
REQ2(next_uuid, errno);
status = account_getgruuid(fd, next_uuid, group, pool);
free(next_uuid);
REQ(status == 0);
*no += 1;
return 0;
}
#endif /* _ACCOUNT_CLIENT */
+53 -40
View File
@@ -1,49 +1,62 @@
#include "pwf.h"
#include <pthread.h>
#include "account_client.h"
#include <grp.h>
#include <string.h>
#include <errno.h>
#define FIX(x) (gr->gr_##x = gr->gr_##x-line+buf)
static int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
{
char *line = 0;
size_t len = 0;
char **mem = 0;
size_t nmem = 0;
int rv = 0;
size_t i;
int cs;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
rv = __getgr_a(name, gid, gr, &line, &len, &mem, &nmem, res);
if (*res && size < len + (nmem+1)*sizeof(char *) + 32) {
*res = 0;
rv = ERANGE;
}
if (*res) {
buf += (16-(uintptr_t)buf)%16;
gr->gr_mem = (void *)buf;
buf += (nmem+1)*sizeof(char *);
memcpy(buf, line, len);
FIX(name);
FIX(passwd);
for (i=0; mem[i]; i++)
gr->gr_mem[i] = mem[i]-line+buf;
gr->gr_mem[i] = 0;
}
free(mem);
free(line);
pthread_setcancelstate(cs, 0);
if (rv) errno = rv;
return rv;
}
#define VERIFYPOOL(pool) if (!pool.ptr || pool.len == 0) { if (res) *res = NULL; return EINVAL; }
int getgrnam_r(const char *name, struct group *gr, char *buf, size_t size, struct group **res)
{
return getgr_r(name, 0, gr, buf, size, res);
int ret;
int saved_errno;
DECLPOOL(pool, buf, size);
VERIFYPOOL(pool);
int fd = account_connect();
if (fd < 0) {
saved_errno = errno;
*res = NULL;
return saved_errno != 0 ? saved_errno : EIO;
}
ret = account_getgrnam(fd, name, gr, &pool);
saved_errno = errno;
spp_close(fd);
if (ret != 0) {
*res = NULL;
return 0;
}
*res = gr;
return 0;
}
int getgrgid_r(gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
{
return getgr_r(0, gid, gr, buf, size, res);
int ret;
int saved_errno;
DECLPOOL(pool, buf, size);
VERIFYPOOL(pool);
int fd = account_connect();
if (fd < 0) {
saved_errno = errno;
*res = NULL;
return saved_errno != 0 ? saved_errno : EIO;
}
ret = account_getgrgid(fd, gid, gr, &pool);
saved_errno = errno;
spp_close(fd);
if (ret != 0) {
*res = NULL;
return 0;
}
*res = gr;
return 0;
}
+50 -19
View File
@@ -1,39 +1,70 @@
#include "pwf.h"
#include <grp.h>
#include <string.h>
#include <errno.h>
#include "account_client.h"
static FILE *f;
static char *line, **mem;
static struct group gr;
static char grs_buf[16384];
unsigned int igrent = 0;
void setgrent()
{
if (f) fclose(f);
f = 0;
igrent = 0;
}
weak_alias(setgrent, endgrent);
struct group *getgrent()
{
struct group *res;
size_t size=0, nmem=0;
if (!f) f = fopen("/etc/group", "rbe");
if (!f) return 0;
__getgrent_a(f, &gr, &line, &size, &mem, &nmem, &res);
return res;
memset(&gr, 0, sizeof(gr));
memset(grs_buf, 0, sizeof(grs_buf));
DECLPOOL(pool, grs_buf, sizeof(grs_buf));
int fd = account_connect();
int status = account_getgrent(fd, &igrent, &gr, &pool);
spp_close(fd);
if (status != 0) return NULL;
return &gr;
}
struct group *getgrgid(gid_t gid)
{
struct group *res;
size_t size=0, nmem=0;
__getgr_a(0, gid, &gr, &line, &size, &mem, &nmem, &res);
return res;
struct group *result;
int ret;
memset(&gr, 0, sizeof(gr));
memset(grs_buf, 0, sizeof(grs_buf));
ret = getgrgid_r(gid, &gr, grs_buf, sizeof(grs_buf), &result);
if (ret != 0) {
errno = ret;
return NULL;
}
if (result == NULL) {
errno = 0;
return NULL;
}
return &gr;
}
struct group *getgrnam(const char *name)
{
struct group *res;
size_t size=0, nmem=0;
__getgr_a(name, 0, &gr, &line, &size, &mem, &nmem, &res);
return res;
struct group *result;
int ret;
memset(&gr, 0, sizeof(gr));
memset(grs_buf, 0, sizeof(grs_buf));
ret = getgrnam_r(name, &gr, grs_buf, sizeof(grs_buf), &result);
if (ret != 0) {
errno = ret;
return NULL;
}
if (result == NULL) {
errno = 0;
return NULL;
}
return &gr;
}
+53 -33
View File
@@ -1,42 +1,62 @@
#include "pwf.h"
#include <pthread.h>
#include "account_client.h"
#include <pwd.h>
#include <string.h>
#include <errno.h>
#define FIX(x) (pw->pw_##x = pw->pw_##x-line+buf)
static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
{
char *line = 0;
size_t len = 0;
int rv = 0;
int cs;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
rv = __getpw_a(name, uid, pw, &line, &len, res);
if (*res && size < len) {
*res = 0;
rv = ERANGE;
}
if (*res) {
memcpy(buf, line, len);
FIX(name);
FIX(passwd);
FIX(gecos);
FIX(dir);
FIX(shell);
}
free(line);
pthread_setcancelstate(cs, 0);
if (rv) errno = rv;
return rv;
}
#define VERIFYPOOL(pool) if (!pool.ptr || pool.len == 0) { if (res) *res = NULL; return EINVAL; }
int getpwnam_r(const char *name, struct passwd *pw, char *buf, size_t size, struct passwd **res)
{
return getpw_r(name, 0, pw, buf, size, res);
int ret;
int saved_errno;
DECLPOOL(pool, buf, size);
VERIFYPOOL(pool);
int fd = account_connect();
if (fd < 0) {
saved_errno = errno;
*res = NULL;
return saved_errno != 0 ? saved_errno : EIO;
}
ret = account_getpwnam(fd, name, pw, &pool);
saved_errno = errno;
spp_close(fd);
if (ret != 0) {
*res = NULL;
return 0;
}
*res = pw;
return 0;
}
int getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
{
return getpw_r(0, uid, pw, buf, size, res);
int ret;
int saved_errno;
DECLPOOL(pool, buf, size);
VERIFYPOOL(pool);
int fd = account_connect();
if (fd < 0) {
saved_errno = errno;
*res = NULL;
return saved_errno != 0 ? saved_errno : EIO;
}
ret = account_getpwuid(fd, uid, pw, &pool);
saved_errno = errno;
spp_close(fd);
if (ret != 0) {
*res = NULL;
return 0;
}
*res = pw;
return 0;
}
+50 -17
View File
@@ -1,37 +1,70 @@
#include "pwf.h"
#include <pwd.h>
#include <string.h>
#include <errno.h>
#include "account_client.h"
static FILE *f;
static char *line;
static struct passwd pw;
static size_t size;
static char pwr_buf[16384];
unsigned int ipwent = 0;
void setpwent()
{
if (f) fclose(f);
f = 0;
ipwent = 0;
}
weak_alias(setpwent, endpwent);
struct passwd *getpwent()
{
struct passwd *res;
if (!f) f = fopen("/etc/passwd", "rbe");
if (!f) return 0;
__getpwent_a(f, &pw, &line, &size, &res);
return res;
memset(&pw, 0, sizeof(pw));
memset(pwr_buf, 0, sizeof(pwr_buf));
DECLPOOL(pool, pwr_buf, sizeof(pwr_buf));
int fd = account_connect();
int status = account_getpwent(fd, &ipwent, &pw, &pool);
spp_close(fd);
if (status != 0) return NULL;
return &pw;
}
struct passwd *getpwuid(uid_t uid)
{
struct passwd *res;
__getpw_a(0, uid, &pw, &line, &size, &res);
return res;
struct passwd *result;
int ret;
memset(&pw, 0, sizeof(pw));
memset(pwr_buf, 0, sizeof(pwr_buf));
ret = getpwuid_r(uid, &pw, pwr_buf, sizeof(pwr_buf), &result);
if (ret != 0) {
errno = ret;
return NULL;
}
if (result == NULL) {
errno = 0;
return NULL;
}
return &pw;
}
struct passwd *getpwnam(const char *name)
{
struct passwd *res;
__getpw_a(name, 0, &pw, &line, &size, &res);
return res;
struct passwd *result;
int ret;
memset(&pw, 0, sizeof(pw));
memset(pwr_buf, 0, sizeof(pwr_buf));
ret = getpwnam_r(name, &pw, pwr_buf, sizeof(pwr_buf), &result);
if (ret != 0) {
errno = ret;
return NULL;
}
if (result == NULL) {
errno = 0;
return NULL;
}
return &pw;
}
+3516
View File
File diff suppressed because it is too large Load Diff
+124
View File
@@ -0,0 +1,124 @@
#ifndef SPP_H
#define SPP_H
#include <sys/socket.h>
#include <sys/un.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <errno.h>
static inline int write_all(int fd, const void *buf, size_t len)
{
const char *p = buf;
size_t remaining = len;
while (remaining > 0) {
ssize_t n = write(fd, p, remaining);
if (n <= 0) return -1;
p += n;
remaining -= (size_t)n;
}
return 0;
}
static inline int read_all(int fd, void *buf, size_t len)
{
char *p = buf;
size_t remaining = len;
while (remaining > 0) {
ssize_t n = read(fd, p, remaining);
if (n <= 0) return -1;
p += n;
remaining -= (size_t)n;
}
return 0;
}
static inline int spp_connect_common(const char *path, int abstract)
{
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd == -1) return -1;
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
size_t len = strlen(path);
if (len >= sizeof(addr.sun_path)) {
close(fd);
errno = ENAMETOOLONG;
return -1;
}
socklen_t addrlen;
if (abstract) {
addr.sun_path[0] = '\0';
memcpy(addr.sun_path + 1, path, len);
addrlen = offsetof(struct sockaddr_un, sun_path) + 1 + len;
} else {
memcpy(addr.sun_path, path, len);
addrlen = offsetof(struct sockaddr_un, sun_path) + len;
}
if (connect(fd, (struct sockaddr *)&addr, addrlen) == -1) {
close(fd);
return -1;
}
return fd;
}
static inline int spp_connect_unix(char *path)
{
return spp_connect_common(path, 0);
}
static inline int spp_connect_linux(char *abstract_name)
{
return spp_connect_common(abstract_name, 1);
}
static inline void spp_close(int fd)
{
if (fd >= 0) close(fd);
}
static inline int spp_send(int fd, char *packet)
{
size_t data_len = strlen(packet);
if (data_len > UINT32_MAX) return -1;
uint32_t len = (uint32_t)data_len;
if (write_all(fd, &len, sizeof(len)) == -1) return -1;
if (data_len > 0 && write_all(fd, packet, data_len) == -1) return -1;
return 0;
}
static inline char *spp_recv(int fd)
{
uint32_t len;
if (read_all(fd, &len, sizeof(len)) == -1) return NULL;
char *buf = malloc(len + 1);
if (!buf) return NULL;
if (len > 0 && read_all(fd, buf, len) == -1) {
free(buf);
return NULL;
}
buf[len] = '\0';
return buf;
}
static inline void spp_free(void *p)
{
free(p);
}
#endif
+3 -3
View File
@@ -132,7 +132,7 @@ static void do_tzset()
"/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";
s = getenv("TZ");
if (!s) s = "/etc/localtime";
if (!s) s = "/var/config/localtime";
if (!*s) s = __utc;
if (old_tz && !strcmp(s, old_tz)) return;
@@ -163,7 +163,7 @@ static void do_tzset()
|| !strcmp(dummy_name, "UTC")
|| !strcmp(dummy_name, "GMT")))
posix_form = 1;
}
}
/* Non-suid can use an absolute tzfile pathname or a relative
* pathame beginning with "."; in secure mode, only the
@@ -171,7 +171,7 @@ static void do_tzset()
if (!posix_form) {
if (*s == ':') s++;
if (*s == '/' || *s == '.') {
if (!libc.secure || !strcmp(s, "/etc/localtime"))
if (!libc.secure || !strcmp(s, "/var/config/localtime"))
map = __map_file(s, &map_size);
} else {
size_t l = strlen(s);
+4 -3
View File
@@ -11,8 +11,7 @@ fn main() {
let dst = args.next().expect("please specify output file");
let mut octos = Vec::new();
let src_content = std::fs::read_to_string(&src)
.expect("cannot read source file");
let src_content = std::fs::read_to_string(&src).expect("cannot read source file");
let mut current_tag = None;
for (nline, line) in src_content.lines().enumerate() {
let line = line.trim();
@@ -129,7 +128,9 @@ fn do_arg(s: &str, content: &mut [u8; 8], cursor: &mut usize) -> Option<(usize,
_ => panic!("unknown radix"),
};
*cursor = 8;
*content = u64::from_str_radix(&digit[1..], radix).unwrap().to_be_bytes();
*content = u64::from_str_radix(&digit[1..], radix)
.unwrap()
.to_be_bytes();
None
} else if let Some(reg_id) = s.strip_prefix("&r") {
content[*cursor] = reg_id.parse::<u8>().unwrap();