mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
Added posix code
This commit is contained in:
90
conts/posix/SConstruct
Normal file
90
conts/posix/SConstruct
Normal file
@@ -0,0 +1,90 @@
|
||||
# -*- mode: python; coding: utf-8; -*-
|
||||
#
|
||||
# Codezero -- Virtualization microkernel for embedded systems.
|
||||
#
|
||||
# Copyright © 2009 B Labs Ltd
|
||||
#
|
||||
import os, shelve, sys
|
||||
from os.path import *
|
||||
|
||||
PROJRELROOT = '../../'
|
||||
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
arch = config.arch
|
||||
|
||||
|
||||
LIBL4_RELDIR = 'conts/libl4'
|
||||
KERNEL_INCLUDE = join(PROJROOT, 'include')
|
||||
LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR)
|
||||
LIBL4_INCLUDE = join(LIBL4_DIR, 'include')
|
||||
LIBL4_LIBPATH = join(BUILDDIR, LIBL4_RELDIR)
|
||||
|
||||
# Locally important paths are here
|
||||
LIBC_RELDIR = 'conts/libc'
|
||||
LIBC_DIR = join(PROJROOT, LIBC_RELDIR)
|
||||
LIBC_LIBPATH = join(BUILDDIR, LIBC_RELDIR)
|
||||
LIBC_INCLUDE = [join(LIBC_DIR, 'include'), \
|
||||
join(LIBC_DIR, 'include/arch' + '/' + arch)]
|
||||
|
||||
LIBMEM_RELDIR = 'conts/libmem'
|
||||
LIBMEM_DIR = join(PROJROOT, LIBMEM_RELDIR)
|
||||
LIBMEM_LIBPATH = join(BUILDDIR, LIBMEM_RELDIR)
|
||||
LIBMEM_INCLUDE = LIBMEM_DIR
|
||||
|
||||
LIBPOSIX_RELDIR = 'conts/posix/libposix'
|
||||
LIBPOSIX_DIR = join(PROJROOT, LIBPOSIX_RELDIR)
|
||||
LIBPOSIX_INCLUDE_SERVER = join(LIBPOSIX_DIR, 'include')
|
||||
LIBPOSIX_INCLUDE_USERSPACE = join(LIBPOSIX_DIR, 'include/posix')
|
||||
LIBPOSIX_LIBPATH = join(BUILDDIR, LIBPOSIX_RELDIR)
|
||||
|
||||
env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', \
|
||||
'-std=gnu99', '-Wall', '-Werror'],
|
||||
LINKFLAGS = ['-nostdlib'], \
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.elf',
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace', 'libmm', 'libmc', 'gcc'],
|
||||
CPPPATH = ['include', LIBC_INCLUDE, KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE],
|
||||
LIBPATH = [LIBC_LIBPATH, LIBL4_LIBPATH, LIBMEM_LIBPATH, LIBPOSIX_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
|
||||
contid = ARGUMENTS.get('cont', '0')
|
||||
|
||||
libposix = SConscript('libposix/SConscript', \
|
||||
exports = { 'config' : config, 'env' : env, 'contid' : contid}, duplicate = 0, \
|
||||
variant_dir = join(BUILDDIR, 'conts' + '/posix' + '/libposix'))
|
||||
|
||||
mm0_env = env.Clone()
|
||||
mm0_env.Append(CPPPATH = LIBPOSIX_INCLUDE_SERVER)
|
||||
mm0 = SConscript('mm0/SConscript', \
|
||||
exports = { 'config' : config, 'env' : mm0_env, 'contid' : contid}, duplicate = 0, \
|
||||
variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/mm0'))
|
||||
|
||||
fs0_env = env.Clone()
|
||||
fs0_env.Append(CPPPATH = LIBPOSIX_INCLUDE_SERVER)
|
||||
fs0 = SConscript('fs0/SConscript', \
|
||||
exports = { 'config' : config, 'env' : fs0_env, 'contid' : contid}, duplicate = 0, \
|
||||
variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/fs0'))
|
||||
|
||||
test0_env = env.Clone()
|
||||
test0_env.Replace(CPPPATH = [LIBPOSIX_INCLUDE_USERSPACE, 'include', LIBC_INCLUDE, KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE])
|
||||
test0_env.Append(CCFLAGS = '-nostdinc')
|
||||
test0 = SConscript('test0/SConscript', \
|
||||
exports = { 'config' : config, 'environment' : test0_env, 'contid' : contid}, duplicate = 0, \
|
||||
variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/test0'))
|
||||
|
||||
Depends(fs0, libposix)
|
||||
Depends(test0, libposix)
|
||||
|
||||
Alias('libposix', libposix)
|
||||
Alias('mm0', mm0)
|
||||
Alias('fs0', fs0)
|
||||
Alias('test0', test0)
|
||||
|
||||
Default([mm0, fs0, libposix, test0])
|
||||
97
conts/posix/bootdesc/SConscript
Normal file
97
conts/posix/bootdesc/SConscript
Normal file
@@ -0,0 +1,97 @@
|
||||
# -*- mode: python; coding: utf-8; -*-
|
||||
|
||||
# Codezero -- a microkernel for embedded systems.
|
||||
#
|
||||
# Copyright © 2009 B Labs Ltd
|
||||
#
|
||||
# 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 3 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, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Author: Russel Winder
|
||||
|
||||
import os.path
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
Import('environment', 'images')
|
||||
|
||||
e = environment.Clone()
|
||||
e.Append(LINKFLAGS = ['-T' + e['posixServicesDirectory'] + '/bootdesc/linker.lds'])
|
||||
e.Append(CPPPATH = ['#' + e['includeDirectory']])
|
||||
|
||||
bootdescTemplate = \
|
||||
'''
|
||||
/* This file is autogenerated, do not edit by hand. */
|
||||
|
||||
/* Supervisor task at load time. */
|
||||
struct svc_image {
|
||||
char name[16];
|
||||
unsigned int phys_start;
|
||||
unsigned int phys_end;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/* Supervisor task descriptor at load time */
|
||||
struct bootdesc {
|
||||
int desc_size;
|
||||
int total_images;
|
||||
struct svc_image images[];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct bootdesc bootdesc = {
|
||||
.desc_size = sizeof(struct bootdesc) + sizeof(struct svc_image) * %s,
|
||||
.total_images = %s,
|
||||
.images = {
|
||||
%s
|
||||
},
|
||||
};
|
||||
'''
|
||||
|
||||
imageTemplate = \
|
||||
''' [%s] = {
|
||||
.name = "%s",
|
||||
.phys_start = %s,
|
||||
.phys_end = %s,
|
||||
},
|
||||
'''
|
||||
|
||||
def generateLocationData(image):
|
||||
process = subprocess.Popen('tools/pyelf/readelf.py --lma-start-end ' + image.path, shell=True, stdout=subprocess.PIPE)
|
||||
assert process.wait() == 0
|
||||
return (process.stdout.readline().strip(), process.stdout.readline().strip().split()[1], process.stdout.readline().strip().split()[1])
|
||||
|
||||
def generateBootdesc(target, source, env):
|
||||
'''
|
||||
Extracts name, start, end information from the kernel and each svc task.
|
||||
Uses this information to produce bootdesc.c
|
||||
'''
|
||||
with open(target[0].path, 'w' ) as f:
|
||||
imagesString = ''
|
||||
numberOfImages = len(source) - 1
|
||||
for index in range(1, len(source)):
|
||||
imagesString += imageTemplate % ((index - 1,) + generateLocationData(source[index]))
|
||||
f.write(bootdescTemplate % (numberOfImages, numberOfImages, imagesString))
|
||||
|
||||
def relocateBootdesc(target, source, env):
|
||||
name, start, end = generateLocationData(source[1])
|
||||
print "arm-none-linux-gnueabi-objcopy" + " --adjust-section-vma .data=" + end + " " + source[0].path
|
||||
# process = subprocess.Popen(executable='arm-none-linux-gnueabi-objcopy', args=(
|
||||
# '--adjust-section-vma .data=' + end,
|
||||
# source[0].path))
|
||||
# assert process.wait() == 0
|
||||
os.system("arm-none-linux-gnueabi-objcopy --adjust-section-vma .data=" + end + " " + source[0].path)
|
||||
shutil.copyfile(source[0].path, target[0].path)
|
||||
|
||||
objects = e.Object(e.Command('bootdesc.c', images, generateBootdesc))
|
||||
Depends(objects, e['configFiles'])
|
||||
bootdesc = e.Command('bootdesc.axf', e.Program('bootdesc_intermediate', objects) + [images[1]] , relocateBootdesc)
|
||||
Depends(bootdesc, e['configFiles'])
|
||||
|
||||
Return('bootdesc')
|
||||
123
conts/posix/bootdesc/SConstruct
Normal file
123
conts/posix/bootdesc/SConstruct
Normal file
@@ -0,0 +1,123 @@
|
||||
#
|
||||
# Build script to autogenerate a bootdesc image
|
||||
#
|
||||
# Copyright (C) 2007 Bahadir Balban
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
from os.path import join
|
||||
|
||||
# The root directory of the repository where this file resides:
|
||||
project_root = "../.."
|
||||
tools_root = "../../tools"
|
||||
|
||||
kernel = join(project_root, "build/start.axf")
|
||||
mm0 = join(project_root, "tasks/mm0/mm0.axf")
|
||||
fs0 = join(project_root, "tasks/fs0/fs0.axf")
|
||||
test0 = join(project_root, "tasks/test0/test0.axf")
|
||||
#test1 = join(project_root, "tasks/test1/test1.axf")
|
||||
#blkdev0 = join(project_root, "tasks/fsbin/blkdev0.axf")
|
||||
|
||||
images = [kernel, mm0, fs0, test0]
|
||||
autogen_templ = "bootdesc.c.append"
|
||||
|
||||
def get_image_name_start_end(image, target):
|
||||
'''
|
||||
Using readelf.py utility, extracts name, start, end triplet from an arm-elf image.
|
||||
'''
|
||||
rest, name = os.path.split(image)
|
||||
if name[-4] == ".":
|
||||
name = name[:-4]
|
||||
os.system(join(tools_root, "pyelf/readelf.py --lma-start-end " + \
|
||||
image + " > " + target))
|
||||
|
||||
bootdesc_template = \
|
||||
'''
|
||||
struct bootdesc bootdesc = {
|
||||
.desc_size = sizeof(struct bootdesc) + sizeof(struct svc_image) * %s,
|
||||
.total_images = %s,
|
||||
.images = {
|
||||
%s
|
||||
},
|
||||
};
|
||||
'''
|
||||
|
||||
images_template = \
|
||||
''' [%s] = {
|
||||
.name = "%s",
|
||||
.phys_start = %s,
|
||||
.phys_end = %s,
|
||||
},
|
||||
'''
|
||||
|
||||
images_template_end = \
|
||||
'''
|
||||
},
|
||||
'''
|
||||
|
||||
def generate_bootdesc(source, target, env):
|
||||
'''
|
||||
Extracts name, start, end information from the kernel and each svc task.
|
||||
Uses this information to produce bootdesc.c
|
||||
'''
|
||||
source.sort()
|
||||
images = []
|
||||
images_string = ""
|
||||
for node in source:
|
||||
if str(node)[-4:] == ".axf":
|
||||
rest, imgname = os.path.split(str(node))
|
||||
images.append((str(node), imgname[:-4]))
|
||||
elif str(node) [-6:] == ".templ":
|
||||
# Static template that has type definitions.
|
||||
#rest, original_template = os.path.split(str(node))
|
||||
original_template = str(node)
|
||||
index = 0
|
||||
for imgpath, imgname in images:
|
||||
get_image_name_start_end(imgpath, imgname + ".txt")
|
||||
if imgname != "start":
|
||||
f = open(imgname + ".txt", "r")
|
||||
svc_name = f.readline()[:-1]
|
||||
[start, startval] = str.split(f.readline()[:-1])
|
||||
[end, endval] = str.split(f.readline()[:-1])
|
||||
f.close()
|
||||
images_string += images_template % (str(index), svc_name, \
|
||||
hex(int(startval, 16)), hex(int(endval, 16)))
|
||||
index += 1
|
||||
|
||||
# Autogenerated template with actual data.
|
||||
autogen_template = open(autogen_templ, "w+")
|
||||
autogen_template.write(bootdesc_template % (str(index), str(index), images_string))
|
||||
autogen_template.close()
|
||||
|
||||
os.system("cat " + original_template + " > " + str(target[0]))
|
||||
os.system("cat " + autogen_templ + " >> " + str(target[0]))
|
||||
|
||||
def relocate_bootdesc(source, target, env):
|
||||
f = open("start.txt", "r")
|
||||
kernel_name = f.readline()[:-1]
|
||||
[start, startval] = str.split(f.readline()[:-1])
|
||||
[end, endval] = str.split(f.readline()[:-1])
|
||||
os.system("arm-none-linux-gnueabi-objcopy --adjust-section-vma .data=" + \
|
||||
hex(int(endval,16)) + " " + str(source[0]))
|
||||
os.system("mv " + str(source[0]) + " " + str(target[0]))
|
||||
# The kernel build environment:
|
||||
env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
|
||||
LINKFLAGS = ['-nostdlib','-Tlinker.lds'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.axf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
LIBS = 'gcc', # libgcc.a - This is required for division routines.
|
||||
CPPPATH = '#include') # `hash' ('#') is a shorthand meaning `relative to
|
||||
# the root directory'. But this only works for
|
||||
# well-defined variables, not all paths, and only
|
||||
# if we use a relative build directory for sources.
|
||||
|
||||
bootdesc_src = env.Command("bootdesc.c", ["bootdesc.c.templ"] + images, generate_bootdesc)
|
||||
objs = env.Object('bootdesc.c')
|
||||
bootdesc = env.Program('bootdesc_data', objs)
|
||||
bootdesc_relocated = env.Command("bootdesc.axf", "bootdesc_data.axf", relocate_bootdesc)
|
||||
env.Depends(bootdesc_relocated, bootdesc)
|
||||
16
conts/posix/bootdesc/bootdesc.c.templ
Normal file
16
conts/posix/bootdesc/bootdesc.c.templ
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
|
||||
/* Supervisor task at load time. */
|
||||
struct svc_image {
|
||||
char name[16];
|
||||
unsigned int phys_start;
|
||||
unsigned int phys_end;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/* Supervisor task descriptor at load time */
|
||||
struct bootdesc {
|
||||
int desc_size;
|
||||
int total_images;
|
||||
struct svc_image images[];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
8
conts/posix/bootdesc/linker.lds
Normal file
8
conts/posix/bootdesc/linker.lds
Normal file
@@ -0,0 +1,8 @@
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
_start = .;
|
||||
.data : { *(.data) }
|
||||
_end = .;
|
||||
}
|
||||
17
conts/posix/fs0/SConscript
Normal file
17
conts/posix/fs0/SConscript
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
Import('config', 'env', 'contid')
|
||||
|
||||
import os, sys
|
||||
|
||||
arch = config.arch
|
||||
|
||||
src = [Glob('*.c') + Glob('src/*.c') + Glob('src/arch/arm/*.c') + Glob('src/memfs/*.c') + Glob('src/lib/*.c')]
|
||||
|
||||
e = env.Clone()
|
||||
e.Append(LIBS = 'posix')
|
||||
e.Append(LINKFLAGS = ['-T' + "fs0/include/linker.lds", '-u_start'])
|
||||
|
||||
objs = e.Object(src)
|
||||
fs0 = e.Program('fs0.elf', objs)
|
||||
|
||||
Return('fs0')
|
||||
75
conts/posix/fs0/SConstruct
Normal file
75
conts/posix/fs0/SConstruct
Normal file
@@ -0,0 +1,75 @@
|
||||
#
|
||||
# User space application build script
|
||||
#
|
||||
# Copyright (C) 2007 Bahadir Balban
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
from os.path import join
|
||||
from glob import glob
|
||||
|
||||
task_name = "fs0"
|
||||
|
||||
# The root directory of the repository where this file resides:
|
||||
project_root = "../.."
|
||||
tools_root = join(project_root, "tools")
|
||||
prev_image = join(project_root, "tasks/mm0/mm0.axf")
|
||||
libs_path = join(project_root, "libs")
|
||||
ld_script = "include/linker.lds"
|
||||
physical_base_ld_script = "include/physical_base.lds"
|
||||
|
||||
# libc paths:
|
||||
libc_variant = "userspace"
|
||||
libc_libpath = join(libs_path, "c/build/%s" % libc_variant)
|
||||
libc_incpath = join(libc_libpath, "include")
|
||||
libc_crt0 = join(libs_path, "c/build/crt/sys-userspace/arch-arm/crt0.o")
|
||||
libc_name = "c-%s" % libc_variant
|
||||
|
||||
#libmem paths:
|
||||
libmem_path = "../libmem"
|
||||
libmem_incpath = "../libmem"
|
||||
|
||||
# libl4 paths:
|
||||
libl4_path = "../libl4"
|
||||
libl4_incpath1 = join(libl4_path, "include")
|
||||
|
||||
# libposix paths:
|
||||
libposix_path = "../libposix"
|
||||
libposix_incpath = join(libposix_path, "include")
|
||||
|
||||
# kernel paths:
|
||||
kernel_incpath = join(project_root, "include")
|
||||
|
||||
# If crt0 is in its library path, it becomes hard to link with it.
|
||||
# For instance the linker script must use an absolute path for it.
|
||||
def copy_crt0(source, target, env):
|
||||
os.system("cp " + str(source[0]) + " " + str(target[0]))
|
||||
|
||||
def get_physical_base(source, target, env):
|
||||
os.system(join(tools_root, "pyelf/readelf.py --first-free-page " + \
|
||||
prev_image + " >> " + physical_base_ld_script))
|
||||
|
||||
# The kernel build environment:
|
||||
env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + ld_script, "-L" + libc_libpath, "-L" + libl4_path,\
|
||||
"-L" + libmem_path, "-L" + libposix_path],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.axf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
LIBS = [libc_name, 'gcc', 'libmc', 'libl4', 'gcc', libc_name, "posix"],
|
||||
CPPFLAGS = "-D__USERSPACE__",
|
||||
CPPPATH = ['#include', libl4_incpath1, kernel_incpath, libc_incpath, \
|
||||
libposix_incpath, libmem_incpath])
|
||||
|
||||
src = [glob("src/*.c"), glob("*.c"), glob("src/arch/arm/*.c"), glob("src/memfs/*.c"), glob("src/lib/*.c")]
|
||||
objs = env.Object(src)
|
||||
physical_base = env.Command(physical_base_ld_script, prev_image, get_physical_base)
|
||||
crt0_copied = env.Command("crt0.o", libc_crt0, copy_crt0)
|
||||
|
||||
task = env.Program(task_name, objs + [crt0_copied])
|
||||
env.Alias(task_name, task)
|
||||
env.Depends(task, physical_base)
|
||||
23
conts/posix/fs0/container.c
Normal file
23
conts/posix/fs0/container.c
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Container entry point for this task
|
||||
*
|
||||
* Copyright (C) 2007-2009 Bahadir Bilgehan Balban
|
||||
*/
|
||||
#include <posix/posix_init.h>
|
||||
#include <l4lib/init.h>
|
||||
#include <l4lib/utcb.h>
|
||||
|
||||
void main(void);
|
||||
|
||||
void __container_init(void)
|
||||
{
|
||||
/* Generic L4 thread initialisation */
|
||||
__l4_init();
|
||||
|
||||
/* FS0 posix-service initialisation */
|
||||
posix_service_init();
|
||||
|
||||
/* Entry to main */
|
||||
main();
|
||||
}
|
||||
|
||||
8
conts/posix/fs0/include/bdev.h
Normal file
8
conts/posix/fs0/include/bdev.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef __BDEV_H__
|
||||
#define __BDEV_H__
|
||||
/*
|
||||
* This is a mock-up compiled in blockdev buffer, to be used temporarily.
|
||||
*/
|
||||
|
||||
void *vfs_rootdev_open(void);
|
||||
#endif/* __BDEV_H__ */
|
||||
6
conts/posix/fs0/include/file.h
Normal file
6
conts/posix/fs0/include/file.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef __FS0_MM_H__
|
||||
#define __FS0_MM_H__
|
||||
|
||||
|
||||
|
||||
#endif /* __FS0_MM_H__ */
|
||||
171
conts/posix/fs0/include/fs.h
Normal file
171
conts/posix/fs0/include/fs.h
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* VFS definitions.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban.
|
||||
*/
|
||||
#ifndef __FS_H__
|
||||
#define __FS_H__
|
||||
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4/macros.h>
|
||||
#include <l4lib/types.h>
|
||||
#include <stat.h>
|
||||
#include <path.h>
|
||||
|
||||
typedef void (*vnode_op_t)(void);
|
||||
typedef void (*file_op_t)(void);
|
||||
|
||||
struct dentry;
|
||||
struct file;
|
||||
struct file_system_type;
|
||||
struct superblock;
|
||||
struct vnode;
|
||||
|
||||
struct dentry_ops {
|
||||
int (*compare)(struct dentry *d, const char *n);
|
||||
};
|
||||
|
||||
/* Operations that work on file content */
|
||||
struct file_ops {
|
||||
|
||||
/* Read a vnode's contents by page range */
|
||||
int (*read)(struct vnode *v, unsigned long pfn,
|
||||
unsigned long npages, void *buf);
|
||||
|
||||
/* Write a vnode's contents by page range */
|
||||
int (*write)(struct vnode *v, unsigned long pfn,
|
||||
unsigned long npages, void *buf);
|
||||
file_op_t open;
|
||||
file_op_t close;
|
||||
file_op_t mmap;
|
||||
file_op_t lseek;
|
||||
file_op_t flush;
|
||||
file_op_t fsync;
|
||||
};
|
||||
|
||||
/* Operations that work on vnode fields and associations between vnodes */
|
||||
struct vnode_ops {
|
||||
vnode_op_t create;
|
||||
struct vnode *(*lookup)(struct vnode *root, struct pathdata *pdata,
|
||||
const char *component);
|
||||
int (*readdir)(struct vnode *v);
|
||||
int (*filldir)(void *buf, struct vnode *v, int count);
|
||||
vnode_op_t link;
|
||||
vnode_op_t unlink;
|
||||
int (*mkdir)(struct vnode *parent, const char *name);
|
||||
struct vnode *(*mknod)(struct vnode *parent, const char *name,
|
||||
unsigned int mode);
|
||||
vnode_op_t rmdir;
|
||||
vnode_op_t rename;
|
||||
vnode_op_t getattr;
|
||||
vnode_op_t setattr;
|
||||
};
|
||||
|
||||
struct superblock_ops {
|
||||
int (*write_sb)(struct superblock *sb);
|
||||
|
||||
/*
|
||||
* Given a vnum, reads the disk-inode and copies its data
|
||||
* into the vnode's generic fields
|
||||
*/
|
||||
int (*read_vnode)(struct superblock *sb, struct vnode *v);
|
||||
|
||||
/* Writes vnode's generic fields into the disk-inode structure */
|
||||
int (*write_vnode)(struct superblock *sb, struct vnode *v);
|
||||
|
||||
/* Allocates a disk-inode along with a vnode, and associates the two */
|
||||
struct vnode *(*alloc_vnode)(struct superblock *sb);
|
||||
|
||||
/* Frees the vnode and the corresponding on-disk inode */
|
||||
int (*free_vnode)(struct superblock *sb, struct vnode *v);
|
||||
};
|
||||
|
||||
#define VFS_DNAME_MAX 256
|
||||
struct dentry {
|
||||
int refcnt;
|
||||
char name[VFS_DNAME_MAX];
|
||||
struct dentry *parent; /* Parent dentry */
|
||||
struct link child; /* List of dentries with same parent */
|
||||
struct link children; /* List of children dentries */
|
||||
struct link vref; /* For vnode's dirent reference list */
|
||||
struct link cache_list; /* Dentry cache reference */
|
||||
struct vnode *vnode; /* The vnode associated with dentry */
|
||||
struct dentry_ops ops;
|
||||
};
|
||||
|
||||
/*
|
||||
* Buffer that maintains directory content for a directory vnode. This is the
|
||||
* only vnode content that fs0 maintains. All other file data is in mm0 page
|
||||
* cache.
|
||||
*/
|
||||
struct dirbuf {
|
||||
unsigned long npages;
|
||||
int dirty;
|
||||
u8 *buffer;
|
||||
};
|
||||
|
||||
/* Posix-style dirent format used by userspace. Returned by sys_readdir() */
|
||||
#define DIRENT_NAME_MAX 32
|
||||
struct dirent {
|
||||
u32 inum; /* Inode number */
|
||||
u32 offset; /* Dentry offset in its buffer */
|
||||
u16 rlength; /* Record length */
|
||||
u8 name[DIRENT_NAME_MAX]; /* Name string */
|
||||
};
|
||||
|
||||
struct vnode {
|
||||
unsigned long vnum; /* Filesystem-wide unique vnode id */
|
||||
int refcnt; /* Reference counter */
|
||||
int links; /* Number of hard links */
|
||||
struct superblock *sb; /* Reference to superblock */
|
||||
struct vnode_ops ops; /* Operations on this vnode */
|
||||
struct file_ops fops; /* File-related operations on this vnode */
|
||||
struct link dentries; /* Dirents that refer to this vnode */
|
||||
struct link cache_list; /* For adding the vnode to vnode cache */
|
||||
struct dirbuf dirbuf; /* Only directory buffers are kept */
|
||||
u32 mode; /* Permissions and vnode type */
|
||||
u32 owner; /* Owner */
|
||||
u64 atime; /* Last access time */
|
||||
u64 mtime; /* Last content modification */
|
||||
u64 ctime; /* Last vnode modification */
|
||||
u64 size; /* Size of contents */
|
||||
void *inode; /* Ptr to fs-specific inode */
|
||||
};
|
||||
|
||||
/* FS0 vfs specific macros */
|
||||
|
||||
/* Check if directory */
|
||||
#define vfs_isdir(v) S_ISDIR((v)->mode)
|
||||
|
||||
/* Set vnode type */
|
||||
#define vfs_set_type(v, type) {v->mode &= ~S_IFMT; v->mode |= S_IFMT & type; }
|
||||
|
||||
struct fstype_ops {
|
||||
struct superblock *(*get_superblock)(void *buf);
|
||||
};
|
||||
|
||||
#define VFS_FSNAME_MAX 256
|
||||
struct file_system_type {
|
||||
char name[VFS_FSNAME_MAX];
|
||||
unsigned long magic;
|
||||
struct fstype_ops ops;
|
||||
struct link list; /* Member of list of all fs types */
|
||||
struct link sblist; /* List of superblocks with this type */
|
||||
};
|
||||
struct superblock *get_superblock(void *buf);
|
||||
|
||||
struct superblock {
|
||||
u64 fssize;
|
||||
unsigned int blocksize;
|
||||
struct link list;
|
||||
struct file_system_type *fs;
|
||||
struct superblock_ops *ops;
|
||||
struct vnode *root;
|
||||
void *fs_super;
|
||||
};
|
||||
|
||||
void vfs_mount_fs(struct superblock *sb);
|
||||
|
||||
extern struct dentry_ops generic_dentry_operations;
|
||||
|
||||
#endif /* __FS_H__ */
|
||||
13
conts/posix/fs0/include/globals.h
Normal file
13
conts/posix/fs0/include/globals.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef __GLOBALS_H__
|
||||
#define __GLOBALS_H__
|
||||
|
||||
struct global_list {
|
||||
int total;
|
||||
struct link list;
|
||||
};
|
||||
|
||||
extern struct global_list global_vm_files;
|
||||
extern struct global_list global_vm_objects;
|
||||
extern struct global_list global_tasks;
|
||||
|
||||
#endif /* __GLOBALS_H__ */
|
||||
7
conts/posix/fs0/include/init.h
Normal file
7
conts/posix/fs0/include/init.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef __INIT_H__
|
||||
#define __INIT_H__
|
||||
|
||||
/* FS0 initialisation */
|
||||
int initialise(void);
|
||||
|
||||
#endif /* __INIT_H__ */
|
||||
44
conts/posix/fs0/include/lib/bit.h
Normal file
44
conts/posix/fs0/include/lib/bit.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef __LIB_BIT_H__
|
||||
#define __LIB_BIT_H__
|
||||
|
||||
#include <l4lib/types.h>
|
||||
|
||||
unsigned int __clz(unsigned int bitvector);
|
||||
int find_and_set_first_free_bit(u32 *word, unsigned int lastbit);
|
||||
int find_and_set_first_free_contig_bits(u32 *word, unsigned int limit,
|
||||
int nbits);
|
||||
int check_and_clear_bit(u32 *word, int bit);
|
||||
int check_and_clear_contig_bits(u32 *word, int first, int nbits);
|
||||
|
||||
int check_and_set_bit(u32 *word, int bit);
|
||||
|
||||
/* Set */
|
||||
static inline void setbit(unsigned int *w, unsigned int flags)
|
||||
{
|
||||
*w |= flags;
|
||||
}
|
||||
|
||||
|
||||
/* Clear */
|
||||
static inline void clrbit(unsigned int *w, unsigned int flags)
|
||||
{
|
||||
*w &= ~flags;
|
||||
}
|
||||
|
||||
/* Test */
|
||||
static inline int tstbit(unsigned int *w, unsigned int flags)
|
||||
{
|
||||
return *w & flags;
|
||||
}
|
||||
|
||||
/* Test and clear */
|
||||
static inline int tstclr(unsigned int *w, unsigned int flags)
|
||||
{
|
||||
int res = tstbit(w, flags);
|
||||
|
||||
clrbit(w, flags);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* __LIB_BIT_H__ */
|
||||
29
conts/posix/fs0/include/lib/idpool.h
Normal file
29
conts/posix/fs0/include/lib/idpool.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef __MM0_IDPOOL_H__
|
||||
#define __MM0_IDPOOL_H__
|
||||
|
||||
#include <lib/bit.h>
|
||||
#include <l4/macros.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include <string.h>
|
||||
|
||||
struct id_pool {
|
||||
int nwords;
|
||||
u32 bitmap[];
|
||||
};
|
||||
|
||||
/* Copy one id pool to another by calculating its size */
|
||||
static inline void id_pool_copy(struct id_pool *to, struct id_pool *from, int totalbits)
|
||||
{
|
||||
int nwords = BITWISE_GETWORD(totalbits);
|
||||
|
||||
memcpy(to, from, nwords * SZ_WORD + sizeof(struct id_pool));
|
||||
}
|
||||
|
||||
struct id_pool *id_pool_new_init(int mapsize);
|
||||
int id_new(struct id_pool *pool);
|
||||
int id_del(struct id_pool *pool, int id);
|
||||
int id_get(struct id_pool *pool, int id);
|
||||
int ids_new_contiguous(struct id_pool *pool, int numids);
|
||||
int ids_del_contiguous(struct id_pool *pool, int first, int numids);
|
||||
|
||||
#endif /* __MM0_IDPOOL_H__ */
|
||||
19
conts/posix/fs0/include/lib/malloc.h
Normal file
19
conts/posix/fs0/include/lib/malloc.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef __PRIVATE_MALLOC_H__
|
||||
#define __PRIVATE_MALLOC_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
void *kmalloc(size_t size);
|
||||
void kfree(void *blk);
|
||||
|
||||
static inline void *kzalloc(size_t size)
|
||||
{
|
||||
void *buf = kmalloc(size);
|
||||
|
||||
memset(buf, 0, size);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
#endif /*__PRIVATE_MALLOC_H__ */
|
||||
9
conts/posix/fs0/include/lib/pathstr.h
Normal file
9
conts/posix/fs0/include/lib/pathstr.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef __LIB_PATHSTR_H__
|
||||
#define __LIB_PATHSTR_H__
|
||||
|
||||
char *strreverse(char *str);
|
||||
char *splitpath_end(char **path, char sep);
|
||||
char *splitpath(char **str, char sep);
|
||||
|
||||
|
||||
#endif /* __LIB_PATHSTR_H__ */
|
||||
15
conts/posix/fs0/include/lib/spinlock.h
Normal file
15
conts/posix/fs0/include/lib/spinlock.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Fake spinlock for future multi-threaded mm0
|
||||
*/
|
||||
#ifndef __MM0_SPINLOCK_H__
|
||||
#define __MM0_SPINLOCK_H__
|
||||
|
||||
struct spinlock {
|
||||
int lock;
|
||||
};
|
||||
|
||||
static inline void spin_lock_init(struct spinlock *s) { }
|
||||
static inline void spin_lock(struct spinlock *s) { }
|
||||
static inline void spin_unlock(struct spinlock *s) { }
|
||||
|
||||
#endif /* __MM0_SPINLOCK_H__ */
|
||||
17
conts/posix/fs0/include/lib/vaddr.h
Normal file
17
conts/posix/fs0/include/lib/vaddr.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Virtual address allocation pool (for shm)
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#ifndef __VADDR_H__
|
||||
#define __VADDR_H__
|
||||
|
||||
#include <lib/idpool.h>
|
||||
|
||||
void vaddr_pool_init(struct id_pool *pool, unsigned long start,
|
||||
unsigned long end);
|
||||
void *vaddr_new(struct id_pool *pool, int npages);
|
||||
int vaddr_del(struct id_pool *, void *vaddr, int npages);
|
||||
|
||||
#endif /* __VADDR_H__ */
|
||||
|
||||
49
conts/posix/fs0/include/linker.lds
Normal file
49
conts/posix/fs0/include/linker.lds
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Simple linker script for userspace or svc tasks.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
|
||||
/*
|
||||
* The only catch with this linker script is that everything
|
||||
* is linked starting at virtual_base, and loaded starting
|
||||
* at physical_base. virtual_base is the predefined region
|
||||
* of virtual memory for userland applications. physical_base
|
||||
* is determined at build-time, it is one of the subsequent pages
|
||||
* that come after the kernel image's load area.
|
||||
*/
|
||||
/* USER_AREA_START, see memlayout.h */
|
||||
virtual_base = 0x10000000;
|
||||
physical_base = 0x8000;
|
||||
__stack = (0x20000000 - 0x1000 - 8); /* First page before env/args page */
|
||||
/* INCLUDE "include/physical_base.lds" */
|
||||
|
||||
/* physical_base = 0x228000; */
|
||||
offset = virtual_base - physical_base;
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = virtual_base;
|
||||
_start_text = .;
|
||||
.text : AT (ADDR(.text) - offset) { *(.text.head) *(.text) }
|
||||
/* rodata is needed else your strings will link at physical! */
|
||||
.rodata : AT (ADDR(.rodata) - offset) { *(.rodata) }
|
||||
.rodata1 : AT (ADDR(.rodata1) - offset) { *(.rodata1) }
|
||||
.data : AT (ADDR(.data) - offset)
|
||||
{
|
||||
. = ALIGN(4K); /* Align UTCB to page boundary */
|
||||
_start_utcb = .;
|
||||
*(.utcb)
|
||||
_end_utcb = .;
|
||||
. = ALIGN(4K);
|
||||
_start_bdev = .;
|
||||
*(.data.memfs)
|
||||
_end_bdev = .;
|
||||
*(.data)
|
||||
}
|
||||
.bss : AT (ADDR(.bss) - offset) { *(.bss) }
|
||||
|
||||
_end = .;
|
||||
}
|
||||
7
conts/posix/fs0/include/memfs/file.h
Normal file
7
conts/posix/fs0/include/memfs/file.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef __MEMFS_FILE_H__
|
||||
#define __MEMFS_FILE_H__
|
||||
|
||||
extern struct file_ops memfs_file_operations;
|
||||
extern struct dentry_ops memfs_dentry_operations;
|
||||
|
||||
#endif /* __MEMFS_FILE_H__ */
|
||||
97
conts/posix/fs0/include/memfs/memfs.h
Normal file
97
conts/posix/fs0/include/memfs/memfs.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* The disk layout of our simple unix-like filesystem.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
*/
|
||||
|
||||
#ifndef __MEMFS_LAYOUT_H__
|
||||
#define __MEMFS_LAYOUT_H__
|
||||
|
||||
#include <l4lib/types.h>
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4/macros.h>
|
||||
#include <l4/config.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include <memcache/memcache.h>
|
||||
#include <lib/idpool.h>
|
||||
|
||||
/*
|
||||
*
|
||||
* Filesystem layout:
|
||||
*
|
||||
* |---------------|
|
||||
* | Superblock |
|
||||
* |---------------|
|
||||
*
|
||||
* Superblock layout:
|
||||
*
|
||||
* |---------------|
|
||||
* | inode cache |
|
||||
* |---------------|
|
||||
* | dentry cache |
|
||||
* |---------------|
|
||||
* | block cache |
|
||||
* |---------------|
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* These fixed filesystem limits make it much easier to implement
|
||||
* filesystem space allocation.
|
||||
*/
|
||||
#define MEMFS_TOTAL_SIZE SZ_4MB
|
||||
#define MEMFS_TOTAL_INODES 128
|
||||
#define MEMFS_TOTAL_BLOCKS 2000
|
||||
#define MEMFS_FMAX_BLOCKS 40
|
||||
#define MEMFS_BLOCK_SIZE PAGE_SIZE
|
||||
#define MEMFS_MAGIC 0xB
|
||||
#define MEMFS_NAME "memfs"
|
||||
#define MEMFS_NAME_SIZE 8
|
||||
|
||||
struct memfs_inode {
|
||||
u32 inum; /* Inode number */
|
||||
u32 mode; /* File permissions */
|
||||
u32 owner; /* File owner */
|
||||
u64 atime; /* Last access time */
|
||||
u64 mtime; /* Last content modification */
|
||||
u64 ctime; /* Last inode modification */
|
||||
u64 size; /* Size of contents */
|
||||
void *block[MEMFS_FMAX_BLOCKS]; /* Number of blocks */
|
||||
};
|
||||
|
||||
struct memfs_superblock {
|
||||
u32 magic; /* Filesystem magic number */
|
||||
char name[8];
|
||||
u32 blocksize; /* Filesystem block size */
|
||||
u64 fmaxblocks; /* Maximum number of blocks per file */
|
||||
u64 fssize; /* Total size of filesystem */
|
||||
unsigned long root_vnum; /* The root vnum of this superblock */
|
||||
struct link inode_cache_list; /* Chain of alloc caches */
|
||||
struct link block_cache_list; /* Chain of alloc caches */
|
||||
struct id_pool *ipool; /* Index pool for inodes */
|
||||
struct id_pool *bpool; /* Index pool for blocks */
|
||||
struct memfs_inode *inode[MEMFS_TOTAL_INODES]; /* Table of inodes */
|
||||
void *block[MEMFS_TOTAL_BLOCKS]; /* Table of fs blocks */
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
#define MEMFS_DNAME_MAX 32
|
||||
struct memfs_dentry {
|
||||
u32 inum; /* Inode number */
|
||||
u32 offset; /* Dentry offset in its buffer */
|
||||
u16 rlength; /* Record length */
|
||||
u8 name[MEMFS_DNAME_MAX]; /* Name string */
|
||||
};
|
||||
|
||||
extern struct vnode_ops memfs_vnode_operations;
|
||||
extern struct superblock_ops memfs_superblock_operations;
|
||||
extern struct file_ops memfs_file_operations;
|
||||
|
||||
int memfs_format_filesystem(void *buffer);
|
||||
struct memfs_inode *memfs_create_inode(struct memfs_superblock *sb);
|
||||
void memfs_register_fstype(struct link *);
|
||||
struct superblock *memfs_get_superblock(void *block);
|
||||
int memfs_generate_superblock(void *block);
|
||||
|
||||
void *memfs_alloc_block(struct memfs_superblock *sb);
|
||||
int memfs_free_block(struct memfs_superblock *sb, void *block);
|
||||
#endif /* __MEMFS_LAYOUT_H__ */
|
||||
7
conts/posix/fs0/include/memfs/vnode.h
Normal file
7
conts/posix/fs0/include/memfs/vnode.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef __MEMFS_VNODE_H__
|
||||
#define __MEMFS_VNODE_H__
|
||||
|
||||
#include <fs.h>
|
||||
|
||||
|
||||
#endif /* __MEMFS_VNODE_H__ */
|
||||
41
conts/posix/fs0/include/path.h
Normal file
41
conts/posix/fs0/include/path.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*
|
||||
* Path lookup related information
|
||||
*/
|
||||
#ifndef __PATH_H__
|
||||
#define __PATH_H__
|
||||
|
||||
#include <l4/lib/list.h>
|
||||
#include <task.h>
|
||||
|
||||
/*
|
||||
* FIXME:
|
||||
* These ought to be strings and split/comparison functions should
|
||||
* always use strings because formats like UTF-8 wouldn't work.
|
||||
*/
|
||||
#define VFS_CHAR_SEP '/'
|
||||
#define VFS_STR_ROOTDIR "/"
|
||||
#define VFS_STR_PARDIR ".."
|
||||
#define VFS_STR_CURDIR "."
|
||||
#define VFS_STR_XATDIR "...."
|
||||
|
||||
struct pathdata {
|
||||
struct link list;
|
||||
struct vnode *vstart;
|
||||
};
|
||||
|
||||
struct pathcomp {
|
||||
struct link list;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
struct pathdata *pathdata_parse(const char *pathname, char *pathbuf,
|
||||
struct tcb *task);
|
||||
void pathdata_destroy(struct pathdata *p);
|
||||
|
||||
/* Destructive, i.e. unlinks those components from list */
|
||||
const char *pathdata_next_component(struct pathdata *pdata);
|
||||
const char *pathdata_last_component(struct pathdata *pdata);
|
||||
|
||||
#endif /* __PATH_H__ */
|
||||
82
conts/posix/fs0/include/stat.h
Normal file
82
conts/posix/fs0/include/stat.h
Normal file
@@ -0,0 +1,82 @@
|
||||
#ifndef __FS0_STAT_H__
|
||||
#define __FS0_STAT_H__
|
||||
|
||||
/* Posix definitions for file mode flags (covers type and access permissions) */
|
||||
#define S_IFMT 00170000
|
||||
#define S_IFSOCK 0140000
|
||||
#define S_IFLNK 0120000
|
||||
#define S_IFREG 0100000
|
||||
#define S_IFBLK 0060000
|
||||
#define S_IFDIR 0040000
|
||||
#define S_IFCHR 0020000
|
||||
#define S_IFIFO 0010000
|
||||
#define S_ISUID 0004000
|
||||
#define S_ISGID 0002000
|
||||
#define S_ISVTX 0001000
|
||||
|
||||
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
|
||||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
|
||||
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
|
||||
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
|
||||
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
|
||||
|
||||
#define S_IRWXU 00700
|
||||
#define S_IRUSR 00400
|
||||
#define S_IWUSR 00200
|
||||
#define S_IXUSR 00100
|
||||
|
||||
#define S_IRWXG 00070
|
||||
#define S_IRGRP 00040
|
||||
#define S_IWGRP 00020
|
||||
#define S_IXGRP 00010
|
||||
|
||||
#define S_IRWXO 00007
|
||||
#define S_IROTH 00004
|
||||
#define S_IWOTH 00002
|
||||
#define S_IXOTH 00001
|
||||
|
||||
#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
|
||||
#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
|
||||
#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
|
||||
#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
|
||||
#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
|
||||
|
||||
#define O_ACCMODE 00000003
|
||||
#define O_RDONLY 00000000
|
||||
#define O_WRONLY 00000001
|
||||
#define O_RDWR 00000002
|
||||
#define O_CREAT 00000100
|
||||
#define O_EXCL 00000200
|
||||
#define O_NOCTTY 00000400
|
||||
#define O_TRUNC 00001000
|
||||
#define O_APPEND 00002000
|
||||
#define O_NONBLOCK 00004000
|
||||
#define O_SYNC 00010000
|
||||
#define FASYNC 00020000
|
||||
#define O_DIRECT 00040000
|
||||
#define O_LARGEFILE 00100000
|
||||
#define O_DIRECTORY 00200000
|
||||
#define O_NOFOLLOW 00400000
|
||||
#define O_NOATIME 01000000
|
||||
#define O_NDELAY O_NONBLOCK
|
||||
|
||||
/*
|
||||
* Internal codezero-specific stat structure.
|
||||
* This is converted to posix stat in userspace
|
||||
*/
|
||||
struct kstat {
|
||||
u64 vnum;
|
||||
u32 mode;
|
||||
int links;
|
||||
u16 uid;
|
||||
u16 gid;
|
||||
u64 size;
|
||||
int blksize;
|
||||
u64 atime;
|
||||
u64 mtime;
|
||||
u64 ctime;
|
||||
};
|
||||
|
||||
#endif /* __FS0_STAT_H__ */
|
||||
35
conts/posix/fs0/include/syscalls.h
Normal file
35
conts/posix/fs0/include/syscalls.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* System call function signatures.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
*/
|
||||
#ifndef __FS0_SYSCALLS_H__
|
||||
#define __FS0_SYSCALLS_H__
|
||||
|
||||
#include <task.h>
|
||||
|
||||
/* Posix calls */
|
||||
int sys_open(struct tcb *sender, const char *pathname, int flags, u32 mode);
|
||||
int sys_readdir(struct tcb *sender, int fd, void *buf, int count);
|
||||
int sys_mkdir(struct tcb *sender, const char *pathname, unsigned int mode);
|
||||
int sys_chdir(struct tcb *sender, const char *pathname);
|
||||
|
||||
/* Calls from pager that completes a posix call */
|
||||
int pager_open_bypath(struct tcb *pager, char *pathname);
|
||||
int pager_sys_open(struct tcb *sender, l4id_t opener, int fd);
|
||||
int pager_sys_read(struct tcb *sender, unsigned long vnum, unsigned long f_offset,
|
||||
unsigned long npages, void *pagebuf);
|
||||
|
||||
int pager_sys_write(struct tcb *sender, unsigned long vnum, unsigned long f_offset,
|
||||
unsigned long npages, void *pagebuf);
|
||||
|
||||
int pager_sys_close(struct tcb *sender, l4id_t closer, int fd);
|
||||
int pager_update_stats(struct tcb *sender, unsigned long vnum,
|
||||
unsigned long newsize);
|
||||
|
||||
int pager_notify_fork(struct tcb *sender, l4id_t parentid,
|
||||
l4id_t childid, unsigned long utcb_address,
|
||||
unsigned int flags);
|
||||
|
||||
int pager_notify_exit(struct tcb *sender, l4id_t tid);
|
||||
#endif /* __FS0_SYSCALLS_H__ */
|
||||
55
conts/posix/fs0/include/task.h
Normal file
55
conts/posix/fs0/include/task.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#ifndef __FS0_TASK_H__
|
||||
#define __FS0_TASK_H__
|
||||
|
||||
#include <lib/idpool.h>
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4/api/kip.h>
|
||||
|
||||
#define __TASKNAME__ __VFSNAME__
|
||||
|
||||
#define TCB_NO_SHARING 0
|
||||
#define TCB_SHARED_VM (1 << 0)
|
||||
#define TCB_SHARED_FILES (1 << 1)
|
||||
#define TCB_SHARED_FS (1 << 2)
|
||||
|
||||
#define TASK_FILES_MAX 32
|
||||
|
||||
struct task_fd_head {
|
||||
int fd[TASK_FILES_MAX];
|
||||
struct id_pool *fdpool;
|
||||
int tcb_refs;
|
||||
};
|
||||
|
||||
struct task_fs_data {
|
||||
struct vnode *curdir;
|
||||
struct vnode *rootdir;
|
||||
int tcb_refs;
|
||||
};
|
||||
|
||||
/* Thread control block, fs0 portion */
|
||||
struct tcb {
|
||||
l4id_t tid;
|
||||
struct link list;
|
||||
unsigned long shpage_address;
|
||||
struct task_fd_head *files;
|
||||
struct task_fs_data *fs_data;
|
||||
};
|
||||
|
||||
/* Structures used when receiving new task info from pager */
|
||||
struct task_data {
|
||||
unsigned long tid;
|
||||
unsigned long shpage_address;
|
||||
};
|
||||
|
||||
struct task_data_head {
|
||||
unsigned long total;
|
||||
struct task_data tdata[];
|
||||
};
|
||||
|
||||
struct tcb *find_task(int tid);
|
||||
int init_task_data(void);
|
||||
|
||||
#endif /* __FS0_TASK_H__ */
|
||||
90
conts/posix/fs0/include/vfs.h
Normal file
90
conts/posix/fs0/include/vfs.h
Normal file
@@ -0,0 +1,90 @@
|
||||
#ifndef __VFS_H__
|
||||
#define __VFS_H__
|
||||
|
||||
#include <fs.h>
|
||||
#include <lib/malloc.h>
|
||||
#include <l4/lib/list.h>
|
||||
#include <memfs/memfs.h>
|
||||
#include <l4/macros.h>
|
||||
#include <stdio.h>
|
||||
#include <task.h>
|
||||
#include <path.h>
|
||||
|
||||
extern struct link vnode_cache;
|
||||
extern struct link dentry_cache;
|
||||
|
||||
/*
|
||||
* This is a temporary origacement for page cache support provided by mm0.
|
||||
* Normally mm0 tracks all vnode pages, but this is used to track pages in
|
||||
* directory vnodes, which are normally never mapped by tasks.
|
||||
*/
|
||||
static inline void *vfs_alloc_dirpage(struct vnode *v)
|
||||
{
|
||||
/*
|
||||
* Urgh, we allocate from the block cache of memfs to store generic vfs directory
|
||||
* pages. This is currently the quickest we can allocate page-aligned memory.
|
||||
*/
|
||||
return memfs_alloc_block(v->sb->fs_super);
|
||||
}
|
||||
|
||||
static inline void vfs_free_dirpage(struct vnode *v, void *block)
|
||||
{
|
||||
memfs_free_block(v->sb->fs_super, block);
|
||||
}
|
||||
|
||||
static inline struct dentry *vfs_alloc_dentry(void)
|
||||
{
|
||||
struct dentry *d = kzalloc(sizeof(struct dentry));
|
||||
|
||||
link_init(&d->child);
|
||||
link_init(&d->children);
|
||||
link_init(&d->vref);
|
||||
link_init(&d->cache_list);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
static inline void vfs_free_dentry(struct dentry *d)
|
||||
{
|
||||
return kfree(d);
|
||||
}
|
||||
|
||||
static inline struct vnode *vfs_alloc_vnode(void)
|
||||
{
|
||||
struct vnode *v = kzalloc(sizeof(struct vnode));
|
||||
|
||||
link_init(&v->dentries);
|
||||
link_init(&v->cache_list);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline void vfs_free_vnode(struct vnode *v)
|
||||
{
|
||||
BUG(); /* Are the dentries freed ??? */
|
||||
list_remove(&v->cache_list);
|
||||
kfree(v);
|
||||
}
|
||||
|
||||
static inline struct superblock *vfs_alloc_superblock(void)
|
||||
{
|
||||
struct superblock *sb = kmalloc(sizeof(struct superblock));
|
||||
link_init(&sb->list);
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
struct vfs_mountpoint {
|
||||
struct superblock *sb; /* The superblock of mounted filesystem */
|
||||
struct vnode *pivot; /* The dentry upon which we mount */
|
||||
};
|
||||
|
||||
extern struct vfs_mountpoint vfs_root;
|
||||
|
||||
int vfs_mount_root(struct superblock *sb);
|
||||
struct vnode *generic_vnode_lookup(struct vnode *thisnode, struct pathdata *p,
|
||||
const char *component);
|
||||
struct vnode *vfs_lookup_bypath(struct pathdata *p);
|
||||
struct vnode *vfs_lookup_byvnum(struct superblock *sb, unsigned long vnum);
|
||||
|
||||
#endif /* __VFS_H__ */
|
||||
148
conts/posix/fs0/main.c
Normal file
148
conts/posix/fs0/main.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* FS0. Filesystem implementation
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/kip.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <fs.h>
|
||||
#include <init.h>
|
||||
#include <syscalls.h>
|
||||
#include <task.h>
|
||||
#include <posix/sys/time.h>
|
||||
#include <l4/api/errno.h>
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* - Have a dentry cache searchable by name
|
||||
* - Have a vnode cache searchable by vnum (and name?)
|
||||
* - fs-specific readdir would read contents by page range, and add vnodes/dentries
|
||||
* to their caches, while populating the directory vnode being read.
|
||||
* - Have 2 vfs_lookup() flavors, one that searches a path, one that searches a vnum.
|
||||
* - dirbuf is either allocated by low-level readdir, or else by a higher level, i.e.
|
||||
* either high-level vfs code, or the mm0 page cache.
|
||||
* - readdir provides a posix-compliant dirent structure list in dirbuf.
|
||||
* - memfs dentries should be identical to posix struct dirents.
|
||||
*
|
||||
* ALL DONE!!! But untested.
|
||||
*
|
||||
* - Add mkdir
|
||||
* - Add create
|
||||
* - Add read/write -> This will need page cache and mm0 involvement.
|
||||
*
|
||||
* Done those, too. but untested.
|
||||
*/
|
||||
|
||||
/* Synchronise with pager via a `wait' tagged ipc with destination as pager */
|
||||
void wait_pager(l4id_t partner)
|
||||
{
|
||||
l4_send(partner, L4_IPC_TAG_SYNC);
|
||||
// printf("%s: Pager synced with us.\n", __TASKNAME__);
|
||||
}
|
||||
|
||||
void handle_fs_requests(void)
|
||||
{
|
||||
u32 mr[MR_UNUSED_TOTAL];
|
||||
l4id_t senderid;
|
||||
struct tcb *sender;
|
||||
int ret;
|
||||
u32 tag;
|
||||
|
||||
if ((ret = l4_receive(L4_ANYTHREAD)) < 0) {
|
||||
printf("%s: %s: IPC Error: %d. Quitting...\n", __TASKNAME__,
|
||||
__FUNCTION__, ret);
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* Read conventional ipc data */
|
||||
tag = l4_get_tag();
|
||||
senderid = l4_get_sender();
|
||||
|
||||
if (!(sender = find_task(senderid))) {
|
||||
l4_ipc_return(-ESRCH);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read mrs not used by syslib */
|
||||
for (int i = 0; i < MR_UNUSED_TOTAL; i++)
|
||||
mr[i] = read_mr(MR_UNUSED_START + i);
|
||||
|
||||
/* FIXME: Fix all these syscalls to read any buffer data from the caller task's utcb.
|
||||
* Make sure to return -EINVAL if data is not valid. */
|
||||
switch(tag) {
|
||||
case L4_IPC_TAG_SYNC:
|
||||
printf("%s: Synced with waiting thread.\n", __TASKNAME__);
|
||||
return; /* No origy for this tag */
|
||||
case L4_IPC_TAG_OPEN:
|
||||
ret = sys_open(sender, (void *)mr[0], (int)mr[1], (unsigned int)mr[2]);
|
||||
break;
|
||||
case L4_IPC_TAG_MKDIR:
|
||||
ret = sys_mkdir(sender, (const char *)mr[0], (unsigned int)mr[1]);
|
||||
break;
|
||||
case L4_IPC_TAG_CHDIR:
|
||||
ret = sys_chdir(sender, (const char *)mr[0]);
|
||||
break;
|
||||
case L4_IPC_TAG_READDIR:
|
||||
ret = sys_readdir(sender, (int)mr[0], (void *)mr[1], (int)mr[2]);
|
||||
break;
|
||||
case L4_IPC_TAG_PAGER_READ:
|
||||
ret = pager_sys_read(sender, (unsigned long)mr[0], (unsigned long)mr[1],
|
||||
(unsigned long)mr[2], (void *)mr[3]);
|
||||
break;
|
||||
case L4_IPC_TAG_PAGER_OPEN:
|
||||
ret = pager_sys_open(sender, (l4id_t)mr[0], (int)mr[1]);
|
||||
break;
|
||||
case L4_IPC_TAG_PAGER_OPEN_BYPATH:
|
||||
ret = pager_open_bypath(sender, (char *)mr[0]);
|
||||
break;
|
||||
case L4_IPC_TAG_PAGER_WRITE:
|
||||
ret = pager_sys_write(sender, (unsigned long)mr[0], (unsigned long)mr[1],
|
||||
(unsigned long)mr[2], (void *)mr[3]);
|
||||
break;
|
||||
case L4_IPC_TAG_PAGER_CLOSE:
|
||||
ret = pager_sys_close(sender, (l4id_t)mr[0], (int)mr[1]);
|
||||
break;
|
||||
case L4_IPC_TAG_PAGER_UPDATE_STATS:
|
||||
ret = pager_update_stats(sender, (unsigned long)mr[0],
|
||||
(unsigned long)mr[1]);
|
||||
break;
|
||||
case L4_IPC_TAG_NOTIFY_FORK:
|
||||
ret = pager_notify_fork(sender, (l4id_t)mr[0], (l4id_t)mr[1],
|
||||
(unsigned long)mr[2], (unsigned int)mr[3]);
|
||||
break;
|
||||
case L4_IPC_TAG_NOTIFY_EXIT:
|
||||
ret = pager_notify_exit(sender, (l4id_t)mr[0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("%s: Unrecognised ipc tag (%d) "
|
||||
"received from tid: %d. Ignoring.\n", __TASKNAME__,
|
||||
mr[MR_TAG], senderid);
|
||||
}
|
||||
|
||||
/* Reply */
|
||||
if ((ret = l4_ipc_return(ret)) < 0) {
|
||||
printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, ret);
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
printf("\n%s: Started with thread id %d\n", __TASKNAME__, self_tid());
|
||||
|
||||
initialise();
|
||||
|
||||
wait_pager(PAGER_TID);
|
||||
|
||||
printf("%s: VFS service initialized. Listening requests.\n", __TASKNAME__);
|
||||
while (1) {
|
||||
handle_fs_requests();
|
||||
}
|
||||
}
|
||||
|
||||
15
conts/posix/fs0/src/bdev.c
Normal file
15
conts/posix/fs0/src/bdev.c
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* This is just to allocate some memory as a block device.
|
||||
*/
|
||||
#include <l4/macros.h>
|
||||
#include <memfs/memfs.h>
|
||||
|
||||
extern char _start_bdev[];
|
||||
extern char _end_bdev[];
|
||||
|
||||
__attribute__((section(".data.memfs"))) char blockdevice[MEMFS_TOTAL_SIZE];
|
||||
|
||||
void *vfs_rootdev_open(void)
|
||||
{
|
||||
return (void *)_start_bdev;
|
||||
}
|
||||
147
conts/posix/fs0/src/bootfs/bootfs.c
Normal file
147
conts/posix/fs0/src/bootfs/bootfs.c
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* A pseudo-filesystem for reading the in-memory
|
||||
* server tasks loaded from the initial elf executable.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
*/
|
||||
#include <fs.h>
|
||||
#include <l4/lib/list.h>
|
||||
#include <malloc.h>
|
||||
|
||||
struct dentry *bootfs_dentry_lookup(struct dentry *d, char *dname)
|
||||
{
|
||||
struct dentry *this;
|
||||
|
||||
list_foreach_struct(this, child, &d->children) {
|
||||
if (this->compare(this, dname))
|
||||
return this;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dentry *path_lookup(struct superblock *sb, char *pathstr)
|
||||
{
|
||||
char *dname;
|
||||
char *splitpath;
|
||||
struct dentry *this, *next;
|
||||
|
||||
/* First dentry is root */
|
||||
this = sb->root;
|
||||
|
||||
/* Get next path component from path string */
|
||||
dname = path_next_dentry_name(pathstr);
|
||||
|
||||
if (!this->compare(dname))
|
||||
return;
|
||||
|
||||
while(!(dname = path_next_dentry_name(pathstr))) {
|
||||
if ((d = this->lookup(this, dname)))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This creates a pseudo-filesystem tree from the loaded
|
||||
* server elf images whose information is available from
|
||||
* initdata.
|
||||
*/
|
||||
void bootfs_populate(struct initdata *initdata, struct superblock *sb)
|
||||
{
|
||||
struct bootdesc *bd = initdata->bootdesc;
|
||||
struct svc_image *img;
|
||||
struct dentry *d;
|
||||
struct vnode *v;
|
||||
struct file *f;
|
||||
|
||||
for (int i = 0; i < bd->total_images; i++) {
|
||||
img = &bd->images[i];
|
||||
|
||||
d = malloc(sizeof(struct dentry));
|
||||
v = malloc(sizeof(struct vnode));
|
||||
f = malloc(sizeof(struct file));
|
||||
|
||||
/* Initialise dentry for image */
|
||||
d->refcnt = 0;
|
||||
d->vnode = v;
|
||||
d->parent = sb->root;
|
||||
strncpy(d->name, img->name, VFS_DENTRY_NAME_MAX);
|
||||
link_init(&d->child);
|
||||
link_init(&d->children);
|
||||
list_insert(&d->child, &sb->root->children);
|
||||
|
||||
/* Initialise vnode for image */
|
||||
v->refcnt = 0;
|
||||
v->id = img->phys_start;
|
||||
v->size = img->phys_end - img->phys_start;
|
||||
link_init(&v->dirents);
|
||||
list_insert(&d->v_ref, &v->dirents);
|
||||
|
||||
/* Initialise file struct for image */
|
||||
f->refcnt = 0;
|
||||
f->dentry = d;
|
||||
|
||||
img_d++;
|
||||
img_vn++;
|
||||
img_f++;
|
||||
}
|
||||
}
|
||||
|
||||
void bootfs_init_root(struct dentry *r)
|
||||
{
|
||||
struct vnode *v = r->vnode;
|
||||
|
||||
/* Initialise dentry for rootdir */
|
||||
r->refcnt = 0;
|
||||
strcpy(r->name, "");
|
||||
link_init(&r->child);
|
||||
link_init(&r->children);
|
||||
link_init(&r->vref);
|
||||
r->parent = r;
|
||||
|
||||
/* Initialise vnode for rootdir */
|
||||
v->id = 0;
|
||||
v->refcnt = 0;
|
||||
link_init(&v->dirents);
|
||||
link_init(&v->state_list);
|
||||
list_insert(&r->vref, &v->dirents);
|
||||
v->size = 0;
|
||||
}
|
||||
|
||||
struct superblock *bootfs_init_sb(struct superblock *sb)
|
||||
{
|
||||
sb->root = malloc(sizeof(struct dentry));
|
||||
sb->root->vnode = malloc(sizeof(struct vnode));
|
||||
|
||||
bootfs_init_root(&sb->root);
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
struct superblock bootfs_sb = {
|
||||
.fs = bootfs_type,
|
||||
.ops = {
|
||||
.read_sb = bootfs_read_sb,
|
||||
.write_sb = bootfs_write_sb,
|
||||
.read_vnode = bootfs_read_vnode,
|
||||
.write_vnode = bootfs_write_vnode,
|
||||
},
|
||||
};
|
||||
|
||||
struct superblock *bootfs_get_sb(void)
|
||||
{
|
||||
bootfs_init_sb(&bootfs_sb);
|
||||
return &bootfs_sb;
|
||||
}
|
||||
|
||||
struct file_system_type bootfs_type = {
|
||||
.name = "bootfs",
|
||||
.magic = 0,
|
||||
.get_sb = bootfs_get_sb,
|
||||
};
|
||||
|
||||
void init_bootfs()
|
||||
{
|
||||
bootfs_init_sb(&bootfs_sb);
|
||||
|
||||
bootfs_populate(&bootfs_sb);
|
||||
}
|
||||
29
conts/posix/fs0/src/c0fs/c0fs.c
Normal file
29
conts/posix/fs0/src/c0fs/c0fs.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* A basic unix-like read/writeable filesystem for Codezero.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
*/
|
||||
#include <init.h>
|
||||
#include <fs.h>
|
||||
|
||||
void sfs_read_sb(struct superblock *sb)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void simplefs_alloc_vnode(struct vnode *)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
struct file_system_type sfs_type = {
|
||||
.name = "c0fs",
|
||||
.magic = 1,
|
||||
.flags = 0,
|
||||
};
|
||||
|
||||
/* Registers sfs as an available filesystem type */
|
||||
void sfs_register_fstype(struct link *fslist)
|
||||
{
|
||||
list_insert(&sfs_type.list, fslist);
|
||||
}
|
||||
113
conts/posix/fs0/src/c0fs/c0fs.h
Normal file
113
conts/posix/fs0/src/c0fs/c0fs.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* The disk layout of our simple unix-like filesystem.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
*/
|
||||
|
||||
#ifndef __C0FS_LAYOUT_H__
|
||||
#define __C0FS_LAYOUT_H__
|
||||
|
||||
#include <l4lib/types.h>
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4/macros.h>
|
||||
#include <l4/config.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
|
||||
/*
|
||||
*
|
||||
* Filesystem layout:
|
||||
*
|
||||
* |---------------|
|
||||
* | Group 0 |
|
||||
* |---------------|
|
||||
* | Group 1 |
|
||||
* |---------------|
|
||||
* | ... |
|
||||
* |---------------|
|
||||
* | Group n |
|
||||
* |---------------|
|
||||
*
|
||||
*
|
||||
* Group layout:
|
||||
*
|
||||
* |---------------|
|
||||
* | Superblock |
|
||||
* |---------------|
|
||||
* | Inode table |
|
||||
* |---------------|
|
||||
* | Data blocks |
|
||||
* |---------------|
|
||||
*
|
||||
* or
|
||||
*
|
||||
* |---------------|
|
||||
* | Data blocks |
|
||||
* |---------------|
|
||||
*
|
||||
*/
|
||||
|
||||
#define BLOCK_SIZE PAGE_SIZE
|
||||
#define BLOCK_BITS PAGE_BITS
|
||||
#define GROUP_SIZE SZ_8MB
|
||||
#define INODE_TABLE_SIZE ((GROUP_SIZE / BLOCK_SIZE) / 2)
|
||||
#define INODE_BITMAP_SIZE (INODE_TABLE_SIZE >> 5)
|
||||
|
||||
|
||||
struct sfs_superblock {
|
||||
u32 magic; /* Filesystem magic number */
|
||||
u64 fssize; /* Total size of filesystem */
|
||||
u32 total; /* To */
|
||||
u32 groupmap[]; /* Bitmap of all fs groups */
|
||||
};
|
||||
|
||||
struct sfs_group_table {
|
||||
u32 total;
|
||||
u32 free;
|
||||
u32 groupmap[];
|
||||
};
|
||||
|
||||
struct sfs_inode_table {
|
||||
u32 total;
|
||||
u32 free;
|
||||
u32 inodemap[INODE_BITMAP_SIZE];
|
||||
struct sfs_inode inode[INODE_TABLE_SIZE];
|
||||
};
|
||||
|
||||
/*
|
||||
* The purpose of an inode:
|
||||
*
|
||||
* 1) Uniquely identify a file or a directory.
|
||||
* 2) Keep file/directory metadata.
|
||||
* 3) Provide access means to file blocks/directory contents.
|
||||
*/
|
||||
#define INODE_DIRECT_BLOCKS 5
|
||||
struct sfs_inode_blocks {
|
||||
int szidx; /* Direct array index size */
|
||||
unsigned long indirect;
|
||||
unsigned long indirect2;
|
||||
unsigned long indirect3;
|
||||
unsigned long direct[];
|
||||
};
|
||||
|
||||
struct sfs_inode {
|
||||
u32 unum; /* Unit number this inode is in */
|
||||
u32 inum; /* Inode number */
|
||||
u32 mode; /* File permissions */
|
||||
u32 owner; /* File owner */
|
||||
u64 atime; /* Last access time */
|
||||
u64 mtime; /* Last content modification */
|
||||
u64 ctime; /* Last inode modification */
|
||||
u64 size; /* Size of contents */
|
||||
struct sfs_inode_blocks blocks;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct sfs_dentry {
|
||||
u32 inum; /* Inode number */
|
||||
u32 nlength; /* Name length */
|
||||
u8 name[]; /* Name string */
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
|
||||
void sfs_register_type(struct link *);
|
||||
|
||||
#endif /* __C0FS_LAYOUT_H__ */
|
||||
94
conts/posix/fs0/src/crt0.S
Normal file
94
conts/posix/fs0/src/crt0.S
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Australian Public Licence B (OZPLB)
|
||||
*
|
||||
* Version 1-0
|
||||
*
|
||||
* Copyright (c) 2004 National ICT Australia
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by: Embedded, Real-time and Operating Systems Program (ERTOS)
|
||||
* National ICT Australia
|
||||
* http://www.ertos.nicta.com.au
|
||||
*
|
||||
* Permission is granted by National ICT Australia, free of charge, to
|
||||
* any person obtaining a copy of this software and any associated
|
||||
* documentation files (the "Software") to deal with the Software without
|
||||
* restriction, including (without limitation) the rights to use, copy,
|
||||
* modify, adapt, merge, publish, distribute, communicate to the public,
|
||||
* sublicense, and/or sell, lend or rent out copies of the Software, and
|
||||
* to permit persons to whom the Software is furnished to do so, subject
|
||||
* to the following conditions:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimers.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimers in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* * Neither the name of National ICT Australia, nor the names of its
|
||||
* contributors, may be used to endorse or promote products derived
|
||||
* from this Software without specific prior written permission.
|
||||
*
|
||||
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
|
||||
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
|
||||
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
|
||||
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
|
||||
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
|
||||
* ERRORS, WHETHER OR NOT DISCOVERABLE.
|
||||
*
|
||||
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
|
||||
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
|
||||
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
|
||||
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
|
||||
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
|
||||
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
|
||||
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
|
||||
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
|
||||
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
|
||||
* DAMAGES OR OTHER LIABILITY.
|
||||
*
|
||||
* If applicable legislation implies representations, warranties, or
|
||||
* conditions, or imposes obligations or liability on National ICT
|
||||
* Australia or one of its contributors in respect of the Software that
|
||||
* cannot be wholly or partly excluded, restricted or modified, the
|
||||
* liability of National ICT Australia or the contributor is limited, to
|
||||
* the full extent permitted by the applicable legislation, at its
|
||||
* option, to:
|
||||
* a. in the case of goods, any one or more of the following:
|
||||
* i. the replacement of the goods or the supply of equivalent goods;
|
||||
* ii. the repair of the goods;
|
||||
* iii. the payment of the cost of replacing the goods or of acquiring
|
||||
* equivalent goods;
|
||||
* iv. the payment of the cost of having the goods repaired; or
|
||||
* b. in the case of services:
|
||||
* i. the supplying of the services again; or
|
||||
* ii. the payment of the cost of having the services supplied again.
|
||||
*
|
||||
* The construction, validity and performance of this licence is governed
|
||||
* by the laws in force in New South Wales, Australia.
|
||||
*/
|
||||
|
||||
#ifdef __thumb__
|
||||
#define bl blx
|
||||
#endif
|
||||
|
||||
.section .text.head
|
||||
.code 32
|
||||
.global _start;
|
||||
.align;
|
||||
_start:
|
||||
ldr sp, =__stack
|
||||
bl platform_init
|
||||
bl __container_init
|
||||
1:
|
||||
b 1b
|
||||
|
||||
25
conts/posix/fs0/src/file.c
Normal file
25
conts/posix/fs0/src/file.c
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* File content tracking.
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <fs.h>
|
||||
#include <file.h>
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4/macros.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* This reads contents of a file in pages, calling the fs-specific file read function to read-in
|
||||
* those pages' contents.
|
||||
*
|
||||
* Normally this is ought to be called by mm0 when a file's pages cannot be found in the page
|
||||
* cache.
|
||||
*/
|
||||
int generic_file_read(struct vnode *v, unsigned long pfn, unsigned long npages, void *page_buf)
|
||||
{
|
||||
BUG_ON(!is_page_aligned(page_buf));
|
||||
|
||||
return v->fops.read(v, pfn, npages, page_buf);
|
||||
}
|
||||
91
conts/posix/fs0/src/init.c
Normal file
91
conts/posix/fs0/src/init.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* FS0 Initialisation.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#include <fs.h>
|
||||
#include <vfs.h>
|
||||
#include <bdev.h>
|
||||
#include <task.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include <memfs/memfs.h>
|
||||
|
||||
struct link fs_type_list;
|
||||
|
||||
struct superblock *vfs_probe_filesystems(void *block)
|
||||
{
|
||||
struct file_system_type *fstype;
|
||||
struct superblock *sb;
|
||||
|
||||
list_foreach_struct(fstype, &fs_type_list, list) {
|
||||
/* Does the superblock match for this fs type? */
|
||||
if ((sb = fstype->ops.get_superblock(block))) {
|
||||
/*
|
||||
* Add this to the list of superblocks this
|
||||
* fs already has.
|
||||
*/
|
||||
list_insert(&sb->list, &fstype->sblist);
|
||||
return sb;
|
||||
}
|
||||
}
|
||||
|
||||
return PTR_ERR(-ENODEV);
|
||||
}
|
||||
|
||||
/*
|
||||
* Registers each available filesystem so that these can be
|
||||
* used when probing superblocks on block devices.
|
||||
*/
|
||||
void vfs_register_filesystems(void)
|
||||
{
|
||||
/* Initialise fstype list */
|
||||
link_init(&fs_type_list);
|
||||
|
||||
/* Call per-fs registration functions */
|
||||
memfs_register_fstype(&fs_type_list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Filesystem initialisation.
|
||||
*/
|
||||
int initialise(void)
|
||||
{
|
||||
void *rootdev_blocks;
|
||||
struct superblock *root_sb;
|
||||
|
||||
/* Get standard init data from microkernel */
|
||||
// request_initdata(&initdata);
|
||||
|
||||
/* Register compiled-in filesystems with vfs core. */
|
||||
vfs_register_filesystems();
|
||||
|
||||
/* Get a pointer to first block of root block device */
|
||||
rootdev_blocks = vfs_rootdev_open();
|
||||
|
||||
/*
|
||||
* Since the *only* filesystem we have is a temporary memory
|
||||
* filesystem, we create it on the root device first.
|
||||
*/
|
||||
memfs_format_filesystem(rootdev_blocks);
|
||||
|
||||
/* Search for a filesystem on the root device */
|
||||
BUG_ON(IS_ERR(root_sb = vfs_probe_filesystems(rootdev_blocks)));
|
||||
|
||||
/* Mount the filesystem on the root device */
|
||||
vfs_mount_root(root_sb);
|
||||
|
||||
printf("%s: Mounted memfs root filesystem.\n", __TASKNAME__);
|
||||
|
||||
/* Learn about what tasks are running */
|
||||
init_task_data();
|
||||
|
||||
/*
|
||||
* Initialisation is done. From here on, we can start
|
||||
* serving filesystem requests.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
111
conts/posix/fs0/src/lib/bit.c
Normal file
111
conts/posix/fs0/src/lib/bit.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Bit manipulation functions.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#include <lib/bit.h>
|
||||
#include <l4/macros.h>
|
||||
#include <l4/config.h>
|
||||
#include <stdio.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
|
||||
/* Emulation of ARM's CLZ (count leading zeroes) instruction */
|
||||
unsigned int __clz(unsigned int bitvector)
|
||||
{
|
||||
unsigned int x = 0;
|
||||
while((!(bitvector & ((unsigned)1 << 31))) && (x < 32)) {
|
||||
bitvector <<= 1;
|
||||
x++;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
int find_and_set_first_free_bit(u32 *word, unsigned int limit)
|
||||
{
|
||||
int success = 0;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < limit; i++) {
|
||||
/* Find first unset bit */
|
||||
if (!(word[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i))) {
|
||||
/* Set it */
|
||||
word[BITWISE_GETWORD(i)] |= BITWISE_GETBIT(i);
|
||||
success = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Return bit just set */
|
||||
if (success)
|
||||
return i;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int find_and_set_first_free_contig_bits(u32 *word, unsigned int limit,
|
||||
int nbits)
|
||||
{
|
||||
int i = 0, first = 0, last = 0, found = 0;
|
||||
|
||||
/* Can't allocate more than the limit */
|
||||
if (nbits > limit)
|
||||
return -1;
|
||||
|
||||
/* This is a state machine that checks n contiguous free bits. */
|
||||
while (i + nbits < limit) {
|
||||
first = i;
|
||||
last = i;
|
||||
while (!(word[BITWISE_GETWORD(last)] & BITWISE_GETBIT(last))) {
|
||||
last++;
|
||||
i++;
|
||||
if (last == first + nbits) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
/* If found, set the bits */
|
||||
if (found) {
|
||||
for (int x = first; x < first + nbits; x++)
|
||||
word[BITWISE_GETWORD(x)] |= BITWISE_GETBIT(x);
|
||||
return first;
|
||||
} else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int check_and_clear_bit(u32 *word, int bit)
|
||||
{
|
||||
/* Check that bit was set */
|
||||
if (word[BITWISE_GETWORD(bit)] & BITWISE_GETBIT(bit)) {
|
||||
word[BITWISE_GETWORD(bit)] &= ~BITWISE_GETBIT(bit);
|
||||
return 0;
|
||||
} else {
|
||||
printf("Trying to clear already clear bit\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int check_and_clear_contig_bits(u32 *word, int first, int nbits)
|
||||
{
|
||||
for (int i = first; i < first + nbits; i++)
|
||||
if (check_and_clear_bit(word, i) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int check_and_set_bit(u32 *word, int bit)
|
||||
{
|
||||
/* Check that bit was clear */
|
||||
if (!(word[BITWISE_GETWORD(bit)] & BITWISE_GETBIT(bit))) {
|
||||
word[BITWISE_GETWORD(bit)] |= BITWISE_GETBIT(bit);
|
||||
return 0;
|
||||
} else {
|
||||
//printf("Trying to set already set bit\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
81
conts/posix/fs0/src/lib/idpool.c
Normal file
81
conts/posix/fs0/src/lib/idpool.c
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Used for thread and space ids.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#include <lib/idpool.h>
|
||||
// #include <kmalloc/kmalloc.h> --> This requires page allocation to grow/shrink.
|
||||
#include <lib/malloc.h> // --> This is a local library that statically allocates its heap.
|
||||
#include <l4/macros.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include <stdio.h>
|
||||
#include <l4/api/errno.h>
|
||||
|
||||
struct id_pool *id_pool_new_init(int totalbits)
|
||||
{
|
||||
int nwords = BITWISE_GETWORD(totalbits);
|
||||
struct id_pool *new = kzalloc((nwords * SZ_WORD)
|
||||
+ sizeof(struct id_pool));
|
||||
if (!new)
|
||||
return PTR_ERR(-ENOMEM);
|
||||
new->nwords = nwords;
|
||||
return new;
|
||||
}
|
||||
|
||||
int id_new(struct id_pool *pool)
|
||||
{
|
||||
int id = find_and_set_first_free_bit(pool->bitmap,
|
||||
pool->nwords * WORD_BITS);
|
||||
if (id < 0)
|
||||
printf("%s: Warning! New id alloc failed\n", __FUNCTION__);
|
||||
return id;
|
||||
}
|
||||
|
||||
/* This finds n contiguous free ids, allocates and returns the first one */
|
||||
int ids_new_contiguous(struct id_pool *pool, int numids)
|
||||
{
|
||||
int id = find_and_set_first_free_contig_bits(pool->bitmap,
|
||||
pool->nwords *WORD_BITS,
|
||||
numids);
|
||||
if (id < 0)
|
||||
printf("%s: Warning! New id alloc failed\n", __FUNCTION__);
|
||||
return id;
|
||||
}
|
||||
|
||||
/* This deletes a list of contiguous ids given the first one and number of ids */
|
||||
int ids_del_contiguous(struct id_pool *pool, int first, int numids)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (pool->nwords * WORD_BITS < first + numids)
|
||||
return -1;
|
||||
if ((ret = check_and_clear_contig_bits(pool->bitmap, first, numids)))
|
||||
printf("%s: Error: Invalid argument range.\n", __FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int id_del(struct id_pool *pool, int id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (pool->nwords * WORD_BITS < id)
|
||||
return -1;
|
||||
|
||||
if ((ret = check_and_clear_bit(pool->bitmap, id) < 0))
|
||||
printf("%s: Error: Could not delete id.\n", __FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Return a specific id, if available */
|
||||
int id_get(struct id_pool *pool, int id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = check_and_set_bit(pool->bitmap, id);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else
|
||||
return id;
|
||||
}
|
||||
|
||||
417
conts/posix/fs0/src/lib/malloc.c
Normal file
417
conts/posix/fs0/src/lib/malloc.c
Normal file
@@ -0,0 +1,417 @@
|
||||
/*****************************************************************************
|
||||
Simple malloc
|
||||
Chris Giese <geezer@execpc.com> http://www.execpc.com/~geezer
|
||||
Release date: Oct 30, 2002
|
||||
This code is public domain (no copyright).
|
||||
You can do whatever you want with it.
|
||||
|
||||
Features:
|
||||
- First-fit
|
||||
- free() coalesces adjacent free blocks
|
||||
- Uses variable-sized heap, enlarged with kbrk()/sbrk() function
|
||||
- Does not use mmap()
|
||||
- Can be easily modified to use fixed-size heap
|
||||
- Works with 16- or 32-bit compilers
|
||||
|
||||
Build this program with either of the two main() functions, then run it.
|
||||
Messages that indicate a software error will contain three asterisks (***).
|
||||
*****************************************************************************/
|
||||
#include <string.h> /* memcpy(), memset() */
|
||||
#include <stdio.h> /* printf() */
|
||||
|
||||
#define _32BIT 1
|
||||
|
||||
/* use small (32K) heap for 16-bit compilers,
|
||||
large (500K) heap for 32-bit compilers */
|
||||
#if defined(_32BIT)
|
||||
#define HEAP_SIZE 500000uL
|
||||
#else
|
||||
#define HEAP_SIZE 32768u
|
||||
#endif
|
||||
|
||||
#define MALLOC_MAGIC 0x6D92 /* must be < 0x8000 */
|
||||
|
||||
typedef struct _malloc /* Turbo C DJGPP */
|
||||
{
|
||||
size_t size; /* 2 bytes 4 bytes */
|
||||
struct _malloc *next; /* 2 bytes 4 bytes */
|
||||
unsigned magic : 15; /* 2 bytes total 4 bytes total */
|
||||
unsigned used : 1;
|
||||
} malloc_t; /* total 6 bytes 12 bytes */
|
||||
|
||||
static char *g_heap_bot, *g_kbrk, *g_heap_top;
|
||||
/*****************************************************************************
|
||||
*****************************************************************************/
|
||||
void dump_heap(void)
|
||||
{
|
||||
unsigned blks_used = 0, blks_free = 0;
|
||||
size_t bytes_used = 0, bytes_free = 0;
|
||||
malloc_t *m;
|
||||
int total;
|
||||
|
||||
printf("===============================================\n");
|
||||
for(m = (malloc_t *)g_heap_bot; m != NULL; m = m->next)
|
||||
{
|
||||
printf("blk %5p: %6u bytes %s\n", m,
|
||||
m->size, m->used ? "used" : "free");
|
||||
if(m->used)
|
||||
{
|
||||
blks_used++;
|
||||
bytes_used += m->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
blks_free++;
|
||||
bytes_free += m->size;
|
||||
}
|
||||
}
|
||||
printf("blks: %6u used, %6u free, %6u total\n", blks_used,
|
||||
blks_free, blks_used + blks_free);
|
||||
printf("bytes: %6u used, %6u free, %6u total\n", bytes_used,
|
||||
bytes_free, bytes_used + bytes_free);
|
||||
printf("g_heap_bot=0x%p, g_kbrk=0x%p, g_heap_top=0x%p\n",
|
||||
g_heap_bot, g_kbrk, g_heap_top);
|
||||
total = (bytes_used + bytes_free) +
|
||||
(blks_used + blks_free) * sizeof(malloc_t);
|
||||
if(total != g_kbrk - g_heap_bot)
|
||||
printf("*** some heap memory is not accounted for\n");
|
||||
printf("===============================================\n");
|
||||
}
|
||||
/*****************************************************************************
|
||||
POSIX sbrk() looks like this
|
||||
void *sbrk(int incr);
|
||||
Mine is a bit different so I can signal the calling function
|
||||
if more memory than desired was allocated (e.g. in a system with paging)
|
||||
If your kbrk()/sbrk() always allocates the amount of memory you ask for,
|
||||
this code can be easily changed.
|
||||
|
||||
int brk( void *sbrk( void *kbrk(
|
||||
function void *adr); int delta); int *delta);
|
||||
---------------------- ------------ ------------ -------------
|
||||
POSIX? yes yes NO
|
||||
return value if error -1 -1 NULL
|
||||
get break value . sbrk(0) int x=0; kbrk(&x);
|
||||
set break value to X brk(X) sbrk(X - sbrk(0)) int x=X, y=0; kbrk(&x) - kbrk(&y);
|
||||
enlarge heap by N bytes . sbrk(+N) int x=N; kbrk(&x);
|
||||
shrink heap by N bytes . sbrk(-N) int x=-N; kbrk(&x);
|
||||
can you tell if you're
|
||||
given more memory
|
||||
than you wanted? no no yes
|
||||
*****************************************************************************/
|
||||
static void *kbrk(int *delta)
|
||||
{
|
||||
static char heap[HEAP_SIZE];
|
||||
/**/
|
||||
char *new_brk, *old_brk;
|
||||
|
||||
/* heap doesn't exist yet */
|
||||
if(g_heap_bot == NULL)
|
||||
{
|
||||
g_heap_bot = g_kbrk = heap;
|
||||
g_heap_top = g_heap_bot + HEAP_SIZE;
|
||||
}
|
||||
new_brk = g_kbrk + (*delta);
|
||||
/* too low: return NULL */
|
||||
if(new_brk < g_heap_bot)
|
||||
return NULL;
|
||||
/* too high: return NULL */
|
||||
if(new_brk >= g_heap_top)
|
||||
return NULL;
|
||||
/* success: adjust brk value... */
|
||||
old_brk = g_kbrk;
|
||||
g_kbrk = new_brk;
|
||||
/* ...return actual delta... (for this sbrk(), they are the same)
|
||||
(*delta) = (*delta); */
|
||||
/* ...return old brk value */
|
||||
return old_brk;
|
||||
}
|
||||
/*****************************************************************************
|
||||
kmalloc() and kfree() use g_heap_bot, but not g_kbrk nor g_heap_top
|
||||
*****************************************************************************/
|
||||
void *kmalloc(size_t size)
|
||||
{
|
||||
unsigned total_size;
|
||||
malloc_t *m, *n;
|
||||
int delta;
|
||||
|
||||
if(size == 0)
|
||||
return NULL;
|
||||
total_size = size + sizeof(malloc_t);
|
||||
/* search heap for free block (FIRST FIT) */
|
||||
m = (malloc_t *)g_heap_bot;
|
||||
/* g_heap_bot == 0 == NULL if heap does not yet exist */
|
||||
if(m != NULL)
|
||||
{
|
||||
if(m->magic != MALLOC_MAGIC)
|
||||
// panic("kernel heap is corrupt in kmalloc()");
|
||||
{
|
||||
printf("*** kernel heap is corrupt in kmalloc()\n");
|
||||
return NULL;
|
||||
}
|
||||
for(; m->next != NULL; m = m->next)
|
||||
{
|
||||
if(m->used)
|
||||
continue;
|
||||
/* size == m->size is a perfect fit */
|
||||
if(size == m->size)
|
||||
m->used = 1;
|
||||
else
|
||||
{
|
||||
/* otherwise, we need an extra sizeof(malloc_t) bytes for the header
|
||||
of a second, free block */
|
||||
if(total_size > m->size)
|
||||
continue;
|
||||
/* create a new, smaller free block after this one */
|
||||
n = (malloc_t *)((char *)m + total_size);
|
||||
n->size = m->size - total_size;
|
||||
n->next = m->next;
|
||||
n->magic = MALLOC_MAGIC;
|
||||
n->used = 0;
|
||||
/* reduce the size of this block and mark it used */
|
||||
m->size = size;
|
||||
m->next = n;
|
||||
m->used = 1;
|
||||
}
|
||||
return (char *)m + sizeof(malloc_t);
|
||||
}
|
||||
}
|
||||
/* use kbrk() to enlarge (or create!) heap */
|
||||
delta = total_size;
|
||||
n = kbrk(&delta);
|
||||
/* uh-oh */
|
||||
if(n == NULL)
|
||||
return NULL;
|
||||
if(m != NULL)
|
||||
m->next = n;
|
||||
n->size = size;
|
||||
n->magic = MALLOC_MAGIC;
|
||||
n->used = 1;
|
||||
/* did kbrk() return the exact amount of memory we wanted?
|
||||
cast to make "gcc -Wall -W ..." shut the hell up */
|
||||
if((int)total_size == delta)
|
||||
n->next = NULL;
|
||||
else
|
||||
{
|
||||
/* it returned more than we wanted (it will never return less):
|
||||
create a new, free block */
|
||||
m = (malloc_t *)((char *)n + total_size);
|
||||
m->size = delta - total_size - sizeof(malloc_t);
|
||||
m->next = NULL;
|
||||
m->magic = MALLOC_MAGIC;
|
||||
m->used = 0;
|
||||
|
||||
n->next = m;
|
||||
}
|
||||
return (char *)n + sizeof(malloc_t);
|
||||
}
|
||||
|
||||
static inline void *kzalloc(size_t size)
|
||||
{
|
||||
void *buf = kmalloc(size);
|
||||
|
||||
memset(buf, 0, size);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*****************************************************************************/
|
||||
void kfree(void *blk)
|
||||
{
|
||||
malloc_t *m, *n;
|
||||
|
||||
/* get address of header */
|
||||
m = (malloc_t *)((char *)blk - sizeof(malloc_t));
|
||||
if(m->magic != MALLOC_MAGIC)
|
||||
// panic("attempt to kfree() block at 0x%p "
|
||||
// "with bad magic value", blk);
|
||||
{
|
||||
printf("*** attempt to kfree() block at 0x%p "
|
||||
"with bad magic value\n", blk);
|
||||
return;
|
||||
}
|
||||
/* find this block in the heap */
|
||||
n = (malloc_t *)g_heap_bot;
|
||||
if(n->magic != MALLOC_MAGIC)
|
||||
// panic("kernel heap is corrupt in kfree()");
|
||||
{
|
||||
printf("*** kernel heap is corrupt in kfree()\n");
|
||||
return;
|
||||
}
|
||||
for(; n != NULL; n = n->next)
|
||||
{
|
||||
if(n == m)
|
||||
break;
|
||||
}
|
||||
/* not found? bad pointer or no heap or something else? */
|
||||
if(n == NULL)
|
||||
// panic("attempt to kfree() block at 0x%p "
|
||||
// "that is not in the heap", blk);
|
||||
{
|
||||
printf("*** attempt to kfree() block at 0x%p "
|
||||
"that is not in the heap\n", blk);
|
||||
return;
|
||||
}
|
||||
/* free the block */
|
||||
m->used = 0;
|
||||
/* coalesce adjacent free blocks
|
||||
Hard to spell, hard to do */
|
||||
for(m = (malloc_t *)g_heap_bot; m != NULL; m = m->next)
|
||||
{
|
||||
while(!m->used && m->next != NULL && !m->next->used)
|
||||
{
|
||||
/* resize this block */
|
||||
m->size += sizeof(malloc_t) + m->next->size;
|
||||
/* merge with next block */
|
||||
m->next = m->next->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*****************************************************************************
|
||||
*****************************************************************************/
|
||||
void *krealloc(void *blk, size_t size)
|
||||
{
|
||||
void *new_blk;
|
||||
malloc_t *m;
|
||||
|
||||
/* size == 0: free block */
|
||||
if(size == 0)
|
||||
{
|
||||
if(blk != NULL)
|
||||
kfree(blk);
|
||||
new_blk = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* allocate new block */
|
||||
new_blk = kmalloc(size);
|
||||
/* if allocation OK, and if old block exists, copy old block to new */
|
||||
if(new_blk != NULL && blk != NULL)
|
||||
{
|
||||
m = (malloc_t *)((char *)blk - sizeof(malloc_t));
|
||||
if(m->magic != MALLOC_MAGIC)
|
||||
// panic("attempt to krealloc() block at "
|
||||
// "0x%p with bad magic value", blk);
|
||||
{
|
||||
printf("*** attempt to krealloc() block at "
|
||||
"0x%p with bad magic value\n", blk);
|
||||
return NULL;
|
||||
}
|
||||
/* copy minimum of old and new block sizes */
|
||||
if(size > m->size)
|
||||
size = m->size;
|
||||
memcpy(new_blk, blk, size);
|
||||
/* free the old block */
|
||||
kfree(blk);
|
||||
}
|
||||
}
|
||||
return new_blk;
|
||||
}
|
||||
/*****************************************************************************
|
||||
*****************************************************************************/
|
||||
|
||||
#if 0
|
||||
|
||||
#include <stdlib.h> /* rand() */
|
||||
|
||||
|
||||
#define SLOTS 17
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned lifetime[SLOTS];
|
||||
void *blk[SLOTS];
|
||||
int i, j, k;
|
||||
|
||||
dump_heap();
|
||||
memset(lifetime, 0, sizeof(lifetime));
|
||||
memset(blk, 0, sizeof(blk));
|
||||
for(i = 0; i < 1000; i++)
|
||||
{
|
||||
printf("Pass %6u\n", i);
|
||||
for(j = 0; j < SLOTS; j++)
|
||||
{
|
||||
/* age the block */
|
||||
if(lifetime[j] != 0)
|
||||
{
|
||||
(lifetime[j])--;
|
||||
continue;
|
||||
}
|
||||
/* too old; free it */
|
||||
if(blk[j] != NULL)
|
||||
{
|
||||
kfree(blk[j]);
|
||||
blk[j] = NULL;
|
||||
}
|
||||
/* alloc new block of random size
|
||||
Note that size_t==unsigned, but kmalloc() uses integer math,
|
||||
so block size must be positive integer */
|
||||
#if defined(_32BIT)
|
||||
k = rand() % 40960 + 1;
|
||||
#else
|
||||
k = rand() % 4096 + 1;
|
||||
#endif
|
||||
blk[j] = kmalloc(k);
|
||||
if(blk[j] == NULL)
|
||||
printf("failed to alloc %u bytes\n", k);
|
||||
else
|
||||
/* give it a random lifetime 0-20 */
|
||||
lifetime[j] = rand() % 21;
|
||||
}
|
||||
}
|
||||
/* let's see what we've wrought */
|
||||
printf("\n\n");
|
||||
dump_heap();
|
||||
/* free everything */
|
||||
for(j = 0; j < SLOTS; j++)
|
||||
{
|
||||
if(blk[j] != NULL)
|
||||
{
|
||||
kfree(blk[j]);
|
||||
blk[j] = NULL;
|
||||
}
|
||||
(lifetime[j]) = 0;
|
||||
}
|
||||
/* after all that, we should have a single, unused block */
|
||||
dump_heap();
|
||||
return 0;
|
||||
}
|
||||
/*****************************************************************************
|
||||
*****************************************************************************/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
void *b1, *b2, *b3;
|
||||
|
||||
dump_heap();
|
||||
|
||||
b1 = kmalloc(42);
|
||||
dump_heap();
|
||||
|
||||
b2 = kmalloc(23);
|
||||
dump_heap();
|
||||
|
||||
b3 = kmalloc(7);
|
||||
dump_heap();
|
||||
|
||||
b2 = krealloc(b2, 24);
|
||||
dump_heap();
|
||||
|
||||
kfree(b1);
|
||||
dump_heap();
|
||||
|
||||
b1 = kmalloc(5);
|
||||
dump_heap();
|
||||
|
||||
kfree(b2);
|
||||
dump_heap();
|
||||
|
||||
kfree(b3);
|
||||
dump_heap();
|
||||
|
||||
kfree(b1);
|
||||
dump_heap();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
92
conts/posix/fs0/src/lib/pathstr.c
Normal file
92
conts/posix/fs0/src/lib/pathstr.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Functions to manipulate path strings.
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <alloca.h>
|
||||
|
||||
/* Reverses a string by allocating on stack. Not super-efficient but easy. */
|
||||
char *strreverse(char *str)
|
||||
{
|
||||
int length = strlen(str);
|
||||
char *tmp = alloca(length);
|
||||
|
||||
strcpy(tmp, str);
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
str[i] = tmp[length - 1 - i];
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Splits the string str according to the given seperator, returns the
|
||||
* first component, and modifies the str so that it points at the next
|
||||
* available component (or a leading separator which can be filtered
|
||||
* out on a subsequent call to this function).
|
||||
*/
|
||||
char *splitpath(char **str, char sep)
|
||||
{
|
||||
char *cursor = *str;
|
||||
char *end;
|
||||
|
||||
/* Move forward until no seperator */
|
||||
while (*cursor == sep) {
|
||||
*cursor = '\0';
|
||||
cursor++; /* Move to first char of component */
|
||||
}
|
||||
|
||||
end = cursor;
|
||||
while (*end != sep && *end != '\0')
|
||||
end++; /* Move until end of component */
|
||||
|
||||
if (*end == sep) { /* if ended with separator */
|
||||
*end = '\0'; /* finish component by null */
|
||||
if (*(end + 1) != '\0') /* if more components after, */
|
||||
*str = end + 1; /* assign beginning to str */
|
||||
else
|
||||
*str = end; /* else str is also depleted, give null */
|
||||
} else /* if end was null, that means the end for str, too. */
|
||||
*str = end;
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/* Same as split path, but splits components from the end. Slow. */
|
||||
char *splitpath_end(char **path, char sep)
|
||||
{
|
||||
char *component;
|
||||
|
||||
/* Reverse the string */
|
||||
strreverse(*path);
|
||||
|
||||
/* Pick one from the start */
|
||||
component = splitpath(path, sep);
|
||||
|
||||
/* Reverse the rest back to original. */
|
||||
strreverse(*path);
|
||||
|
||||
/* Reverse component back to original */
|
||||
strreverse(component);
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
/* Splitpath test program. Tests all 3 functions.
|
||||
int main()
|
||||
{
|
||||
char str1[256] = "/a/b/c/d/////e/f";
|
||||
char *str2 = malloc(strlen(str1) + 1);
|
||||
char *comp;
|
||||
|
||||
strcpy(str2, str1);
|
||||
|
||||
comp = splitpath_end(&str2, '/');
|
||||
while (*comp) {
|
||||
printf("%s and %s\n", comp, str2);
|
||||
comp = splitpath_end(&str2, '/');
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
39
conts/posix/fs0/src/lib/vaddr.c
Normal file
39
conts/posix/fs0/src/lib/vaddr.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This module allocates an unused virtual address range for shm segments.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#include <lib/bit.h>
|
||||
#include <l4/macros.h>
|
||||
#include <l4/types.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include <lib/vaddr.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void vaddr_pool_init(struct id_pool *pool, unsigned long start, unsigned long end)
|
||||
{
|
||||
pool = id_pool_new_init(__pfn(end - start));
|
||||
}
|
||||
|
||||
void *vaddr_new(struct id_pool *pool, int npages)
|
||||
{
|
||||
unsigned int shm_vpfn;
|
||||
|
||||
if ((int)(shm_vpfn = ids_new_contiguous(pool, npages)) < 0)
|
||||
return 0;
|
||||
|
||||
return (void *)__pfn_to_addr(shm_vpfn + SHM_AREA_START);
|
||||
}
|
||||
|
||||
int vaddr_del(struct id_pool *pool, void *vaddr, int npages)
|
||||
{
|
||||
unsigned long idpfn = __pfn(page_align(vaddr) - SHM_AREA_START);
|
||||
|
||||
if (ids_del_contiguous(pool, idpfn, npages) < 0) {
|
||||
printf("%s: Invalid address range returned to "
|
||||
"virtual address pool.\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
90
conts/posix/fs0/src/lookup.c
Normal file
90
conts/posix/fs0/src/lookup.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Inode lookup.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
*/
|
||||
#include <fs.h>
|
||||
#include <vfs.h>
|
||||
#include <stat.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include <lib/pathstr.h>
|
||||
#include <path.h>
|
||||
|
||||
/*
|
||||
* Given a dentry that has been populated by readdir with children dentries
|
||||
* and their vnodes, this itself checks all those children on that level for
|
||||
* a match, but it also calls lookup, which recursively checks lower levels.
|
||||
*/
|
||||
struct vnode *lookup_dentry_children(struct dentry *parentdir,
|
||||
struct pathdata *pdata)
|
||||
{
|
||||
struct dentry *childdir;
|
||||
struct vnode *v;
|
||||
const char *component = pathdata_next_component(pdata);
|
||||
|
||||
list_foreach_struct(childdir, &parentdir->children, child)
|
||||
if (IS_ERR(v = childdir->vnode->ops.lookup(childdir->vnode,
|
||||
pdata, component)))
|
||||
/* Means not found, continue search */
|
||||
if ((int)v == -ENOENT)
|
||||
continue;
|
||||
else /* A real error */
|
||||
return v;
|
||||
else /* No error, so found it */
|
||||
return v;
|
||||
|
||||
/* Out of all children dentries, neither was a match */
|
||||
return PTR_ERR(-ENOENT);
|
||||
}
|
||||
|
||||
/* Lookup, recursive, assuming single-mountpoint */
|
||||
struct vnode *generic_vnode_lookup(struct vnode *thisnode,
|
||||
struct pathdata *pdata,
|
||||
const char *component)
|
||||
{
|
||||
struct dentry *d;
|
||||
struct vnode *found;
|
||||
int err;
|
||||
|
||||
/* Does this path component match with any of this vnode's dentries? */
|
||||
list_foreach_struct(d, &thisnode->dentries, vref) {
|
||||
if (d->ops.compare(d, component)) {
|
||||
/* Is this a directory? */
|
||||
if (vfs_isdir(thisnode)) {
|
||||
/* Are there more path components? */
|
||||
if (!list_empty(&pdata->list)) {
|
||||
/* Read directory contents */
|
||||
if ((err = d->vnode->ops.readdir(d->vnode)) < 0)
|
||||
return PTR_ERR(err);
|
||||
|
||||
/* Search all children one level below. */
|
||||
if ((found = lookup_dentry_children(d, pdata)))
|
||||
/* Either found, or non-zero error */
|
||||
return found;
|
||||
} else
|
||||
return thisnode;
|
||||
} else { /* Its a file */
|
||||
if (!list_empty(&pdata->list)) /* There's still path, but not directory */
|
||||
return PTR_ERR(-ENOTDIR);
|
||||
else /* No path left, found it, so return file */
|
||||
return thisnode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Not found, return nothing */
|
||||
return PTR_ERR(-ENOENT);
|
||||
}
|
||||
|
||||
int generic_dentry_compare(struct dentry *d, const char *name)
|
||||
{
|
||||
if (!strcmp(d->name, name) || !strcmp(name, VFS_STR_CURDIR))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dentry_ops generic_dentry_operations = {
|
||||
.compare = generic_dentry_compare,
|
||||
};
|
||||
|
||||
142
conts/posix/fs0/src/memfs/file.c
Normal file
142
conts/posix/fs0/src/memfs/file.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Memfs file operations
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <fs.h>
|
||||
#include <vfs.h>
|
||||
#include <file.h>
|
||||
#include <memfs/memfs.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <l4/macros.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
* FIXME: read_write() could be more layered using these functions.
|
||||
*/
|
||||
void *memfs_read_block(struct vnode *v, int blknum)
|
||||
{
|
||||
void *buf = vfs_alloc_block();
|
||||
|
||||
if (!buf)
|
||||
return PTR_ERR(-ENOMEM);
|
||||
|
||||
if(!v->block[blknum])
|
||||
return PTR_ERR(-EEXIST);
|
||||
|
||||
memcpy(buf, &v->block[blknum], v->sb->blocksize);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int memfs_write_block(struct vnode *v, int blknum, void *buf)
|
||||
{
|
||||
if(!v->block[blknum])
|
||||
return -EEXIST;
|
||||
|
||||
memcpy(&v->block[blknum], buf, v->sb->blocksize);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Handles both read and writes since most details are common.
|
||||
*
|
||||
* TODO: Think about whether to use inode or the vnode's fields (e.g. size)
|
||||
* and when updated, which one is to be updated first. Normally if you use and
|
||||
* update inode, then you sync vnode via read_vnode. but this is not really meant for
|
||||
* this use, its meant for retrieving an unknown inode under the vnode with valid vnum.
|
||||
* here we already have the inode.
|
||||
*/
|
||||
int memfs_file_read_write(struct vnode *v, unsigned int pfn,
|
||||
unsigned int npages, void *buf, int wr)
|
||||
{
|
||||
struct memfs_inode *i;
|
||||
struct memfs_superblock *memfs_sb;
|
||||
unsigned int start, end, count;
|
||||
u32 blocksize;
|
||||
|
||||
/* Don't support different block and page sizes for now */
|
||||
BUG_ON(v->sb->blocksize != PAGE_SIZE);
|
||||
|
||||
/* Buffer must be page aligned */
|
||||
BUG_ON(!is_page_aligned(buf));
|
||||
|
||||
/* Low-level fs refs must be valid */
|
||||
BUG_ON(!(i = v->inode));
|
||||
BUG_ON(!(memfs_sb = v->sb->fs_super));
|
||||
blocksize = v->sb->blocksize;
|
||||
|
||||
/* Check filesystem per-file size limit */
|
||||
if ((pfn + npages) > memfs_sb->fmaxblocks) {
|
||||
printf("%s: fslimit: Trying to %s outside maximum file range: %x-%x\n",
|
||||
__FUNCTION__, (wr) ? "write" : "read", pfn, pfn + npages);
|
||||
return -EINVAL; /* Same error that posix llseek returns */
|
||||
}
|
||||
|
||||
/* Read-specific operations */
|
||||
if (!wr) {
|
||||
/* Find read boundaries from expected range and file's current range */
|
||||
start = pfn < __pfn(v->size) ? pfn : __pfn(v->size);
|
||||
end = pfn + npages < __pfn(page_align_up(v->size))
|
||||
? pfn + npages : __pfn(page_align_up(v->size));
|
||||
count = end - start;
|
||||
|
||||
/* Copy the data from inode blocks into page buffer */
|
||||
for (int x = start, bufpage = 0; x < end; x++, bufpage++)
|
||||
memcpy(((void *)buf) + (bufpage * blocksize),
|
||||
i->block[x], blocksize);
|
||||
return (int)(count * blocksize);
|
||||
} else { /* Write-specific operations */
|
||||
/* Is the write beyond current file size? */
|
||||
if (v->size < ((pfn + npages) * (blocksize))) {
|
||||
unsigned long pagediff = pfn + npages - __pfn(v->size);
|
||||
unsigned long holes;
|
||||
|
||||
/*
|
||||
* If write is not consecutively after the currently
|
||||
* last file block, the gap must be filled in by holes.
|
||||
*/
|
||||
if (pfn > __pfn(v->size))
|
||||
holes = pfn - __pfn(v->size);
|
||||
else
|
||||
holes = 0;
|
||||
|
||||
/* Allocate new blocks */
|
||||
for (int x = 0; x < pagediff; x++)
|
||||
if (!(i->block[__pfn(v->size) + x] =
|
||||
memfs_alloc_block(v->sb->fs_super)))
|
||||
return -ENOSPC;
|
||||
|
||||
/* Zero out the holes. FIXME: How do we zero out non-page-aligned bytes?` */
|
||||
for (int x = 0; x < holes; x++)
|
||||
memset(i->block[__pfn(v->size) + x], 0, blocksize);
|
||||
}
|
||||
|
||||
/* Copy the data from page buffer into inode blocks */
|
||||
for (int x = pfn, bufpage = 0; x < pfn + npages; x++, bufpage++)
|
||||
memcpy(i->block[x], ((void *)buf) + (bufpage * blocksize), blocksize);
|
||||
}
|
||||
|
||||
return (int)(npages * blocksize);
|
||||
}
|
||||
|
||||
int memfs_file_write(struct vnode *v, unsigned long pfn, unsigned long npages, void *buf)
|
||||
{
|
||||
return memfs_file_read_write(v, pfn, npages, buf, 1);
|
||||
}
|
||||
|
||||
int memfs_file_read(struct vnode *v, unsigned long pfn, unsigned long npages, void *buf)
|
||||
{
|
||||
return memfs_file_read_write(v, pfn, npages, buf, 0);
|
||||
}
|
||||
|
||||
struct file_ops memfs_file_operations = {
|
||||
.read = memfs_file_read,
|
||||
.write = memfs_file_write,
|
||||
};
|
||||
|
||||
215
conts/posix/fs0/src/memfs/memfs.c
Normal file
215
conts/posix/fs0/src/memfs/memfs.c
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* A simple read/writeable memory-only filesystem.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
*/
|
||||
#include <init.h>
|
||||
#include <fs.h>
|
||||
#include <vfs.h>
|
||||
#include <task.h>
|
||||
#include <stdio.h>
|
||||
#include <memfs/memfs.h>
|
||||
#include <memfs/vnode.h>
|
||||
#include <lib/idpool.h>
|
||||
#include <l4/macros.h>
|
||||
#include <l4/types.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
|
||||
struct memfs_superblock *memfs_superblock;
|
||||
|
||||
/* Initialise allocation caches as part of superblock initialisation */
|
||||
int memfs_init_caches(struct memfs_superblock *sb)
|
||||
{
|
||||
void *free_block;
|
||||
struct mem_cache *block_cache;
|
||||
struct mem_cache *inode_cache;
|
||||
|
||||
/* Use the whole filesystem space to initialise block cache */
|
||||
free_block = (void *)sb + sizeof(*sb);
|
||||
block_cache = mem_cache_init(free_block, sb->fssize - sizeof(*sb),
|
||||
sb->blocksize, 1);
|
||||
list_insert(&block_cache->list, &sb->block_cache_list);
|
||||
|
||||
/* Allocate a block and initialise it as first inode cache */
|
||||
free_block = mem_cache_alloc(block_cache);
|
||||
inode_cache = mem_cache_init(free_block, sb->blocksize,
|
||||
sizeof(struct memfs_inode), 0);
|
||||
list_insert(&inode_cache->list, &sb->inode_cache_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given an empty block buffer, initialises a filesystem there.
|
||||
*/
|
||||
int memfs_format_filesystem(void *buffer)
|
||||
{
|
||||
struct memfs_superblock *sb = buffer; /* Buffer is the first block */
|
||||
|
||||
/* Zero initialise the superblock area */
|
||||
memset(sb, 0, sizeof(*sb));
|
||||
|
||||
/* Initialise filesystem parameters */
|
||||
sb->magic = MEMFS_MAGIC;
|
||||
memcpy(sb->name, MEMFS_NAME, MEMFS_NAME_SIZE);
|
||||
sb->blocksize = MEMFS_BLOCK_SIZE;
|
||||
sb->fmaxblocks = MEMFS_FMAX_BLOCKS;
|
||||
sb->fssize = MEMFS_TOTAL_SIZE;
|
||||
|
||||
/* Initialise block and inode index pools */
|
||||
sb->ipool = id_pool_new_init(MEMFS_TOTAL_INODES);
|
||||
sb->bpool = id_pool_new_init(MEMFS_TOTAL_BLOCKS);
|
||||
|
||||
/* Initialise bitmap allocation lists for blocks and inodes */
|
||||
link_init(&sb->block_cache_list);
|
||||
link_init(&sb->inode_cache_list);
|
||||
memfs_init_caches(sb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocates a block of unused buffer */
|
||||
void *memfs_alloc_block(struct memfs_superblock *sb)
|
||||
{
|
||||
struct mem_cache *cache;
|
||||
|
||||
list_foreach_struct(cache, &sb->block_cache_list, list) {
|
||||
if (cache->free)
|
||||
return mem_cache_zalloc(cache);
|
||||
else
|
||||
continue;
|
||||
}
|
||||
return PTR_ERR(-ENOSPC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Even though on a list, block allocation is currently from a single cache.
|
||||
* This frees a block back to the free buffer cache.
|
||||
*/
|
||||
int memfs_free_block(struct memfs_superblock *sb, void *block)
|
||||
{
|
||||
struct mem_cache *c, *tmp;
|
||||
|
||||
list_foreach_removable_struct(c, tmp, &sb->block_cache_list, list)
|
||||
if (!mem_cache_free(c, block))
|
||||
return 0;
|
||||
else
|
||||
return -EINVAL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
struct superblock *memfs_get_superblock(void *block);
|
||||
|
||||
struct file_system_type memfs_fstype = {
|
||||
.name = "memfs",
|
||||
.magic = MEMFS_MAGIC,
|
||||
.ops = {
|
||||
.get_superblock = memfs_get_superblock,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialise root inode as a directory, as in the mknod() call
|
||||
* but differently since root is parentless and is the parent of itself.
|
||||
*/
|
||||
int memfs_init_rootdir(struct superblock *sb)
|
||||
{
|
||||
struct memfs_superblock *msb = sb->fs_super;
|
||||
struct dentry *d;
|
||||
struct vnode *v;
|
||||
|
||||
/*
|
||||
* Create the root vnode. Since this is memfs, root vnode is
|
||||
* not read-in but dynamically created here. We expect this
|
||||
* first vnode to have vnum = 0.
|
||||
*/
|
||||
v = sb->root = sb->ops->alloc_vnode(sb);
|
||||
msb->root_vnum = sb->root->vnum;
|
||||
BUG_ON(msb->root_vnum != 0);
|
||||
|
||||
/* Initialise fields */
|
||||
vfs_set_type(v, S_IFDIR);
|
||||
|
||||
/* Allocate a new vfs dentry */
|
||||
if (!(d = vfs_alloc_dentry()))
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Initialise root dentry.
|
||||
*
|
||||
* NOTE: Root's parent is itself.
|
||||
* Here's how it looks like in structures:
|
||||
* root's parent is root. But root's child is not root.
|
||||
*
|
||||
* NOTE: Root has no name. This helps since splitpath
|
||||
* cuts out the '/' and "" is left for root name search.
|
||||
*/
|
||||
strncpy(d->name, VFS_STR_ROOTDIR, VFS_DNAME_MAX);
|
||||
d->ops = generic_dentry_operations;
|
||||
d->parent = d;
|
||||
d->vnode = v;
|
||||
|
||||
/* Associate dentry with its vnode */
|
||||
list_insert(&d->vref, &d->vnode->dentries);
|
||||
|
||||
/* Add both vnode and dentry to their flat caches */
|
||||
list_insert(&d->cache_list, &dentry_cache);
|
||||
list_insert(&v->cache_list, &vnode_cache);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copies fs-specific superblock into generic vfs superblock */
|
||||
struct superblock *memfs_fill_superblock(struct memfs_superblock *sb,
|
||||
struct superblock *vfs_sb)
|
||||
{
|
||||
vfs_sb->fs = &memfs_fstype;
|
||||
vfs_sb->ops = &memfs_superblock_operations;
|
||||
vfs_sb->fs_super = sb;
|
||||
vfs_sb->fssize = sb->fssize;
|
||||
vfs_sb->blocksize = sb->blocksize;
|
||||
|
||||
/* We initialise the root vnode as the root directory */
|
||||
memfs_init_rootdir(vfs_sb);
|
||||
|
||||
return vfs_sb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Probes block buffer for a valid memfs superblock, if found,
|
||||
* allocates and copies data to a vfs superblock, and returns it.
|
||||
*/
|
||||
struct superblock *memfs_get_superblock(void *block)
|
||||
{
|
||||
struct memfs_superblock *sb = block;
|
||||
struct superblock *vfs_sb;
|
||||
|
||||
// printf("%s: %s: Reading superblock.\n", __TASKNAME__, __FUNCTION__);
|
||||
/* We don't do sanity checks here, just confirm id. */
|
||||
if (strcmp(sb->name, "memfs")) {
|
||||
printf("%s: Name does not match: %s\n", __FUNCTION__, sb->name);
|
||||
return 0;
|
||||
}
|
||||
if (sb->magic != MEMFS_MAGIC) {
|
||||
printf("%s: Magic number not match: %u\n", __FUNCTION__, sb->magic);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate a vfs superblock. */
|
||||
vfs_sb = vfs_alloc_superblock();
|
||||
|
||||
/* Fill generic sb from fs-specific sb */
|
||||
return memfs_fill_superblock(sb, vfs_sb);
|
||||
}
|
||||
|
||||
/* Registers sfs as an available filesystem type */
|
||||
void memfs_register_fstype(struct link *fslist)
|
||||
{
|
||||
/* Initialise superblock list for this fstype */
|
||||
link_init(&memfs_fstype.sblist);
|
||||
|
||||
/* Add this fstype to list of available fstypes. */
|
||||
list_insert(&memfs_fstype.list, fslist);
|
||||
}
|
||||
|
||||
427
conts/posix/fs0/src/memfs/vnode.c
Normal file
427
conts/posix/fs0/src/memfs/vnode.c
Normal file
@@ -0,0 +1,427 @@
|
||||
/*
|
||||
* Inode and vnode implementation.
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <fs.h>
|
||||
#include <vfs.h>
|
||||
#include <memfs/memfs.h>
|
||||
#include <memfs/file.h>
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include <l4/macros.h>
|
||||
#include <lib/malloc.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
struct memfs_inode *memfs_alloc_inode(struct memfs_superblock *sb)
|
||||
{
|
||||
struct mem_cache *cache;
|
||||
struct memfs_inode *i;
|
||||
void *free_block;
|
||||
|
||||
/* Ask existing inode caches for a new inode */
|
||||
list_foreach_struct(cache, &sb->inode_cache_list, list) {
|
||||
if (cache->free)
|
||||
if (!(i = mem_cache_zalloc(cache)))
|
||||
return PTR_ERR(-ENOSPC);
|
||||
else
|
||||
return i;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Ask existing block caches for a new block */
|
||||
if (IS_ERR(free_block = memfs_alloc_block(sb)))
|
||||
return PTR_ERR(free_block);
|
||||
|
||||
/* Initialise it as an inode cache */
|
||||
cache = mem_cache_init(free_block, sb->blocksize,
|
||||
sizeof(struct memfs_inode), 0);
|
||||
list_insert(&cache->list, &sb->inode_cache_list);
|
||||
|
||||
if (!(i = mem_cache_zalloc(cache)))
|
||||
return PTR_ERR(-ENOSPC);
|
||||
else
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* O(n^2) complexity but its simple, yet it would only reveal on high numbers.
|
||||
*/
|
||||
int memfs_free_inode(struct memfs_superblock *sb, struct memfs_inode *i)
|
||||
{
|
||||
struct mem_cache *c, *tmp;
|
||||
|
||||
list_foreach_removable_struct(c, tmp, &sb->inode_cache_list, list) {
|
||||
/* Free it, if success */
|
||||
if (!mem_cache_free(c, i)) {
|
||||
/* If cache completely emtpy */
|
||||
if (mem_cache_is_empty(c)) {
|
||||
/* Free the block, too. */
|
||||
list_remove(&c->list);
|
||||
memfs_free_block(sb, c);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Allocates *and* initialises the inode */
|
||||
struct memfs_inode *memfs_create_inode(struct memfs_superblock *sb)
|
||||
{
|
||||
struct memfs_inode *i;
|
||||
|
||||
/* Allocate the inode */
|
||||
if (PTR_ERR(i = memfs_alloc_inode(sb)) < 0)
|
||||
return i;
|
||||
|
||||
/* Allocate a new inode number */
|
||||
if ((i->inum = id_new(sb->ipool)) < 0)
|
||||
return i;
|
||||
|
||||
/* Put a reference to this inode in the inode table at this index */
|
||||
sb->inode[i->inum] = i;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Deallocate the inode and any other closely relevant structure */
|
||||
int memfs_destroy_inode(struct memfs_superblock *sb, struct memfs_inode *i)
|
||||
{
|
||||
int inum = i->inum;
|
||||
|
||||
/* Deallocate the inode */
|
||||
if (memfs_free_inode(sb, i) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Deallocate the inode number */
|
||||
if (id_del(sb->ipool, inum) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Clear the ref in inode table */
|
||||
sb->inode[inum] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocates both an inode and a vnode and associates the two together */
|
||||
struct vnode *memfs_alloc_vnode(struct superblock *sb)
|
||||
{
|
||||
struct memfs_inode *i;
|
||||
struct vnode *v;
|
||||
|
||||
/* Get a (pseudo-disk) memfs inode */
|
||||
if (IS_ERR(i = memfs_create_inode(sb->fs_super)))
|
||||
return PTR_ERR(i);
|
||||
|
||||
/* Get a vnode */
|
||||
if (!(v = vfs_alloc_vnode()))
|
||||
return PTR_ERR(-ENOMEM);
|
||||
|
||||
/* Associate the two together */
|
||||
v->inode = i;
|
||||
v->vnum = i->inum;
|
||||
|
||||
/* Associate memfs-specific fields with vnode */
|
||||
v->ops = memfs_vnode_operations;
|
||||
v->fops = memfs_file_operations;
|
||||
v->sb = sb;
|
||||
|
||||
/* Return the vnode */
|
||||
return v;
|
||||
}
|
||||
|
||||
/* Frees the inode and the corresponding vnode */
|
||||
int memfs_free_vnode(struct superblock *sb, struct vnode *v)
|
||||
{
|
||||
struct memfs_inode *i = v->inode;
|
||||
|
||||
BUG_ON(!i); /* Vnodes that come here must have valid inodes */
|
||||
|
||||
/* Destroy on-disk inode */
|
||||
memfs_destroy_inode(sb->fs_super, i);
|
||||
|
||||
/* Free vnode */
|
||||
vfs_free_vnode(v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a vnode with a valid vnum, this retrieves the corresponding
|
||||
* inode from the filesystem.
|
||||
*/
|
||||
struct memfs_inode *memfs_read_inode(struct superblock *sb, struct vnode *v)
|
||||
{
|
||||
struct memfs_superblock *fssb = sb->fs_super;
|
||||
|
||||
BUG_ON(!fssb->inode[v->vnum]);
|
||||
|
||||
return fssb->inode[v->vnum];
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a preallocated vnode with a valid vnum, this reads the corresponding
|
||||
* inode from the filesystem and fills in the vnode's fields.
|
||||
*/
|
||||
int memfs_read_vnode(struct superblock *sb, struct vnode *v)
|
||||
{
|
||||
struct memfs_inode *i = memfs_read_inode(sb, v);
|
||||
|
||||
if (!i)
|
||||
return -EEXIST;
|
||||
|
||||
/* Simply copy common fields */
|
||||
v->vnum = i->inum;
|
||||
v->size = i->size;
|
||||
v->mode = i->mode;
|
||||
v->owner = i->owner;
|
||||
v->atime = i->atime;
|
||||
v->mtime = i->mtime;
|
||||
v->ctime = i->ctime;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Writes a valid vnode's fields back to its fs-specific inode */
|
||||
int memfs_write_vnode(struct superblock *sb, struct vnode *v)
|
||||
{
|
||||
struct memfs_inode *i = v->inode;
|
||||
|
||||
/* Vnodes that come here must have valid inodes */
|
||||
BUG_ON(!i);
|
||||
|
||||
/* Simply copy common fields */
|
||||
i->inum = v->vnum;
|
||||
i->size = v->size;
|
||||
i->mode = v->mode;
|
||||
i->owner = v->owner;
|
||||
i->atime = v->atime;
|
||||
i->mtime = v->mtime;
|
||||
i->ctime = v->ctime;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Creates ordinary files and directories at the moment. In the future,
|
||||
* other file types will be added. Returns the created node.
|
||||
*/
|
||||
struct vnode *memfs_vnode_mknod(struct vnode *v, const char *dirname,
|
||||
unsigned int mode)
|
||||
{
|
||||
struct dentry *d, *parent = link_to_struct(v->dentries.next,
|
||||
struct dentry, vref);
|
||||
struct memfs_dentry *memfsd;
|
||||
struct dentry *newd;
|
||||
struct vnode *newv;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* Precautions to prove that parent is the *only* dentry,
|
||||
* since directories can't have multiple dentries associated
|
||||
* with them.
|
||||
*/
|
||||
BUG_ON(list_empty(&v->dentries));
|
||||
BUG_ON(parent->vref.next != &v->dentries);
|
||||
BUG_ON(!vfs_isdir(v));
|
||||
|
||||
/* Populate the children */
|
||||
if ((err = v->ops.readdir(v)) < 0)
|
||||
return PTR_ERR(err);
|
||||
|
||||
/* Check there's no existing child with same name */
|
||||
list_foreach_struct(d, &parent->children, child) {
|
||||
/* Does the name exist as a child? */
|
||||
if(d->ops.compare(d, dirname))
|
||||
return PTR_ERR(-EEXIST);
|
||||
}
|
||||
|
||||
/* Allocate a new vnode for the new directory */
|
||||
if (IS_ERR(newv = v->sb->ops->alloc_vnode(v->sb)))
|
||||
return newv;
|
||||
|
||||
/* Initialise the vnode */
|
||||
vfs_set_type(newv, mode);
|
||||
|
||||
/* Get the next directory entry available on the parent vnode */
|
||||
if (v->dirbuf.npages * PAGE_SIZE <= v->size)
|
||||
return PTR_ERR(-ENOSPC);
|
||||
|
||||
/* Fill in the new entry to parent directory entry */
|
||||
memfsd = (struct memfs_dentry *)&v->dirbuf.buffer[v->size];
|
||||
memfsd->offset = v->size;
|
||||
memfsd->rlength = sizeof(*memfsd);
|
||||
memfsd->inum = ((struct memfs_inode *)newv->inode)->inum;
|
||||
strncpy((char *)memfsd->name, dirname, MEMFS_DNAME_MAX);
|
||||
memfsd->name[MEMFS_DNAME_MAX - 1] = '\0';
|
||||
|
||||
/* Write the updated directory buffer back to disk block */
|
||||
if ((err = v->fops.write(v, 0, 1, v->dirbuf.buffer)) < 0)
|
||||
return PTR_ERR(err); /* FIXME: free all you allocated so far */
|
||||
|
||||
/* Update parent vnode size */
|
||||
v->size += sizeof(*memfsd);
|
||||
v->sb->ops->write_vnode(v->sb, v);
|
||||
|
||||
/* Allocate a new vfs dentry */
|
||||
if (!(newd = vfs_alloc_dentry()))
|
||||
return PTR_ERR(-ENOMEM);
|
||||
|
||||
/* Initialise it */
|
||||
newd->ops = generic_dentry_operations;
|
||||
newd->parent = parent;
|
||||
newd->vnode = newv;
|
||||
strncpy(newd->name, dirname, VFS_DNAME_MAX);
|
||||
|
||||
/* Associate dentry with its vnode */
|
||||
list_insert(&newd->vref, &newd->vnode->dentries);
|
||||
|
||||
/* Associate dentry with its parent */
|
||||
list_insert(&newd->child, &parent->children);
|
||||
|
||||
/* Add both vnode and dentry to their flat caches */
|
||||
list_insert(&newd->cache_list, &dentry_cache);
|
||||
list_insert(&newv->cache_list, &vnode_cache);
|
||||
|
||||
return newv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads the vnode directory contents into vnode's buffer in a posix-compliant
|
||||
* struct dirent format.
|
||||
*
|
||||
* Reading the buffer, allocates and populates all dentries and their
|
||||
* corresponding vnodes that are the direct children of vnode v. This means
|
||||
* that by each call to readdir, the vfs layer increases its cache of filesystem
|
||||
* tree by one level beneath that directory.
|
||||
*/
|
||||
int memfs_vnode_readdir(struct vnode *v)
|
||||
{
|
||||
int err;
|
||||
struct memfs_dentry *memfsd;
|
||||
struct dentry *parent = link_to_struct(v->dentries.next,
|
||||
struct dentry, vref);
|
||||
|
||||
/*
|
||||
* Precautions to prove that parent is the *only* dentry,
|
||||
* since directories can't have multiple dentries associated
|
||||
* with them.
|
||||
*/
|
||||
BUG_ON(parent->vref.next != &v->dentries);
|
||||
BUG_ON(!vfs_isdir(v));
|
||||
|
||||
/* If a buffer is there, it means the directory is already read */
|
||||
if (v->dirbuf.buffer)
|
||||
return 0;
|
||||
|
||||
/* This is as big as a page */
|
||||
if (IS_ERR(v->dirbuf.buffer = vfs_alloc_dirpage(v))) {
|
||||
printf("%s: Could not allocate dirbuf.\n", __FUNCTION__);
|
||||
return (int)v->dirbuf.buffer;
|
||||
}
|
||||
v->dirbuf.npages = 1;
|
||||
|
||||
/*
|
||||
* Fail if vnode size is bigger than a page. Since this allocation
|
||||
* method is to be origaced, we can live with this limitation for now.
|
||||
*/
|
||||
BUG_ON(v->size > PAGE_SIZE);
|
||||
|
||||
/* Read memfsd contents into the buffer */
|
||||
if ((err = v->fops.read(v, 0, 1, v->dirbuf.buffer)))
|
||||
return err;
|
||||
|
||||
memfsd = (struct memfs_dentry *)v->dirbuf.buffer;
|
||||
|
||||
/* Read fs-specific directory entry into vnode and dentry caches. */
|
||||
for (int i = 0; i < (v->size / sizeof(struct memfs_dentry)); i++) {
|
||||
struct dentry *newd;
|
||||
struct vnode *newv;
|
||||
|
||||
/* Allocate a vfs dentry */
|
||||
if (!(newd = vfs_alloc_dentry()))
|
||||
return -ENOMEM;
|
||||
|
||||
/* Initialise it */
|
||||
newd->ops = generic_dentry_operations;
|
||||
newd->parent = parent;
|
||||
list_insert(&newd->child, &parent->children);
|
||||
|
||||
/*
|
||||
* Lookup the vnode for dentry by its vnode number. We call
|
||||
* vnode_lookup_byvnum instead of directly reading it because
|
||||
* this dentry might just be a link to a vnode that's already
|
||||
* in the vnode cache. If it's not there, the lookup function
|
||||
* allocates and reads it for us as well.
|
||||
*/
|
||||
newv = newd->vnode = vfs_lookup_byvnum(v->sb, memfsd[i].inum);
|
||||
if (!newv) {
|
||||
printf("Filesystem seems to be broken. Directory has"
|
||||
"inode number: %d, but no such inode found.\n",
|
||||
memfsd[i].inum);
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* Assing this dentry as a name of its vnode */
|
||||
list_insert(&newd->vref, &newd->vnode->dentries);
|
||||
|
||||
/* Increase link count */
|
||||
newv->links++;
|
||||
|
||||
/* Copy fields into generic dentry */
|
||||
memcpy(newd->name, memfsd[i].name, MEMFS_DNAME_MAX);
|
||||
|
||||
/* Add both vnode and dentry to their caches */
|
||||
list_insert(&newd->cache_list, &dentry_cache);
|
||||
list_insert(&newv->cache_list, &vnode_cache);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copies fs-specific dirent data into user buffer in
|
||||
* generic struct dirent format.
|
||||
*/
|
||||
int memfs_vnode_filldir(void *userbuf, struct vnode *v, int count)
|
||||
{
|
||||
int nbytes;
|
||||
int err;
|
||||
|
||||
/* Bytes to read, minimum of vnode size and count requested */
|
||||
nbytes = (v->size <= count) ? v->size : count;
|
||||
|
||||
/* Read the dir content from fs, if haven't done so yet */
|
||||
if ((err = v->ops.readdir(v)) < 0)
|
||||
return err;
|
||||
|
||||
/* Do we have those bytes at hand? */
|
||||
if (v->dirbuf.buffer && (v->dirbuf.npages * PAGE_SIZE) >= nbytes) {
|
||||
/*
|
||||
* Memfs does a direct copy since memfs dirent format
|
||||
* is the same as generic dirent format.
|
||||
*/
|
||||
memcpy(userbuf, v->dirbuf.buffer, nbytes);
|
||||
return nbytes;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct vnode_ops memfs_vnode_operations = {
|
||||
.readdir = memfs_vnode_readdir,
|
||||
.filldir = memfs_vnode_filldir,
|
||||
.mknod = memfs_vnode_mknod,
|
||||
.lookup = generic_vnode_lookup,
|
||||
};
|
||||
|
||||
struct superblock_ops memfs_superblock_operations = {
|
||||
.read_vnode = memfs_read_vnode,
|
||||
.write_vnode = memfs_write_vnode,
|
||||
.alloc_vnode = memfs_alloc_vnode,
|
||||
.free_vnode = memfs_free_vnode,
|
||||
};
|
||||
|
||||
145
conts/posix/fs0/src/path.c
Normal file
145
conts/posix/fs0/src/path.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Path manipulation functions.
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <l4/macros.h>
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include <lib/pathstr.h>
|
||||
#include <lib/malloc.h>
|
||||
#include <path.h>
|
||||
#include <stdio.h>
|
||||
#include <fs.h>
|
||||
#include <task.h>
|
||||
#include <vfs.h>
|
||||
|
||||
const char *pathdata_next_component(struct pathdata *pdata)
|
||||
{
|
||||
struct pathcomp *p, *n;
|
||||
const char *pathstr;
|
||||
|
||||
list_foreach_removable_struct(p, n, &pdata->list, list) {
|
||||
list_remove(&p->list);
|
||||
pathstr = p->str;
|
||||
kfree(p);
|
||||
return pathstr;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/* Check there's at least one element, unlink and return the last element */
|
||||
const char *pathdata_last_component(struct pathdata *pdata)
|
||||
{
|
||||
struct pathcomp *p;
|
||||
const char *pathstr;
|
||||
|
||||
if (!list_empty(&pdata->list)) {
|
||||
p = link_to_struct(pdata->list.prev, struct pathcomp, list);
|
||||
list_remove(&p->list);
|
||||
pathstr = p->str;
|
||||
kfree(p);
|
||||
return pathstr;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/* Unlink and free all path components in pathdata, and then free pathdata */
|
||||
void pathdata_destroy(struct pathdata *p)
|
||||
{
|
||||
struct pathcomp *c, *n;
|
||||
|
||||
list_foreach_removable_struct(c, n, &p->list, list) {
|
||||
list_remove(&c->list);
|
||||
kfree(c);
|
||||
}
|
||||
kfree(p);
|
||||
}
|
||||
|
||||
void pathdata_print(struct pathdata *p)
|
||||
{
|
||||
struct pathcomp *comp;
|
||||
|
||||
printf("Extracted path is:\n");
|
||||
list_foreach_struct(comp, &p->list, list)
|
||||
printf("%s\n", comp->str);
|
||||
}
|
||||
|
||||
/* Extracts all path components from pathname into more presentable form */
|
||||
struct pathdata *pathdata_parse(const char *pathname,
|
||||
char *pathbuf, struct tcb *task)
|
||||
{
|
||||
struct pathdata *pdata = kzalloc(sizeof(*pdata));
|
||||
struct pathcomp *comp;
|
||||
char *str;
|
||||
|
||||
if (!pdata)
|
||||
return PTR_ERR(-ENOMEM);
|
||||
|
||||
/* Initialise pathdata */
|
||||
link_init(&pdata->list);
|
||||
strcpy(pathbuf, pathname);
|
||||
|
||||
/* First component is root if there's a root */
|
||||
if (pathname[0] == VFS_CHAR_SEP) {
|
||||
if (!(comp = kzalloc(sizeof(*comp)))) {
|
||||
kfree(pdata);
|
||||
return PTR_ERR(-ENOMEM);
|
||||
}
|
||||
link_init(&comp->list);
|
||||
comp->str = VFS_STR_ROOTDIR;
|
||||
list_insert_tail(&comp->list, &pdata->list);
|
||||
|
||||
if (task)
|
||||
/* Lookup start vnode is root vnode */
|
||||
pdata->vstart = task->fs_data->rootdir;
|
||||
else /* If no task, we use the root mountpoint pivot vnode */
|
||||
pdata->vstart = vfs_root.pivot;
|
||||
|
||||
/* Otherwise start from current directory */
|
||||
} else {
|
||||
struct dentry *curdir;
|
||||
|
||||
if (!(comp = kzalloc(sizeof(*comp)))) {
|
||||
kfree(pdata);
|
||||
return PTR_ERR(-ENOMEM);
|
||||
}
|
||||
link_init(&comp->list);
|
||||
|
||||
/* Get current dentry for this task */
|
||||
curdir = link_to_struct(task->fs_data->curdir->dentries.next,
|
||||
struct dentry, vref);
|
||||
|
||||
/* Use its name in path component */
|
||||
comp->str = curdir->name;
|
||||
list_insert_tail(&comp->list, &pdata->list);
|
||||
|
||||
/* Lookup start vnode is current dir vnode */
|
||||
pdata->vstart = task->fs_data->curdir;
|
||||
}
|
||||
|
||||
/* Add every other path component */
|
||||
str = splitpath(&pathbuf, VFS_CHAR_SEP);
|
||||
while(*str) {
|
||||
/* Any curdir components in path are ignored. */
|
||||
if (!strcmp(str, VFS_STR_CURDIR)) {
|
||||
;
|
||||
} else {
|
||||
if (!(comp = kzalloc(sizeof(*comp)))) {
|
||||
pathdata_destroy(pdata);
|
||||
return PTR_ERR(-ENOMEM);
|
||||
}
|
||||
link_init(&comp->list);
|
||||
comp->str = str;
|
||||
list_insert_tail(&comp->list, &pdata->list);
|
||||
}
|
||||
|
||||
/* Next component */
|
||||
str = splitpath(&pathbuf, VFS_CHAR_SEP);
|
||||
}
|
||||
// pathdata_print(pdata);
|
||||
|
||||
return pdata;
|
||||
}
|
||||
|
||||
86
conts/posix/fs0/src/romfs/romfs.c
Normal file
86
conts/posix/fs0/src/romfs/romfs.c
Normal file
@@ -0,0 +1,86 @@
|
||||
#include <stdio.h>
|
||||
#include <block.h>
|
||||
#include <l4/lib/math.h>
|
||||
#include <l4/macros.h>
|
||||
#include <l4/types.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
|
||||
/*
|
||||
* Romfs superblock descriptor:
|
||||
*
|
||||
* All words are Big-Endian.
|
||||
*
|
||||
* Word 0: | - | r | o | m |
|
||||
* Word 1: | 1 | f | s | - |
|
||||
* Word 2: | Size | The number of bytes in this fs.
|
||||
* Word 3: | Checksum | The checksum of first 512 bytes.
|
||||
* Word 4: | Volume Name | The name of volume, padded to 16-byte boundary.
|
||||
* Rest: | File Headers | The rest of the data.
|
||||
*/
|
||||
struct romfs_superblock {
|
||||
u32 word0;
|
||||
u32 word1;
|
||||
u32 size;
|
||||
u32 checksum;
|
||||
char name[0];
|
||||
};
|
||||
|
||||
struct romfs_inode {
|
||||
unsigned long mdata_size; /* Size of metadata */
|
||||
unsigned long data_offset; /* Offset of data from start of fs */
|
||||
};
|
||||
|
||||
static u32
|
||||
romfs_checksum(void *data)
|
||||
{
|
||||
u32 sum = 0;
|
||||
u32 *ptr = data;
|
||||
|
||||
size >>= 2;
|
||||
while (size > 0) {
|
||||
sum += be32_to_cpu(*ptr++);
|
||||
size--;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
int romfs_fill_super(struct superblock *sb)
|
||||
{
|
||||
char buf[PAGE_SIZE];
|
||||
struct romfs_superblock *romfs_sb = (struct romfs_superblock *)buf;
|
||||
unsigned long vroot_offset;
|
||||
struct vnode *vroot;
|
||||
|
||||
/* Read first page from block device */
|
||||
bdev_readpage(0, buf);
|
||||
|
||||
/* Check superblock sanity */
|
||||
if (strcmp(be32_to_cpu(romfs_sb->word0), ROMFS_SB_WORD0)) {
|
||||
printf("Bad magic word 0\n");
|
||||
}
|
||||
if (strcmp(be32_to_cpu(romfs_sb->word1), ROMFS_SB_WORD1)) {
|
||||
printf("Bad magic word 1\n");
|
||||
}
|
||||
if (romfs_checksum(romfs_sb, min(romfs_sb->size, PAGE_SIZE))) {
|
||||
printf("Bad checksum.\n");
|
||||
}
|
||||
|
||||
/* Copy some params to generic superblock */
|
||||
sb->size = be32_to_cpu(romfs_sb->size);
|
||||
sb->magic = ROMFS_MAGIC;
|
||||
sb->ops = romfs_ops;
|
||||
|
||||
/* Offset of first vnode, which is the root vnode */
|
||||
vroot_offset = align_up(strnlen(romfs_sb->name, ROMFS_MAXNAME) + 1, 16);
|
||||
if (!(vroot = romfs_read_vnode(s, vroot_offset))) {
|
||||
printf("Error, could not get root inode.\n");
|
||||
}
|
||||
|
||||
/* Get the dirent for this vnode */
|
||||
if (!(sb->root = new_dentry(vroot))) {
|
||||
printf("Error: Could not get new dentry for root vnode.\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
43
conts/posix/fs0/src/romfs/romfs.h
Normal file
43
conts/posix/fs0/src/romfs/romfs.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef __ROMFS_H__
|
||||
#define __ROMFS_H__
|
||||
|
||||
#define ROMFS_MAGIC 0x7275
|
||||
|
||||
#define ROMFS_FTYPE_MSK 0xF /* File mask */
|
||||
#define ROMFS_FTYPE_HRD 0 /* Hard link */
|
||||
#define ROMFS_FTYPE_DIR 1 /* Directory */
|
||||
#define ROMFS_FTYPE_REG 2 /* Regular file */
|
||||
#define ROMFS_FTYPE_SYM 3 /* Symbolic link */
|
||||
#define ROMFS_FTYPE_BLK 4 /* Block device */
|
||||
#define ROMFS_FTYPE_CHR 5 /* Char device */
|
||||
#define ROMFS_FTYPE_SCK 6 /* Socket */
|
||||
#define ROMFS_FTYPE_FIF 7 /* FIFO */
|
||||
#define ROMFS_FTYPE_EXE 8 /* Executable */
|
||||
|
||||
#define ROMFS_NAME_ALIGN 16 /* Alignment size of names */
|
||||
|
||||
#define ROMFS_SB_WORD0 "-rom"
|
||||
#define ROMFS_SB_WORD1 "1fs-"
|
||||
|
||||
/*
|
||||
* Romfs superblock descriptor:
|
||||
*
|
||||
* All words are Big-Endian.
|
||||
*
|
||||
* Word 0: | - | r | o | m |
|
||||
* Word 1: | 1 | f | s | - |
|
||||
* Word 2: | Size | The number of bytes in this fs.
|
||||
* Word 3: | Checksum | The checksum of first 512 bytes.
|
||||
* Word 4: | Volume Name | The name of volume, padded to 16-byte boundary.
|
||||
* Rest: | File Headers | The rest of the data.
|
||||
*/
|
||||
struct romfs_superblock {
|
||||
u32 word0;
|
||||
u32 word1;
|
||||
u32 size;
|
||||
u32 checksum;
|
||||
char name[0];
|
||||
};
|
||||
|
||||
|
||||
#endif /* __ROMFS_H__ */
|
||||
61
conts/posix/fs0/src/romfs/romfs_fs.h
Normal file
61
conts/posix/fs0/src/romfs/romfs_fs.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef __LINUX_ROMFS_FS_H
|
||||
#define __LINUX_ROMFS_FS_H
|
||||
|
||||
/* The basic structures of the romfs filesystem */
|
||||
|
||||
#define ROMBSIZE BLOCK_SIZE
|
||||
#define ROMBSBITS BLOCK_SIZE_BITS
|
||||
#define ROMBMASK (ROMBSIZE-1)
|
||||
#define ROMFS_MAGIC 0x7275
|
||||
|
||||
#define ROMFS_MAXFN 128
|
||||
|
||||
#define __mkw(h,l) (((h)&0x00ff)<< 8|((l)&0x00ff))
|
||||
#define __mkl(h,l) (((h)&0xffff)<<16|((l)&0xffff))
|
||||
#define __mk4(a,b,c,d) cpu_to_be32(__mkl(__mkw(a,b),__mkw(c,d)))
|
||||
#define ROMSB_WORD0 __mk4('-','r','o','m')
|
||||
#define ROMSB_WORD1 __mk4('1','f','s','-')
|
||||
|
||||
/* On-disk "super block" */
|
||||
|
||||
struct romfs_super_block {
|
||||
__be32 word0;
|
||||
__be32 word1;
|
||||
__be32 size;
|
||||
__be32 checksum;
|
||||
char name[0]; /* volume name */
|
||||
};
|
||||
|
||||
/* On disk inode */
|
||||
|
||||
struct romfs_inode {
|
||||
__be32 next; /* low 4 bits see ROMFH_ */
|
||||
__be32 spec;
|
||||
__be32 size;
|
||||
__be32 checksum;
|
||||
char name[0];
|
||||
};
|
||||
|
||||
#define ROMFH_TYPE 7
|
||||
#define ROMFH_HRD 0
|
||||
#define ROMFH_DIR 1
|
||||
#define ROMFH_REG 2
|
||||
#define ROMFH_SYM 3
|
||||
#define ROMFH_BLK 4
|
||||
#define ROMFH_CHR 5
|
||||
#define ROMFH_SCK 6
|
||||
#define ROMFH_FIF 7
|
||||
#define ROMFH_EXEC 8
|
||||
|
||||
/* Alignment */
|
||||
|
||||
#define ROMFH_SIZE 16
|
||||
#define ROMFH_PAD (ROMFH_SIZE-1)
|
||||
#define ROMFH_MASK (~ROMFH_PAD)
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/* Not much now */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif
|
||||
528
conts/posix/fs0/src/syscalls.c
Normal file
528
conts/posix/fs0/src/syscalls.c
Normal file
@@ -0,0 +1,528 @@
|
||||
/*
|
||||
* Some syscall stubs
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <l4/api/errno.h>
|
||||
#include <l4lib/types.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <lib/pathstr.h>
|
||||
#include <lib/malloc.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <task.h>
|
||||
#include <stat.h>
|
||||
#include <vfs.h>
|
||||
#include <alloca.h>
|
||||
#include <path.h>
|
||||
#include <syscalls.h>
|
||||
|
||||
#define NILFD -1
|
||||
|
||||
/*
|
||||
* This informs mm0 about an opened file descriptors.
|
||||
*
|
||||
* MM0 *also* keeps track of fd's because mm0 is a better candidate
|
||||
* for handling syscalls that access file content (i.e. read/write) since
|
||||
* it maintains the page cache. MM0 is not notified about opened files
|
||||
* but is rather informed when it asks to be. This avoids deadlocks by
|
||||
* keeping the request flow in one way.
|
||||
*/
|
||||
|
||||
int pager_sys_open(struct tcb *pager, l4id_t opener, int fd)
|
||||
{
|
||||
struct tcb *task;
|
||||
struct vnode *v;
|
||||
|
||||
//printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
|
||||
if (pager->tid != PAGER_TID)
|
||||
return -EINVAL;
|
||||
|
||||
/* Check if such task exists */
|
||||
if (!(task = find_task(opener)))
|
||||
return -ESRCH;
|
||||
|
||||
/* Check if that fd has been opened */
|
||||
if (task->files->fd[fd] == NILFD)
|
||||
return -EBADF;
|
||||
|
||||
/* Search the vnode by that vnum */
|
||||
if (IS_ERR(v = vfs_lookup_byvnum(vfs_root.pivot->sb,
|
||||
task->files->fd[fd])))
|
||||
return (int)v;
|
||||
|
||||
/*
|
||||
* Write file information, they will
|
||||
* be sent via the return origy.
|
||||
*/
|
||||
write_mr(L4SYS_ARG0, v->vnum);
|
||||
write_mr(L4SYS_ARG1, v->size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is called when the pager needs to open a vfs file via its path */
|
||||
int pager_open_bypath(struct tcb *pager, char *pathname)
|
||||
{
|
||||
struct pathdata *pdata;
|
||||
struct tcb *task;
|
||||
struct vnode *v;
|
||||
int retval;
|
||||
|
||||
//printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
|
||||
if (pager->tid != PAGER_TID)
|
||||
return -EINVAL;
|
||||
|
||||
/* Parse path data */
|
||||
if (IS_ERR(pdata = pathdata_parse(pathname,
|
||||
alloca(strlen(pathname) + 1),
|
||||
task)))
|
||||
return (int)pdata;
|
||||
|
||||
/* Search the vnode by that path */
|
||||
if (IS_ERR(v = vfs_lookup_bypath(pdata))) {
|
||||
retval = (int)v;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write file information, they will
|
||||
* be sent via the return origy.
|
||||
*/
|
||||
write_mr(L4SYS_ARG0, v->vnum);
|
||||
write_mr(L4SYS_ARG1, v->size);
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
pathdata_destroy(pdata);
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Directories only for now */
|
||||
void print_vnode(struct vnode *v)
|
||||
{
|
||||
struct dentry *d, *c;
|
||||
|
||||
printf("Vnode names:\n");
|
||||
list_foreach_struct(d, &v->dentries, vref) {
|
||||
printf("%s\n", d->name);
|
||||
printf("Children dentries:\n");
|
||||
list_foreach_struct(c, &d->children, child)
|
||||
printf("%s\n", c->name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Creates a node under a directory, e.g. a file, directory. */
|
||||
struct vnode *vfs_create(struct tcb *task, struct pathdata *pdata,
|
||||
unsigned int mode)
|
||||
{
|
||||
struct vnode *vparent, *newnode;
|
||||
const char *nodename;
|
||||
|
||||
/* The last component is to be created */
|
||||
nodename = pathdata_last_component(pdata);
|
||||
|
||||
/* Check that the parent directory exists. */
|
||||
if (IS_ERR(vparent = vfs_lookup_bypath(pdata)))
|
||||
return vparent;
|
||||
|
||||
/* The parent vnode must be a directory. */
|
||||
if (!vfs_isdir(vparent))
|
||||
return PTR_ERR(-ENOENT);
|
||||
|
||||
/* Create new directory under the parent */
|
||||
if (IS_ERR(newnode = vparent->ops.mknod(vparent, nodename, mode)))
|
||||
return newnode;
|
||||
|
||||
// print_vnode(vparent);
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pager notifies vfs about a closed file descriptor.
|
||||
*
|
||||
* FIXME: fsync + close could be done under a single "close" ipc
|
||||
* from pager. Currently there are 2 ipcs: 1 fsync + 1 fd close.
|
||||
*/
|
||||
int pager_sys_close(struct tcb *sender, l4id_t closer, int fd)
|
||||
{
|
||||
struct tcb *task;
|
||||
int err;
|
||||
|
||||
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
|
||||
|
||||
BUG_ON(!(task = find_task(closer)));
|
||||
|
||||
if ((err = id_del(task->files->fdpool, fd)) < 0) {
|
||||
printf("%s: Error releasing fd identifier.\n",
|
||||
__FUNCTION__);
|
||||
return err;
|
||||
}
|
||||
task->files->fd[fd] = NILFD;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME:
|
||||
* - Is it already open?
|
||||
* - Allocate a copy of path string since lookup destroys it
|
||||
* - Check flags and mode.
|
||||
*/
|
||||
int sys_open(struct tcb *task, const char *pathname, int flags, unsigned int mode)
|
||||
{
|
||||
struct pathdata *pdata;
|
||||
struct vnode *v;
|
||||
int fd;
|
||||
int retval;
|
||||
|
||||
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
|
||||
|
||||
/* Parse path data */
|
||||
if (IS_ERR(pdata = pathdata_parse(pathname,
|
||||
alloca(strlen(pathname) + 1),
|
||||
task)))
|
||||
return (int)pdata;
|
||||
|
||||
/* Creating new file */
|
||||
if (flags & O_CREAT) {
|
||||
/* Make sure mode identifies a file */
|
||||
mode |= S_IFREG;
|
||||
if (IS_ERR(v = vfs_create(task, pdata, mode))) {
|
||||
retval = (int)v;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* Not creating, just opening, get the vnode */
|
||||
if (IS_ERR(v = vfs_lookup_bypath(pdata))) {
|
||||
retval = (int)v;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get a new fd */
|
||||
BUG_ON((fd = id_new(task->files->fdpool)) < 0);
|
||||
retval = fd;
|
||||
|
||||
/* Assign the new fd with the vnode's number */
|
||||
task->files->fd[fd] = v->vnum;
|
||||
|
||||
out:
|
||||
pathdata_destroy(pdata);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int sys_mkdir(struct tcb *task, const char *pathname, unsigned int mode)
|
||||
{
|
||||
struct pathdata *pdata;
|
||||
struct vnode *v;
|
||||
int ret = 0;
|
||||
|
||||
/* Parse path data */
|
||||
if (IS_ERR(pdata = pathdata_parse(pathname,
|
||||
alloca(strlen(pathname) + 1),
|
||||
task)))
|
||||
return (int)pdata;
|
||||
|
||||
/* Make sure we create a directory */
|
||||
mode |= S_IFDIR;
|
||||
|
||||
/* Create the directory or fail */
|
||||
if (IS_ERR(v = vfs_create(task, pdata, mode)))
|
||||
ret = (int)v;
|
||||
|
||||
/* Destroy extracted path data */
|
||||
pathdata_destroy(pdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sys_chdir(struct tcb *task, const char *pathname)
|
||||
{
|
||||
struct vnode *v;
|
||||
struct pathdata *pdata;
|
||||
int ret = 0;
|
||||
|
||||
/* Parse path data */
|
||||
if (IS_ERR(pdata = pathdata_parse(pathname,
|
||||
alloca(strlen(pathname) + 1),
|
||||
task)))
|
||||
return (int)pdata;
|
||||
|
||||
/* Get the vnode */
|
||||
if (IS_ERR(v = vfs_lookup_bypath(pdata))) {
|
||||
ret = (int)v;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Ensure it's a directory */
|
||||
if (!vfs_isdir(v)) {
|
||||
ret = -ENOTDIR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Assign the current directory pointer */
|
||||
task->fs_data->curdir = v;
|
||||
|
||||
out:
|
||||
/* Destroy extracted path data */
|
||||
pathdata_destroy(pdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fill_kstat(struct vnode *v, struct kstat *ks)
|
||||
{
|
||||
ks->vnum = (u64)v->vnum;
|
||||
ks->mode = v->mode;
|
||||
ks->links = v->links;
|
||||
ks->uid = v->owner & 0xFFFF;
|
||||
ks->gid = (v->owner >> 16) & 0xFFFF;
|
||||
ks->size = v->size;
|
||||
ks->blksize = v->sb->blocksize;
|
||||
ks->atime = v->atime;
|
||||
ks->mtime = v->mtime;
|
||||
ks->ctime = v->ctime;
|
||||
}
|
||||
|
||||
int sys_fstat(struct tcb *task, int fd, void *statbuf)
|
||||
{
|
||||
struct vnode *v;
|
||||
unsigned long vnum;
|
||||
|
||||
/* Get the vnum */
|
||||
if (fd < 0 || fd > TASK_FILES_MAX || task->files->fd[fd] == NILFD)
|
||||
return -EBADF;
|
||||
|
||||
vnum = task->files->fd[fd];
|
||||
|
||||
/* Lookup vnode */
|
||||
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum)))
|
||||
return -EINVAL;
|
||||
|
||||
/* Fill in the c0-style stat structure */
|
||||
fill_kstat(v, statbuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns codezero-style stat structure which in turn is
|
||||
* converted to posix style stat structure via the libposix
|
||||
* library in userspace.
|
||||
*/
|
||||
int sys_stat(struct tcb *task, const char *pathname, void *statbuf)
|
||||
{
|
||||
struct vnode *v;
|
||||
struct pathdata *pdata;
|
||||
int ret = 0;
|
||||
|
||||
/* Parse path data */
|
||||
if (IS_ERR(pdata = pathdata_parse(pathname,
|
||||
alloca(strlen(pathname) + 1),
|
||||
task)))
|
||||
return (int)pdata;
|
||||
|
||||
/* Get the vnode */
|
||||
if (IS_ERR(v = vfs_lookup_bypath(pdata))) {
|
||||
ret = (int)v;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Fill in the c0-style stat structure */
|
||||
fill_kstat(v, statbuf);
|
||||
|
||||
out:
|
||||
/* Destroy extracted path data */
|
||||
pathdata_destroy(pdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note this can be solely called by the pager and is not the posix read call.
|
||||
* That call is in the pager. This merely supplies the pages the pager needs
|
||||
* if they're not in the page cache.
|
||||
*/
|
||||
int pager_sys_read(struct tcb *pager, unsigned long vnum, unsigned long f_offset,
|
||||
unsigned long npages, void *pagebuf)
|
||||
{
|
||||
struct vnode *v;
|
||||
|
||||
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
|
||||
|
||||
if (pager->tid != PAGER_TID)
|
||||
return -EINVAL;
|
||||
|
||||
/* Lookup vnode */
|
||||
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum)))
|
||||
return -EINVAL;
|
||||
|
||||
/* Ensure vnode is not a directory */
|
||||
if (vfs_isdir(v))
|
||||
return -EISDIR;
|
||||
|
||||
return v->fops.read(v, f_offset, npages, pagebuf);
|
||||
}
|
||||
|
||||
int pager_update_stats(struct tcb *pager, unsigned long vnum,
|
||||
unsigned long newsize)
|
||||
{
|
||||
struct vnode *v;
|
||||
|
||||
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
|
||||
|
||||
if (pager->tid != PAGER_TID)
|
||||
return -EINVAL;
|
||||
|
||||
/* Lookup vnode */
|
||||
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum)))
|
||||
return -EINVAL;
|
||||
|
||||
v->size = newsize;
|
||||
v->sb->ops->write_vnode(v->sb, v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This can be solely called by the pager and is not the posix write call.
|
||||
* That call is in the pager. This writes the dirty pages of a file
|
||||
* back to disk via vfs.
|
||||
*
|
||||
* The buffer must be contiguous by page, if npages > 1.
|
||||
*/
|
||||
int pager_sys_write(struct tcb *pager, unsigned long vnum, unsigned long f_offset,
|
||||
unsigned long npages, void *pagebuf)
|
||||
{
|
||||
struct vnode *v;
|
||||
int ret;
|
||||
int fwrite_end;
|
||||
|
||||
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
|
||||
|
||||
if (pager->tid != PAGER_TID)
|
||||
return -EINVAL;
|
||||
|
||||
/* Lookup vnode */
|
||||
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum)))
|
||||
return -EINVAL;
|
||||
|
||||
/* Ensure vnode is not a directory */
|
||||
if (vfs_isdir(v))
|
||||
return -EISDIR;
|
||||
|
||||
//printf("%s/%s: Writing to vnode %lu, at pgoff 0x%x, %d pages, buf at 0x%x\n",
|
||||
// __TASKNAME__, __FUNCTION__, vnum, f_offset, npages, pagebuf);
|
||||
|
||||
if ((ret = v->fops.write(v, f_offset, npages, pagebuf)) < 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* If the file is extended, write silently extends it.
|
||||
* We update the extended size here. Otherwise subsequent write's
|
||||
* may fail by relying on wrong file size.
|
||||
*/
|
||||
fwrite_end = __pfn_to_addr(f_offset) + ret;
|
||||
if (v->size < fwrite_end) {
|
||||
v->size = fwrite_end;
|
||||
v->sb->ops->write_vnode(v->sb, v);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: Here's how this should have been:
|
||||
* v->ops.readdir() -> Reads fs-specific directory contents. i.e. reads
|
||||
* the directory buffer, doesn't care however contained vnode details are
|
||||
* stored.
|
||||
*
|
||||
* After reading, it converts the fs-spceific contents into generic vfs
|
||||
* dentries and populates the dentries of those vnodes.
|
||||
*
|
||||
* If vfs_readdir() is issued, those generic dentries are converted into
|
||||
* the posix-defined directory record structure. During this on-the-fly
|
||||
* generation, pseudo-entries such as . and .. are also added.
|
||||
*
|
||||
* If this layering is not done, i.e. the low-level dentry buffer already
|
||||
* keeps this record structure and we try to return that, then we wont
|
||||
* have a chance to add the pseudo-entries . and .. These record entries
|
||||
* are essentially created from parent vnode and current vnode but using
|
||||
* the names . and ..
|
||||
*/
|
||||
|
||||
int fill_dirent(void *buf, unsigned long vnum, int offset, char *name)
|
||||
{
|
||||
struct dirent *d = buf;
|
||||
|
||||
d->inum = (unsigned int)vnum;
|
||||
d->offset = offset;
|
||||
d->rlength = sizeof(struct dirent);
|
||||
strncpy((char *)d->name, name, DIRENT_NAME_MAX);
|
||||
|
||||
return d->rlength;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads @count bytes of posix struct dirents into @buf. This implements
|
||||
* the raw dirent read syscall upon which readdir() etc. posix calls
|
||||
* can be built in userspace.
|
||||
*
|
||||
* FIXME: Ensure buf is in shared utcb, and count does not exceed it.
|
||||
*/
|
||||
int sys_readdir(struct tcb *t, int fd, void *buf, int count)
|
||||
{
|
||||
int dirent_size = sizeof(struct dirent);
|
||||
int total = 0, nbytes = 0;
|
||||
unsigned long vnum;
|
||||
struct vnode *v;
|
||||
struct dentry *d;
|
||||
|
||||
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
|
||||
|
||||
/* Check address is in task's utcb */
|
||||
if ((unsigned long)buf < t->shpage_address ||
|
||||
(unsigned long)buf > t->shpage_address + PAGE_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (fd < 0 || fd > TASK_FILES_MAX || t->files->fd[fd] == NILFD)
|
||||
return -EBADF;
|
||||
|
||||
vnum = t->files->fd[fd];
|
||||
|
||||
/* Lookup vnode */
|
||||
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum)))
|
||||
return -EINVAL;
|
||||
|
||||
d = link_to_struct(v->dentries.next, struct dentry, vref);
|
||||
|
||||
/* Ensure vnode is a directory */
|
||||
if (!vfs_isdir(v))
|
||||
return -ENOTDIR;
|
||||
|
||||
/* Write pseudo-entries . and .. to user buffer */
|
||||
if (count < dirent_size)
|
||||
return 0;
|
||||
|
||||
fill_dirent(buf, v->vnum, nbytes, VFS_STR_CURDIR);
|
||||
nbytes += dirent_size;
|
||||
buf += dirent_size;
|
||||
count -= dirent_size;
|
||||
|
||||
if (count < dirent_size)
|
||||
return 0;
|
||||
|
||||
fill_dirent(buf, d->parent->vnode->vnum, nbytes, VFS_STR_PARDIR);
|
||||
nbytes += dirent_size;
|
||||
buf += dirent_size;
|
||||
count -= dirent_size;
|
||||
|
||||
/* Copy fs-specific dir to buf in struct dirent format */
|
||||
if ((total = v->ops.filldir(buf, v, count)) < 0)
|
||||
return total;
|
||||
|
||||
return nbytes + total;
|
||||
}
|
||||
|
||||
315
conts/posix/fs0/src/task.c
Normal file
315
conts/posix/fs0/src/task.c
Normal file
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* FS0 task data initialisation.
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <l4/macros.h>
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/arch/utcb.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <lib/malloc.h>
|
||||
#include <lib/idpool.h>
|
||||
#include <task.h>
|
||||
#include <vfs.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <syscalls.h>
|
||||
#include <globals.h>
|
||||
|
||||
|
||||
extern void *shared_page;
|
||||
|
||||
struct global_list global_tasks = {
|
||||
.list = { &global_tasks.list, &global_tasks.list },
|
||||
.total = 0,
|
||||
};
|
||||
|
||||
void global_add_task(struct tcb *task)
|
||||
{
|
||||
BUG_ON(!list_empty(&task->list));
|
||||
list_insert_tail(&task->list, &global_tasks.list);
|
||||
global_tasks.total++;
|
||||
}
|
||||
|
||||
void global_remove_task(struct tcb *task)
|
||||
{
|
||||
BUG_ON(list_empty(&task->list));
|
||||
list_remove_init(&task->list);
|
||||
BUG_ON(--global_tasks.total < 0);
|
||||
}
|
||||
|
||||
struct tcb *find_task(int tid)
|
||||
{
|
||||
struct tcb *t;
|
||||
|
||||
list_foreach_struct(t, &global_tasks.list, list)
|
||||
if (t->tid == tid)
|
||||
return t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate a vfs task structure according to given flags */
|
||||
struct tcb *tcb_alloc_init(unsigned int flags)
|
||||
{
|
||||
struct tcb *task;
|
||||
|
||||
if (!(task = kzalloc(sizeof(struct tcb))))
|
||||
return PTR_ERR(-ENOMEM);
|
||||
|
||||
/* Allocate new fs data struct if its not shared */
|
||||
if (!(flags & TCB_SHARED_FS)) {
|
||||
if (!(task->fs_data =
|
||||
kzalloc(sizeof(*task->fs_data)))) {
|
||||
kfree(task);
|
||||
return PTR_ERR(-ENOMEM);
|
||||
}
|
||||
task->fs_data->tcb_refs = 1;
|
||||
}
|
||||
|
||||
/* Allocate file structures if not shared */
|
||||
if (!(flags & TCB_SHARED_FILES)) {
|
||||
if (!(task->files =
|
||||
kzalloc(sizeof(*task->files)))) {
|
||||
kfree(task->fs_data);
|
||||
kfree(task);
|
||||
return PTR_ERR(-ENOMEM);
|
||||
}
|
||||
if (IS_ERR(task->files->fdpool =
|
||||
id_pool_new_init(TASK_FILES_MAX))) {
|
||||
void *err = task->files->fdpool;
|
||||
|
||||
kfree(task->files);
|
||||
kfree(task->fs_data);
|
||||
kfree(task);
|
||||
return err;
|
||||
}
|
||||
task->files->tcb_refs = 1;
|
||||
}
|
||||
|
||||
/* Ids will be set up later */
|
||||
task->tid = TASK_ID_INVALID;
|
||||
|
||||
/* Initialise list structure */
|
||||
link_init(&task->list);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
void copy_tcb(struct tcb *to, struct tcb *from, unsigned int share_flags)
|
||||
{
|
||||
if (share_flags & TCB_SHARED_FILES) {
|
||||
to->files = from->files;
|
||||
to->files->tcb_refs++;
|
||||
} else {
|
||||
/* Copy all file descriptors */
|
||||
memcpy(to->files->fd, from->files->fd,
|
||||
TASK_FILES_MAX * sizeof(to->files->fd[0]));
|
||||
|
||||
/* Copy the idpool */
|
||||
id_pool_copy(to->files->fdpool, from->files->fdpool, TASK_FILES_MAX);
|
||||
}
|
||||
|
||||
if (share_flags & TCB_SHARED_FS) {
|
||||
to->fs_data = from->fs_data;
|
||||
to->fs_data->tcb_refs++;
|
||||
} else
|
||||
memcpy(to->fs_data, from->fs_data, sizeof(*to->fs_data));
|
||||
}
|
||||
|
||||
/* Allocate a task struct and initialise it */
|
||||
struct tcb *tcb_create(struct tcb *orig, l4id_t tid, unsigned long shpage,
|
||||
unsigned int share_flags)
|
||||
{
|
||||
struct tcb *task;
|
||||
|
||||
/* Can't have some share flags with no original task */
|
||||
BUG_ON(!orig && share_flags);
|
||||
|
||||
/* Create a task and use given space and thread ids. */
|
||||
if (IS_ERR(task = tcb_alloc_init(share_flags)))
|
||||
return task;
|
||||
|
||||
task->tid = tid;
|
||||
task->shpage_address = shpage;
|
||||
|
||||
/*
|
||||
* If there's an original task that means this will be a full
|
||||
* or partial copy of it. We copy depending on share_flags.
|
||||
*/
|
||||
if (orig)
|
||||
copy_tcb(task, orig, share_flags);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
/* Free shared structures if no references left */
|
||||
void tcb_free_resources(struct tcb *task)
|
||||
{
|
||||
|
||||
if (--task->fs_data->tcb_refs == 0)
|
||||
kfree(task->fs_data);
|
||||
|
||||
if (--task->files->tcb_refs == 0) {
|
||||
kfree(task->files->fdpool);
|
||||
kfree(task->files);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void tcb_destroy(struct tcb *task)
|
||||
{
|
||||
global_remove_task(task);
|
||||
|
||||
tcb_free_resources(task);
|
||||
|
||||
kfree(task);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attaches to task's utcb. TODO: Add SHM_RDONLY and test it.
|
||||
* FIXME: This calls the pager and is a potential for deadlock
|
||||
* it only doesn't lock because it is called during initialisation.
|
||||
*/
|
||||
int task_utcb_attach(struct tcb *t)
|
||||
{
|
||||
int shmid;
|
||||
void *shmaddr;
|
||||
|
||||
/* Use it as a key to create a shared memory region */
|
||||
if ((shmid = shmget((key_t)t->shpage_address, PAGE_SIZE, 0)) == -1)
|
||||
goto out_err;
|
||||
|
||||
/* Attach to the region */
|
||||
if ((int)(shmaddr = shmat(shmid, (void *)t->shpage_address, 0)) == -1)
|
||||
goto out_err;
|
||||
|
||||
/* Ensure address is right */
|
||||
if ((unsigned long)shmaddr != t->shpage_address)
|
||||
return -EINVAL;
|
||||
|
||||
// printf("%s: Mapped shared page of task %d @ 0x%x\n",
|
||||
// __TASKNAME__, t->tid, shmaddr);
|
||||
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
printf("%s: Mapping utcb of task %d failed with err: %d.\n",
|
||||
__TASKNAME__, t->tid, errno);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Receives ipc from pager about a new fork event and
|
||||
* the information on the resulting child task.
|
||||
*/
|
||||
int pager_notify_fork(struct tcb *sender, l4id_t parentid,
|
||||
l4id_t childid, unsigned long shpage_address,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct tcb *child, *parent;
|
||||
|
||||
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
|
||||
BUG_ON(!(parent = find_task(parentid)));
|
||||
|
||||
/* Create a child vfs tcb using given parent and copy flags */
|
||||
if (IS_ERR(child = tcb_create(parent, childid, shpage_address, flags)))
|
||||
return (int)child;
|
||||
|
||||
global_add_task(child);
|
||||
|
||||
// printf("%s/%s: Exiting...\n", __TASKNAME__, __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Pager tells us that a task is exiting by this call.
|
||||
*/
|
||||
int pager_notify_exit(struct tcb *sender, l4id_t tid)
|
||||
{
|
||||
struct tcb *task;
|
||||
|
||||
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
|
||||
BUG_ON(!(task = find_task(tid)));
|
||||
|
||||
tcb_destroy(task);
|
||||
|
||||
// printf("%s/%s: Exiting...\n", __TASKNAME__, __FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Read task information into the utcb page, since it won't fit into mrs. */
|
||||
struct task_data_head *receive_pager_taskdata(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Make the actual ipc call */
|
||||
if ((err = l4_sendrecv(PAGER_TID, PAGER_TID,
|
||||
L4_IPC_TAG_TASKDATA)) < 0) {
|
||||
printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err);
|
||||
return PTR_ERR(err);
|
||||
}
|
||||
|
||||
/* Check if call itself was successful */
|
||||
if ((err = l4_get_retval()) < 0) {
|
||||
printf("%s: Error: %d.\n", __FUNCTION__, err);
|
||||
return PTR_ERR(err);
|
||||
}
|
||||
|
||||
/* Data is expected in the utcb page */
|
||||
// printf("%s: %d Total tasks.\n", __FUNCTION__,
|
||||
// ((struct task_data_head *)shared_page)->total);
|
||||
|
||||
return (struct task_data_head *)shared_page;
|
||||
}
|
||||
|
||||
|
||||
int init_task_structs(struct task_data_head *tdata_head)
|
||||
{
|
||||
struct tcb *t;
|
||||
|
||||
for (int i = 0; i < tdata_head->total; i++) {
|
||||
/* New tcb with fields sent by pager */
|
||||
if (IS_ERR(t = tcb_create(0, tdata_head->tdata[i].tid,
|
||||
tdata_head->tdata[i].shpage_address,
|
||||
0)))
|
||||
return (int)t;
|
||||
|
||||
/* Initialise vfs specific fields. */
|
||||
t->fs_data->rootdir = vfs_root.pivot;
|
||||
t->fs_data->curdir = vfs_root.pivot;
|
||||
|
||||
/* Print task information */
|
||||
//printf("%s: Task info received from mm0:\n", __TASKNAME__);
|
||||
//printf("%s: task id: %d, utcb address: 0x%x\n",
|
||||
// __TASKNAME__, t->tid, t->utcb_address);
|
||||
|
||||
/* shm attach to the utcbs for all these tasks except own */
|
||||
if (t->tid != self_tid())
|
||||
task_utcb_attach(t);
|
||||
global_add_task(t);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_task_data(void)
|
||||
{
|
||||
struct task_data_head *tdata_head;
|
||||
|
||||
/* Read how many tasks and tids of each */
|
||||
BUG_ON((tdata_head = receive_pager_taskdata()) < 0);
|
||||
|
||||
/* Initialise local task structs using this info */
|
||||
BUG_ON(init_task_structs(tdata_head) < 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
84
conts/posix/fs0/src/vfs.c
Normal file
84
conts/posix/fs0/src/vfs.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* High-level vfs implementation.
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <fs.h>
|
||||
#include <vfs.h>
|
||||
#include <task.h>
|
||||
#include <path.h>
|
||||
|
||||
LINK_DECLARE(vnode_cache);
|
||||
LINK_DECLARE(dentry_cache);
|
||||
|
||||
/*
|
||||
* /
|
||||
* /boot
|
||||
* /boot/images/mm0.axf
|
||||
* /boot/images/fs0.axf
|
||||
* /boot/images/test0.axf
|
||||
* /file.txt
|
||||
*/
|
||||
struct vfs_mountpoint vfs_root;
|
||||
|
||||
/*
|
||||
* Vnodes in the vnode cache have 2 keys. One is their dentry names, the other
|
||||
* is their vnum. This one checks the vnode cache by the given vnum first.
|
||||
* If nothing is found, it reads the vnode from disk into cache. This is called
|
||||
* by system calls since tasks keep an fd-to-vnum table.
|
||||
*/
|
||||
struct vnode *vfs_lookup_byvnum(struct superblock *sb, unsigned long vnum)
|
||||
{
|
||||
struct vnode *v;
|
||||
int err;
|
||||
|
||||
/* Check the vnode flat list by vnum */
|
||||
list_foreach_struct(v, &vnode_cache, cache_list)
|
||||
if (v->vnum == vnum)
|
||||
return v;
|
||||
|
||||
/* Check the actual filesystem for the vnode */
|
||||
v = vfs_alloc_vnode();
|
||||
v->vnum = vnum;
|
||||
|
||||
/* Note this only checks given superblock */
|
||||
if ((err = sb->ops->read_vnode(sb, v)) < 0) {
|
||||
vfs_free_vnode(v);
|
||||
return PTR_ERR(err);
|
||||
}
|
||||
|
||||
/* Add the vnode back to vnode flat list */
|
||||
list_insert(&v->cache_list, &vnode_cache);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
* Vnodes in the vnode cache have 2 keys. One is the set of dentry names they
|
||||
* have, the other is their vnum. This one checks the vnode cache by the path
|
||||
* first. If nothing is found, it reads the vnode from disk into the cache.
|
||||
*/
|
||||
struct vnode *vfs_lookup_bypath(struct pathdata *pdata)
|
||||
{
|
||||
const char *firstcomp;
|
||||
|
||||
/*
|
||||
* This does vfs cache + fs lookup.
|
||||
*/
|
||||
BUG_ON(list_empty(&pdata->list));
|
||||
firstcomp = pathdata_next_component(pdata);
|
||||
return pdata->vstart->ops.lookup(pdata->vstart, pdata, firstcomp);
|
||||
}
|
||||
|
||||
int vfs_mount_root(struct superblock *sb)
|
||||
{
|
||||
/*
|
||||
* Lookup the root vnode of this superblock.
|
||||
* The root superblock has vnode number 0.
|
||||
*/
|
||||
vfs_root.pivot = vfs_lookup_byvnum(sb, 0);
|
||||
vfs_root.sb = sb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
27
conts/posix/fs0/tools/generate_bootdesc.py
Executable file
27
conts/posix/fs0/tools/generate_bootdesc.py
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/python
|
||||
import os
|
||||
import sys
|
||||
|
||||
compiler_prefix = "arm-linux-"
|
||||
objdump = "objdump"
|
||||
command = "-t"
|
||||
image_name = "roottask.axf"
|
||||
linkoutput_file_suffix = "-linkinfo.txt"
|
||||
linkoutput_file = image_name + linkoutput_file_suffix
|
||||
def generate_bootdesc():
|
||||
command = compiler_prefix + objdump + " -t " + image_name + " > " + linkoutput_file
|
||||
print command
|
||||
os.system(command)
|
||||
f = open(linkoutput_file, "r")
|
||||
|
||||
while True:
|
||||
line = f.readline()
|
||||
if len(line) is 0:
|
||||
break
|
||||
if "_start" in line or "_end" in line:
|
||||
print line
|
||||
f.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
generate_bootdesc()
|
||||
|
||||
84
conts/posix/libposix/README
Normal file
84
conts/posix/libposix/README
Normal file
@@ -0,0 +1,84 @@
|
||||
|
||||
libposix
|
||||
|
||||
Copyright (C) 2007 Bahadir Balban
|
||||
|
||||
Despite the name, this is a library that supports only a small portion of posix
|
||||
functions.
|
||||
|
||||
Note however, that unlike many other shallow POSIX implementations function
|
||||
listed below are backed by a real virtual memory subsystem and a virtual
|
||||
filesystem.
|
||||
|
||||
Highest priority POSIX functions are:
|
||||
|
||||
shmat
|
||||
shmget
|
||||
shmdt
|
||||
mmap
|
||||
munmap
|
||||
sbrk
|
||||
read
|
||||
readdir
|
||||
write
|
||||
lseek
|
||||
open
|
||||
close
|
||||
creat
|
||||
mkdir
|
||||
mknod
|
||||
link
|
||||
unlink
|
||||
fork
|
||||
clone
|
||||
execve
|
||||
getpid
|
||||
wait
|
||||
kill
|
||||
getenv
|
||||
setenv
|
||||
|
||||
|
||||
Currently supported functions are:
|
||||
|
||||
shmat
|
||||
shmget
|
||||
shmdt
|
||||
mmap
|
||||
munmap
|
||||
read
|
||||
readdir
|
||||
write
|
||||
lseek
|
||||
open
|
||||
close
|
||||
creat
|
||||
mkdir
|
||||
mknod
|
||||
fork
|
||||
clone
|
||||
execve
|
||||
exit
|
||||
getpid
|
||||
|
||||
|
||||
Functions to be supported in the near future are:
|
||||
|
||||
link
|
||||
unlink
|
||||
wait
|
||||
kill
|
||||
sbrk
|
||||
getenv
|
||||
setenv
|
||||
|
||||
|
||||
Other calls:
|
||||
pipe
|
||||
mount
|
||||
unmount
|
||||
swapon
|
||||
|
||||
|
||||
New ones will be added as needed.
|
||||
|
||||
16
conts/posix/libposix/SConscript
Normal file
16
conts/posix/libposix/SConscript
Normal file
@@ -0,0 +1,16 @@
|
||||
# -*- mode: python; coding: utf-8; -*-
|
||||
|
||||
# Codezero -- A Virtualization microkernel for embedded systems.
|
||||
#
|
||||
# Copyright © 2009 B Labs Ltd
|
||||
|
||||
Import('env')
|
||||
|
||||
e = env.Clone()
|
||||
e.Append(CPPPATH = ['include', 'include/posix'])
|
||||
e.Replace(CCFLAGS = ['-g', '-nostdlib', '-Wall', '-ffreestanding', '-std=gnu99'])
|
||||
|
||||
objects = e.StaticObject(Glob('*.c'))
|
||||
libposix = e.StaticLibrary('posix', objects)
|
||||
|
||||
Return('libposix')
|
||||
74
conts/posix/libposix/SConstruct
Normal file
74
conts/posix/libposix/SConstruct
Normal file
@@ -0,0 +1,74 @@
|
||||
#
|
||||
# Copyright (C) 2007 Bahadir Balban
|
||||
#
|
||||
|
||||
import os
|
||||
import glob
|
||||
import sys
|
||||
from os.path import join
|
||||
from string import split
|
||||
|
||||
project_root = "../.."
|
||||
kernel_headers = join(project_root, "include")
|
||||
l4lib_headers = join(project_root, "tasks/libl4/include")
|
||||
config_h = join(project_root, "include/l4/config.h")
|
||||
|
||||
env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
|
||||
CCFLAGS = ['-g', '-std=gnu99', '-nostdlib', '-ffreestanding'],
|
||||
LINKFLAGS = ['-nostdlib'],
|
||||
CPPPATH = ['#include'],
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
LIBS = 'gcc')
|
||||
|
||||
|
||||
def extract_arch_subarch_plat(config_header):
|
||||
'''
|
||||
From the autogenerated kernel config.h, extracts platform, archictecture,
|
||||
subarchitecture information. This is used to include the relevant headers
|
||||
from the kernel directories.
|
||||
'''
|
||||
arch = None
|
||||
subarch = None
|
||||
plat = None
|
||||
|
||||
if not os.path.exists(config_header):
|
||||
print "\n\nconfig.h does not exist. "\
|
||||
"Please run: `scons configure' first\n\n"
|
||||
sys.exit()
|
||||
f = open(config_h, "r")
|
||||
while True:
|
||||
line = f.readline()
|
||||
if line == "":
|
||||
break
|
||||
parts = split(line)
|
||||
if len(parts) > 0:
|
||||
if parts[0] == "#define":
|
||||
if parts[1] == "__ARCH__":
|
||||
arch = parts[2]
|
||||
elif parts[1] == "__PLATFORM__":
|
||||
plat = parts[2]
|
||||
elif parts[1] == "__SUBARCH__":
|
||||
subarch = parts[2]
|
||||
f.close()
|
||||
if arch == None:
|
||||
print "Error: No config symbol found for architecture"
|
||||
sys.exit()
|
||||
if subarch == None:
|
||||
print "Error: No config symbol found for subarchitecture"
|
||||
sys.exit()
|
||||
if plat == None:
|
||||
print "Error: No config symbol found for platform"
|
||||
sys.exit()
|
||||
return arch, subarch, plat
|
||||
|
||||
arch, subarch, plat = extract_arch_subarch_plat(config_h)
|
||||
|
||||
headers = ["#include/posix", l4lib_headers, kernel_headers]
|
||||
|
||||
env.Append(CPPPATH = headers)
|
||||
|
||||
src = glob.glob("src/*.c") + glob.glob("*.c")
|
||||
|
||||
libposix = env.StaticLibrary('posix', src)
|
||||
|
||||
|
||||
54
conts/posix/libposix/chdir.c
Normal file
54
conts/posix/libposix/chdir.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* l4/posix glue for mkdir()
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <shpage.h>
|
||||
#include <libposix.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4/macros.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
|
||||
static inline int l4_chdir(const char *pathname)
|
||||
{
|
||||
int fd;
|
||||
|
||||
// write_mr(L4SYS_ARG0, (unsigned long)pathname);
|
||||
copy_to_shpage((void *)pathname, 0, strlen(pathname) + 1);
|
||||
write_mr(L4SYS_ARG0, (unsigned long)shared_page);
|
||||
|
||||
/* Call pager with shmget() request. Check ipc error. */
|
||||
if ((fd = l4_sendrecv(VFS_TID, VFS_TID, L4_IPC_TAG_CHDIR)) < 0) {
|
||||
print_err("%s: L4 IPC Error: %d.\n", __FUNCTION__, fd);
|
||||
return fd;
|
||||
}
|
||||
/* Check if syscall itself was successful */
|
||||
if ((fd = l4_get_retval()) < 0) {
|
||||
print_err("%s: MKDIR Error: %d.\n", __FUNCTION__, fd);
|
||||
return fd;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int chdir(const char *pathname)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* If error, return positive error code */
|
||||
if ((ret = l4_chdir(pathname)) < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
/* else return value */
|
||||
return ret;
|
||||
}
|
||||
|
||||
78
conts/posix/libposix/close.c
Normal file
78
conts/posix/libposix/close.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* l4/posix glue for close() and fsync()
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4/macros.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include <libposix.h>
|
||||
|
||||
static inline int l4_close(int fd)
|
||||
{
|
||||
write_mr(L4SYS_ARG0, fd);
|
||||
|
||||
/* Call pager with close() request. Check ipc error. */
|
||||
if ((fd = l4_sendrecv(PAGER_TID, PAGER_TID, L4_IPC_TAG_CLOSE)) < 0) {
|
||||
print_err("%s: L4 IPC Error: %d.\n", __FUNCTION__, fd);
|
||||
return fd;
|
||||
}
|
||||
/* Check if syscall itself was successful */
|
||||
if ((fd = l4_get_retval()) < 0) {
|
||||
print_err("%s: CLOSE Error: %d.\n", __FUNCTION__, fd);
|
||||
return fd;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int close(int fd)
|
||||
{
|
||||
int ret = l4_close(fd);
|
||||
|
||||
/* If error, return positive error code */
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* else return value */
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int l4_fsync(int fd)
|
||||
{
|
||||
write_mr(L4SYS_ARG0, fd);
|
||||
|
||||
/* Call pager with close() request. Check ipc error. */
|
||||
if ((fd = l4_sendrecv(PAGER_TID, PAGER_TID, L4_IPC_TAG_FSYNC)) < 0) {
|
||||
print_err("%s: L4 IPC Error: %d.\n", __FUNCTION__, fd);
|
||||
return fd;
|
||||
}
|
||||
/* Check if syscall itself was successful */
|
||||
if ((fd = l4_get_retval()) < 0) {
|
||||
print_err("%s: CLOSE Error: %d.\n", __FUNCTION__, fd);
|
||||
return fd;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int fsync(int fd)
|
||||
{
|
||||
int ret = l4_fsync(fd);
|
||||
|
||||
/* If error, return positive error code */
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* else return value */
|
||||
return ret;
|
||||
}
|
||||
|
||||
35
conts/posix/libposix/env.c
Normal file
35
conts/posix/libposix/env.c
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Environment accessor functions
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <libposix.h>
|
||||
|
||||
char **__environ;
|
||||
|
||||
/*
|
||||
* Search for given name in name=value string pairs located
|
||||
* in the environment segment, and return the pointer to value
|
||||
* string.
|
||||
*/
|
||||
char *getenv(const char *name)
|
||||
{
|
||||
char **envp = __environ;
|
||||
int length;
|
||||
|
||||
if (!envp)
|
||||
return 0;
|
||||
length = strlen(name);
|
||||
|
||||
while(*envp) {
|
||||
if (memcmp(name, *envp, length) == 0 &&
|
||||
(*envp)[length] == '=')
|
||||
return *envp + length + 1;
|
||||
envp++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
15
conts/posix/libposix/errno.c
Normal file
15
conts/posix/libposix/errno.c
Normal file
@@ -0,0 +1,15 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <libposix.h>
|
||||
|
||||
int errno_variable;
|
||||
|
||||
void perror(const char *str)
|
||||
{
|
||||
print_err("%s: %d\n", str, errno);
|
||||
}
|
||||
|
||||
int *__errno_location(void)
|
||||
{
|
||||
return &errno_variable;
|
||||
}
|
||||
67
conts/posix/libposix/execve.c
Normal file
67
conts/posix/libposix/execve.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* l4/posix glue for execve()
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <fcntl.h>
|
||||
#include <l4/macros.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include <libposix.h>
|
||||
|
||||
|
||||
struct sys_execve_args {
|
||||
char *path;
|
||||
char **argv;
|
||||
char **envp;
|
||||
};
|
||||
|
||||
static inline int l4_execve(const char *pathname, char *const argv[], char *const envp[])
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
write_mr(L4SYS_ARG0, (unsigned long)pathname);
|
||||
write_mr(L4SYS_ARG1, (unsigned long)argv);
|
||||
write_mr(L4SYS_ARG2, (unsigned long)envp);
|
||||
|
||||
|
||||
/* Call pager with open() request. Check ipc error. */
|
||||
if ((err = l4_sendrecv(PAGER_TID, PAGER_TID, L4_IPC_TAG_EXECVE)) < 0) {
|
||||
print_err("%s: L4 IPC Error: %d.\n", __FUNCTION__, err);
|
||||
return err;
|
||||
}
|
||||
/* Check if syscall itself was successful */
|
||||
if ((err = l4_get_retval()) < 0) {
|
||||
print_err("%s: OPEN Error: %d.\n", __FUNCTION__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int execve(const char *pathname, char *const argv[], char *const envp[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = l4_execve(pathname, argv, envp);
|
||||
|
||||
/* If error, return positive error code */
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
/* else return value */
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
27
conts/posix/libposix/exit.c
Normal file
27
conts/posix/libposix/exit.c
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <unistd.h>
|
||||
#include <l4/macros.h>
|
||||
#include <libposix.h>
|
||||
|
||||
static inline void __attribute__ ((noreturn)) l4_exit(int status)
|
||||
{
|
||||
int ret;
|
||||
|
||||
write_mr(L4SYS_ARG0, status);
|
||||
|
||||
/* Call pager with exit() request and block on its receive phase */
|
||||
ret = l4_sendrecv(PAGER_TID, PAGER_TID, L4_IPC_TAG_EXIT);
|
||||
|
||||
/* This call should not fail or return */
|
||||
print_err("%s: L4 IPC returned: %d.\n", __FUNCTION__, ret);
|
||||
BUG();
|
||||
}
|
||||
|
||||
void __attribute__ ((noreturn)) _exit(int status)
|
||||
{
|
||||
l4_exit(status);
|
||||
}
|
||||
|
||||
90
conts/posix/libposix/fork.c
Normal file
90
conts/posix/libposix/fork.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* l4/posix glue for fork()
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4/macros.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include <shpage.h>
|
||||
#include <libposix.h>
|
||||
|
||||
static inline int l4_fork(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Call pager with open() request. Check ipc error. */
|
||||
if ((err = l4_sendrecv(PAGER_TID, PAGER_TID, L4_IPC_TAG_FORK)) < 0) {
|
||||
print_err("%s: L4 IPC Error: %d.\n", __FUNCTION__, err);
|
||||
return err;
|
||||
}
|
||||
/* Check if syscall itself was successful */
|
||||
if ((err = l4_get_retval()) < 0) {
|
||||
print_err("%s: OPEN Error: %d.\n", __FUNCTION__, err);
|
||||
return err;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int fork(void)
|
||||
{
|
||||
int ret = l4_fork();
|
||||
|
||||
/* If error, return positive error code */
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're a child, we need to initialise the default
|
||||
* shared page via libposix_init()
|
||||
*/
|
||||
if (ret == 0)
|
||||
shared_page_init();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern int arch_clone(l4id_t to, l4id_t from, unsigned int flags);
|
||||
|
||||
int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...)
|
||||
{
|
||||
/* Set up the child stack */
|
||||
unsigned int *stack = child_stack;
|
||||
int ret;
|
||||
|
||||
/* First word of new stack is arg */
|
||||
stack[-1] = (unsigned long)arg;
|
||||
|
||||
/* Second word of new stack is function address */
|
||||
stack[-2] = (unsigned long)fn;
|
||||
|
||||
/* Write the tag */
|
||||
l4_set_tag(L4_IPC_TAG_CLONE);
|
||||
|
||||
/* Write the args as in usual ipc */
|
||||
write_mr(L4SYS_ARG0, (unsigned long)child_stack);
|
||||
write_mr(L4SYS_ARG1, flags);
|
||||
|
||||
/* Perform an ipc but with different return logic. See implementation. */
|
||||
if ((ret = arch_clone(PAGER_TID, PAGER_TID, 0)) < 0) {
|
||||
print_err("%s: L4 IPC Error: %d.\n", __FUNCTION__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = l4_get_retval()) < 0) {
|
||||
print_err("%s: CLONE Error: %d.\n", __FUNCTION__, ret);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
11
conts/posix/libposix/getpid.c
Normal file
11
conts/posix/libposix/getpid.c
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <libposix.h>
|
||||
|
||||
pid_t getpid(void)
|
||||
{
|
||||
return self_tid();
|
||||
}
|
||||
13
conts/posix/libposix/include/libposix.h
Normal file
13
conts/posix/libposix/include/libposix.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef __LIBPOSIX_H__
|
||||
#define __LIBPOSIX_H__
|
||||
|
||||
/* Abort debugging conditions */
|
||||
// #define LIBPOSIX_ERROR_MESSAGES
|
||||
#if defined (LIBPOSIX_ERROR_MESSAGES)
|
||||
#define print_err(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define print_err(...)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __LIBPOSIX_H__ */
|
||||
29
conts/posix/libposix/include/posix/_lfs_64.h
Normal file
29
conts/posix/libposix/include/posix/_lfs_64.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
|
||||
*
|
||||
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
|
||||
*/
|
||||
#include <features.h>
|
||||
|
||||
#ifdef __UCLIBC_HAS_LFS__
|
||||
|
||||
#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS != 64
|
||||
#undef _FILE_OFFSET_BITS
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#endif
|
||||
|
||||
#ifndef __USE_LARGEFILE64
|
||||
# define __USE_LARGEFILE64 1
|
||||
#endif
|
||||
|
||||
/* We absolutely do _NOT_ want interfaces silently
|
||||
* renamed under us or very bad things will happen... */
|
||||
#ifdef __USE_FILE_OFFSET64
|
||||
# undef __USE_FILE_OFFSET64
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
# error Do not include this header in files not built when LFS is disabled
|
||||
|
||||
#endif
|
||||
5
conts/posix/libposix/include/posix/a.out.h
Normal file
5
conts/posix/libposix/include/posix/a.out.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#ifdef _LIBC
|
||||
# include_next <linux/a.out.h>
|
||||
#else
|
||||
# include <linux/a.out.h>
|
||||
#endif
|
||||
43
conts/posix/libposix/include/posix/alloca.h
Normal file
43
conts/posix/libposix/include/posix/alloca.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* Copyright (C) 1992, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _ALLOCA_H
|
||||
#define _ALLOCA_H 1
|
||||
|
||||
#include <features.h>
|
||||
|
||||
#define __need_size_t
|
||||
#include <stddef.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* Remove any previous definitions. */
|
||||
#undef alloca
|
||||
|
||||
/* Allocate a block that will be freed when the calling function exits. */
|
||||
extern void *alloca (size_t __size) __THROW;
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define alloca(size) __builtin_alloca (size)
|
||||
#endif /* GCC. */
|
||||
|
||||
#define __MAX_ALLOCA_CUTOFF 65536
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* alloca.h */
|
||||
48
conts/posix/libposix/include/posix/ar.h
Normal file
48
conts/posix/libposix/include/posix/ar.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* Header describing `ar' archive file format.
|
||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _AR_H
|
||||
#define _AR_H 1
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/* Archive files start with the ARMAG identifying string. Then follows a
|
||||
`struct ar_hdr', and as many bytes of member file data as its `ar_size'
|
||||
member indicates, for each member file. */
|
||||
|
||||
#define ARMAG "!<arch>\n" /* String that begins an archive file. */
|
||||
#define SARMAG 8 /* Size of that string. */
|
||||
|
||||
#define ARFMAG "`\n" /* String in ar_fmag at end of each header. */
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct ar_hdr
|
||||
{
|
||||
char ar_name[16]; /* Member file name, sometimes / terminated. */
|
||||
char ar_date[12]; /* File date, decimal seconds since Epoch. */
|
||||
char ar_uid[6], ar_gid[6]; /* User and group IDs, in ASCII decimal. */
|
||||
char ar_mode[8]; /* File mode, in ASCII octal. */
|
||||
char ar_size[10]; /* File size, in ASCII decimal. */
|
||||
char ar_fmag[2]; /* Always contains ARFMAG. */
|
||||
};
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* ar.h */
|
||||
105
conts/posix/libposix/include/posix/arpa/ftp.h
Normal file
105
conts/posix/libposix/include/posix/arpa/ftp.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ftp.h 8.1 (Berkeley) 6/2/93
|
||||
*/
|
||||
|
||||
#ifndef _ARPA_FTP_H
|
||||
#define _ARPA_FTP_H 1
|
||||
|
||||
/* Definitions for FTP; see RFC-765. */
|
||||
|
||||
/*
|
||||
* Reply codes.
|
||||
*/
|
||||
#define PRELIM 1 /* positive preliminary */
|
||||
#define COMPLETE 2 /* positive completion */
|
||||
#define CONTINUE 3 /* positive intermediate */
|
||||
#define TRANSIENT 4 /* transient negative completion */
|
||||
#define ERROR 5 /* permanent negative completion */
|
||||
|
||||
/*
|
||||
* Type codes
|
||||
*/
|
||||
#define TYPE_A 1 /* ASCII */
|
||||
#define TYPE_E 2 /* EBCDIC */
|
||||
#define TYPE_I 3 /* image */
|
||||
#define TYPE_L 4 /* local byte size */
|
||||
|
||||
#ifdef FTP_NAMES
|
||||
char *typenames[] = {"0", "ASCII", "EBCDIC", "Image", "Local" };
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Form codes
|
||||
*/
|
||||
#define FORM_N 1 /* non-print */
|
||||
#define FORM_T 2 /* telnet format effectors */
|
||||
#define FORM_C 3 /* carriage control (ASA) */
|
||||
#ifdef FTP_NAMES
|
||||
char *formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control" };
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Structure codes
|
||||
*/
|
||||
#define STRU_F 1 /* file (no record structure) */
|
||||
#define STRU_R 2 /* record structure */
|
||||
#define STRU_P 3 /* page structure */
|
||||
#ifdef FTP_NAMES
|
||||
char *strunames[] = {"0", "File", "Record", "Page" };
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mode types
|
||||
*/
|
||||
#define MODE_S 1 /* stream */
|
||||
#define MODE_B 2 /* block */
|
||||
#define MODE_C 3 /* compressed */
|
||||
#ifdef FTP_NAMES
|
||||
char *modenames[] = {"0", "Stream", "Block", "Compressed" };
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Record Tokens
|
||||
*/
|
||||
#define REC_ESC '\377' /* Record-mode Escape */
|
||||
#define REC_EOR '\001' /* Record-mode End-of-Record */
|
||||
#define REC_EOF '\002' /* Record-mode End-of-File */
|
||||
|
||||
/*
|
||||
* Block Header
|
||||
*/
|
||||
#define BLK_EOR 0x80 /* Block is End-of-Record */
|
||||
#define BLK_EOF 0x40 /* Block is End-of-File */
|
||||
#define BLK_ERRORS 0x20 /* Block is suspected of containing errors */
|
||||
#define BLK_RESTART 0x10 /* Block is Restart Marker */
|
||||
|
||||
#define BLK_BYTECOUNT 2 /* Bytes in this block */
|
||||
|
||||
#endif /* arpa/ftp.h */
|
||||
106
conts/posix/libposix/include/posix/arpa/inet.h
Normal file
106
conts/posix/libposix/include/posix/arpa/inet.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/* Copyright (C) 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _ARPA_INET_H
|
||||
#define _ARPA_INET_H 1
|
||||
|
||||
#include <features.h>
|
||||
#include <netinet/in.h> /* To define `struct in_addr'. */
|
||||
|
||||
/* Type for length arguments in socket calls. */
|
||||
#ifndef __socklen_t_defined
|
||||
typedef __socklen_t socklen_t;
|
||||
# define __socklen_t_defined
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* Convert Internet host address from numbers-and-dots notation in CP
|
||||
into binary data in network byte order. */
|
||||
extern in_addr_t inet_addr (__const char *__cp) __THROW;
|
||||
|
||||
/* Return the local host address part of the Internet address in IN. */
|
||||
extern in_addr_t inet_lnaof (struct in_addr __in) __THROW;
|
||||
|
||||
/* Make Internet host address in network byte order by combining the
|
||||
network number NET with the local address HOST. */
|
||||
extern struct in_addr inet_makeaddr (in_addr_t __net, in_addr_t __host)
|
||||
__THROW;
|
||||
|
||||
/* Return network number part of the Internet address IN. */
|
||||
extern in_addr_t inet_netof (struct in_addr __in) __THROW;
|
||||
|
||||
/* Extract the network number in network byte order from the address
|
||||
in numbers-and-dots natation starting at CP. */
|
||||
extern in_addr_t inet_network (__const char *__cp) __THROW;
|
||||
|
||||
/* Convert Internet number in IN to ASCII representation. The return value
|
||||
is a pointer to an internal array containing the string. */
|
||||
extern char *inet_ntoa (struct in_addr __in) __THROW;
|
||||
|
||||
/* Convert from presentation format of an Internet number in buffer
|
||||
starting at CP to the binary network format and store result for
|
||||
interface type AF in buffer starting at BUF. */
|
||||
extern int inet_pton (int __af, __const char *__restrict __cp,
|
||||
void *__restrict __buf) __THROW;
|
||||
|
||||
/* Convert a Internet address in binary network format for interface
|
||||
type AF in buffer starting at CP to presentation form and place
|
||||
result in buffer of length LEN astarting at BUF. */
|
||||
extern __const char *inet_ntop (int __af, __const void *__restrict __cp,
|
||||
char *__restrict __buf, socklen_t __len)
|
||||
__THROW;
|
||||
|
||||
|
||||
/* The following functions are not part of XNS 5.2. */
|
||||
#ifdef __USE_MISC
|
||||
/* Convert Internet host address from numbers-and-dots notation in CP
|
||||
into binary data and store the result in the structure INP. */
|
||||
extern int inet_aton (__const char *__cp, struct in_addr *__inp) __THROW;
|
||||
|
||||
/* Format a network number NET into presentation format and place result
|
||||
in buffer starting at BUF with length of LEN bytes. */
|
||||
extern char *inet_neta (in_addr_t __net, char *__buf, size_t __len) __THROW;
|
||||
|
||||
/* Convert network number for interface type AF in buffer starting at
|
||||
CP to presentation format. The result will specifiy BITS bits of
|
||||
the number. */
|
||||
extern char *inet_net_ntop (int __af, __const void *__cp, int __bits,
|
||||
char *__buf, size_t __len) __THROW;
|
||||
|
||||
/* Convert network number for interface type AF from presentation in
|
||||
buffer starting at CP to network format and store result int
|
||||
buffer starting at BUF of size LEN. */
|
||||
extern int inet_net_pton (int __af, __const char *__cp,
|
||||
void *__buf, size_t __len) __THROW;
|
||||
|
||||
/* Convert ASCII representation in hexadecimal form of the Internet
|
||||
address to binary form and place result in buffer of length LEN
|
||||
starting at BUF. */
|
||||
extern unsigned int inet_nsap_addr (__const char *__cp,
|
||||
unsigned char *__buf, int __len) __THROW;
|
||||
|
||||
/* Convert internet address in binary form in LEN bytes starting at CP
|
||||
a presentation form and place result in BUF. */
|
||||
extern char *inet_nsap_ntoa (int __len, __const unsigned char *__cp,
|
||||
char *__buf) __THROW;
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* arpa/inet.h */
|
||||
557
conts/posix/libposix/include/posix/arpa/nameser.h
Normal file
557
conts/posix/libposix/include/posix/arpa/nameser.h
Normal file
@@ -0,0 +1,557 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $BINDId: nameser.h,v 8.37 2000/03/30 21:16:49 vixie Exp $
|
||||
*/
|
||||
|
||||
#ifndef _ARPA_NAMESER_H_
|
||||
#define _ARPA_NAMESER_H_
|
||||
|
||||
#define BIND_4_COMPAT
|
||||
|
||||
#include <sys/param.h>
|
||||
#if (!defined(BSD)) || (BSD < 199306)
|
||||
# include <sys/bitypes.h>
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/*
|
||||
* Revision information. This is the release date in YYYYMMDD format.
|
||||
* It can change every day so the right thing to do with it is use it
|
||||
* in preprocessor commands such as "#if (__NAMESER > 19931104)". Do not
|
||||
* compare for equality; rather, use it to determine whether your libbind.a
|
||||
* contains a new enough lib/nameser/ to support the feature you need.
|
||||
*/
|
||||
|
||||
#define __NAMESER 19991006 /* New interface version stamp. */
|
||||
|
||||
/*
|
||||
* Define constants based on RFC 883, RFC 1034, RFC 1035
|
||||
*/
|
||||
#define NS_PACKETSZ 512 /* maximum packet size */
|
||||
#define NS_MAXDNAME 1025 /* maximum domain name */
|
||||
#define NS_MAXCDNAME 255 /* maximum compressed domain name */
|
||||
#define NS_MAXLABEL 63 /* maximum length of domain label */
|
||||
#define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */
|
||||
#define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */
|
||||
#define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
|
||||
#define NS_INT32SZ 4 /* #/bytes of data in a u_int32_t */
|
||||
#define NS_INT16SZ 2 /* #/bytes of data in a u_int16_t */
|
||||
#define NS_INT8SZ 1 /* #/bytes of data in a u_int8_t */
|
||||
#define NS_INADDRSZ 4 /* IPv4 T_A */
|
||||
#define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */
|
||||
#define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */
|
||||
#define NS_DEFAULTPORT 53 /* For both TCP and UDP. */
|
||||
|
||||
/*
|
||||
* These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord()
|
||||
* in synch with it.
|
||||
*/
|
||||
typedef enum __ns_sect {
|
||||
ns_s_qd = 0, /* Query: Question. */
|
||||
ns_s_zn = 0, /* Update: Zone. */
|
||||
ns_s_an = 1, /* Query: Answer. */
|
||||
ns_s_pr = 1, /* Update: Prerequisites. */
|
||||
ns_s_ns = 2, /* Query: Name servers. */
|
||||
ns_s_ud = 2, /* Update: Update. */
|
||||
ns_s_ar = 3, /* Query|Update: Additional records. */
|
||||
ns_s_max = 4
|
||||
} ns_sect;
|
||||
|
||||
/*
|
||||
* This is a message handle. It is caller allocated and has no dynamic data.
|
||||
* This structure is intended to be opaque to all but ns_parse.c, thus the
|
||||
* leading _'s on the member names. Use the accessor functions, not the _'s.
|
||||
*/
|
||||
typedef struct __ns_msg {
|
||||
const u_char *_msg, *_eom;
|
||||
u_int16_t _id, _flags, _counts[ns_s_max];
|
||||
const u_char *_sections[ns_s_max];
|
||||
ns_sect _sect;
|
||||
int _rrnum;
|
||||
const u_char *_ptr;
|
||||
} ns_msg;
|
||||
|
||||
/* Private data structure - do not use from outside library. */
|
||||
struct _ns_flagdata { int mask, shift; };
|
||||
extern struct _ns_flagdata _ns_flagdata[];
|
||||
|
||||
/* Accessor macros - this is part of the public interface. */
|
||||
#define ns_msg_getflag(handle, flag) ( \
|
||||
((handle)._flags & _ns_flagdata[flag].mask) \
|
||||
>> _ns_flagdata[flag].shift \
|
||||
)
|
||||
#define ns_msg_id(handle) ((handle)._id + 0)
|
||||
#define ns_msg_base(handle) ((handle)._msg + 0)
|
||||
#define ns_msg_end(handle) ((handle)._eom + 0)
|
||||
#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
|
||||
#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
|
||||
|
||||
/*
|
||||
* This is a parsed record. It is caller allocated and has no dynamic data.
|
||||
*/
|
||||
typedef struct __ns_rr {
|
||||
char name[NS_MAXDNAME];
|
||||
u_int16_t type;
|
||||
u_int16_t rr_class;
|
||||
u_int32_t ttl;
|
||||
u_int16_t rdlength;
|
||||
const u_char * rdata;
|
||||
} ns_rr;
|
||||
|
||||
/* Accessor macros - this is part of the public interface. */
|
||||
#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
|
||||
#define ns_rr_type(rr) ((ns_type)((rr).type + 0))
|
||||
#define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0))
|
||||
#define ns_rr_ttl(rr) ((rr).ttl + 0)
|
||||
#define ns_rr_rdlen(rr) ((rr).rdlength + 0)
|
||||
#define ns_rr_rdata(rr) ((rr).rdata + 0)
|
||||
|
||||
/*
|
||||
* These don't have to be in the same order as in the packet flags word,
|
||||
* and they can even overlap in some cases, but they will need to be kept
|
||||
* in synch with ns_parse.c:ns_flagdata[].
|
||||
*/
|
||||
typedef enum __ns_flag {
|
||||
ns_f_qr, /* Question/Response. */
|
||||
ns_f_opcode, /* Operation code. */
|
||||
ns_f_aa, /* Authoritative Answer. */
|
||||
ns_f_tc, /* Truncation occurred. */
|
||||
ns_f_rd, /* Recursion Desired. */
|
||||
ns_f_ra, /* Recursion Available. */
|
||||
ns_f_z, /* MBZ. */
|
||||
ns_f_ad, /* Authentic Data (DNSSEC). */
|
||||
ns_f_cd, /* Checking Disabled (DNSSEC). */
|
||||
ns_f_rcode, /* Response code. */
|
||||
ns_f_max
|
||||
} ns_flag;
|
||||
|
||||
/*
|
||||
* Currently defined opcodes.
|
||||
*/
|
||||
typedef enum __ns_opcode {
|
||||
ns_o_query = 0, /* Standard query. */
|
||||
ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */
|
||||
ns_o_status = 2, /* Name server status query (unsupported). */
|
||||
/* Opcode 3 is undefined/reserved. */
|
||||
ns_o_notify = 4, /* Zone change notification. */
|
||||
ns_o_update = 5, /* Zone update message. */
|
||||
ns_o_max = 6
|
||||
} ns_opcode;
|
||||
|
||||
/*
|
||||
* Currently defined response codes.
|
||||
*/
|
||||
typedef enum __ns_rcode {
|
||||
ns_r_noerror = 0, /* No error occurred. */
|
||||
ns_r_formerr = 1, /* Format error. */
|
||||
ns_r_servfail = 2, /* Server failure. */
|
||||
ns_r_nxdomain = 3, /* Name error. */
|
||||
ns_r_notimpl = 4, /* Unimplemented. */
|
||||
ns_r_refused = 5, /* Operation refused. */
|
||||
/* these are for BIND_UPDATE */
|
||||
ns_r_yxdomain = 6, /* Name exists */
|
||||
ns_r_yxrrset = 7, /* RRset exists */
|
||||
ns_r_nxrrset = 8, /* RRset does not exist */
|
||||
ns_r_notauth = 9, /* Not authoritative for zone */
|
||||
ns_r_notzone = 10, /* Zone of record different from zone section */
|
||||
ns_r_max = 11,
|
||||
/* The following are TSIG extended errors */
|
||||
ns_r_badsig = 16,
|
||||
ns_r_badkey = 17,
|
||||
ns_r_badtime = 18
|
||||
} ns_rcode;
|
||||
|
||||
/* BIND_UPDATE */
|
||||
typedef enum __ns_update_operation {
|
||||
ns_uop_delete = 0,
|
||||
ns_uop_add = 1,
|
||||
ns_uop_max = 2
|
||||
} ns_update_operation;
|
||||
|
||||
/*
|
||||
* This structure is used for TSIG authenticated messages
|
||||
*/
|
||||
struct ns_tsig_key {
|
||||
char name[NS_MAXDNAME], alg[NS_MAXDNAME];
|
||||
unsigned char *data;
|
||||
int len;
|
||||
};
|
||||
typedef struct ns_tsig_key ns_tsig_key;
|
||||
|
||||
/*
|
||||
* This structure is used for TSIG authenticated TCP messages
|
||||
*/
|
||||
struct ns_tcp_tsig_state {
|
||||
int counter;
|
||||
struct dst_key *key;
|
||||
void *ctx;
|
||||
unsigned char sig[NS_PACKETSZ];
|
||||
int siglen;
|
||||
};
|
||||
typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
|
||||
|
||||
#define NS_TSIG_FUDGE 300
|
||||
#define NS_TSIG_TCP_COUNT 100
|
||||
#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
|
||||
|
||||
#define NS_TSIG_ERROR_NO_TSIG -10
|
||||
#define NS_TSIG_ERROR_NO_SPACE -11
|
||||
#define NS_TSIG_ERROR_FORMERR -12
|
||||
|
||||
/*
|
||||
* Currently defined type values for resources and queries.
|
||||
*/
|
||||
typedef enum __ns_type {
|
||||
ns_t_invalid = 0, /* Cookie. */
|
||||
ns_t_a = 1, /* Host address. */
|
||||
ns_t_ns = 2, /* Authoritative server. */
|
||||
ns_t_md = 3, /* Mail destination. */
|
||||
ns_t_mf = 4, /* Mail forwarder. */
|
||||
ns_t_cname = 5, /* Canonical name. */
|
||||
ns_t_soa = 6, /* Start of authority zone. */
|
||||
ns_t_mb = 7, /* Mailbox domain name. */
|
||||
ns_t_mg = 8, /* Mail group member. */
|
||||
ns_t_mr = 9, /* Mail rename name. */
|
||||
ns_t_null = 10, /* Null resource record. */
|
||||
ns_t_wks = 11, /* Well known service. */
|
||||
ns_t_ptr = 12, /* Domain name pointer. */
|
||||
ns_t_hinfo = 13, /* Host information. */
|
||||
ns_t_minfo = 14, /* Mailbox information. */
|
||||
ns_t_mx = 15, /* Mail routing information. */
|
||||
ns_t_txt = 16, /* Text strings. */
|
||||
ns_t_rp = 17, /* Responsible person. */
|
||||
ns_t_afsdb = 18, /* AFS cell database. */
|
||||
ns_t_x25 = 19, /* X_25 calling address. */
|
||||
ns_t_isdn = 20, /* ISDN calling address. */
|
||||
ns_t_rt = 21, /* Router. */
|
||||
ns_t_nsap = 22, /* NSAP address. */
|
||||
ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */
|
||||
ns_t_sig = 24, /* Security signature. */
|
||||
ns_t_key = 25, /* Security key. */
|
||||
ns_t_px = 26, /* X.400 mail mapping. */
|
||||
ns_t_gpos = 27, /* Geographical position (withdrawn). */
|
||||
ns_t_aaaa = 28, /* Ip6 Address. */
|
||||
ns_t_loc = 29, /* Location Information. */
|
||||
ns_t_nxt = 30, /* Next domain (security). */
|
||||
ns_t_eid = 31, /* Endpoint identifier. */
|
||||
ns_t_nimloc = 32, /* Nimrod Locator. */
|
||||
ns_t_srv = 33, /* Server Selection. */
|
||||
ns_t_atma = 34, /* ATM Address */
|
||||
ns_t_naptr = 35, /* Naming Authority PoinTeR */
|
||||
ns_t_kx = 36, /* Key Exchange */
|
||||
ns_t_cert = 37, /* Certification record */
|
||||
ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */
|
||||
ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */
|
||||
ns_t_sink = 40, /* Kitchen sink (experimentatl) */
|
||||
ns_t_opt = 41, /* EDNS0 option (meta-RR) */
|
||||
ns_t_tsig = 250, /* Transaction signature. */
|
||||
ns_t_ixfr = 251, /* Incremental zone transfer. */
|
||||
ns_t_axfr = 252, /* Transfer zone of authority. */
|
||||
ns_t_mailb = 253, /* Transfer mailbox records. */
|
||||
ns_t_maila = 254, /* Transfer mail agent records. */
|
||||
ns_t_any = 255, /* Wildcard match. */
|
||||
ns_t_zxfr = 256, /* BIND-specific, nonstandard. */
|
||||
ns_t_max = 65536
|
||||
} ns_type;
|
||||
|
||||
/* Exclusively a QTYPE? (not also an RTYPE) */
|
||||
#define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \
|
||||
(t) == ns_t_mailb || (t) == ns_t_maila)
|
||||
/* Some kind of meta-RR? (not a QTYPE, but also not an RTYPE) */
|
||||
#define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
|
||||
/* Exclusively an RTYPE? (not also a QTYPE or a meta-RR) */
|
||||
#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
|
||||
#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
|
||||
#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \
|
||||
(t) == ns_t_zxfr)
|
||||
|
||||
/*
|
||||
* Values for class field
|
||||
*/
|
||||
typedef enum __ns_class {
|
||||
ns_c_invalid = 0, /* Cookie. */
|
||||
ns_c_in = 1, /* Internet. */
|
||||
ns_c_2 = 2, /* unallocated/unsupported. */
|
||||
ns_c_chaos = 3, /* MIT Chaos-net. */
|
||||
ns_c_hs = 4, /* MIT Hesiod. */
|
||||
/* Query class values which do not appear in resource records */
|
||||
ns_c_none = 254, /* for prereq. sections in update requests */
|
||||
ns_c_any = 255, /* Wildcard match. */
|
||||
ns_c_max = 65536
|
||||
} ns_class;
|
||||
|
||||
/* DNSSEC constants. */
|
||||
|
||||
typedef enum __ns_key_types {
|
||||
ns_kt_rsa = 1, /* key type RSA/MD5 */
|
||||
ns_kt_dh = 2, /* Diffie Hellman */
|
||||
ns_kt_dsa = 3, /* Digital Signature Standard (MANDATORY) */
|
||||
ns_kt_private = 254 /* Private key type starts with OID */
|
||||
} ns_key_types;
|
||||
|
||||
typedef enum __ns_cert_types {
|
||||
cert_t_pkix = 1, /* PKIX (X.509v3) */
|
||||
cert_t_spki = 2, /* SPKI */
|
||||
cert_t_pgp = 3, /* PGP */
|
||||
cert_t_url = 253, /* URL private type */
|
||||
cert_t_oid = 254 /* OID private type */
|
||||
} ns_cert_types;
|
||||
|
||||
/* Flags field of the KEY RR rdata. */
|
||||
#define NS_KEY_TYPEMASK 0xC000 /* Mask for "type" bits */
|
||||
#define NS_KEY_TYPE_AUTH_CONF 0x0000 /* Key usable for both */
|
||||
#define NS_KEY_TYPE_CONF_ONLY 0x8000 /* Key usable for confidentiality */
|
||||
#define NS_KEY_TYPE_AUTH_ONLY 0x4000 /* Key usable for authentication */
|
||||
#define NS_KEY_TYPE_NO_KEY 0xC000 /* No key usable for either; no key */
|
||||
/* The type bits can also be interpreted independently, as single bits: */
|
||||
#define NS_KEY_NO_AUTH 0x8000 /* Key unusable for authentication */
|
||||
#define NS_KEY_NO_CONF 0x4000 /* Key unusable for confidentiality */
|
||||
#define NS_KEY_RESERVED2 0x2000 /* Security is *mandatory* if bit=0 */
|
||||
#define NS_KEY_EXTENDED_FLAGS 0x1000 /* reserved - must be zero */
|
||||
#define NS_KEY_RESERVED4 0x0800 /* reserved - must be zero */
|
||||
#define NS_KEY_RESERVED5 0x0400 /* reserved - must be zero */
|
||||
#define NS_KEY_NAME_TYPE 0x0300 /* these bits determine the type */
|
||||
#define NS_KEY_NAME_USER 0x0000 /* key is assoc. with user */
|
||||
#define NS_KEY_NAME_ENTITY 0x0200 /* key is assoc. with entity eg host */
|
||||
#define NS_KEY_NAME_ZONE 0x0100 /* key is zone key */
|
||||
#define NS_KEY_NAME_RESERVED 0x0300 /* reserved meaning */
|
||||
#define NS_KEY_RESERVED8 0x0080 /* reserved - must be zero */
|
||||
#define NS_KEY_RESERVED9 0x0040 /* reserved - must be zero */
|
||||
#define NS_KEY_RESERVED10 0x0020 /* reserved - must be zero */
|
||||
#define NS_KEY_RESERVED11 0x0010 /* reserved - must be zero */
|
||||
#define NS_KEY_SIGNATORYMASK 0x000F /* key can sign RR's of same name */
|
||||
#define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \
|
||||
NS_KEY_RESERVED4 | \
|
||||
NS_KEY_RESERVED5 | \
|
||||
NS_KEY_RESERVED8 | \
|
||||
NS_KEY_RESERVED9 | \
|
||||
NS_KEY_RESERVED10 | \
|
||||
NS_KEY_RESERVED11 )
|
||||
#define NS_KEY_RESERVED_BITMASK2 0xFFFF /* no bits defined here */
|
||||
|
||||
/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
|
||||
#define NS_ALG_MD5RSA 1 /* MD5 with RSA */
|
||||
#define NS_ALG_DH 2 /* Diffie Hellman KEY */
|
||||
#define NS_ALG_DSA 3 /* DSA KEY */
|
||||
#define NS_ALG_DSS NS_ALG_DSA
|
||||
#define NS_ALG_EXPIRE_ONLY 253 /* No alg, no security */
|
||||
#define NS_ALG_PRIVATE_OID 254 /* Key begins with OID giving alg */
|
||||
|
||||
/* Protocol values */
|
||||
/* value 0 is reserved */
|
||||
#define NS_KEY_PROT_TLS 1
|
||||
#define NS_KEY_PROT_EMAIL 2
|
||||
#define NS_KEY_PROT_DNSSEC 3
|
||||
#define NS_KEY_PROT_IPSEC 4
|
||||
#define NS_KEY_PROT_ANY 255
|
||||
|
||||
/* Signatures */
|
||||
#define NS_MD5RSA_MIN_BITS 512 /* Size of a mod or exp in bits */
|
||||
#define NS_MD5RSA_MAX_BITS 2552
|
||||
/* Total of binary mod and exp */
|
||||
#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3)
|
||||
/* Max length of text sig block */
|
||||
#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4)
|
||||
#define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS+7)/8)
|
||||
#define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS+7)/8)
|
||||
|
||||
#define NS_DSA_SIG_SIZE 41
|
||||
#define NS_DSA_MIN_SIZE 213
|
||||
#define NS_DSA_MAX_BYTES 405
|
||||
|
||||
/* Offsets into SIG record rdata to find various values */
|
||||
#define NS_SIG_TYPE 0 /* Type flags */
|
||||
#define NS_SIG_ALG 2 /* Algorithm */
|
||||
#define NS_SIG_LABELS 3 /* How many labels in name */
|
||||
#define NS_SIG_OTTL 4 /* Original TTL */
|
||||
#define NS_SIG_EXPIR 8 /* Expiration time */
|
||||
#define NS_SIG_SIGNED 12 /* Signature time */
|
||||
#define NS_SIG_FOOT 16 /* Key footprint */
|
||||
#define NS_SIG_SIGNER 18 /* Domain name of who signed it */
|
||||
|
||||
/* How RR types are represented as bit-flags in NXT records */
|
||||
#define NS_NXT_BITS 8
|
||||
#define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS)))
|
||||
#define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
|
||||
#define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS)))
|
||||
#define NS_NXT_MAX 127
|
||||
|
||||
/*
|
||||
* Inline versions of get/put short/long. Pointer is advanced.
|
||||
*/
|
||||
#define NS_GET16(s, cp) do { \
|
||||
register u_char *t_cp = (u_char *)(cp); \
|
||||
(s) = ((u_int16_t)t_cp[0] << 8) \
|
||||
| ((u_int16_t)t_cp[1]) \
|
||||
; \
|
||||
(cp) += NS_INT16SZ; \
|
||||
} while (0)
|
||||
|
||||
#define NS_GET32(l, cp) do { \
|
||||
register u_char *t_cp = (u_char *)(cp); \
|
||||
(l) = ((u_int32_t)t_cp[0] << 24) \
|
||||
| ((u_int32_t)t_cp[1] << 16) \
|
||||
| ((u_int32_t)t_cp[2] << 8) \
|
||||
| ((u_int32_t)t_cp[3]) \
|
||||
; \
|
||||
(cp) += NS_INT32SZ; \
|
||||
} while (0)
|
||||
|
||||
#define NS_PUT16(s, cp) do { \
|
||||
register u_int16_t t_s = (u_int16_t)(s); \
|
||||
register u_char *t_cp = (u_char *)(cp); \
|
||||
*t_cp++ = t_s >> 8; \
|
||||
*t_cp = t_s; \
|
||||
(cp) += NS_INT16SZ; \
|
||||
} while (0)
|
||||
|
||||
#define NS_PUT32(l, cp) do { \
|
||||
register u_int32_t t_l = (u_int32_t)(l); \
|
||||
register u_char *t_cp = (u_char *)(cp); \
|
||||
*t_cp++ = t_l >> 24; \
|
||||
*t_cp++ = t_l >> 16; \
|
||||
*t_cp++ = t_l >> 8; \
|
||||
*t_cp = t_l; \
|
||||
(cp) += NS_INT32SZ; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* ANSI C identifier hiding for bind's lib/nameser.
|
||||
*/
|
||||
#define ns_get16 __ns_get16
|
||||
#define ns_get32 __ns_get32
|
||||
#define ns_put16 __ns_put16
|
||||
#define ns_put32 __ns_put32
|
||||
#define ns_initparse __ns_initparse
|
||||
#define ns_skiprr __ns_skiprr
|
||||
#define ns_parserr __ns_parserr
|
||||
#define ns_sprintrr __ns_sprintrr
|
||||
#define ns_sprintrrf __ns_sprintrrf
|
||||
#define ns_format_ttl __ns_format_ttl
|
||||
#define ns_parse_ttl __ns_parse_ttl
|
||||
#define ns_datetosecs __ns_datetosecs
|
||||
#define ns_name_ntol __ns_name_ntol
|
||||
#define ns_name_ntop __ns_name_ntop
|
||||
#define ns_name_pton __ns_name_pton
|
||||
#define ns_name_unpack __ns_name_unpack
|
||||
#define ns_name_pack __ns_name_pack
|
||||
#define ns_name_compress __ns_name_compress
|
||||
#define ns_name_uncompress __ns_name_uncompress
|
||||
#define ns_name_skip __ns_name_skip
|
||||
#define ns_name_rollback __ns_name_rollback
|
||||
#define ns_sign __ns_sign
|
||||
#define ns_sign_tcp __ns_sign_tcp
|
||||
#define ns_sign_tcp_init __ns_sign_tcp_init
|
||||
#define ns_find_tsig __ns_find_tsig
|
||||
#define ns_verify __ns_verify
|
||||
#define ns_verify_tcp __ns_verify_tcp
|
||||
#define ns_verify_tcp_init __ns_verify_tcp_init
|
||||
#define ns_samedomain __ns_samedomain
|
||||
#define ns_subdomain __ns_subdomain
|
||||
#define ns_makecanon __ns_makecanon
|
||||
#define ns_samename __ns_samename
|
||||
|
||||
__BEGIN_DECLS
|
||||
u_int ns_get16 (const u_char *) __THROW;
|
||||
u_long ns_get32 (const u_char *) __THROW;
|
||||
void ns_put16 (u_int, u_char *) __THROW;
|
||||
void ns_put32 (u_long, u_char *) __THROW;
|
||||
int ns_initparse (const u_char *, int, ns_msg *) __THROW;
|
||||
int ns_skiprr (const u_char *, const u_char *, ns_sect, int)
|
||||
__THROW;
|
||||
int ns_parserr (ns_msg *, ns_sect, int, ns_rr *) __THROW;
|
||||
int ns_sprintrr (const ns_msg *, const ns_rr *,
|
||||
const char *, const char *, char *, size_t)
|
||||
__THROW;
|
||||
int ns_sprintrrf (const u_char *, size_t, const char *,
|
||||
ns_class, ns_type, u_long, const u_char *,
|
||||
size_t, const char *, const char *,
|
||||
char *, size_t) __THROW;
|
||||
int ns_format_ttl (u_long, char *, size_t) __THROW;
|
||||
int ns_parse_ttl (const char *, u_long *) __THROW;
|
||||
u_int32_t ns_datetosecs (const char *cp, int *errp) __THROW;
|
||||
int ns_name_ntol (const u_char *, u_char *, size_t) __THROW;
|
||||
int ns_name_ntop (const u_char *, char *, size_t) __THROW;
|
||||
int ns_name_pton (const char *, u_char *, size_t) __THROW;
|
||||
int ns_name_unpack (const u_char *, const u_char *,
|
||||
const u_char *, u_char *, size_t) __THROW;
|
||||
int ns_name_pack (const u_char *, u_char *, int,
|
||||
const u_char **, const u_char **) __THROW;
|
||||
int ns_name_uncompress (const u_char *, const u_char *,
|
||||
const u_char *, char *, size_t) __THROW;
|
||||
int ns_name_compress (const char *, u_char *, size_t,
|
||||
const u_char **, const u_char **) __THROW;
|
||||
int ns_name_skip (const u_char **, const u_char *) __THROW;
|
||||
void ns_name_rollback (const u_char *, const u_char **,
|
||||
const u_char **) __THROW;
|
||||
int ns_sign (u_char *, int *, int, int, void *,
|
||||
const u_char *, int, u_char *, int *, time_t) __THROW;
|
||||
int ns_sign_tcp (u_char *, int *, int, int,
|
||||
ns_tcp_tsig_state *, int) __THROW;
|
||||
int ns_sign_tcp_init (void *, const u_char *, int,
|
||||
ns_tcp_tsig_state *) __THROW;
|
||||
u_char *ns_find_tsig (u_char *, u_char *) __THROW;
|
||||
int ns_verify (u_char *, int *, void *, const u_char *, int,
|
||||
u_char *, int *, time_t *, int) __THROW;
|
||||
int ns_verify_tcp (u_char *, int *, ns_tcp_tsig_state *, int)
|
||||
__THROW;
|
||||
int ns_verify_tcp_init (void *, const u_char *, int,
|
||||
ns_tcp_tsig_state *) __THROW;
|
||||
int ns_samedomain (const char *, const char *) __THROW;
|
||||
int ns_subdomain (const char *, const char *) __THROW;
|
||||
int ns_makecanon (const char *, char *, size_t) __THROW;
|
||||
int ns_samename (const char *, const char *) __THROW;
|
||||
__END_DECLS
|
||||
|
||||
#ifdef BIND_4_COMPAT
|
||||
#include <arpa/nameser_compat.h>
|
||||
#endif
|
||||
|
||||
#endif /* !_ARPA_NAMESER_H_ */
|
||||
183
conts/posix/libposix/include/posix/arpa/nameser_compat.h
Normal file
183
conts/posix/libposix/include/posix/arpa/nameser_compat.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/* Copyright (c) 1983, 1989
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* from nameser.h 8.1 (Berkeley) 6/2/93
|
||||
* $BINDId: nameser_compat.h,v 8.11 1999/01/02 08:00:58 vixie Exp $
|
||||
*/
|
||||
|
||||
#ifndef _ARPA_NAMESER_COMPAT_
|
||||
#define _ARPA_NAMESER_COMPAT_
|
||||
|
||||
#define __BIND 19950621 /* (DEAD) interface version stamp. */
|
||||
|
||||
#include <endian.h>
|
||||
|
||||
/*
|
||||
* Structure for query header. The order of the fields is machine- and
|
||||
* compiler-dependent, depending on the byte/bit order and the layout
|
||||
* of bit fields. We use bit fields only in int variables, as this
|
||||
* is all ANSI requires. This requires a somewhat confusing rearrangement.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned id :16; /* query identification number */
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
/* fields in third byte */
|
||||
unsigned qr: 1; /* response flag */
|
||||
unsigned opcode: 4; /* purpose of message */
|
||||
unsigned aa: 1; /* authoritive answer */
|
||||
unsigned tc: 1; /* truncated message */
|
||||
unsigned rd: 1; /* recursion desired */
|
||||
/* fields in fourth byte */
|
||||
unsigned ra: 1; /* recursion available */
|
||||
unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
|
||||
unsigned ad: 1; /* authentic data from named */
|
||||
unsigned cd: 1; /* checking disabled by resolver */
|
||||
unsigned rcode :4; /* response code */
|
||||
#endif
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
|
||||
/* fields in third byte */
|
||||
unsigned rd :1; /* recursion desired */
|
||||
unsigned tc :1; /* truncated message */
|
||||
unsigned aa :1; /* authoritive answer */
|
||||
unsigned opcode :4; /* purpose of message */
|
||||
unsigned qr :1; /* response flag */
|
||||
/* fields in fourth byte */
|
||||
unsigned rcode :4; /* response code */
|
||||
unsigned cd: 1; /* checking disabled by resolver */
|
||||
unsigned ad: 1; /* authentic data from named */
|
||||
unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
|
||||
unsigned ra :1; /* recursion available */
|
||||
#endif
|
||||
/* remaining bytes */
|
||||
unsigned qdcount :16; /* number of question entries */
|
||||
unsigned ancount :16; /* number of answer entries */
|
||||
unsigned nscount :16; /* number of authority entries */
|
||||
unsigned arcount :16; /* number of resource entries */
|
||||
} HEADER;
|
||||
|
||||
#define PACKETSZ NS_PACKETSZ
|
||||
#define MAXDNAME NS_MAXDNAME
|
||||
#define MAXCDNAME NS_MAXCDNAME
|
||||
#define MAXLABEL NS_MAXLABEL
|
||||
#define HFIXEDSZ NS_HFIXEDSZ
|
||||
#define QFIXEDSZ NS_QFIXEDSZ
|
||||
#define RRFIXEDSZ NS_RRFIXEDSZ
|
||||
#define INT32SZ NS_INT32SZ
|
||||
#define INT16SZ NS_INT16SZ
|
||||
#define INADDRSZ NS_INADDRSZ
|
||||
#define IN6ADDRSZ NS_IN6ADDRSZ
|
||||
#define INDIR_MASK NS_CMPRSFLGS
|
||||
#define NAMESERVER_PORT NS_DEFAULTPORT
|
||||
|
||||
#define S_ZONE ns_s_zn
|
||||
#define S_PREREQ ns_s_pr
|
||||
#define S_UPDATE ns_s_ud
|
||||
#define S_ADDT ns_s_ar
|
||||
|
||||
#define QUERY ns_o_query
|
||||
#define IQUERY ns_o_iquery
|
||||
#define STATUS ns_o_status
|
||||
#define NS_NOTIFY_OP ns_o_notify
|
||||
#define NS_UPDATE_OP ns_o_update
|
||||
|
||||
#define NOERROR ns_r_noerror
|
||||
#define FORMERR ns_r_formerr
|
||||
#define SERVFAIL ns_r_servfail
|
||||
#define NXDOMAIN ns_r_nxdomain
|
||||
#define NOTIMP ns_r_notimpl
|
||||
#define REFUSED ns_r_refused
|
||||
#define YXDOMAIN ns_r_yxdomain
|
||||
#define YXRRSET ns_r_yxrrset
|
||||
#define NXRRSET ns_r_nxrrset
|
||||
#define NOTAUTH ns_r_notauth
|
||||
#define NOTZONE ns_r_notzone
|
||||
/*#define BADSIG ns_r_badsig*/
|
||||
/*#define BADKEY ns_r_badkey*/
|
||||
/*#define BADTIME ns_r_badtime*/
|
||||
|
||||
|
||||
#define DELETE ns_uop_delete
|
||||
#define ADD ns_uop_add
|
||||
|
||||
#define T_A ns_t_a
|
||||
#define T_NS ns_t_ns
|
||||
#define T_MD ns_t_md
|
||||
#define T_MF ns_t_mf
|
||||
#define T_CNAME ns_t_cname
|
||||
#define T_SOA ns_t_soa
|
||||
#define T_MB ns_t_mb
|
||||
#define T_MG ns_t_mg
|
||||
#define T_MR ns_t_mr
|
||||
#define T_NULL ns_t_null
|
||||
#define T_WKS ns_t_wks
|
||||
#define T_PTR ns_t_ptr
|
||||
#define T_HINFO ns_t_hinfo
|
||||
#define T_MINFO ns_t_minfo
|
||||
#define T_MX ns_t_mx
|
||||
#define T_TXT ns_t_txt
|
||||
#define T_RP ns_t_rp
|
||||
#define T_AFSDB ns_t_afsdb
|
||||
#define T_X25 ns_t_x25
|
||||
#define T_ISDN ns_t_isdn
|
||||
#define T_RT ns_t_rt
|
||||
#define T_NSAP ns_t_nsap
|
||||
#define T_NSAP_PTR ns_t_nsap_ptr
|
||||
#define T_SIG ns_t_sig
|
||||
#define T_KEY ns_t_key
|
||||
#define T_PX ns_t_px
|
||||
#define T_GPOS ns_t_gpos
|
||||
#define T_AAAA ns_t_aaaa
|
||||
#define T_LOC ns_t_loc
|
||||
#define T_NXT ns_t_nxt
|
||||
#define T_EID ns_t_eid
|
||||
#define T_NIMLOC ns_t_nimloc
|
||||
#define T_SRV ns_t_srv
|
||||
#define T_ATMA ns_t_atma
|
||||
#define T_NAPTR ns_t_naptr
|
||||
#define T_TSIG ns_t_tsig
|
||||
#define T_IXFR ns_t_ixfr
|
||||
#define T_AXFR ns_t_axfr
|
||||
#define T_MAILB ns_t_mailb
|
||||
#define T_MAILA ns_t_maila
|
||||
#define T_ANY ns_t_any
|
||||
|
||||
#define C_IN ns_c_in
|
||||
#define C_CHAOS ns_c_chaos
|
||||
#define C_HS ns_c_hs
|
||||
/* BIND_UPDATE */
|
||||
#define C_NONE ns_c_none
|
||||
#define C_ANY ns_c_any
|
||||
|
||||
#define GETSHORT NS_GET16
|
||||
#define GETLONG NS_GET32
|
||||
#define PUTSHORT NS_PUT16
|
||||
#define PUTLONG NS_PUT32
|
||||
|
||||
#endif /* _ARPA_NAMESER_COMPAT_ */
|
||||
316
conts/posix/libposix/include/posix/arpa/telnet.h
Normal file
316
conts/posix/libposix/include/posix/arpa/telnet.h
Normal file
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)telnet.h 8.2 (Berkeley) 12/15/93
|
||||
*/
|
||||
|
||||
#ifndef _ARPA_TELNET_H
|
||||
#define _ARPA_TELNET_H 1
|
||||
|
||||
/*
|
||||
* Definitions for the TELNET protocol.
|
||||
*/
|
||||
#define IAC 255 /* interpret as command: */
|
||||
#define DONT 254 /* you are not to use option */
|
||||
#define DO 253 /* please, you use option */
|
||||
#define WONT 252 /* I won't use option */
|
||||
#define WILL 251 /* I will use option */
|
||||
#define SB 250 /* interpret as subnegotiation */
|
||||
#define GA 249 /* you may reverse the line */
|
||||
#define EL 248 /* erase the current line */
|
||||
#define EC 247 /* erase the current character */
|
||||
#define AYT 246 /* are you there */
|
||||
#define AO 245 /* abort output--but let prog finish */
|
||||
#define IP 244 /* interrupt process--permanently */
|
||||
#define BREAK 243 /* break */
|
||||
#define DM 242 /* data mark--for connect. cleaning */
|
||||
#define NOP 241 /* nop */
|
||||
#define SE 240 /* end sub negotiation */
|
||||
#define EOR 239 /* end of record (transparent mode) */
|
||||
#define ABORT 238 /* Abort process */
|
||||
#define SUSP 237 /* Suspend process */
|
||||
#define xEOF 236 /* End of file: EOF is already used... */
|
||||
|
||||
#define SYNCH 242 /* for telfunc calls */
|
||||
|
||||
#ifdef TELCMDS
|
||||
char *telcmds[] = {
|
||||
"EOF", "SUSP", "ABORT", "EOR",
|
||||
"SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
|
||||
"EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0,
|
||||
};
|
||||
#else
|
||||
extern char *telcmds[];
|
||||
#endif
|
||||
|
||||
#define TELCMD_FIRST xEOF
|
||||
#define TELCMD_LAST IAC
|
||||
#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \
|
||||
(unsigned int)(x) >= TELCMD_FIRST)
|
||||
#define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
|
||||
|
||||
/* telnet options */
|
||||
#define TELOPT_BINARY 0 /* 8-bit data path */
|
||||
#define TELOPT_ECHO 1 /* echo */
|
||||
#define TELOPT_RCP 2 /* prepare to reconnect */
|
||||
#define TELOPT_SGA 3 /* suppress go ahead */
|
||||
#define TELOPT_NAMS 4 /* approximate message size */
|
||||
#define TELOPT_STATUS 5 /* give status */
|
||||
#define TELOPT_TM 6 /* timing mark */
|
||||
#define TELOPT_RCTE 7 /* remote controlled transmission and echo */
|
||||
#define TELOPT_NAOL 8 /* negotiate about output line width */
|
||||
#define TELOPT_NAOP 9 /* negotiate about output page size */
|
||||
#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
|
||||
#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
|
||||
#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
|
||||
#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
|
||||
#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
|
||||
#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
|
||||
#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
|
||||
#define TELOPT_XASCII 17 /* extended ascii character set */
|
||||
#define TELOPT_LOGOUT 18 /* force logout */
|
||||
#define TELOPT_BM 19 /* byte macro */
|
||||
#define TELOPT_DET 20 /* data entry terminal */
|
||||
#define TELOPT_SUPDUP 21 /* supdup protocol */
|
||||
#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
|
||||
#define TELOPT_SNDLOC 23 /* send location */
|
||||
#define TELOPT_TTYPE 24 /* terminal type */
|
||||
#define TELOPT_EOR 25 /* end or record */
|
||||
#define TELOPT_TUID 26 /* TACACS user identification */
|
||||
#define TELOPT_OUTMRK 27 /* output marking */
|
||||
#define TELOPT_TTYLOC 28 /* terminal location number */
|
||||
#define TELOPT_3270REGIME 29 /* 3270 regime */
|
||||
#define TELOPT_X3PAD 30 /* X.3 PAD */
|
||||
#define TELOPT_NAWS 31 /* window size */
|
||||
#define TELOPT_TSPEED 32 /* terminal speed */
|
||||
#define TELOPT_LFLOW 33 /* remote flow control */
|
||||
#define TELOPT_LINEMODE 34 /* Linemode option */
|
||||
#define TELOPT_XDISPLOC 35 /* X Display Location */
|
||||
#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */
|
||||
#define TELOPT_AUTHENTICATION 37/* Authenticate */
|
||||
#define TELOPT_ENCRYPT 38 /* Encryption option */
|
||||
#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */
|
||||
#define TELOPT_EXOPL 255 /* extended-options-list */
|
||||
|
||||
|
||||
#define NTELOPTS (1+TELOPT_NEW_ENVIRON)
|
||||
#ifdef TELOPTS
|
||||
char *telopts[NTELOPTS+1] = {
|
||||
"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
|
||||
"STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
|
||||
"NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
|
||||
"NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
|
||||
"DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
|
||||
"SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
|
||||
"TACACS UID", "OUTPUT MARKING", "TTYLOC",
|
||||
"3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
|
||||
"LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
|
||||
"ENCRYPT", "NEW-ENVIRON",
|
||||
0,
|
||||
};
|
||||
#define TELOPT_FIRST TELOPT_BINARY
|
||||
#define TELOPT_LAST TELOPT_NEW_ENVIRON
|
||||
#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST)
|
||||
#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
|
||||
#endif
|
||||
|
||||
/* sub-option qualifiers */
|
||||
#define TELQUAL_IS 0 /* option is... */
|
||||
#define TELQUAL_SEND 1 /* send option */
|
||||
#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */
|
||||
#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */
|
||||
#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */
|
||||
|
||||
#define LFLOW_OFF 0 /* Disable remote flow control */
|
||||
#define LFLOW_ON 1 /* Enable remote flow control */
|
||||
#define LFLOW_RESTART_ANY 2 /* Restart output on any char */
|
||||
#define LFLOW_RESTART_XON 3 /* Restart output only on XON */
|
||||
|
||||
/*
|
||||
* LINEMODE suboptions
|
||||
*/
|
||||
|
||||
#define LM_MODE 1
|
||||
#define LM_FORWARDMASK 2
|
||||
#define LM_SLC 3
|
||||
|
||||
#define MODE_EDIT 0x01
|
||||
#define MODE_TRAPSIG 0x02
|
||||
#define MODE_ACK 0x04
|
||||
#define MODE_SOFT_TAB 0x08
|
||||
#define MODE_LIT_ECHO 0x10
|
||||
|
||||
#define MODE_MASK 0x1f
|
||||
|
||||
/* Not part of protocol, but needed to simplify things... */
|
||||
#define MODE_FLOW 0x0100
|
||||
#define MODE_ECHO 0x0200
|
||||
#define MODE_INBIN 0x0400
|
||||
#define MODE_OUTBIN 0x0800
|
||||
#define MODE_FORCE 0x1000
|
||||
|
||||
#define SLC_SYNCH 1
|
||||
#define SLC_BRK 2
|
||||
#define SLC_IP 3
|
||||
#define SLC_AO 4
|
||||
#define SLC_AYT 5
|
||||
#define SLC_EOR 6
|
||||
#define SLC_ABORT 7
|
||||
#define SLC_EOF 8
|
||||
#define SLC_SUSP 9
|
||||
#define SLC_EC 10
|
||||
#define SLC_EL 11
|
||||
#define SLC_EW 12
|
||||
#define SLC_RP 13
|
||||
#define SLC_LNEXT 14
|
||||
#define SLC_XON 15
|
||||
#define SLC_XOFF 16
|
||||
#define SLC_FORW1 17
|
||||
#define SLC_FORW2 18
|
||||
|
||||
#define NSLC 18
|
||||
|
||||
/*
|
||||
* For backwards compatibility, we define SLC_NAMES to be the
|
||||
* list of names if SLC_NAMES is not defined.
|
||||
*/
|
||||
#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
|
||||
"ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
|
||||
"LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0,
|
||||
#ifdef SLC_NAMES
|
||||
char *slc_names[] = {
|
||||
SLC_NAMELIST
|
||||
};
|
||||
#else
|
||||
extern char *slc_names[];
|
||||
#define SLC_NAMES SLC_NAMELIST
|
||||
#endif
|
||||
|
||||
#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC)
|
||||
#define SLC_NAME(x) slc_names[x]
|
||||
|
||||
#define SLC_NOSUPPORT 0
|
||||
#define SLC_CANTCHANGE 1
|
||||
#define SLC_VARIABLE 2
|
||||
#define SLC_DEFAULT 3
|
||||
#define SLC_LEVELBITS 0x03
|
||||
|
||||
#define SLC_FUNC 0
|
||||
#define SLC_FLAGS 1
|
||||
#define SLC_VALUE 2
|
||||
|
||||
#define SLC_ACK 0x80
|
||||
#define SLC_FLUSHIN 0x40
|
||||
#define SLC_FLUSHOUT 0x20
|
||||
|
||||
#define OLD_ENV_VAR 1
|
||||
#define OLD_ENV_VALUE 0
|
||||
#define NEW_ENV_VAR 0
|
||||
#define NEW_ENV_VALUE 1
|
||||
#define ENV_ESC 2
|
||||
#define ENV_USERVAR 3
|
||||
|
||||
/*
|
||||
* AUTHENTICATION suboptions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Who is authenticating who ...
|
||||
*/
|
||||
#define AUTH_WHO_CLIENT 0 /* Client authenticating server */
|
||||
#define AUTH_WHO_SERVER 1 /* Server authenticating client */
|
||||
#define AUTH_WHO_MASK 1
|
||||
|
||||
/*
|
||||
* amount of authentication done
|
||||
*/
|
||||
#define AUTH_HOW_ONE_WAY 0
|
||||
#define AUTH_HOW_MUTUAL 2
|
||||
#define AUTH_HOW_MASK 2
|
||||
|
||||
#define AUTHTYPE_NULL 0
|
||||
#define AUTHTYPE_KERBEROS_V4 1
|
||||
#define AUTHTYPE_KERBEROS_V5 2
|
||||
#define AUTHTYPE_SPX 3
|
||||
#define AUTHTYPE_MINK 4
|
||||
#define AUTHTYPE_CNT 5
|
||||
|
||||
#define AUTHTYPE_TEST 99
|
||||
|
||||
#ifdef AUTH_NAMES
|
||||
char *authtype_names[] = {
|
||||
"NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
|
||||
};
|
||||
#else
|
||||
extern char *authtype_names[];
|
||||
#endif
|
||||
|
||||
#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT)
|
||||
#define AUTHTYPE_NAME(x) authtype_names[x]
|
||||
|
||||
/*
|
||||
* ENCRYPTion suboptions
|
||||
*/
|
||||
#define ENCRYPT_IS 0 /* I pick encryption type ... */
|
||||
#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */
|
||||
#define ENCRYPT_REPLY 2 /* Initial setup response */
|
||||
#define ENCRYPT_START 3 /* Am starting to send encrypted */
|
||||
#define ENCRYPT_END 4 /* Am ending encrypted */
|
||||
#define ENCRYPT_REQSTART 5 /* Request you start encrypting */
|
||||
#define ENCRYPT_REQEND 6 /* Request you send encrypting */
|
||||
#define ENCRYPT_ENC_KEYID 7
|
||||
#define ENCRYPT_DEC_KEYID 8
|
||||
#define ENCRYPT_CNT 9
|
||||
|
||||
#define ENCTYPE_ANY 0
|
||||
#define ENCTYPE_DES_CFB64 1
|
||||
#define ENCTYPE_DES_OFB64 2
|
||||
#define ENCTYPE_CNT 3
|
||||
|
||||
#ifdef ENCRYPT_NAMES
|
||||
char *encrypt_names[] = {
|
||||
"IS", "SUPPORT", "REPLY", "START", "END",
|
||||
"REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
|
||||
0,
|
||||
};
|
||||
char *enctype_names[] = {
|
||||
"ANY", "DES_CFB64", "DES_OFB64", 0,
|
||||
};
|
||||
#else
|
||||
extern char *encrypt_names[];
|
||||
extern char *enctype_names[];
|
||||
#endif
|
||||
|
||||
|
||||
#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT)
|
||||
#define ENCRYPT_NAME(x) encrypt_names[x]
|
||||
|
||||
#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT)
|
||||
#define ENCTYPE_NAME(x) enctype_names[x]
|
||||
|
||||
#endif /* arpa/telnet.h */
|
||||
76
conts/posix/libposix/include/posix/arpa/tftp.h
Normal file
76
conts/posix/libposix/include/posix/arpa/tftp.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)tftp.h 8.1 (Berkeley) 6/2/93
|
||||
*/
|
||||
|
||||
#ifndef _ARPA_TFTP_H
|
||||
#define _ARPA_TFTP_H 1
|
||||
|
||||
/*
|
||||
* Trivial File Transfer Protocol (IEN-133)
|
||||
*/
|
||||
#define SEGSIZE 512 /* data segment size */
|
||||
|
||||
/*
|
||||
* Packet types.
|
||||
*/
|
||||
#define RRQ 01 /* read request */
|
||||
#define WRQ 02 /* write request */
|
||||
#define DATA 03 /* data packet */
|
||||
#define ACK 04 /* acknowledgement */
|
||||
#define ERROR 05 /* error code */
|
||||
|
||||
struct tftphdr {
|
||||
short th_opcode; /* packet type */
|
||||
union {
|
||||
unsigned short tu_block; /* block # */
|
||||
short tu_code; /* error code */
|
||||
char tu_stuff[1]; /* request packet stuff */
|
||||
} __attribute__ ((__packed__)) th_u;
|
||||
char th_data[1]; /* data or error string */
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
#define th_block th_u.tu_block
|
||||
#define th_code th_u.tu_code
|
||||
#define th_stuff th_u.tu_stuff
|
||||
#define th_msg th_data
|
||||
|
||||
/*
|
||||
* Error codes.
|
||||
*/
|
||||
#define EUNDEF 0 /* not defined */
|
||||
#define ENOTFOUND 1 /* file not found */
|
||||
#define EACCESS 2 /* access violation */
|
||||
#define ENOSPACE 3 /* disk full or allocation exceeded */
|
||||
#define EBADOP 4 /* illegal TFTP operation */
|
||||
#define EBADID 5 /* unknown transfer ID */
|
||||
#define EEXISTS 6 /* file already exists */
|
||||
#define ENOUSER 7 /* no such user */
|
||||
|
||||
#endif /* arpa/tftp.h */
|
||||
82
conts/posix/libposix/include/posix/assert.h
Normal file
82
conts/posix/libposix/include/posix/assert.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* Copyright (C) 1991,1992,1994-2001,2003,2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/*
|
||||
* ISO C99 Standard: 7.2 Diagnostics <assert.h>
|
||||
*/
|
||||
|
||||
#ifdef _ASSERT_H
|
||||
|
||||
# undef _ASSERT_H
|
||||
# undef assert
|
||||
# undef __ASSERT_VOID_CAST
|
||||
|
||||
#endif /* assert.h */
|
||||
|
||||
#define _ASSERT_H 1
|
||||
#include <features.h>
|
||||
|
||||
#if defined __cplusplus && __GNUC_PREREQ(2,95)
|
||||
# define __ASSERT_VOID_CAST static_cast<void>
|
||||
#else
|
||||
# define __ASSERT_VOID_CAST (void)
|
||||
#endif
|
||||
|
||||
/* void assert (int expression);
|
||||
|
||||
If NDEBUG is defined, do nothing.
|
||||
If not, and EXPRESSION is zero, print an error message and abort. */
|
||||
|
||||
#ifdef NDEBUG
|
||||
|
||||
# define assert(expr) (__ASSERT_VOID_CAST (0))
|
||||
|
||||
#else /* Not NDEBUG. */
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* This prints an "Assertion failed" message and aborts. */
|
||||
extern void __assert __P((const char *, const char *, int, const char *));
|
||||
|
||||
__END_DECLS
|
||||
|
||||
# define assert(expr) \
|
||||
(__ASSERT_VOID_CAST ((expr) ? 0 : \
|
||||
(__assert (__STRING(expr), __FILE__, __LINE__, \
|
||||
__ASSERT_FUNCTION), 0)))
|
||||
|
||||
/* Define some temporaries to workaround tinyx makedepend bug */
|
||||
#define __GNUC_PREREQ_2_6 __GNUC_PREREQ(2, 6)
|
||||
#define __GNUC_PREREQ_2_4 __GNUC_PREREQ(2, 4)
|
||||
/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
|
||||
which contains the name of the function currently being defined.
|
||||
This is broken in G++ before version 2.6.
|
||||
C9x has a similar variable called __func__, but prefer the GCC one since
|
||||
it demangles C++ function names. */
|
||||
|
||||
# if defined __cplusplus ? __GNUC_PREREQ_2_6 : __GNUC_PREREQ_2_4
|
||||
# define __ASSERT_FUNCTION __PRETTY_FUNCTION__
|
||||
# else
|
||||
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
||||
# define __ASSERT_FUNCTION __func__
|
||||
# else
|
||||
# define __ASSERT_FUNCTION ((__const char *) 0)
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif /* NDEBUG. */
|
||||
261
conts/posix/libposix/include/posix/atomic.h
Normal file
261
conts/posix/libposix/include/posix/atomic.h
Normal file
@@ -0,0 +1,261 @@
|
||||
/* Internal macros for atomic operations for GNU C Library.
|
||||
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _ATOMIC_H
|
||||
#define _ATOMIC_H 1
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <bits/atomic.h>
|
||||
|
||||
/* Wrapper macros to call pre_NN_post (mem, ...) where NN is the
|
||||
bit width of *MEM. The calling macro puts parens around MEM
|
||||
and following args. */
|
||||
#define __atomic_val_bysize(pre, post, mem, ...) \
|
||||
({ \
|
||||
__typeof (*mem) __result; \
|
||||
if (sizeof (*mem) == 1) \
|
||||
__result = pre##_8_##post (mem, __VA_ARGS__); \
|
||||
else if (sizeof (*mem) == 2) \
|
||||
__result = pre##_16_##post (mem, __VA_ARGS__); \
|
||||
else if (sizeof (*mem) == 4) \
|
||||
__result = pre##_32_##post (mem, __VA_ARGS__); \
|
||||
else if (sizeof (*mem) == 8) \
|
||||
__result = pre##_64_##post (mem, __VA_ARGS__); \
|
||||
else \
|
||||
abort (); \
|
||||
__result; \
|
||||
})
|
||||
#define __atomic_bool_bysize(pre, post, mem, ...) \
|
||||
({ \
|
||||
int __result; \
|
||||
if (sizeof (*mem) == 1) \
|
||||
__result = pre##_8_##post (mem, __VA_ARGS__); \
|
||||
else if (sizeof (*mem) == 2) \
|
||||
__result = pre##_16_##post (mem, __VA_ARGS__); \
|
||||
else if (sizeof (*mem) == 4) \
|
||||
__result = pre##_32_##post (mem, __VA_ARGS__); \
|
||||
else if (sizeof (*mem) == 8) \
|
||||
__result = pre##_64_##post (mem, __VA_ARGS__); \
|
||||
else \
|
||||
abort (); \
|
||||
__result; \
|
||||
})
|
||||
|
||||
|
||||
/* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL.
|
||||
Return the old *MEM value. */
|
||||
#if !defined atomic_compare_and_exchange_val_acq \
|
||||
&& defined __arch_compare_and_exchange_val_32_acq
|
||||
# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
|
||||
__atomic_val_bysize (__arch_compare_and_exchange_val,acq, \
|
||||
mem, newval, oldval)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_compare_and_exchange_val_rel
|
||||
# define atomic_compare_and_exchange_val_rel(mem, newval, oldval) \
|
||||
atomic_compare_and_exchange_val_acq (mem, newval, oldval)
|
||||
#endif
|
||||
|
||||
|
||||
/* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL.
|
||||
Return zero if *MEM was changed or non-zero if no exchange happened. */
|
||||
#ifndef atomic_compare_and_exchange_bool_acq
|
||||
# ifdef __arch_compare_and_exchange_bool_32_acq
|
||||
# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
|
||||
__atomic_bool_bysize (__arch_compare_and_exchange_bool,acq, \
|
||||
mem, newval, oldval)
|
||||
# else
|
||||
# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
|
||||
({ /* Cannot use __oldval here, because macros later in this file might \
|
||||
call this macro with __oldval argument. */ \
|
||||
__typeof (oldval) __old = (oldval); \
|
||||
atomic_compare_and_exchange_val_acq (mem, newval, __old) != __old; \
|
||||
})
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_compare_and_exchange_bool_rel
|
||||
# define atomic_compare_and_exchange_bool_rel(mem, newval, oldval) \
|
||||
atomic_compare_and_exchange_bool_acq (mem, newval, oldval)
|
||||
#endif
|
||||
|
||||
|
||||
/* Store NEWVALUE in *MEM and return the old value. */
|
||||
#ifndef atomic_exchange_acq
|
||||
# define atomic_exchange_acq(mem, newvalue) \
|
||||
({ __typeof (*(mem)) __oldval; \
|
||||
__typeof (mem) __memp = (mem); \
|
||||
__typeof (*(mem)) __value = (newvalue); \
|
||||
\
|
||||
do \
|
||||
__oldval = (*__memp); \
|
||||
while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
|
||||
__value, \
|
||||
__oldval),\
|
||||
0)); \
|
||||
\
|
||||
__oldval; })
|
||||
#endif
|
||||
|
||||
#ifndef atomic_exchange_rel
|
||||
# define atomic_exchange_rel(mem, newvalue) atomic_exchange_acq (mem, newvalue)
|
||||
#endif
|
||||
|
||||
|
||||
/* Add VALUE to *MEM and return the old value of *MEM. */
|
||||
#ifndef atomic_exchange_and_add
|
||||
# define atomic_exchange_and_add(mem, value) \
|
||||
({ __typeof (*(mem)) __oldval; \
|
||||
__typeof (mem) __memp = (mem); \
|
||||
__typeof (*(mem)) __value = (value); \
|
||||
\
|
||||
do \
|
||||
__oldval = (*__memp); \
|
||||
while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
|
||||
__oldval \
|
||||
+ __value,\
|
||||
__oldval),\
|
||||
0)); \
|
||||
\
|
||||
__oldval; })
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_add
|
||||
# define atomic_add(mem, value) (void) atomic_exchange_and_add ((mem), (value))
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_increment
|
||||
# define atomic_increment(mem) atomic_add ((mem), 1)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_increment_val
|
||||
# define atomic_increment_val(mem) (atomic_exchange_and_add ((mem), 1) + 1)
|
||||
#endif
|
||||
|
||||
|
||||
/* Add one to *MEM and return true iff it's now zero. */
|
||||
#ifndef atomic_increment_and_test
|
||||
# define atomic_increment_and_test(mem) \
|
||||
(atomic_exchange_and_add ((mem), 1) + 1 == 0)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_decrement
|
||||
# define atomic_decrement(mem) atomic_add ((mem), -1)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_decrement_val
|
||||
# define atomic_decrement_val(mem) (atomic_exchange_and_add ((mem), -1) - 1)
|
||||
#endif
|
||||
|
||||
|
||||
/* Subtract 1 from *MEM and return true iff it's now zero. */
|
||||
#ifndef atomic_decrement_and_test
|
||||
# define atomic_decrement_and_test(mem) \
|
||||
(atomic_exchange_and_add ((mem), -1) == 1)
|
||||
#endif
|
||||
|
||||
|
||||
/* Decrement *MEM if it is > 0, and return the old value. */
|
||||
#ifndef atomic_decrement_if_positive
|
||||
# define atomic_decrement_if_positive(mem) \
|
||||
({ __typeof (*(mem)) __oldval; \
|
||||
__typeof (mem) __memp = (mem); \
|
||||
\
|
||||
do \
|
||||
{ \
|
||||
__oldval = *__memp; \
|
||||
if (__builtin_expect (__oldval <= 0, 0)) \
|
||||
break; \
|
||||
} \
|
||||
while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
|
||||
__oldval \
|
||||
- 1, \
|
||||
__oldval),\
|
||||
0));\
|
||||
__oldval; })
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_add_negative
|
||||
# define atomic_add_negative(mem, value) \
|
||||
({ __typeof (value) __aan_value = (value); \
|
||||
atomic_exchange_and_add (mem, __aan_value) < -__aan_value; })
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_add_zero
|
||||
# define atomic_add_zero(mem, value) \
|
||||
({ __typeof (value) __aaz_value = (value); \
|
||||
atomic_exchange_and_add (mem, __aaz_value) == -__aaz_value; })
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_bit_set
|
||||
# define atomic_bit_set(mem, bit) \
|
||||
(void) atomic_bit_test_set(mem, bit)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_bit_test_set
|
||||
# define atomic_bit_test_set(mem, bit) \
|
||||
({ __typeof (*(mem)) __oldval; \
|
||||
__typeof (mem) __memp = (mem); \
|
||||
__typeof (*(mem)) __mask = ((__typeof (*(mem))) 1 << (bit)); \
|
||||
\
|
||||
do \
|
||||
__oldval = (*__memp); \
|
||||
while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
|
||||
__oldval \
|
||||
| __mask, \
|
||||
__oldval),\
|
||||
0)); \
|
||||
\
|
||||
__oldval & __mask; })
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_full_barrier
|
||||
# define atomic_full_barrier() __asm ("" ::: "memory")
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_read_barrier
|
||||
# define atomic_read_barrier() atomic_full_barrier ()
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_write_barrier
|
||||
# define atomic_write_barrier() atomic_full_barrier ()
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef atomic_delay
|
||||
# define atomic_delay() do { /* nothing */ } while (0)
|
||||
#endif
|
||||
|
||||
#endif /* atomic.h */
|
||||
73
conts/posix/libposix/include/posix/bits/armsigctx.h
Normal file
73
conts/posix/libposix/include/posix/bits/armsigctx.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* Definition of `struct sigcontext' for Linux/ARM
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* The format of struct sigcontext changed between 2.0 and 2.1 kernels.
|
||||
Fortunately 2.0 puts a magic number in the first word and this is not
|
||||
a legal value for `trap_no', so we can tell them apart. */
|
||||
|
||||
/* Early 2.2 and 2.3 kernels do not have the `fault_address' member in
|
||||
the sigcontext structure. Unfortunately there is no reliable way
|
||||
to test for its presence and this word will contain garbage for too-old
|
||||
kernels. Versions 2.2.14 and 2.3.35 (plus later versions) are known to
|
||||
include this element. */
|
||||
|
||||
#ifndef __ARMSIGCTX_H
|
||||
#define __ARMSIGCTX_H 1
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
union k_sigcontext
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned long int trap_no;
|
||||
unsigned long int error_code;
|
||||
unsigned long int oldmask;
|
||||
unsigned long int arm_r0;
|
||||
unsigned long int arm_r1;
|
||||
unsigned long int arm_r2;
|
||||
unsigned long int arm_r3;
|
||||
unsigned long int arm_r4;
|
||||
unsigned long int arm_r5;
|
||||
unsigned long int arm_r6;
|
||||
unsigned long int arm_r7;
|
||||
unsigned long int arm_r8;
|
||||
unsigned long int arm_r9;
|
||||
unsigned long int arm_r10;
|
||||
unsigned long int arm_fp;
|
||||
unsigned long int arm_ip;
|
||||
unsigned long int arm_sp;
|
||||
unsigned long int arm_lr;
|
||||
unsigned long int arm_pc;
|
||||
unsigned long int arm_cpsr;
|
||||
unsigned long fault_address;
|
||||
} v21;
|
||||
struct
|
||||
{
|
||||
unsigned long int magic;
|
||||
struct pt_regs reg;
|
||||
unsigned long int trap_no;
|
||||
unsigned long int error_code;
|
||||
unsigned long int oldmask;
|
||||
} v20;
|
||||
};
|
||||
|
||||
#define SIGCONTEXT_2_0_MAGIC 0x4B534154
|
||||
|
||||
#endif /* bits/armsigctx.h */
|
||||
43
conts/posix/libposix/include/posix/bits/atomic.h
Normal file
43
conts/posix/libposix/include/posix/bits/atomic.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _BITS_ATOMIC_H
|
||||
#define _BITS_ATOMIC_H 1
|
||||
|
||||
/* We have by default no support for atomic operations. So define
|
||||
them non-atomic. If this is a problem somebody will have to come
|
||||
up with real definitions. */
|
||||
|
||||
/* The only basic operation needed is compare and exchange. */
|
||||
#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
|
||||
({ __typeof (mem) __gmemp = (mem); \
|
||||
__typeof (*mem) __gret = *__gmemp; \
|
||||
__typeof (*mem) __gnewval = (newval); \
|
||||
\
|
||||
if (__gret == (oldval)) \
|
||||
*__gmemp = __gnewval; \
|
||||
__gret; })
|
||||
|
||||
#define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
|
||||
({ __typeof (mem) __gmemp = (mem); \
|
||||
__typeof (*mem) __gnewval = (newval); \
|
||||
\
|
||||
*__gmemp == (oldval) ? (*__gmemp = __gnewval, 0) : 1; })
|
||||
|
||||
#endif /* bits/atomic.h */
|
||||
87
conts/posix/libposix/include/posix/bits/byteswap.h
Normal file
87
conts/posix/libposix/include/posix/bits/byteswap.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* Macros to swap the order of bytes in integer values.
|
||||
Copyright (C) 1997,1998,2000,2001,2002,2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
|
||||
# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef _BITS_BYTESWAP_H
|
||||
#define _BITS_BYTESWAP_H 1
|
||||
|
||||
/* Swap bytes in 16 bit value. */
|
||||
#define __bswap_constant_16(x) \
|
||||
((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8))
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define __bswap_16(x) \
|
||||
(__extension__ \
|
||||
({ unsigned short int __bsx = (x); __bswap_constant_16 (__bsx); }))
|
||||
#else
|
||||
static __inline unsigned short int
|
||||
__bswap_16 (unsigned short int __bsx)
|
||||
{
|
||||
return __bswap_constant_16 (__bsx);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Swap bytes in 32 bit value. */
|
||||
#define __bswap_constant_32(x) \
|
||||
((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) | \
|
||||
(((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24))
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define __bswap_32(x) \
|
||||
(__extension__ \
|
||||
({ register unsigned int __bsx = (x); __bswap_constant_32 (__bsx); }))
|
||||
#else
|
||||
static __inline unsigned int
|
||||
__bswap_32 (unsigned int __bsx)
|
||||
{
|
||||
return __bswap_constant_32 (__bsx);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__ && __GNUC__ >= 2
|
||||
/* Swap bytes in 64 bit value. */
|
||||
# define __bswap_constant_64(x) \
|
||||
((((x) & 0xff00000000000000ull) >> 56) \
|
||||
| (((x) & 0x00ff000000000000ull) >> 40) \
|
||||
| (((x) & 0x0000ff0000000000ull) >> 24) \
|
||||
| (((x) & 0x000000ff00000000ull) >> 8) \
|
||||
| (((x) & 0x00000000ff000000ull) << 8) \
|
||||
| (((x) & 0x0000000000ff0000ull) << 24) \
|
||||
| (((x) & 0x000000000000ff00ull) << 40) \
|
||||
| (((x) & 0x00000000000000ffull) << 56))
|
||||
|
||||
# define __bswap_64(x) \
|
||||
(__extension__ \
|
||||
({ union { __extension__ unsigned long long int __ll; \
|
||||
unsigned int __l[2]; } __w, __r; \
|
||||
if (__builtin_constant_p (x)) \
|
||||
__r.__ll = __bswap_constant_64 (x); \
|
||||
else \
|
||||
{ \
|
||||
__w.__ll = (x); \
|
||||
__r.__l[0] = __bswap_32 (__w.__l[1]); \
|
||||
__r.__l[1] = __bswap_32 (__w.__l[0]); \
|
||||
} \
|
||||
__r.__ll; }))
|
||||
#endif
|
||||
|
||||
#endif /* _BITS_BYTESWAP_H */
|
||||
158
conts/posix/libposix/include/posix/bits/cmathcalls.h
Normal file
158
conts/posix/libposix/include/posix/bits/cmathcalls.h
Normal file
@@ -0,0 +1,158 @@
|
||||
/* Prototype declarations for complex math functions;
|
||||
helper file for <complex.h>.
|
||||
Copyright (C) 1997, 1998, 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* NOTE: Because of the special way this file is used by <complex.h>, this
|
||||
file must NOT be protected from multiple inclusion as header files
|
||||
usually are.
|
||||
|
||||
This file provides prototype declarations for the math functions.
|
||||
Most functions are declared using the macro:
|
||||
|
||||
__MATHCALL (NAME, (ARGS...));
|
||||
|
||||
This means there is a function `NAME' returning `double' and a function
|
||||
`NAMEf' returning `float'. Each place `_Mdouble_' appears in the
|
||||
prototype, that is actually `double' in the prototype for `NAME' and
|
||||
`float' in the prototype for `NAMEf'. Reentrant variant functions are
|
||||
called `NAME_r' and `NAMEf_r'.
|
||||
|
||||
Functions returning other types like `int' are declared using the macro:
|
||||
|
||||
__MATHDECL (TYPE, NAME, (ARGS...));
|
||||
|
||||
This is just like __MATHCALL but for a function returning `TYPE'
|
||||
instead of `_Mdouble_'. In all of these cases, there is still
|
||||
both a `NAME' and a `NAMEf' that takes `float' arguments. */
|
||||
|
||||
#ifndef _COMPLEX_H
|
||||
#error "Never use <bits/cmathcalls.h> directly; include <complex.h> instead."
|
||||
#endif
|
||||
|
||||
#define _Mdouble_complex_ _Mdouble_ _Complex
|
||||
|
||||
|
||||
/* Trigonometric functions. */
|
||||
|
||||
/* Arc cosine of Z. */
|
||||
__MATHCALL (cacos, (_Mdouble_complex_ __z));
|
||||
/* Arc sine of Z. */
|
||||
__MATHCALL (casin, (_Mdouble_complex_ __z));
|
||||
/* Arc tangent of Z. */
|
||||
__MATHCALL (catan, (_Mdouble_complex_ __z));
|
||||
|
||||
/* Cosine of Z. */
|
||||
__MATHCALL (ccos, (_Mdouble_complex_ __z));
|
||||
/* Sine of Z. */
|
||||
__MATHCALL (csin, (_Mdouble_complex_ __z));
|
||||
/* Tangent of Z. */
|
||||
__MATHCALL (ctan, (_Mdouble_complex_ __z));
|
||||
|
||||
|
||||
/* Hyperbolic functions. */
|
||||
|
||||
/* Hyperbolic arc cosine of Z. */
|
||||
__MATHCALL (cacosh, (_Mdouble_complex_ __z));
|
||||
/* Hyperbolic arc sine of Z. */
|
||||
__MATHCALL (casinh, (_Mdouble_complex_ __z));
|
||||
/* Hyperbolic arc tangent of Z. */
|
||||
__MATHCALL (catanh, (_Mdouble_complex_ __z));
|
||||
|
||||
/* Hyperbolic cosine of Z. */
|
||||
__MATHCALL (ccosh, (_Mdouble_complex_ __z));
|
||||
/* Hyperbolic sine of Z. */
|
||||
__MATHCALL (csinh, (_Mdouble_complex_ __z));
|
||||
/* Hyperbolic tangent of Z. */
|
||||
__MATHCALL (ctanh, (_Mdouble_complex_ __z));
|
||||
|
||||
|
||||
/* Exponential and logarithmic functions. */
|
||||
|
||||
/* Exponential function of Z. */
|
||||
__MATHCALL (cexp, (_Mdouble_complex_ __z));
|
||||
|
||||
/* Natural logarithm of Z. */
|
||||
__MATHCALL (clog, (_Mdouble_complex_ __z));
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* The base 10 logarithm is not defined by the standard but to implement
|
||||
the standard C++ library it is handy. */
|
||||
__MATHCALL (clog10, (_Mdouble_complex_ __z));
|
||||
#endif
|
||||
|
||||
/* Power functions. */
|
||||
|
||||
/* Return X to the Y power. */
|
||||
__MATHCALL (cpow, (_Mdouble_complex_ __x, _Mdouble_complex_ __y));
|
||||
|
||||
/* Return the square root of Z. */
|
||||
__MATHCALL (csqrt, (_Mdouble_complex_ __z));
|
||||
|
||||
|
||||
/* Absolute value, conjugates, and projection. */
|
||||
|
||||
/* Absolute value of Z. */
|
||||
__MATHDECL (_Mdouble_,cabs, (_Mdouble_complex_ __z));
|
||||
|
||||
/* Argument value of Z. */
|
||||
__MATHDECL (_Mdouble_,carg, (_Mdouble_complex_ __z));
|
||||
|
||||
/* Complex conjugate of Z. */
|
||||
__MATHCALL (conj, (_Mdouble_complex_ __z));
|
||||
|
||||
/* Projection of Z onto the Riemann sphere. */
|
||||
__MATHCALL (cproj, (_Mdouble_complex_ __z));
|
||||
|
||||
|
||||
/* Decomposing complex values. */
|
||||
|
||||
/* Imaginary part of Z. */
|
||||
__MATHDECL (_Mdouble_,cimag, (_Mdouble_complex_ __z));
|
||||
|
||||
/* Real part of Z. */
|
||||
__MATHDECL (_Mdouble_,creal, (_Mdouble_complex_ __z));
|
||||
|
||||
|
||||
/* Now some optimized versions. GCC has handy notations for these
|
||||
functions. Recent GCC handles these as builtin functions so does
|
||||
not need inlines. */
|
||||
#if defined __GNUC__ && !__GNUC_PREREQ (2, 97) && defined __OPTIMIZE__
|
||||
|
||||
/* Imaginary part of Z. */
|
||||
extern __inline _Mdouble_
|
||||
__MATH_PRECNAME(cimag) (_Mdouble_complex_ __z) __THROW
|
||||
{
|
||||
return __imag__ __z;
|
||||
}
|
||||
|
||||
/* Real part of Z. */
|
||||
extern __inline _Mdouble_
|
||||
__MATH_PRECNAME(creal) (_Mdouble_complex_ __z) __THROW
|
||||
{
|
||||
return __real__ __z;
|
||||
}
|
||||
|
||||
/* Complex conjugate of Z. */
|
||||
extern __inline _Mdouble_complex_
|
||||
__MATH_PRECNAME(conj) (_Mdouble_complex_ __z) __THROW
|
||||
{
|
||||
return __extension__ ~__z;
|
||||
}
|
||||
|
||||
#endif
|
||||
606
conts/posix/libposix/include/posix/bits/confname.h
Normal file
606
conts/posix/libposix/include/posix/bits/confname.h
Normal file
@@ -0,0 +1,606 @@
|
||||
/* `sysconf', `pathconf', and `confstr' NAME values. Generic version.
|
||||
Copyright (C) 1993,1995-1998,2000,2001,2003,2004
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _UNISTD_H
|
||||
# error "Never use <bits/confname.h> directly; include <unistd.h> instead."
|
||||
#endif
|
||||
|
||||
/* Values for the NAME argument to `pathconf' and `fpathconf'. */
|
||||
enum
|
||||
{
|
||||
_PC_LINK_MAX,
|
||||
#define _PC_LINK_MAX _PC_LINK_MAX
|
||||
_PC_MAX_CANON,
|
||||
#define _PC_MAX_CANON _PC_MAX_CANON
|
||||
_PC_MAX_INPUT,
|
||||
#define _PC_MAX_INPUT _PC_MAX_INPUT
|
||||
_PC_NAME_MAX,
|
||||
#define _PC_NAME_MAX _PC_NAME_MAX
|
||||
_PC_PATH_MAX,
|
||||
#define _PC_PATH_MAX _PC_PATH_MAX
|
||||
_PC_PIPE_BUF,
|
||||
#define _PC_PIPE_BUF _PC_PIPE_BUF
|
||||
_PC_CHOWN_RESTRICTED,
|
||||
#define _PC_CHOWN_RESTRICTED _PC_CHOWN_RESTRICTED
|
||||
_PC_NO_TRUNC,
|
||||
#define _PC_NO_TRUNC _PC_NO_TRUNC
|
||||
_PC_VDISABLE,
|
||||
#define _PC_VDISABLE _PC_VDISABLE
|
||||
_PC_SYNC_IO,
|
||||
#define _PC_SYNC_IO _PC_SYNC_IO
|
||||
_PC_ASYNC_IO,
|
||||
#define _PC_ASYNC_IO _PC_ASYNC_IO
|
||||
_PC_PRIO_IO,
|
||||
#define _PC_PRIO_IO _PC_PRIO_IO
|
||||
_PC_SOCK_MAXBUF,
|
||||
#define _PC_SOCK_MAXBUF _PC_SOCK_MAXBUF
|
||||
_PC_FILESIZEBITS,
|
||||
#define _PC_FILESIZEBITS _PC_FILESIZEBITS
|
||||
_PC_REC_INCR_XFER_SIZE,
|
||||
#define _PC_REC_INCR_XFER_SIZE _PC_REC_INCR_XFER_SIZE
|
||||
_PC_REC_MAX_XFER_SIZE,
|
||||
#define _PC_REC_MAX_XFER_SIZE _PC_REC_MAX_XFER_SIZE
|
||||
_PC_REC_MIN_XFER_SIZE,
|
||||
#define _PC_REC_MIN_XFER_SIZE _PC_REC_MIN_XFER_SIZE
|
||||
_PC_REC_XFER_ALIGN,
|
||||
#define _PC_REC_XFER_ALIGN _PC_REC_XFER_ALIGN
|
||||
_PC_ALLOC_SIZE_MIN,
|
||||
#define _PC_ALLOC_SIZE_MIN _PC_ALLOC_SIZE_MIN
|
||||
_PC_SYMLINK_MAX,
|
||||
#define _PC_SYMLINK_MAX _PC_SYMLINK_MAX
|
||||
_PC_2_SYMLINKS
|
||||
#define _PC_2_SYMLINKS _PC_2_SYMLINKS
|
||||
};
|
||||
|
||||
/* Values for the argument to `sysconf'. */
|
||||
enum
|
||||
{
|
||||
_SC_ARG_MAX,
|
||||
#define _SC_ARG_MAX _SC_ARG_MAX
|
||||
_SC_CHILD_MAX,
|
||||
#define _SC_CHILD_MAX _SC_CHILD_MAX
|
||||
_SC_CLK_TCK,
|
||||
#define _SC_CLK_TCK _SC_CLK_TCK
|
||||
_SC_NGROUPS_MAX,
|
||||
#define _SC_NGROUPS_MAX _SC_NGROUPS_MAX
|
||||
_SC_OPEN_MAX,
|
||||
#define _SC_OPEN_MAX _SC_OPEN_MAX
|
||||
_SC_STREAM_MAX,
|
||||
#define _SC_STREAM_MAX _SC_STREAM_MAX
|
||||
_SC_TZNAME_MAX,
|
||||
#define _SC_TZNAME_MAX _SC_TZNAME_MAX
|
||||
_SC_JOB_CONTROL,
|
||||
#define _SC_JOB_CONTROL _SC_JOB_CONTROL
|
||||
_SC_SAVED_IDS,
|
||||
#define _SC_SAVED_IDS _SC_SAVED_IDS
|
||||
_SC_REALTIME_SIGNALS,
|
||||
#define _SC_REALTIME_SIGNALS _SC_REALTIME_SIGNALS
|
||||
_SC_PRIORITY_SCHEDULING,
|
||||
#define _SC_PRIORITY_SCHEDULING _SC_PRIORITY_SCHEDULING
|
||||
_SC_TIMERS,
|
||||
#define _SC_TIMERS _SC_TIMERS
|
||||
_SC_ASYNCHRONOUS_IO,
|
||||
#define _SC_ASYNCHRONOUS_IO _SC_ASYNCHRONOUS_IO
|
||||
_SC_PRIORITIZED_IO,
|
||||
#define _SC_PRIORITIZED_IO _SC_PRIORITIZED_IO
|
||||
_SC_SYNCHRONIZED_IO,
|
||||
#define _SC_SYNCHRONIZED_IO _SC_SYNCHRONIZED_IO
|
||||
_SC_FSYNC,
|
||||
#define _SC_FSYNC _SC_FSYNC
|
||||
_SC_MAPPED_FILES,
|
||||
#define _SC_MAPPED_FILES _SC_MAPPED_FILES
|
||||
_SC_MEMLOCK,
|
||||
#define _SC_MEMLOCK _SC_MEMLOCK
|
||||
_SC_MEMLOCK_RANGE,
|
||||
#define _SC_MEMLOCK_RANGE _SC_MEMLOCK_RANGE
|
||||
_SC_MEMORY_PROTECTION,
|
||||
#define _SC_MEMORY_PROTECTION _SC_MEMORY_PROTECTION
|
||||
_SC_MESSAGE_PASSING,
|
||||
#define _SC_MESSAGE_PASSING _SC_MESSAGE_PASSING
|
||||
_SC_SEMAPHORES,
|
||||
#define _SC_SEMAPHORES _SC_SEMAPHORES
|
||||
_SC_SHARED_MEMORY_OBJECTS,
|
||||
#define _SC_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS
|
||||
_SC_AIO_LISTIO_MAX,
|
||||
#define _SC_AIO_LISTIO_MAX _SC_AIO_LISTIO_MAX
|
||||
_SC_AIO_MAX,
|
||||
#define _SC_AIO_MAX _SC_AIO_MAX
|
||||
_SC_AIO_PRIO_DELTA_MAX,
|
||||
#define _SC_AIO_PRIO_DELTA_MAX _SC_AIO_PRIO_DELTA_MAX
|
||||
_SC_DELAYTIMER_MAX,
|
||||
#define _SC_DELAYTIMER_MAX _SC_DELAYTIMER_MAX
|
||||
_SC_MQ_OPEN_MAX,
|
||||
#define _SC_MQ_OPEN_MAX _SC_MQ_OPEN_MAX
|
||||
_SC_MQ_PRIO_MAX,
|
||||
#define _SC_MQ_PRIO_MAX _SC_MQ_PRIO_MAX
|
||||
_SC_VERSION,
|
||||
#define _SC_VERSION _SC_VERSION
|
||||
_SC_PAGESIZE,
|
||||
#define _SC_PAGESIZE _SC_PAGESIZE
|
||||
#define _SC_PAGE_SIZE _SC_PAGESIZE
|
||||
_SC_RTSIG_MAX,
|
||||
#define _SC_RTSIG_MAX _SC_RTSIG_MAX
|
||||
_SC_SEM_NSEMS_MAX,
|
||||
#define _SC_SEM_NSEMS_MAX _SC_SEM_NSEMS_MAX
|
||||
_SC_SEM_VALUE_MAX,
|
||||
#define _SC_SEM_VALUE_MAX _SC_SEM_VALUE_MAX
|
||||
_SC_SIGQUEUE_MAX,
|
||||
#define _SC_SIGQUEUE_MAX _SC_SIGQUEUE_MAX
|
||||
_SC_TIMER_MAX,
|
||||
#define _SC_TIMER_MAX _SC_TIMER_MAX
|
||||
|
||||
/* Values for the argument to `sysconf'
|
||||
corresponding to _POSIX2_* symbols. */
|
||||
_SC_BC_BASE_MAX,
|
||||
#define _SC_BC_BASE_MAX _SC_BC_BASE_MAX
|
||||
_SC_BC_DIM_MAX,
|
||||
#define _SC_BC_DIM_MAX _SC_BC_DIM_MAX
|
||||
_SC_BC_SCALE_MAX,
|
||||
#define _SC_BC_SCALE_MAX _SC_BC_SCALE_MAX
|
||||
_SC_BC_STRING_MAX,
|
||||
#define _SC_BC_STRING_MAX _SC_BC_STRING_MAX
|
||||
_SC_COLL_WEIGHTS_MAX,
|
||||
#define _SC_COLL_WEIGHTS_MAX _SC_COLL_WEIGHTS_MAX
|
||||
_SC_EQUIV_CLASS_MAX,
|
||||
#define _SC_EQUIV_CLASS_MAX _SC_EQUIV_CLASS_MAX
|
||||
_SC_EXPR_NEST_MAX,
|
||||
#define _SC_EXPR_NEST_MAX _SC_EXPR_NEST_MAX
|
||||
_SC_LINE_MAX,
|
||||
#define _SC_LINE_MAX _SC_LINE_MAX
|
||||
_SC_RE_DUP_MAX,
|
||||
#define _SC_RE_DUP_MAX _SC_RE_DUP_MAX
|
||||
_SC_CHARCLASS_NAME_MAX,
|
||||
#define _SC_CHARCLASS_NAME_MAX _SC_CHARCLASS_NAME_MAX
|
||||
|
||||
_SC_2_VERSION,
|
||||
#define _SC_2_VERSION _SC_2_VERSION
|
||||
_SC_2_C_BIND,
|
||||
#define _SC_2_C_BIND _SC_2_C_BIND
|
||||
_SC_2_C_DEV,
|
||||
#define _SC_2_C_DEV _SC_2_C_DEV
|
||||
_SC_2_FORT_DEV,
|
||||
#define _SC_2_FORT_DEV _SC_2_FORT_DEV
|
||||
_SC_2_FORT_RUN,
|
||||
#define _SC_2_FORT_RUN _SC_2_FORT_RUN
|
||||
_SC_2_SW_DEV,
|
||||
#define _SC_2_SW_DEV _SC_2_SW_DEV
|
||||
_SC_2_LOCALEDEF,
|
||||
#define _SC_2_LOCALEDEF _SC_2_LOCALEDEF
|
||||
|
||||
_SC_PII,
|
||||
#define _SC_PII _SC_PII
|
||||
_SC_PII_XTI,
|
||||
#define _SC_PII_XTI _SC_PII_XTI
|
||||
_SC_PII_SOCKET,
|
||||
#define _SC_PII_SOCKET _SC_PII_SOCKET
|
||||
_SC_PII_INTERNET,
|
||||
#define _SC_PII_INTERNET _SC_PII_INTERNET
|
||||
_SC_PII_OSI,
|
||||
#define _SC_PII_OSI _SC_PII_OSI
|
||||
_SC_POLL,
|
||||
#define _SC_POLL _SC_POLL
|
||||
_SC_SELECT,
|
||||
#define _SC_SELECT _SC_SELECT
|
||||
_SC_UIO_MAXIOV,
|
||||
#define _SC_UIO_MAXIOV _SC_UIO_MAXIOV
|
||||
_SC_IOV_MAX = _SC_UIO_MAXIOV,
|
||||
#define _SC_IOV_MAX _SC_IOV_MAX
|
||||
_SC_PII_INTERNET_STREAM,
|
||||
#define _SC_PII_INTERNET_STREAM _SC_PII_INTERNET_STREAM
|
||||
_SC_PII_INTERNET_DGRAM,
|
||||
#define _SC_PII_INTERNET_DGRAM _SC_PII_INTERNET_DGRAM
|
||||
_SC_PII_OSI_COTS,
|
||||
#define _SC_PII_OSI_COTS _SC_PII_OSI_COTS
|
||||
_SC_PII_OSI_CLTS,
|
||||
#define _SC_PII_OSI_CLTS _SC_PII_OSI_CLTS
|
||||
_SC_PII_OSI_M,
|
||||
#define _SC_PII_OSI_M _SC_PII_OSI_M
|
||||
_SC_T_IOV_MAX,
|
||||
#define _SC_T_IOV_MAX _SC_T_IOV_MAX
|
||||
|
||||
/* Values according to POSIX 1003.1c (POSIX threads). */
|
||||
_SC_THREADS,
|
||||
#define _SC_THREADS _SC_THREADS
|
||||
_SC_THREAD_SAFE_FUNCTIONS,
|
||||
#define _SC_THREAD_SAFE_FUNCTIONS _SC_THREAD_SAFE_FUNCTIONS
|
||||
_SC_GETGR_R_SIZE_MAX,
|
||||
#define _SC_GETGR_R_SIZE_MAX _SC_GETGR_R_SIZE_MAX
|
||||
_SC_GETPW_R_SIZE_MAX,
|
||||
#define _SC_GETPW_R_SIZE_MAX _SC_GETPW_R_SIZE_MAX
|
||||
_SC_LOGIN_NAME_MAX,
|
||||
#define _SC_LOGIN_NAME_MAX _SC_LOGIN_NAME_MAX
|
||||
_SC_TTY_NAME_MAX,
|
||||
#define _SC_TTY_NAME_MAX _SC_TTY_NAME_MAX
|
||||
_SC_THREAD_DESTRUCTOR_ITERATIONS,
|
||||
#define _SC_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_DESTRUCTOR_ITERATIONS
|
||||
_SC_THREAD_KEYS_MAX,
|
||||
#define _SC_THREAD_KEYS_MAX _SC_THREAD_KEYS_MAX
|
||||
_SC_THREAD_STACK_MIN,
|
||||
#define _SC_THREAD_STACK_MIN _SC_THREAD_STACK_MIN
|
||||
_SC_THREAD_THREADS_MAX,
|
||||
#define _SC_THREAD_THREADS_MAX _SC_THREAD_THREADS_MAX
|
||||
_SC_THREAD_ATTR_STACKADDR,
|
||||
#define _SC_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKADDR
|
||||
_SC_THREAD_ATTR_STACKSIZE,
|
||||
#define _SC_THREAD_ATTR_STACKSIZE _SC_THREAD_ATTR_STACKSIZE
|
||||
_SC_THREAD_PRIORITY_SCHEDULING,
|
||||
#define _SC_THREAD_PRIORITY_SCHEDULING _SC_THREAD_PRIORITY_SCHEDULING
|
||||
_SC_THREAD_PRIO_INHERIT,
|
||||
#define _SC_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_INHERIT
|
||||
_SC_THREAD_PRIO_PROTECT,
|
||||
#define _SC_THREAD_PRIO_PROTECT _SC_THREAD_PRIO_PROTECT
|
||||
_SC_THREAD_PROCESS_SHARED,
|
||||
#define _SC_THREAD_PROCESS_SHARED _SC_THREAD_PROCESS_SHARED
|
||||
|
||||
_SC_NPROCESSORS_CONF,
|
||||
#define _SC_NPROCESSORS_CONF _SC_NPROCESSORS_CONF
|
||||
_SC_NPROCESSORS_ONLN,
|
||||
#define _SC_NPROCESSORS_ONLN _SC_NPROCESSORS_ONLN
|
||||
_SC_PHYS_PAGES,
|
||||
#define _SC_PHYS_PAGES _SC_PHYS_PAGES
|
||||
_SC_AVPHYS_PAGES,
|
||||
#define _SC_AVPHYS_PAGES _SC_AVPHYS_PAGES
|
||||
_SC_ATEXIT_MAX,
|
||||
#define _SC_ATEXIT_MAX _SC_ATEXIT_MAX
|
||||
_SC_PASS_MAX,
|
||||
#define _SC_PASS_MAX _SC_PASS_MAX
|
||||
|
||||
_SC_XOPEN_VERSION,
|
||||
#define _SC_XOPEN_VERSION _SC_XOPEN_VERSION
|
||||
_SC_XOPEN_XCU_VERSION,
|
||||
#define _SC_XOPEN_XCU_VERSION _SC_XOPEN_XCU_VERSION
|
||||
_SC_XOPEN_UNIX,
|
||||
#define _SC_XOPEN_UNIX _SC_XOPEN_UNIX
|
||||
_SC_XOPEN_CRYPT,
|
||||
#define _SC_XOPEN_CRYPT _SC_XOPEN_CRYPT
|
||||
_SC_XOPEN_ENH_I18N,
|
||||
#define _SC_XOPEN_ENH_I18N _SC_XOPEN_ENH_I18N
|
||||
_SC_XOPEN_SHM,
|
||||
#define _SC_XOPEN_SHM _SC_XOPEN_SHM
|
||||
|
||||
_SC_2_CHAR_TERM,
|
||||
#define _SC_2_CHAR_TERM _SC_2_CHAR_TERM
|
||||
_SC_2_C_VERSION,
|
||||
#define _SC_2_C_VERSION _SC_2_C_VERSION
|
||||
_SC_2_UPE,
|
||||
#define _SC_2_UPE _SC_2_UPE
|
||||
|
||||
_SC_XOPEN_XPG2,
|
||||
#define _SC_XOPEN_XPG2 _SC_XOPEN_XPG2
|
||||
_SC_XOPEN_XPG3,
|
||||
#define _SC_XOPEN_XPG3 _SC_XOPEN_XPG3
|
||||
_SC_XOPEN_XPG4,
|
||||
#define _SC_XOPEN_XPG4 _SC_XOPEN_XPG4
|
||||
|
||||
_SC_CHAR_BIT,
|
||||
#define _SC_CHAR_BIT _SC_CHAR_BIT
|
||||
_SC_CHAR_MAX,
|
||||
#define _SC_CHAR_MAX _SC_CHAR_MAX
|
||||
_SC_CHAR_MIN,
|
||||
#define _SC_CHAR_MIN _SC_CHAR_MIN
|
||||
_SC_INT_MAX,
|
||||
#define _SC_INT_MAX _SC_INT_MAX
|
||||
_SC_INT_MIN,
|
||||
#define _SC_INT_MIN _SC_INT_MIN
|
||||
_SC_LONG_BIT,
|
||||
#define _SC_LONG_BIT _SC_LONG_BIT
|
||||
_SC_WORD_BIT,
|
||||
#define _SC_WORD_BIT _SC_WORD_BIT
|
||||
_SC_MB_LEN_MAX,
|
||||
#define _SC_MB_LEN_MAX _SC_MB_LEN_MAX
|
||||
_SC_NZERO,
|
||||
#define _SC_NZERO _SC_NZERO
|
||||
_SC_SSIZE_MAX,
|
||||
#define _SC_SSIZE_MAX _SC_SSIZE_MAX
|
||||
_SC_SCHAR_MAX,
|
||||
#define _SC_SCHAR_MAX _SC_SCHAR_MAX
|
||||
_SC_SCHAR_MIN,
|
||||
#define _SC_SCHAR_MIN _SC_SCHAR_MIN
|
||||
_SC_SHRT_MAX,
|
||||
#define _SC_SHRT_MAX _SC_SHRT_MAX
|
||||
_SC_SHRT_MIN,
|
||||
#define _SC_SHRT_MIN _SC_SHRT_MIN
|
||||
_SC_UCHAR_MAX,
|
||||
#define _SC_UCHAR_MAX _SC_UCHAR_MAX
|
||||
_SC_UINT_MAX,
|
||||
#define _SC_UINT_MAX _SC_UINT_MAX
|
||||
_SC_ULONG_MAX,
|
||||
#define _SC_ULONG_MAX _SC_ULONG_MAX
|
||||
_SC_USHRT_MAX,
|
||||
#define _SC_USHRT_MAX _SC_USHRT_MAX
|
||||
|
||||
_SC_NL_ARGMAX,
|
||||
#define _SC_NL_ARGMAX _SC_NL_ARGMAX
|
||||
_SC_NL_LANGMAX,
|
||||
#define _SC_NL_LANGMAX _SC_NL_LANGMAX
|
||||
_SC_NL_MSGMAX,
|
||||
#define _SC_NL_MSGMAX _SC_NL_MSGMAX
|
||||
_SC_NL_NMAX,
|
||||
#define _SC_NL_NMAX _SC_NL_NMAX
|
||||
_SC_NL_SETMAX,
|
||||
#define _SC_NL_SETMAX _SC_NL_SETMAX
|
||||
_SC_NL_TEXTMAX,
|
||||
#define _SC_NL_TEXTMAX _SC_NL_TEXTMAX
|
||||
|
||||
_SC_XBS5_ILP32_OFF32,
|
||||
#define _SC_XBS5_ILP32_OFF32 _SC_XBS5_ILP32_OFF32
|
||||
_SC_XBS5_ILP32_OFFBIG,
|
||||
#define _SC_XBS5_ILP32_OFFBIG _SC_XBS5_ILP32_OFFBIG
|
||||
_SC_XBS5_LP64_OFF64,
|
||||
#define _SC_XBS5_LP64_OFF64 _SC_XBS5_LP64_OFF64
|
||||
_SC_XBS5_LPBIG_OFFBIG,
|
||||
#define _SC_XBS5_LPBIG_OFFBIG _SC_XBS5_LPBIG_OFFBIG
|
||||
|
||||
_SC_XOPEN_LEGACY,
|
||||
#define _SC_XOPEN_LEGACY _SC_XOPEN_LEGACY
|
||||
_SC_XOPEN_REALTIME,
|
||||
#define _SC_XOPEN_REALTIME _SC_XOPEN_REALTIME
|
||||
_SC_XOPEN_REALTIME_THREADS,
|
||||
#define _SC_XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS
|
||||
|
||||
_SC_ADVISORY_INFO,
|
||||
#define _SC_ADVISORY_INFO _SC_ADVISORY_INFO
|
||||
_SC_BARRIERS,
|
||||
#define _SC_BARRIERS _SC_BARRIERS
|
||||
_SC_BASE,
|
||||
#define _SC_BASE _SC_BASE
|
||||
_SC_C_LANG_SUPPORT,
|
||||
#define _SC_C_LANG_SUPPORT _SC_C_LANG_SUPPORT
|
||||
_SC_C_LANG_SUPPORT_R,
|
||||
#define _SC_C_LANG_SUPPORT_R _SC_C_LANG_SUPPORT_R
|
||||
_SC_CLOCK_SELECTION,
|
||||
#define _SC_CLOCK_SELECTION _SC_CLOCK_SELECTION
|
||||
_SC_CPUTIME,
|
||||
#define _SC_CPUTIME _SC_CPUTIME
|
||||
_SC_THREAD_CPUTIME,
|
||||
#define _SC_THREAD_CPUTIME _SC_THREAD_CPUTIME
|
||||
_SC_DEVICE_IO,
|
||||
#define _SC_DEVICE_IO _SC_DEVICE_IO
|
||||
_SC_DEVICE_SPECIFIC,
|
||||
#define _SC_DEVICE_SPECIFIC _SC_DEVICE_SPECIFIC
|
||||
_SC_DEVICE_SPECIFIC_R,
|
||||
#define _SC_DEVICE_SPECIFIC_R _SC_DEVICE_SPECIFIC_R
|
||||
_SC_FD_MGMT,
|
||||
#define _SC_FD_MGMT _SC_FD_MGMT
|
||||
_SC_FIFO,
|
||||
#define _SC_FIFO _SC_FIFO
|
||||
_SC_PIPE,
|
||||
#define _SC_PIPE _SC_PIPE
|
||||
_SC_FILE_ATTRIBUTES,
|
||||
#define _SC_FILE_ATTRIBUTES _SC_FILE_ATTRIBUTES
|
||||
_SC_FILE_LOCKING,
|
||||
#define _SC_FILE_LOCKING _SC_FILE_LOCKING
|
||||
_SC_FILE_SYSTEM,
|
||||
#define _SC_FILE_SYSTEM _SC_FILE_SYSTEM
|
||||
_SC_MONOTONIC_CLOCK,
|
||||
#define _SC_MONOTONIC_CLOCK _SC_MONOTONIC_CLOCK
|
||||
_SC_MULTI_PROCESS,
|
||||
#define _SC_MULTI_PROCESS _SC_MULTI_PROCESS
|
||||
_SC_SINGLE_PROCESS,
|
||||
#define _SC_SINGLE_PROCESS _SC_SINGLE_PROCESS
|
||||
_SC_NETWORKING,
|
||||
#define _SC_NETWORKING _SC_NETWORKING
|
||||
_SC_READER_WRITER_LOCKS,
|
||||
#define _SC_READER_WRITER_LOCKS _SC_READER_WRITER_LOCKS
|
||||
_SC_SPIN_LOCKS,
|
||||
#define _SC_SPIN_LOCKS _SC_SPIN_LOCKS
|
||||
_SC_REGEXP,
|
||||
#define _SC_REGEXP _SC_REGEXP
|
||||
_SC_REGEX_VERSION,
|
||||
#define _SC_REGEX_VERSION _SC_REGEX_VERSION
|
||||
_SC_SHELL,
|
||||
#define _SC_SHELL _SC_SHELL
|
||||
_SC_SIGNALS,
|
||||
#define _SC_SIGNALS _SC_SIGNALS
|
||||
_SC_SPAWN,
|
||||
#define _SC_SPAWN _SC_SPAWN
|
||||
_SC_SPORADIC_SERVER,
|
||||
#define _SC_SPORADIC_SERVER _SC_SPORADIC_SERVER
|
||||
_SC_THREAD_SPORADIC_SERVER,
|
||||
#define _SC_THREAD_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER
|
||||
_SC_SYSTEM_DATABASE,
|
||||
#define _SC_SYSTEM_DATABASE _SC_SYSTEM_DATABASE
|
||||
_SC_SYSTEM_DATABASE_R,
|
||||
#define _SC_SYSTEM_DATABASE_R _SC_SYSTEM_DATABASE_R
|
||||
_SC_TIMEOUTS,
|
||||
#define _SC_TIMEOUTS _SC_TIMEOUTS
|
||||
_SC_TYPED_MEMORY_OBJECTS,
|
||||
#define _SC_TYPED_MEMORY_OBJECTS _SC_TYPED_MEMORY_OBJECTS
|
||||
_SC_USER_GROUPS,
|
||||
#define _SC_USER_GROUPS _SC_USER_GROUPS
|
||||
_SC_USER_GROUPS_R,
|
||||
#define _SC_USER_GROUPS_R _SC_USER_GROUPS_R
|
||||
_SC_2_PBS,
|
||||
#define _SC_2_PBS _SC_2_PBS
|
||||
_SC_2_PBS_ACCOUNTING,
|
||||
#define _SC_2_PBS_ACCOUNTING _SC_2_PBS_ACCOUNTING
|
||||
_SC_2_PBS_LOCATE,
|
||||
#define _SC_2_PBS_LOCATE _SC_2_PBS_LOCATE
|
||||
_SC_2_PBS_MESSAGE,
|
||||
#define _SC_2_PBS_MESSAGE _SC_2_PBS_MESSAGE
|
||||
_SC_2_PBS_TRACK,
|
||||
#define _SC_2_PBS_TRACK _SC_2_PBS_TRACK
|
||||
_SC_SYMLOOP_MAX,
|
||||
#define _SC_SYMLOOP_MAX _SC_SYMLOOP_MAX
|
||||
_SC_STREAMS,
|
||||
#define _SC_STREAMS _SC_STREAMS
|
||||
_SC_2_PBS_CHECKPOINT,
|
||||
#define _SC_2_PBS_CHECKPOINT _SC_2_PBS_CHECKPOINT
|
||||
|
||||
_SC_V6_ILP32_OFF32,
|
||||
#define _SC_V6_ILP32_OFF32 _SC_V6_ILP32_OFF32
|
||||
_SC_V6_ILP32_OFFBIG,
|
||||
#define _SC_V6_ILP32_OFFBIG _SC_V6_ILP32_OFFBIG
|
||||
_SC_V6_LP64_OFF64,
|
||||
#define _SC_V6_LP64_OFF64 _SC_V6_LP64_OFF64
|
||||
_SC_V6_LPBIG_OFFBIG,
|
||||
#define _SC_V6_LPBIG_OFFBIG _SC_V6_LPBIG_OFFBIG
|
||||
|
||||
_SC_HOST_NAME_MAX,
|
||||
#define _SC_HOST_NAME_MAX _SC_HOST_NAME_MAX
|
||||
_SC_TRACE,
|
||||
#define _SC_TRACE _SC_TRACE
|
||||
_SC_TRACE_EVENT_FILTER,
|
||||
#define _SC_TRACE_EVENT_FILTER _SC_TRACE_EVENT_FILTER
|
||||
_SC_TRACE_INHERIT,
|
||||
#define _SC_TRACE_INHERIT _SC_TRACE_INHERIT
|
||||
_SC_TRACE_LOG,
|
||||
#define _SC_TRACE_LOG _SC_TRACE_LOG
|
||||
|
||||
_SC_LEVEL1_ICACHE_SIZE,
|
||||
#define _SC_LEVEL1_ICACHE_SIZE _SC_LEVEL1_ICACHE_SIZE
|
||||
_SC_LEVEL1_ICACHE_ASSOC,
|
||||
#define _SC_LEVEL1_ICACHE_ASSOC _SC_LEVEL1_ICACHE_ASSOC
|
||||
_SC_LEVEL1_ICACHE_LINESIZE,
|
||||
#define _SC_LEVEL1_ICACHE_LINESIZE _SC_LEVEL1_ICACHE_LINESIZE
|
||||
_SC_LEVEL1_DCACHE_SIZE,
|
||||
#define _SC_LEVEL1_DCACHE_SIZE _SC_LEVEL1_DCACHE_SIZE
|
||||
_SC_LEVEL1_DCACHE_ASSOC,
|
||||
#define _SC_LEVEL1_DCACHE_ASSOC _SC_LEVEL1_DCACHE_ASSOC
|
||||
_SC_LEVEL1_DCACHE_LINESIZE,
|
||||
#define _SC_LEVEL1_DCACHE_LINESIZE _SC_LEVEL1_DCACHE_LINESIZE
|
||||
_SC_LEVEL2_CACHE_SIZE,
|
||||
#define _SC_LEVEL2_CACHE_SIZE _SC_LEVEL2_CACHE_SIZE
|
||||
_SC_LEVEL2_CACHE_ASSOC,
|
||||
#define _SC_LEVEL2_CACHE_ASSOC _SC_LEVEL2_CACHE_ASSOC
|
||||
_SC_LEVEL2_CACHE_LINESIZE,
|
||||
#define _SC_LEVEL2_CACHE_LINESIZE _SC_LEVEL2_CACHE_LINESIZE
|
||||
_SC_LEVEL3_CACHE_SIZE,
|
||||
#define _SC_LEVEL3_CACHE_SIZE _SC_LEVEL3_CACHE_SIZE
|
||||
_SC_LEVEL3_CACHE_ASSOC,
|
||||
#define _SC_LEVEL3_CACHE_ASSOC _SC_LEVEL3_CACHE_ASSOC
|
||||
_SC_LEVEL3_CACHE_LINESIZE,
|
||||
#define _SC_LEVEL3_CACHE_LINESIZE _SC_LEVEL3_CACHE_LINESIZE
|
||||
_SC_LEVEL4_CACHE_SIZE,
|
||||
#define _SC_LEVEL4_CACHE_SIZE _SC_LEVEL4_CACHE_SIZE
|
||||
_SC_LEVEL4_CACHE_ASSOC,
|
||||
#define _SC_LEVEL4_CACHE_ASSOC _SC_LEVEL4_CACHE_ASSOC
|
||||
_SC_LEVEL4_CACHE_LINESIZE,
|
||||
#define _SC_LEVEL4_CACHE_LINESIZE _SC_LEVEL4_CACHE_LINESIZE
|
||||
/* Leave room here, maybe we need a few more cache levels some day. */
|
||||
|
||||
_SC_IPV6 = _SC_LEVEL1_ICACHE_SIZE + 50,
|
||||
#define _SC_IPV6 _SC_IPV6
|
||||
_SC_RAW_SOCKETS
|
||||
#define _SC_RAW_SOCKETS _SC_RAW_SOCKETS
|
||||
};
|
||||
|
||||
#if (defined __USE_POSIX2 || defined __USE_UNIX98 \
|
||||
|| defined __USE_FILE_OFFSET64 || defined __USE_LARGEFILE64 \
|
||||
|| defined __USE_LARGEFILE)
|
||||
/* Values for the NAME argument to `confstr'. */
|
||||
enum
|
||||
{
|
||||
_CS_PATH, /* The default search path. */
|
||||
#define _CS_PATH _CS_PATH
|
||||
|
||||
_CS_V6_WIDTH_RESTRICTED_ENVS,
|
||||
# define _CS_V6_WIDTH_RESTRICTED_ENVS _CS_V6_WIDTH_RESTRICTED_ENVS
|
||||
|
||||
# if (defined __USE_FILE_OFFSET64 || defined __USE_LARGEFILE64 \
|
||||
|| defined __USE_LARGEFILE)
|
||||
_CS_LFS_CFLAGS = 1000,
|
||||
#define _CS_LFS_CFLAGS _CS_LFS_CFLAGS
|
||||
_CS_LFS_LDFLAGS,
|
||||
#define _CS_LFS_LDFLAGS _CS_LFS_LDFLAGS
|
||||
_CS_LFS_LIBS,
|
||||
#define _CS_LFS_LIBS _CS_LFS_LIBS
|
||||
_CS_LFS_LINTFLAGS,
|
||||
#define _CS_LFS_LINTFLAGS _CS_LFS_LINTFLAGS
|
||||
_CS_LFS64_CFLAGS,
|
||||
#define _CS_LFS64_CFLAGS _CS_LFS64_CFLAGS
|
||||
_CS_LFS64_LDFLAGS,
|
||||
#define _CS_LFS64_LDFLAGS _CS_LFS64_LDFLAGS
|
||||
_CS_LFS64_LIBS,
|
||||
#define _CS_LFS64_LIBS _CS_LFS64_LIBS
|
||||
_CS_LFS64_LINTFLAGS,
|
||||
#define _CS_LFS64_LINTFLAGS _CS_LFS64_LINTFLAGS
|
||||
# endif
|
||||
|
||||
# ifdef __USE_UNIX98
|
||||
_CS_XBS5_ILP32_OFF32_CFLAGS = 1100,
|
||||
#define _CS_XBS5_ILP32_OFF32_CFLAGS _CS_XBS5_ILP32_OFF32_CFLAGS
|
||||
_CS_XBS5_ILP32_OFF32_LDFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFF32_LDFLAGS _CS_XBS5_ILP32_OFF32_LDFLAGS
|
||||
_CS_XBS5_ILP32_OFF32_LIBS,
|
||||
#define _CS_XBS5_ILP32_OFF32_LIBS _CS_XBS5_ILP32_OFF32_LIBS
|
||||
_CS_XBS5_ILP32_OFF32_LINTFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFF32_LINTFLAGS _CS_XBS5_ILP32_OFF32_LINTFLAGS
|
||||
_CS_XBS5_ILP32_OFFBIG_CFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_CFLAGS _CS_XBS5_ILP32_OFFBIG_CFLAGS
|
||||
_CS_XBS5_ILP32_OFFBIG_LDFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_LDFLAGS _CS_XBS5_ILP32_OFFBIG_LDFLAGS
|
||||
_CS_XBS5_ILP32_OFFBIG_LIBS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_LIBS _CS_XBS5_ILP32_OFFBIG_LIBS
|
||||
_CS_XBS5_ILP32_OFFBIG_LINTFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_LINTFLAGS _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
|
||||
_CS_XBS5_LP64_OFF64_CFLAGS,
|
||||
#define _CS_XBS5_LP64_OFF64_CFLAGS _CS_XBS5_LP64_OFF64_CFLAGS
|
||||
_CS_XBS5_LP64_OFF64_LDFLAGS,
|
||||
#define _CS_XBS5_LP64_OFF64_LDFLAGS _CS_XBS5_LP64_OFF64_LDFLAGS
|
||||
_CS_XBS5_LP64_OFF64_LIBS,
|
||||
#define _CS_XBS5_LP64_OFF64_LIBS _CS_XBS5_LP64_OFF64_LIBS
|
||||
_CS_XBS5_LP64_OFF64_LINTFLAGS,
|
||||
#define _CS_XBS5_LP64_OFF64_LINTFLAGS _CS_XBS5_LP64_OFF64_LINTFLAGS
|
||||
_CS_XBS5_LPBIG_OFFBIG_CFLAGS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_CFLAGS _CS_XBS5_LPBIG_OFFBIG_CFLAGS
|
||||
_CS_XBS5_LPBIG_OFFBIG_LDFLAGS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_LDFLAGS _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
|
||||
_CS_XBS5_LPBIG_OFFBIG_LIBS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_LIBS _CS_XBS5_LPBIG_OFFBIG_LIBS
|
||||
_CS_XBS5_LPBIG_OFFBIG_LINTFLAGS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
|
||||
# endif
|
||||
# ifdef __USE_XOPEN2K
|
||||
_CS_POSIX_V6_ILP32_OFF32_CFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS _CS_POSIX_V6_ILP32_OFF32_CFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFF32_LDFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS _CS_POSIX_V6_ILP32_OFF32_LDFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFF32_LIBS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_LIBS _CS_POSIX_V6_ILP32_OFF32_LIBS
|
||||
_CS_POSIX_V6_ILP32_OFF32_LINTFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_LIBS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS _CS_POSIX_V6_ILP32_OFFBIG_LIBS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS
|
||||
_CS_POSIX_V6_LP64_OFF64_CFLAGS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_CFLAGS _CS_POSIX_V6_LP64_OFF64_CFLAGS
|
||||
_CS_POSIX_V6_LP64_OFF64_LDFLAGS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS _CS_POSIX_V6_LP64_OFF64_LDFLAGS
|
||||
_CS_POSIX_V6_LP64_OFF64_LIBS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_LIBS _CS_POSIX_V6_LP64_OFF64_LIBS
|
||||
_CS_POSIX_V6_LP64_OFF64_LINTFLAGS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_LINTFLAGS _CS_POSIX_V6_LP64_OFF64_LINTFLAGS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS,
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS,
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_LIBS,
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS _CS_POSIX_V6_LPBIG_OFFBIG_LIBS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS
|
||||
# endif
|
||||
};
|
||||
#endif
|
||||
53
conts/posix/libposix/include/posix/bits/dirent.h
Normal file
53
conts/posix/libposix/include/posix/bits/dirent.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _DIRENT_H
|
||||
# error "Never use <bits/dirent.h> directly; include <dirent.h> instead."
|
||||
#endif
|
||||
|
||||
struct dirent
|
||||
{
|
||||
#ifndef __USE_FILE_OFFSET64
|
||||
__ino_t d_ino;
|
||||
__off_t d_off;
|
||||
#else
|
||||
__ino64_t d_ino;
|
||||
__off64_t d_off;
|
||||
#endif
|
||||
unsigned short int d_reclen;
|
||||
unsigned char d_type;
|
||||
char d_name[256]; /* We must not include limits.h! */
|
||||
};
|
||||
|
||||
#ifdef __USE_LARGEFILE64
|
||||
struct dirent64
|
||||
{
|
||||
__ino64_t d_ino;
|
||||
__off64_t d_off;
|
||||
unsigned short int d_reclen;
|
||||
unsigned char d_type;
|
||||
char d_name[256]; /* We must not include limits.h! */
|
||||
};
|
||||
#endif
|
||||
|
||||
#define d_fileno d_ino /* Backwards compatibility. */
|
||||
|
||||
#undef _DIRENT_HAVE_D_NAMLEN
|
||||
#define _DIRENT_HAVE_D_RECLEN
|
||||
#define _DIRENT_HAVE_D_OFF
|
||||
#define _DIRENT_HAVE_D_TYPE
|
||||
67
conts/posix/libposix/include/posix/bits/dlfcn.h
Normal file
67
conts/posix/libposix/include/posix/bits/dlfcn.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* System dependent definitions for run-time dynamic loading.
|
||||
Copyright (C) 1996-2001, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _DLFCN_H
|
||||
# error "Never use <bits/dlfcn.h> directly; include <dlfcn.h> instead."
|
||||
#endif
|
||||
|
||||
/* The MODE argument to `dlopen' contains one of the following: */
|
||||
#define RTLD_LAZY 0x00001 /* Lazy function call binding. */
|
||||
#define RTLD_NOW 0x00002 /* Immediate function call binding. */
|
||||
#if 0 /* uClibc doesnt support these */
|
||||
#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */
|
||||
#define RTLD_NOLOAD 0x00004 /* Do not load the object. */
|
||||
#define RTLD_DEEPBIND 0x00008 /* Use deep binding. */
|
||||
#endif
|
||||
|
||||
/* If the following bit is set in the MODE argument to `dlopen',
|
||||
the symbols of the loaded object and its dependencies are made
|
||||
visible as if the object were linked directly into the program. */
|
||||
#define RTLD_GLOBAL 0x00100
|
||||
|
||||
/* Unix98 demands the following flag which is the inverse to RTLD_GLOBAL.
|
||||
The implementation does this by default and so we can define the
|
||||
value to zero. */
|
||||
#define RTLD_LOCAL 0
|
||||
|
||||
/* Do not delete object when closed. */
|
||||
#define RTLD_NODELETE 0x01000
|
||||
|
||||
#if 0 /*def __USE_GNU*/
|
||||
/* To support profiling of shared objects it is a good idea to call
|
||||
the function found using `dlsym' using the following macro since
|
||||
these calls do not use the PLT. But this would mean the dynamic
|
||||
loader has no chance to find out when the function is called. The
|
||||
macro applies the necessary magic so that profiling is possible.
|
||||
Rewrite
|
||||
foo = (*fctp) (arg1, arg2);
|
||||
into
|
||||
foo = DL_CALL_FCT (fctp, (arg1, arg2));
|
||||
*/
|
||||
# define DL_CALL_FCT(fctp, args) \
|
||||
(_dl_mcount_wrapper_check ((void *) (fctp)), (*(fctp)) args)
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* This function calls the profiling functions. */
|
||||
extern void _dl_mcount_wrapper_check (void *__selfpc) __THROW;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
14
conts/posix/libposix/include/posix/bits/elfclass.h
Normal file
14
conts/posix/libposix/include/posix/bits/elfclass.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/* This file specifies the native word size of the machine, which indicates
|
||||
the ELF file class used for executables and shared objects on this
|
||||
machine. */
|
||||
|
||||
#ifndef _LINK_H
|
||||
# error "Never use <bits/elfclass.h> directly; include <link.h> instead."
|
||||
#endif
|
||||
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
#define __ELF_NATIVE_CLASS __WORDSIZE
|
||||
|
||||
/* The entries in the .hash table always have a size of 32 bits. */
|
||||
typedef uint32_t Elf_Symndx;
|
||||
19
conts/posix/libposix/include/posix/bits/endian.h
Normal file
19
conts/posix/libposix/include/posix/bits/endian.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef _ENDIAN_H
|
||||
# error "Never use <bits/endian.h> directly; include <endian.h> instead."
|
||||
#endif
|
||||
|
||||
/* ARM can be either big or little endian. */
|
||||
#ifdef __ARMEB__
|
||||
# define __BYTE_ORDER __BIG_ENDIAN
|
||||
#else
|
||||
# define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
/* FPA floating point units are always big-endian, irrespective of the
|
||||
CPU endianness. VFP floating point units use the same endianness
|
||||
as the rest of the system. */
|
||||
#if defined __VFP_FP__ || defined __MAVERICK__
|
||||
# define __FLOAT_WORD_ORDER __BYTE_ORDER
|
||||
#else
|
||||
# define __FLOAT_WORD_ORDER __BIG_ENDIAN
|
||||
#endif
|
||||
78
conts/posix/libposix/include/posix/bits/environments.h
Normal file
78
conts/posix/libposix/include/posix/bits/environments.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* Copyright (C) 1999, 2001, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _UNISTD_H
|
||||
# error "Never include this file directly. Use <unistd.h> instead"
|
||||
#endif
|
||||
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
/* This header should define the following symbols under the described
|
||||
situations. A value `1' means that the model is always supported,
|
||||
`-1' means it is never supported. Undefined means it cannot be
|
||||
statically decided.
|
||||
|
||||
_POSIX_V6_ILP32_OFF32 32bit int, long, pointers, and off_t type
|
||||
_POSIX_V6_ILP32_OFFBIG 32bit int, long, and pointers and larger off_t type
|
||||
|
||||
_POSIX_V6_LP64_OFF32 64bit long and pointers and 32bit off_t type
|
||||
_POSIX_V6_LPBIG_OFFBIG 64bit long and pointers and large off_t type
|
||||
|
||||
The macros _XBS5_ILP32_OFF32, _XBS5_ILP32_OFFBIG, _XBS5_LP64_OFF32, and
|
||||
_XBS5_LPBIG_OFFBIG were used in previous versions of the Unix standard
|
||||
and are available only for compatibility.
|
||||
*/
|
||||
|
||||
#if __WORDSIZE == 64
|
||||
|
||||
/* We can never provide environments with 32-bit wide pointers. */
|
||||
# define _POSIX_V6_ILP32_OFF32 -1
|
||||
# define _POSIX_V6_ILP32_OFFBIG -1
|
||||
# define _XBS5_ILP32_OFF32 -1
|
||||
# define _XBS5_ILP32_OFFBIG -1
|
||||
/* We also have no use (for now) for an environment with bigger pointers
|
||||
and offsets. */
|
||||
# define _POSIX_V6_LPBIG_OFFBIG -1
|
||||
# define _XBS5_LPBIG_OFFBIG -1
|
||||
|
||||
/* By default we have 64-bit wide `long int', pointers and `off_t'. */
|
||||
# define _POSIX_V6_LP64_OFF64 1
|
||||
# define _XBS5_LP64_OFF64 1
|
||||
|
||||
#else /* __WORDSIZE == 32 */
|
||||
|
||||
/* By default we have 32-bit wide `int', `long int', pointers and `off_t'
|
||||
and all platforms support LFS. */
|
||||
# define _POSIX_V6_ILP32_OFF32 1
|
||||
# define _POSIX_V6_ILP32_OFFBIG 1
|
||||
# define _XBS5_ILP32_OFF32 1
|
||||
# define _XBS5_ILP32_OFFBIG 1
|
||||
|
||||
/* We optionally provide an environment with the above size but an 64-bit
|
||||
side `off_t'. Therefore we don't define _XBS5_ILP32_OFFBIG. */
|
||||
|
||||
/* We can never provide environments with 64-bit wide pointers. */
|
||||
# define _POSIX_V6_LP64_OFF64 -1
|
||||
# define _POSIX_V6_LPBIG_OFFBIG -1
|
||||
# define _XBS5_LP64_OFF64 -1
|
||||
# define _XBS5_LPBIG_OFFBIG -1
|
||||
|
||||
/* CFLAGS. */
|
||||
#define __ILP32_OFFBIG_CFLAGS "-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
|
||||
#endif /* __WORDSIZE == 32 */
|
||||
59
conts/posix/libposix/include/posix/bits/errno.h
Normal file
59
conts/posix/libposix/include/posix/bits/errno.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* Error constants. Linux specific version.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifdef _ERRNO_H
|
||||
|
||||
# undef EDOM
|
||||
# undef EILSEQ
|
||||
# undef ERANGE
|
||||
# include <bits/errno_values.h>
|
||||
|
||||
/* Linux has no ENOTSUP error code. */
|
||||
# define ENOTSUP EOPNOTSUPP
|
||||
|
||||
/* Older Linux versions also had no ECANCELED error code. */
|
||||
# ifndef ECANCELED
|
||||
# define ECANCELED 125
|
||||
# endif
|
||||
|
||||
/* Support for error codes to support robust mutexes was added later, too. */
|
||||
# ifndef EOWNERDEAD
|
||||
# define EOWNERDEAD 130
|
||||
# define ENOTRECOVERABLE 131
|
||||
# endif
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
/* Function to get address of global `errno' variable. */
|
||||
extern int *__errno_location (void) __THROW __attribute__ ((__const__));
|
||||
|
||||
# ifdef __UCLIBC_HAS_THREADS__
|
||||
/* When using threads, errno is a per-thread value. */
|
||||
# define errno (*__errno_location ())
|
||||
# endif
|
||||
# endif /* !__ASSEMBLER__ */
|
||||
#endif /* _ERRNO_H */
|
||||
|
||||
#if !defined _ERRNO_H && defined __need_Emath
|
||||
/* This is ugly but the kernel header is not clean enough. We must
|
||||
define only the values EDOM, EILSEQ and ERANGE in case __need_Emath is
|
||||
defined. */
|
||||
# define EDOM 33 /* Math argument out of domain of function. */
|
||||
# define EILSEQ 84 /* Illegal byte sequence. */
|
||||
# define ERANGE 34 /* Math result not representable. */
|
||||
#endif /* !_ERRNO_H && __need_Emath */
|
||||
137
conts/posix/libposix/include/posix/bits/errno_values.h
Normal file
137
conts/posix/libposix/include/posix/bits/errno_values.h
Normal file
@@ -0,0 +1,137 @@
|
||||
#ifndef _BITS_ERRNO_VALUES_H
|
||||
#define _BITS_ERRNO_VALUES_H
|
||||
|
||||
/* Most architectures use these errno values (i.e. arm cris
|
||||
* i386 ia64 m68k parisc ppc ppc64 s390 s390x sh x86_64, etc)
|
||||
*
|
||||
* A few arches do their own wierd thing, specifically alpha,
|
||||
* mips, and sparc.
|
||||
*
|
||||
*/
|
||||
|
||||
#define EPERM 1 /* Operation not permitted */
|
||||
#define ENOENT 2 /* No such file or directory */
|
||||
#define ESRCH 3 /* No such process */
|
||||
#define EINTR 4 /* Interrupted system call */
|
||||
#define EIO 5 /* I/O error */
|
||||
#define ENXIO 6 /* No such device or address */
|
||||
#define E2BIG 7 /* Argument list too long */
|
||||
#define ENOEXEC 8 /* Exec format error */
|
||||
#define EBADF 9 /* Bad file number */
|
||||
#define ECHILD 10 /* No child processes */
|
||||
#define EAGAIN 11 /* Try again */
|
||||
#define ENOMEM 12 /* Out of memory */
|
||||
#define EACCES 13 /* Permission denied */
|
||||
#define EFAULT 14 /* Bad address */
|
||||
#define ENOTBLK 15 /* Block device required */
|
||||
#define EBUSY 16 /* Device or resource busy */
|
||||
#define EEXIST 17 /* File exists */
|
||||
#define EXDEV 18 /* Cross-device link */
|
||||
#define ENODEV 19 /* No such device */
|
||||
#define ENOTDIR 20 /* Not a directory */
|
||||
#define EISDIR 21 /* Is a directory */
|
||||
#define EINVAL 22 /* Invalid argument */
|
||||
#define ENFILE 23 /* File table overflow */
|
||||
#define EMFILE 24 /* Too many open files */
|
||||
#define ENOTTY 25 /* Not a typewriter */
|
||||
#define ETXTBSY 26 /* Text file busy */
|
||||
#define EFBIG 27 /* File too large */
|
||||
#define ENOSPC 28 /* No space left on device */
|
||||
#define ESPIPE 29 /* Illegal seek */
|
||||
#define EROFS 30 /* Read-only file system */
|
||||
#define EMLINK 31 /* Too many links */
|
||||
#define EPIPE 32 /* Broken pipe */
|
||||
#define EDOM 33 /* Math argument out of domain of func */
|
||||
#define ERANGE 34 /* Math result not representable */
|
||||
#define EDEADLK 35 /* Resource deadlock would occur */
|
||||
#define ENAMETOOLONG 36 /* File name too long */
|
||||
#define ENOLCK 37 /* No record locks available */
|
||||
#define ENOSYS 38 /* Function not implemented */
|
||||
#define ENOTEMPTY 39 /* Directory not empty */
|
||||
#define ELOOP 40 /* Too many symbolic links encountered */
|
||||
#define EWOULDBLOCK EAGAIN /* Operation would block */
|
||||
#define ENOMSG 42 /* No message of desired type */
|
||||
#define EIDRM 43 /* Identifier removed */
|
||||
#define ECHRNG 44 /* Channel number out of range */
|
||||
#define EL2NSYNC 45 /* Level 2 not synchronized */
|
||||
#define EL3HLT 46 /* Level 3 halted */
|
||||
#define EL3RST 47 /* Level 3 reset */
|
||||
#define ELNRNG 48 /* Link number out of range */
|
||||
#define EUNATCH 49 /* Protocol driver not attached */
|
||||
#define ENOCSI 50 /* No CSI structure available */
|
||||
#define EL2HLT 51 /* Level 2 halted */
|
||||
#define EBADE 52 /* Invalid exchange */
|
||||
#define EBADR 53 /* Invalid request descriptor */
|
||||
#define EXFULL 54 /* Exchange full */
|
||||
#define ENOANO 55 /* No anode */
|
||||
#define EBADRQC 56 /* Invalid request code */
|
||||
#define EBADSLT 57 /* Invalid slot */
|
||||
#define EDEADLOCK EDEADLK
|
||||
#define EBFONT 59 /* Bad font file format */
|
||||
#define ENOSTR 60 /* Device not a stream */
|
||||
#define ENODATA 61 /* No data available */
|
||||
#define ETIME 62 /* Timer expired */
|
||||
#define ENOSR 63 /* Out of streams resources */
|
||||
#define ENONET 64 /* Machine is not on the network */
|
||||
#define ENOPKG 65 /* Package not installed */
|
||||
#define EREMOTE 66 /* Object is remote */
|
||||
#define ENOLINK 67 /* Link has been severed */
|
||||
#define EADV 68 /* Advertise error */
|
||||
#define ESRMNT 69 /* Srmount error */
|
||||
#define ECOMM 70 /* Communication error on send */
|
||||
#define EPROTO 71 /* Protocol error */
|
||||
#define EMULTIHOP 72 /* Multihop attempted */
|
||||
#define EDOTDOT 73 /* RFS specific error */
|
||||
#define EBADMSG 74 /* Not a data message */
|
||||
#define EOVERFLOW 75 /* Value too large for defined data type */
|
||||
#define ENOTUNIQ 76 /* Name not unique on network */
|
||||
#define EBADFD 77 /* File descriptor in bad state */
|
||||
#define EREMCHG 78 /* Remote address changed */
|
||||
#define ELIBACC 79 /* Can not access a needed shared library */
|
||||
#define ELIBBAD 80 /* Accessing a corrupted shared library */
|
||||
#define ELIBSCN 81 /* .lib section in a.out corrupted */
|
||||
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
|
||||
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
|
||||
#define EILSEQ 84 /* Illegal byte sequence */
|
||||
#define ERESTART 85 /* Interrupted system call should be restarted */
|
||||
#define ESTRPIPE 86 /* Streams pipe error */
|
||||
#define EUSERS 87 /* Too many users */
|
||||
#define ENOTSOCK 88 /* Socket operation on non-socket */
|
||||
#define EDESTADDRREQ 89 /* Destination address required */
|
||||
#define EMSGSIZE 90 /* Message too long */
|
||||
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
|
||||
#define ENOPROTOOPT 92 /* Protocol not available */
|
||||
#define EPROTONOSUPPORT 93 /* Protocol not supported */
|
||||
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
|
||||
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
|
||||
#define EPFNOSUPPORT 96 /* Protocol family not supported */
|
||||
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
|
||||
#define EADDRINUSE 98 /* Address already in use */
|
||||
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
|
||||
#define ENETDOWN 100 /* Network is down */
|
||||
#define ENETUNREACH 101 /* Network is unreachable */
|
||||
#define ENETRESET 102 /* Network dropped connection because of reset */
|
||||
#define ECONNABORTED 103 /* Software caused connection abort */
|
||||
#define ECONNRESET 104 /* Connection reset by peer */
|
||||
#define ENOBUFS 105 /* No buffer space available */
|
||||
#define EISCONN 106 /* Transport endpoint is already connected */
|
||||
#define ENOTCONN 107 /* Transport endpoint is not connected */
|
||||
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
|
||||
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
|
||||
#define ETIMEDOUT 110 /* Connection timed out */
|
||||
#define ECONNREFUSED 111 /* Connection refused */
|
||||
#define EHOSTDOWN 112 /* Host is down */
|
||||
#define EHOSTUNREACH 113 /* No route to host */
|
||||
#define EALREADY 114 /* Operation already in progress */
|
||||
#define EINPROGRESS 115 /* Operation now in progress */
|
||||
#define ESTALE 116 /* Stale NFS file handle */
|
||||
#define EUCLEAN 117 /* Structure needs cleaning */
|
||||
#define ENOTNAM 118 /* Not a XENIX named type file */
|
||||
#define ENAVAIL 119 /* No XENIX semaphores available */
|
||||
#define EISNAM 120 /* Is a named type file */
|
||||
#define EREMOTEIO 121 /* Remote I/O error */
|
||||
#define EDQUOT 122 /* Quota exceeded */
|
||||
#define ENOMEDIUM 123 /* No medium found */
|
||||
#define EMEDIUMTYPE 124 /* Wrong medium type */
|
||||
|
||||
#endif /* _BITS_ERRNO_VALUES_H */
|
||||
237
conts/posix/libposix/include/posix/bits/fcntl.h
Normal file
237
conts/posix/libposix/include/posix/bits/fcntl.h
Normal file
@@ -0,0 +1,237 @@
|
||||
/* O_*, F_*, FD_* bit values for Linux.
|
||||
Copyright (C) 1995-1998, 2000, 2004, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _FCNTL_H
|
||||
# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef __USE_GNU
|
||||
# include <bits/uio.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
|
||||
located on an ext2 file system */
|
||||
#define O_ACCMODE 0003
|
||||
#define O_RDONLY 00
|
||||
#define O_WRONLY 01
|
||||
#define O_RDWR 02
|
||||
#define O_CREAT 0100 /* not fcntl */
|
||||
#define O_EXCL 0200 /* not fcntl */
|
||||
#define O_NOCTTY 0400 /* not fcntl */
|
||||
#define O_TRUNC 01000 /* not fcntl */
|
||||
#define O_APPEND 02000
|
||||
#define O_NONBLOCK 04000
|
||||
#define O_NDELAY O_NONBLOCK
|
||||
#define O_SYNC 010000
|
||||
#define O_FSYNC O_SYNC
|
||||
#define O_ASYNC 020000
|
||||
|
||||
#ifdef __USE_GNU
|
||||
# define O_DIRECTORY 040000 /* Must be a directory. */
|
||||
# define O_NOFOLLOW 0100000 /* Do not follow links. */
|
||||
# define O_DIRECT 0200000 /* Direct disk access. */
|
||||
# define O_NOATIME 01000000 /* Do not set atime. */
|
||||
#endif
|
||||
|
||||
/* For now Linux has synchronisity options for data and read operations.
|
||||
We define the symbols here but let them do the same as O_SYNC since
|
||||
this is a superset. */
|
||||
#if defined __USE_POSIX199309 || defined __USE_UNIX98
|
||||
# define O_DSYNC O_SYNC /* Synchronize data. */
|
||||
# define O_RSYNC O_SYNC /* Synchronize read operations. */
|
||||
#endif
|
||||
|
||||
#ifdef __USE_LARGEFILE64
|
||||
# define O_LARGEFILE 0400000
|
||||
#endif
|
||||
|
||||
/* Values for the second argument to `fcntl'. */
|
||||
#define F_DUPFD 0 /* Duplicate file descriptor. */
|
||||
#define F_GETFD 1 /* Get file descriptor flags. */
|
||||
#define F_SETFD 2 /* Set file descriptor flags. */
|
||||
#define F_GETFL 3 /* Get file status flags. */
|
||||
#define F_SETFL 4 /* Set file status flags. */
|
||||
#ifndef __USE_FILE_OFFSET64
|
||||
# define F_GETLK 5 /* Get record locking info. */
|
||||
# define F_SETLK 6 /* Set record locking info (non-blocking). */
|
||||
# define F_SETLKW 7 /* Set record locking info (blocking). */
|
||||
#else
|
||||
# define F_GETLK F_GETLK64 /* Get record locking info. */
|
||||
# define F_SETLK F_SETLK64 /* Set record locking info (non-blocking).*/
|
||||
# define F_SETLKW F_SETLKW64 /* Set record locking info (blocking). */
|
||||
#endif
|
||||
#define F_GETLK64 12 /* Get record locking info. */
|
||||
#define F_SETLK64 13 /* Set record locking info (non-blocking). */
|
||||
#define F_SETLKW64 14 /* Set record locking info (blocking). */
|
||||
|
||||
#if defined __USE_BSD || defined __USE_UNIX98
|
||||
# define F_SETOWN 8 /* Get owner of socket (receiver of SIGIO). */
|
||||
# define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */
|
||||
#endif
|
||||
|
||||
#ifdef __USE_GNU
|
||||
# define F_SETSIG 10 /* Set number of signal to be sent. */
|
||||
# define F_GETSIG 11 /* Get number of signal to be sent. */
|
||||
#endif
|
||||
|
||||
#ifdef __USE_GNU
|
||||
# define F_SETLEASE 1024 /* Set a lease. */
|
||||
# define F_GETLEASE 1025 /* Enquire what lease is active. */
|
||||
# define F_NOTIFY 1026 /* Request notfications on a directory. */
|
||||
#endif
|
||||
|
||||
/* For F_[GET|SET]FL. */
|
||||
#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
|
||||
|
||||
/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
|
||||
#define F_RDLCK 0 /* Read lock. */
|
||||
#define F_WRLCK 1 /* Write lock. */
|
||||
#define F_UNLCK 2 /* Remove lock. */
|
||||
|
||||
/* For old implementation of bsd flock(). */
|
||||
#define F_EXLCK 4 /* or 3 */
|
||||
#define F_SHLCK 8 /* or 4 */
|
||||
|
||||
#ifdef __USE_BSD
|
||||
/* Operations for bsd flock(), also used by the kernel implementation. */
|
||||
# define LOCK_SH 1 /* shared lock */
|
||||
# define LOCK_EX 2 /* exclusive lock */
|
||||
# define LOCK_NB 4 /* or'd with one of the above to prevent
|
||||
blocking */
|
||||
# define LOCK_UN 8 /* remove lock */
|
||||
#endif
|
||||
|
||||
#ifdef __USE_GNU
|
||||
# define LOCK_MAND 32 /* This is a mandatory flock: */
|
||||
# define LOCK_READ 64 /* ... which allows concurrent read operations. */
|
||||
# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */
|
||||
# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */
|
||||
#endif
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Types of directory notifications that may be requested with F_NOTIFY. */
|
||||
# define DN_ACCESS 0x00000001 /* File accessed. */
|
||||
# define DN_MODIFY 0x00000002 /* File modified. */
|
||||
# define DN_CREATE 0x00000004 /* File created. */
|
||||
# define DN_DELETE 0x00000008 /* File removed. */
|
||||
# define DN_RENAME 0x00000010 /* File renamed. */
|
||||
# define DN_ATTRIB 0x00000020 /* File changed attibutes. */
|
||||
# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */
|
||||
#endif
|
||||
|
||||
struct flock
|
||||
{
|
||||
short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
|
||||
short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
|
||||
#ifndef __USE_FILE_OFFSET64
|
||||
__off_t l_start; /* Offset where the lock begins. */
|
||||
__off_t l_len; /* Size of the locked area; zero means until EOF. */
|
||||
#else
|
||||
__off64_t l_start; /* Offset where the lock begins. */
|
||||
__off64_t l_len; /* Size of the locked area; zero means until EOF. */
|
||||
#endif
|
||||
__pid_t l_pid; /* Process holding the lock. */
|
||||
};
|
||||
|
||||
#ifdef __USE_LARGEFILE64
|
||||
struct flock64
|
||||
{
|
||||
short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
|
||||
short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
|
||||
__off64_t l_start; /* Offset where the lock begins. */
|
||||
__off64_t l_len; /* Size of the locked area; zero means until EOF. */
|
||||
__pid_t l_pid; /* Process holding the lock. */
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Define some more compatibility macros to be backward compatible with
|
||||
BSD systems which did not managed to hide these kernel macros. */
|
||||
#ifdef __USE_BSD
|
||||
# define FAPPEND O_APPEND
|
||||
# define FFSYNC O_FSYNC
|
||||
# define FASYNC O_ASYNC
|
||||
# define FNONBLOCK O_NONBLOCK
|
||||
# define FNDELAY O_NDELAY
|
||||
#endif /* Use BSD. */
|
||||
|
||||
/* Advise to `posix_fadvise'. */
|
||||
#ifdef __USE_XOPEN2K
|
||||
# define POSIX_FADV_NORMAL 0 /* No further special treatment. */
|
||||
# define POSIX_FADV_RANDOM 1 /* Expect random page references. */
|
||||
# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
|
||||
# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
|
||||
# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
|
||||
# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Flags for SYNC_FILE_RANGE. */
|
||||
# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
|
||||
in the range before performing the
|
||||
write. */
|
||||
# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
|
||||
dirty pages in the range which are
|
||||
not presently under writeback. */
|
||||
# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
|
||||
the range after performing the
|
||||
write. */
|
||||
|
||||
/* Flags for SPLICE and VMSPLICE. */
|
||||
# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */
|
||||
# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing
|
||||
(but we may still block on the fd
|
||||
we splice from/to). */
|
||||
# define SPLICE_F_MORE 4 /* Expect more data. */
|
||||
# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#ifdef __USE_GNU
|
||||
|
||||
/* Provide kernel hint to read ahead. */
|
||||
extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
|
||||
__THROW;
|
||||
|
||||
|
||||
#if 0
|
||||
/* Selective file content synch'ing. */
|
||||
extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
|
||||
unsigned int __flags);
|
||||
|
||||
|
||||
/* Splice address range into a pipe. */
|
||||
extern int vmsplice (int __fdout, const struct iovec *__iov, size_t __count,
|
||||
unsigned int __flags);
|
||||
|
||||
/* Splice two files together. */
|
||||
extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
|
||||
__THROW;
|
||||
|
||||
/* In-kernel implementation of tee for pipe buffers. */
|
||||
extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
|
||||
__THROW;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
99
conts/posix/libposix/include/posix/bits/fenv.h
Normal file
99
conts/posix/libposix/include/posix/bits/fenv.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _FENV_H
|
||||
# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
|
||||
#endif
|
||||
|
||||
#ifdef __MAVERICK__
|
||||
|
||||
/* Define bits representing exceptions in the FPU status word. */
|
||||
enum
|
||||
{
|
||||
FE_INVALID = 1,
|
||||
#define FE_INVALID FE_INVALID
|
||||
FE_OVERFLOW = 4,
|
||||
#define FE_OVERFLOW FE_OVERFLOW
|
||||
FE_UNDERFLOW = 8,
|
||||
#define FE_UNDERFLOW FE_UNDERFLOW
|
||||
FE_INEXACT = 16,
|
||||
#define FE_INEXACT FE_INEXACT
|
||||
};
|
||||
|
||||
/* Amount to shift by to convert an exception to a mask bit. */
|
||||
#define FE_EXCEPT_SHIFT 5
|
||||
|
||||
/* All supported exceptions. */
|
||||
#define FE_ALL_EXCEPT \
|
||||
(FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
|
||||
|
||||
/* IEEE rounding modes. */
|
||||
enum
|
||||
{
|
||||
FE_TONEAREST = 0,
|
||||
#define FE_TONEAREST FE_TONEAREST
|
||||
FE_TOWARDZERO = 0x400,
|
||||
#define FE_TOWARDZERO FE_TOWARDZERO
|
||||
FE_DOWNWARD = 0x800,
|
||||
#define FE_DOWNWARD FE_DOWNWARD
|
||||
FE_UPWARD = 0xc00,
|
||||
#define FE_UPWARD FE_UPWARD
|
||||
};
|
||||
|
||||
#define FE_ROUND_MASK (FE_UPWARD)
|
||||
|
||||
#else /* !__MAVERICK__ */
|
||||
|
||||
/* Define bits representing exceptions in the FPU status word. */
|
||||
enum
|
||||
{
|
||||
FE_INVALID = 1,
|
||||
#define FE_INVALID FE_INVALID
|
||||
FE_DIVBYZERO = 2,
|
||||
#define FE_DIVBYZERO FE_DIVBYZERO
|
||||
FE_OVERFLOW = 4,
|
||||
#define FE_OVERFLOW FE_OVERFLOW
|
||||
FE_UNDERFLOW = 8,
|
||||
#define FE_UNDERFLOW FE_UNDERFLOW
|
||||
};
|
||||
|
||||
/* Amount to shift by to convert an exception to a mask bit. */
|
||||
#define FE_EXCEPT_SHIFT 16
|
||||
|
||||
/* All supported exceptions. */
|
||||
#define FE_ALL_EXCEPT \
|
||||
(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)
|
||||
|
||||
/* The ARM FPU basically only supports round-to-nearest. Other rounding
|
||||
modes exist, but you have to encode them in the actual instruction. */
|
||||
#define FE_TONEAREST 0
|
||||
|
||||
#endif /* __MAVERICK__ */
|
||||
|
||||
/* Type representing exception flags. */
|
||||
typedef unsigned long int fexcept_t;
|
||||
|
||||
/* Type representing floating-point environment. */
|
||||
typedef struct
|
||||
{
|
||||
unsigned long int __cw;
|
||||
}
|
||||
fenv_t;
|
||||
|
||||
/* If the default argument is used we use this value. */
|
||||
#define FE_DFL_ENV ((fenv_t *) -1l)
|
||||
8
conts/posix/libposix/include/posix/bits/fenvinline.h
Normal file
8
conts/posix/libposix/include/posix/bits/fenvinline.h
Normal file
@@ -0,0 +1,8 @@
|
||||
/* This file provides inline versions of floating-pint environment
|
||||
handling functions. If there were any. */
|
||||
|
||||
#ifndef __NO_MATH_INLINES
|
||||
|
||||
/* Here is where the code would go. */
|
||||
|
||||
#endif
|
||||
181
conts/posix/libposix/include/posix/bits/getopt.h
Normal file
181
conts/posix/libposix/include/posix/bits/getopt.h
Normal file
@@ -0,0 +1,181 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989-1994,1996-1999,2001,2003,2004
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
|
||||
#include <features.h>
|
||||
|
||||
#ifndef __need_getopt
|
||||
# define _GETOPT_H 1
|
||||
#endif
|
||||
|
||||
/* If __GNU_LIBRARY__ is not already defined, either we are being used
|
||||
standalone, or this is the first header included in the source file.
|
||||
If we are being used with glibc, we need to include <features.h>, but
|
||||
that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
|
||||
not defined, include <ctype.h>, which will pull in <features.h> for us
|
||||
if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
|
||||
doesn't flood the namespace with stuff the way some other headers do.) */
|
||||
#if !defined __GNU_LIBRARY__
|
||||
# include <ctype.h>
|
||||
#endif
|
||||
|
||||
#ifndef __THROW
|
||||
# ifndef __GNUC_PREREQ
|
||||
# define __GNUC_PREREQ(maj, min) (0)
|
||||
# endif
|
||||
# if defined __cplusplus && __GNUC_PREREQ (2,8)
|
||||
# define __THROW throw ()
|
||||
# else
|
||||
# define __THROW
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns -1, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
#ifndef __need_getopt
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
const char *name;
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
# define no_argument 0
|
||||
# define required_argument 1
|
||||
# define optional_argument 2
|
||||
#endif /* need getopt */
|
||||
|
||||
|
||||
/* Get definitions and prototypes for functions to process the
|
||||
arguments in ARGV (ARGC of them, minus the program name) for
|
||||
options given in OPTS.
|
||||
|
||||
Return the option character from OPTS just read. Return -1 when
|
||||
there are no more options. For unrecognized options, or options
|
||||
missing arguments, `optopt' is set to the option letter, and '?' is
|
||||
returned.
|
||||
|
||||
The OPTS string is a list of characters which are recognized option
|
||||
letters, optionally followed by colons, specifying that that letter
|
||||
takes an argument, to be placed in `optarg'.
|
||||
|
||||
If a letter in OPTS is followed by two colons, its argument is
|
||||
optional. This behavior is specific to the GNU `getopt'.
|
||||
|
||||
The argument `--' causes premature termination of argument
|
||||
scanning, explicitly telling `getopt' that there are no more
|
||||
options.
|
||||
|
||||
If OPTS begins with `--', then non-option arguments are treated as
|
||||
arguments to the option '\0'. This behavior is specific to the GNU
|
||||
`getopt'. */
|
||||
|
||||
#if defined __GNU_LIBRARY__ || defined __UCLIBC__
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
|
||||
__THROW;
|
||||
#else /* not __GNU_LIBRARY__ */
|
||||
extern int getopt ();
|
||||
#endif /* __GNU_LIBRARY__ */
|
||||
|
||||
#if defined __UCLIBC_HAS_GNU_GETOPT__ || defined __UCLIBC_HAS_GETOPT_LONG__
|
||||
#ifndef __need_getopt
|
||||
extern int getopt_long (int ___argc, char *const *___argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind)
|
||||
__THROW;
|
||||
extern int getopt_long_only (int ___argc, char *const *___argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind)
|
||||
__THROW;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make sure we later can get all the definitions and declarations. */
|
||||
#undef __need_getopt
|
||||
|
||||
#endif /* getopt.h */
|
||||
72
conts/posix/libposix/include/posix/bits/huge_val.h
Normal file
72
conts/posix/libposix/include/posix/bits/huge_val.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* `HUGE_VAL' constant for IEEE 754 machines (where it is infinity).
|
||||
Used by <stdlib.h> and <math.h> functions for overflow.
|
||||
ARM version.
|
||||
Copyright (C) 1992, 95, 96, 97, 98, 99, 2000, 2004
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _MATH_H
|
||||
# error "Never use <bits/huge_val.h> directly; include <math.h> instead."
|
||||
#endif
|
||||
|
||||
/* IEEE positive infinity (-HUGE_VAL is negative infinity). */
|
||||
|
||||
#if __GNUC_PREREQ(3,3)
|
||||
# define HUGE_VAL (__builtin_huge_val())
|
||||
#elif __GNUC_PREREQ(2,96)
|
||||
# define HUGE_VAL (__extension__ 0x1.0p2047)
|
||||
#elif defined __GNUC__
|
||||
|
||||
#ifndef __CONFIG_ARM_EABI__
|
||||
# define HUGE_VAL \
|
||||
(__extension__ \
|
||||
((union { unsigned __l __attribute__((__mode__(__DI__))); double __d; }) \
|
||||
{ __l: 0x000000007ff00000ULL }).__d)
|
||||
#else
|
||||
# define HUGE_VAL \
|
||||
(__extension__ \
|
||||
((union { unsigned __l __attribute__((__mode__(__DI__))); double __d; }) \
|
||||
{ __l: 0x7ff0000000000000ULL }).__d)
|
||||
#endif
|
||||
|
||||
#else /* not GCC */
|
||||
|
||||
# include <endian.h>
|
||||
|
||||
typedef union { unsigned char __c[8]; double __d; } __huge_val_t;
|
||||
|
||||
#ifndef __CONFIG_ARM_EABI__
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define __HUGE_VAL_bytes { 0, 0, 0, 0, 0x7f, 0xf0, 0, 0 }
|
||||
# endif
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define __HUGE_VAL_bytes { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 }
|
||||
# endif
|
||||
#else
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define __HUGE_VAL_bytes { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }
|
||||
# endif
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define __HUGE_VAL_bytes { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static __huge_val_t __huge_val = { __HUGE_VAL_bytes };
|
||||
# define HUGE_VAL (__huge_val.__d)
|
||||
|
||||
#endif /* GCC. */
|
||||
53
conts/posix/libposix/include/posix/bits/huge_valf.h
Normal file
53
conts/posix/libposix/include/posix/bits/huge_valf.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* `HUGE_VALF' constant for IEEE 754 machines (where it is infinity).
|
||||
Used by <stdlib.h> and <math.h> functions for overflow.
|
||||
Copyright (C) 1992, 1995, 1996, 1997, 1999, 2000, 2004
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _MATH_H
|
||||
# error "Never use <bits/huge_valf.h> directly; include <math.h> instead."
|
||||
#endif
|
||||
|
||||
/* IEEE positive infinity (-HUGE_VAL is negative infinity). */
|
||||
|
||||
#if __GNUC_PREREQ(3,3)
|
||||
# define HUGE_VALF (__builtin_huge_valf())
|
||||
#elif __GNUC_PREREQ(2,96)
|
||||
# define HUGE_VALF (__extension__ 0x1.0p255f)
|
||||
#elif defined __GNUC__
|
||||
|
||||
# define HUGE_VALF \
|
||||
(__extension__ \
|
||||
((union { unsigned __l __attribute__((__mode__(__SI__))); float __d; }) \
|
||||
{ __l: 0x7f800000UL }).__d)
|
||||
|
||||
#else /* not GCC */
|
||||
|
||||
typedef union { unsigned char __c[4]; float __f; } __huge_valf_t;
|
||||
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define __HUGE_VALF_bytes { 0x7f, 0x80, 0, 0 }
|
||||
# endif
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define __HUGE_VALF_bytes { 0, 0, 0x80, 0x7f }
|
||||
# endif
|
||||
|
||||
static __huge_valf_t __huge_valf = { __HUGE_VALF_bytes };
|
||||
# define HUGE_VALF (__huge_valf.__f)
|
||||
|
||||
#endif /* GCC. */
|
||||
29
conts/posix/libposix/include/posix/bits/huge_vall.h
Normal file
29
conts/posix/libposix/include/posix/bits/huge_vall.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* Default `HUGE_VALL' constant.
|
||||
Used by <stdlib.h> and <math.h> functions for overflow.
|
||||
Copyright (C) 1992, 1996, 1997, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _MATH_H
|
||||
# error "Never use <bits/huge_vall.h> directly; include <math.h> instead."
|
||||
#endif
|
||||
|
||||
#if __GNUC_PREREQ(3,3)
|
||||
# define HUGE_VALL (__builtin_huge_vall())
|
||||
#else
|
||||
# define HUGE_VALL ((long double) HUGE_VAL)
|
||||
#endif
|
||||
170
conts/posix/libposix/include/posix/bits/in.h
Normal file
170
conts/posix/libposix/include/posix/bits/in.h
Normal file
@@ -0,0 +1,170 @@
|
||||
/* Copyright (C) 1991-1999, 2000, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* Linux version. */
|
||||
|
||||
#ifndef _NETINET_IN_H
|
||||
# error "Never use <bits/in.h> directly; include <netinet/in.h> instead."
|
||||
#endif
|
||||
|
||||
/* Options for use with `getsockopt' and `setsockopt' at the IP level.
|
||||
The first word in the comment at the right is the data type used;
|
||||
"bool" means a boolean value stored in an `int'. */
|
||||
#define IP_OPTIONS 4 /* ip_opts; IP per-packet options. */
|
||||
#define IP_HDRINCL 3 /* int; Header is included with data. */
|
||||
#define IP_TOS 1 /* int; IP type of service and precedence. */
|
||||
#define IP_TTL 2 /* int; IP time to live. */
|
||||
#define IP_RECVOPTS 6 /* bool; Receive all IP options w/datagram. */
|
||||
/* For BSD compatibility. */
|
||||
#define IP_RECVRETOPTS IP_RETOPTS /* bool; Receive IP options for response. */
|
||||
#define IP_RETOPTS 7 /* ip_opts; Set/get IP per-packet options. */
|
||||
#define IP_MULTICAST_IF 32 /* in_addr; set/get IP multicast i/f */
|
||||
#define IP_MULTICAST_TTL 33 /* u_char; set/get IP multicast ttl */
|
||||
#define IP_MULTICAST_LOOP 34 /* i_char; set/get IP multicast loopback */
|
||||
#define IP_ADD_MEMBERSHIP 35 /* ip_mreq; add an IP group membership */
|
||||
#define IP_DROP_MEMBERSHIP 36 /* ip_mreq; drop an IP group membership */
|
||||
#define IP_UNBLOCK_SOURCE 37 /* ip_mreq_source: unblock data from source */
|
||||
#define IP_BLOCK_SOURCE 38 /* ip_mreq_source: block data from source */
|
||||
#define IP_ADD_SOURCE_MEMBERSHIP 39 /* ip_mreq_source: join source group */
|
||||
#define IP_DROP_SOURCE_MEMBERSHIP 40 /* ip_mreq_source: leave source group */
|
||||
#define IP_MSFILTER 41
|
||||
#define MCAST_JOIN_GROUP 42 /* group_req: join any-source group */
|
||||
#define MCAST_BLOCK_SOURCE 43 /* group_source_req: block from given group */
|
||||
#define MCAST_UNBLOCK_SOURCE 44 /* group_source_req: unblock from given group*/
|
||||
#define MCAST_LEAVE_GROUP 45 /* group_req: leave any-source group */
|
||||
#define MCAST_JOIN_SOURCE_GROUP 46 /* group_source_req: join source-spec gr */
|
||||
#define MCAST_LEAVE_SOURCE_GROUP 47 /* group_source_req: leave source-spec gr*/
|
||||
#define MCAST_MSFILTER 48
|
||||
|
||||
#define MCAST_EXCLUDE 0
|
||||
#define MCAST_INCLUDE 1
|
||||
|
||||
#define IP_ROUTER_ALERT 5 /* bool */
|
||||
#define IP_PKTINFO 8 /* bool */
|
||||
#define IP_PKTOPTIONS 9
|
||||
#define IP_PMTUDISC 10 /* obsolete name? */
|
||||
#define IP_MTU_DISCOVER 10 /* int; see below */
|
||||
#define IP_RECVERR 11 /* bool */
|
||||
#define IP_RECVTTL 12 /* bool */
|
||||
#define IP_RECVTOS 13 /* bool */
|
||||
|
||||
|
||||
/* IP_MTU_DISCOVER arguments. */
|
||||
#define IP_PMTUDISC_DONT 0 /* Never send DF frames. */
|
||||
#define IP_PMTUDISC_WANT 1 /* Use per route hints. */
|
||||
#define IP_PMTUDISC_DO 2 /* Always DF. */
|
||||
|
||||
/* To select the IP level. */
|
||||
#define SOL_IP 0
|
||||
|
||||
#define IP_DEFAULT_MULTICAST_TTL 1
|
||||
#define IP_DEFAULT_MULTICAST_LOOP 1
|
||||
#define IP_MAX_MEMBERSHIPS 20
|
||||
|
||||
/* Structure used to describe IP options for IP_OPTIONS and IP_RETOPTS.
|
||||
The `ip_dst' field is used for the first-hop gateway when using a
|
||||
source route (this gets put into the header proper). */
|
||||
struct ip_opts
|
||||
{
|
||||
struct in_addr ip_dst; /* First hop; zero without source route. */
|
||||
char ip_opts[40]; /* Actually variable in size. */
|
||||
};
|
||||
|
||||
/* Like `struct ip_mreq' but including interface specification by index. */
|
||||
struct ip_mreqn
|
||||
{
|
||||
struct in_addr imr_multiaddr; /* IP multicast address of group */
|
||||
struct in_addr imr_address; /* local IP address of interface */
|
||||
int imr_ifindex; /* Interface index */
|
||||
};
|
||||
|
||||
/* Structure used for IP_PKTINFO. */
|
||||
struct in_pktinfo
|
||||
{
|
||||
int ipi_ifindex; /* Interface index */
|
||||
struct in_addr ipi_spec_dst; /* Routing destination address */
|
||||
struct in_addr ipi_addr; /* Header destination address */
|
||||
};
|
||||
|
||||
/* Options for use with `getsockopt' and `setsockopt' at the IPv6 level.
|
||||
The first word in the comment at the right is the data type used;
|
||||
"bool" means a boolean value stored in an `int'. */
|
||||
#define IPV6_ADDRFORM 1
|
||||
#define IPV6_2292PKTINFO 2
|
||||
#define IPV6_2292HOPOPTS 3
|
||||
#define IPV6_2292DSTOPTS 4
|
||||
#define IPV6_2292RTHDR 5
|
||||
#define IPV6_2292PKTOPTIONS 6
|
||||
#define IPV6_CHECKSUM 7
|
||||
#define IPV6_2292HOPLIMIT 8
|
||||
|
||||
#define SCM_SRCRT IPV6_RXSRCRT
|
||||
|
||||
#define IPV6_NEXTHOP 9
|
||||
#define IPV6_AUTHHDR 10
|
||||
#define IPV6_UNICAST_HOPS 16
|
||||
#define IPV6_MULTICAST_IF 17
|
||||
#define IPV6_MULTICAST_HOPS 18
|
||||
#define IPV6_MULTICAST_LOOP 19
|
||||
#define IPV6_JOIN_GROUP 20
|
||||
#define IPV6_LEAVE_GROUP 21
|
||||
#define IPV6_ROUTER_ALERT 22
|
||||
#define IPV6_MTU_DISCOVER 23
|
||||
#define IPV6_MTU 24
|
||||
#define IPV6_RECVERR 25
|
||||
#define IPV6_V6ONLY 26
|
||||
#define IPV6_JOIN_ANYCAST 27
|
||||
#define IPV6_LEAVE_ANYCAST 28
|
||||
#define IPV6_IPSEC_POLICY 34
|
||||
#define IPV6_XFRM_POLICY 35
|
||||
|
||||
#define IPV6_RECVPKTINFO 49
|
||||
#define IPV6_PKTINFO 50
|
||||
#define IPV6_RECVHOPLIMIT 51
|
||||
#define IPV6_HOPLIMIT 52
|
||||
#define IPV6_RECVHOPOPTS 53
|
||||
#define IPV6_HOPOPTS 54
|
||||
#define IPV6_RTHDRDSTOPTS 55
|
||||
#define IPV6_RECVRTHDR 56
|
||||
#define IPV6_RTHDR 57
|
||||
#define IPV6_RECVDSTOPTS 58
|
||||
#define IPV6_DSTOPTS 59
|
||||
|
||||
#define IPV6_RECVTCLASS 66
|
||||
#define IPV6_TCLASS 67
|
||||
|
||||
/* Obsolete synonyms for the above. */
|
||||
#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
|
||||
#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
|
||||
#define IPV6_RXHOPOPTS IPV6_HOPOPTS
|
||||
#define IPV6_RXDSTOPTS IPV6_DSTOPTS
|
||||
|
||||
/* IPV6_MTU_DISCOVER values. */
|
||||
#define IPV6_PMTUDISC_DONT 0 /* Never send DF frames. */
|
||||
#define IPV6_PMTUDISC_WANT 1 /* Use per route hints. */
|
||||
#define IPV6_PMTUDISC_DO 2 /* Always DF. */
|
||||
|
||||
/* Socket level values for IPv6. */
|
||||
#define SOL_IPV6 41
|
||||
#define SOL_ICMPV6 58
|
||||
|
||||
/* Routing header options for IPv6. */
|
||||
#define IPV6_RTHDR_LOOSE 0 /* Hop doesn't need to be neighbour. */
|
||||
#define IPV6_RTHDR_STRICT 1 /* Hop must be a neighbour. */
|
||||
|
||||
#define IPV6_RTHDR_TYPE_0 0 /* IPv6 Routing header type 0. */
|
||||
30
conts/posix/libposix/include/posix/bits/inf.h
Normal file
30
conts/posix/libposix/include/posix/bits/inf.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* `INFINITY' constant for IEEE 754 machines.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _MATH_H
|
||||
# error "Never use <bits/inf.h> directly; include <math.h> instead."
|
||||
#endif
|
||||
|
||||
/* IEEE positive infinity. */
|
||||
|
||||
#if __GNUC_PREREQ(3,3)
|
||||
# define INFINITY (__builtin_inff())
|
||||
#else
|
||||
# define INFINITY HUGE_VALF
|
||||
#endif
|
||||
28
conts/posix/libposix/include/posix/bits/initspin.h
Normal file
28
conts/posix/libposix/include/posix/bits/initspin.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/* Generic definitions for spinlock initializers.
|
||||
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Initial value of a spinlock. Most platforms should use zero,
|
||||
unless they only implement a "test and clear" operation instead of
|
||||
the usual "test and set". */
|
||||
#define __LT_SPINLOCK_INIT 0
|
||||
|
||||
/* Macros for lock initializers, using the above definition. */
|
||||
#define __LOCK_INITIALIZER { 0, __LT_SPINLOCK_INIT }
|
||||
#define __ALT_LOCK_INITIALIZER { 0, __LT_SPINLOCK_INIT }
|
||||
#define __ATOMIC_INITIALIZER { 0, __LT_SPINLOCK_INIT }
|
||||
78
conts/posix/libposix/include/posix/bits/ioctl-types.h
Normal file
78
conts/posix/libposix/include/posix/bits/ioctl-types.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* Structure types for pre-termios terminal ioctls. Linux version.
|
||||
Copyright (C) 1996, 1997, 1999, 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _SYS_IOCTL_H
|
||||
# error "Never use <bits/ioctl-types.h> directly; include <sys/ioctl.h> instead."
|
||||
#endif
|
||||
|
||||
/* Get definition of constants for use with `ioctl'. */
|
||||
#include <asm/ioctls.h>
|
||||
|
||||
|
||||
struct winsize
|
||||
{
|
||||
unsigned short int ws_row;
|
||||
unsigned short int ws_col;
|
||||
unsigned short int ws_xpixel;
|
||||
unsigned short int ws_ypixel;
|
||||
};
|
||||
|
||||
#define NCC 8
|
||||
struct termio
|
||||
{
|
||||
unsigned short int c_iflag; /* input mode flags */
|
||||
unsigned short int c_oflag; /* output mode flags */
|
||||
unsigned short int c_cflag; /* control mode flags */
|
||||
unsigned short int c_lflag; /* local mode flags */
|
||||
unsigned char c_line; /* line discipline */
|
||||
unsigned char c_cc[NCC]; /* control characters */
|
||||
};
|
||||
|
||||
/* modem lines */
|
||||
#define TIOCM_LE 0x001
|
||||
#define TIOCM_DTR 0x002
|
||||
#define TIOCM_RTS 0x004
|
||||
#define TIOCM_ST 0x008
|
||||
#define TIOCM_SR 0x010
|
||||
#define TIOCM_CTS 0x020
|
||||
#define TIOCM_CAR 0x040
|
||||
#define TIOCM_RNG 0x080
|
||||
#define TIOCM_DSR 0x100
|
||||
#define TIOCM_CD TIOCM_CAR
|
||||
#define TIOCM_RI TIOCM_RNG
|
||||
|
||||
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
|
||||
|
||||
/* line disciplines */
|
||||
#define N_TTY 0
|
||||
#define N_SLIP 1
|
||||
#define N_MOUSE 2
|
||||
#define N_PPP 3
|
||||
#define N_STRIP 4
|
||||
#define N_AX25 5
|
||||
#define N_X25 6 /* X.25 async */
|
||||
#define N_6PACK 7
|
||||
#define N_MASC 8 /* Mobitex module */
|
||||
#define N_R3964 9 /* Simatic R3964 module */
|
||||
#define N_PROFIBUS_FDL 10 /* Profibus */
|
||||
#define N_IRDA 11 /* Linux IR */
|
||||
#define N_SMSBLOCK 12 /* SMS block mode */
|
||||
#define N_HDLC 13 /* synchronous HDLC */
|
||||
#define N_SYNC_PPP 14 /* synchronous PPP */
|
||||
#define N_HCI 15 /* Bluetooth HCI UART */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user